From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36017) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WxIal-0003Ks-3h for qemu-devel@nongnu.org; Wed, 18 Jun 2014 12:20:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WxIaf-0008Ld-PO for qemu-devel@nongnu.org; Wed, 18 Jun 2014 12:20:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]:8976) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WxIaf-0008IW-GA for qemu-devel@nongnu.org; Wed, 18 Jun 2014 12:20:01 -0400 Date: Wed, 18 Jun 2014 19:20:22 +0300 From: "Michael S. Tsirkin" Message-ID: <1403108034-32054-74-git-send-email-mst@redhat.com> References: <1403108034-32054-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1403108034-32054-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PULL v2 073/106] Introduce signed range. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Anthony Liguori , Hu Tao From: Hu Tao Signed-off-by: Hu Tao Acked-by: Michael S. Tsirkin Tested-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin MST: split up patch --- include/qemu/range.h | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/include/qemu/range.h b/include/qemu/range.h index aae9720..cfa021f 100644 --- a/include/qemu/range.h +++ b/include/qemu/range.h @@ -3,6 +3,7 @@ #include #include +#include "qemu/queue.h" /* * Operations on 64 bit address ranges. @@ -60,4 +61,75 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1, return !(last2 < first1 || last1 < first2); } +/* 0,1 can merge with 1,2 but don't overlap */ +static inline bool ranges_can_merge(Range *range1, Range *range2) +{ + return !(range1->end < range2->begin || range2->end < range1->begin); +} + +static inline int range_merge(Range *range1, Range *range2) +{ + if (ranges_can_merge(range1, range2)) { + if (range1->end < range2->end) { + range1->end = range2->end; + } + if (range1->begin > range2->begin) { + range1->begin = range2->begin; + } + return 0; + } + + return -1; +} + +static inline GList *g_list_insert_sorted_merged(GList *list, + gpointer data, + GCompareFunc func) +{ + GList *l, *next = NULL; + Range *r, *nextr; + + if (!list) { + list = g_list_insert_sorted(list, data, func); + return list; + } + + nextr = data; + l = list; + while (l && l != next && nextr) { + r = l->data; + if (ranges_can_merge(r, nextr)) { + range_merge(r, nextr); + l = g_list_remove_link(l, next); + next = g_list_next(l); + if (next) { + nextr = next->data; + } else { + nextr = NULL; + } + } else { + l = g_list_next(l); + } + } + + if (!l) { + list = g_list_insert_sorted(list, data, func); + } + + return list; +} + +static inline gint range_compare(gconstpointer a, gconstpointer b) +{ + Range *ra = (Range *)a, *rb = (Range *)b; + if (ra->begin == rb->begin && ra->end == rb->end) { + return 0; + } else if (range_get_last(ra->begin, ra->end) < + range_get_last(rb->begin, rb->end)) { + return -1; + } else { + return 1; + } +} + #endif -- MST