X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Futil.c;h=4e8b011639958587c173161a974d25739d8ea847;hb=9f0e2f7de7d919d6a83944f0e7fdbd07cb6c4189;hp=be378ef84409cd23bec31a6fff7e3caa1fa51f7a;hpb=772058dfc33fbe4857864b4bdb8ba947eca19303;p=bluesky.git diff --git a/bluesky/util.c b/bluesky/util.c index be378ef..4e8b011 100644 --- a/bluesky/util.c +++ b/bluesky/util.c @@ -229,30 +229,66 @@ BlueSkyInode *bluesky_list_tail(GList *head) * should be extended later to track properly. */ struct BlueSkyRangeset { - GHashTable *hashtable; + GSequence *seq; }; +static gint compare64(gconstpointer a, gconstpointer b, gpointer user_data) +{ + uint64_t x = *(uint64_t *)a; + uint64_t y = *(uint64_t *)b; + + if (x < y) + return -1; + else if (x > y) + return 1; + else + return 0; +} + BlueSkyRangeset *bluesky_rangeset_new() { BlueSkyRangeset *rangeset = g_new(BlueSkyRangeset, 1); - rangeset->hashtable = g_hash_table_new(g_direct_hash, g_direct_equal); + rangeset->seq = g_sequence_new(g_free); return rangeset; } void bluesky_rangeset_free(BlueSkyRangeset *rangeset) { - g_hash_table_unref(rangeset->hashtable); + g_sequence_free(rangeset->seq); g_free(rangeset); } gboolean bluesky_rangeset_insert(BlueSkyRangeset *rangeset, - int start, int length, gpointer data) + uint64_t start, uint64_t length, + gpointer data) { - g_hash_table_insert(rangeset->hashtable, GINT_TO_POINTER(start), data); + GSequenceIter *i; + i = g_sequence_search(rangeset->seq, &start, compare64, NULL); + i = g_sequence_iter_prev(i); + + /* TODO: Checks that no other item overlaps. */ + + BlueSkyRangesetItem *item = g_new(BlueSkyRangesetItem, 1); + item->start = start; + item->length = length; + item->data = data; + g_sequence_insert_sorted(rangeset->seq, item, compare64, NULL); + return TRUE; } -gpointer bluesky_rangeset_lookup(BlueSkyRangeset *rangeset, int start) +const BlueSkyRangesetItem *bluesky_rangeset_lookup(BlueSkyRangeset *rangeset, + uint64_t offset) { - return g_hash_table_lookup(rangeset->hashtable, GINT_TO_POINTER(start)); + GSequenceIter *i; + i = g_sequence_search(rangeset->seq, &offset, compare64, NULL); + i = g_sequence_iter_prev(i); + if (g_sequence_iter_is_end(i)) + return NULL; + + BlueSkyRangesetItem *item = (BlueSkyRangesetItem *)g_sequence_get(i); + if (offset >= item->start && offset < item->start + item->length) + return item; + else + return NULL; }