range: add some more functions

Add some more functions that will be used in memory-device context.

range_init(): Init using lower bound and size, check for validity
range_init_nofail(): Init using lower bound and size, validity asserted
range_size(): Extract the size of a range
range_overlaps_range(): Check for overlaps of two ranges
range_contains_range(): Check if one range is contained in the other

Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20181214131043.25071-2-david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
David Hildenbrand 2018-12-14 14:10:42 +01:00 committed by Eduardo Habkost
parent c73e661f2a
commit f3b0b626f6

View File

@ -112,6 +112,68 @@ static inline uint64_t range_upb(Range *range)
return range->upb;
}
/*
* Initialize @range to span the interval [@lob,@lob + @size - 1].
* @size may be 0. If the range would overflow, returns -ERANGE, otherwise
* 0.
*/
static inline int QEMU_WARN_UNUSED_RESULT range_init(Range *range, uint64_t lob,
uint64_t size)
{
if (lob + size < lob) {
return -ERANGE;
}
range->lob = lob;
range->upb = lob + size - 1;
range_invariant(range);
return 0;
}
/*
* Initialize @range to span the interval [@lob,@lob + @size - 1].
* @size may be 0. Range must not overflow.
*/
static inline void range_init_nofail(Range *range, uint64_t lob, uint64_t size)
{
range->lob = lob;
range->upb = lob + size - 1;
range_invariant(range);
}
/*
* Get the size of @range.
*/
static inline uint64_t range_size(const Range *range)
{
return range->upb - range->lob + 1;
}
/*
* Check if @range1 overlaps with @range2. If one of the ranges is empty,
* the result is always "false".
*/
static inline bool range_overlaps_range(const Range *range1,
const Range *range2)
{
if (range_is_empty(range1) || range_is_empty(range2)) {
return false;
}
return !(range2->upb < range1->lob || range1->upb < range2->lob);
}
/*
* Check if @range1 contains @range2. If one of the ranges is empty,
* the result is always "false".
*/
static inline bool range_contains_range(const Range *range1,
const Range *range2)
{
if (range_is_empty(range1) || range_is_empty(range2)) {
return false;
}
return range1->lob <= range2->lob && range1->upb >= range2->upb;
}
/*
* Extend @range to the smallest interval that includes @extend_by, too.
*/