bitmap: use external iterator
authorTom Gundersen <teg@jklm.no>
Thu, 16 Jul 2015 12:06:11 +0000 (14:06 +0200)
committerTom Gundersen <teg@jklm.no>
Thu, 16 Jul 2015 12:11:12 +0000 (14:11 +0200)
Reuse the Iterator object from hashmap.h and expose a similar API.

This allows us to do

{
    Iterator i;
    unsigned n;

    BITMAP_FOREACH(n, b, i) {
        Iterator j;
        unsigned m;

        BITMAP_FOREACH(m, b, j) {
            ...
        }
    }
}

without getting confused. Requested by David.

src/basic/bitmap.c
src/basic/bitmap.h
src/resolve/resolved-dns-packet.c
src/resolve/resolved-dns-rr.c
src/test/test-bitmap.c

index d865e2f..d559be1 100644 (file)
@@ -27,7 +27,6 @@ struct Bitmap {
         long long unsigned *bitmaps;
         size_t n_bitmaps;
         size_t bitmaps_allocated;
-        unsigned next_entry;
 };
 
 /* Bitmaps are only meant to store relatively small numbers
@@ -149,22 +148,15 @@ void bitmap_clear(Bitmap *b) {
                 b->bitmaps[i] = 0;
 }
 
-void bitmap_rewind(Bitmap *b) {
-        if (!b)
-                return;
-
-        b->next_entry = 0;
-}
-
-bool bitmap_next(Bitmap *b, unsigned *n) {
+bool bitmap_iterate(Bitmap *b, Iterator *i, unsigned *n) {
         long long bitmask;
         unsigned offset, rem;
 
-        if (!b && b->next_entry == BITMAP_END)
+        if (!b && i->idx == BITMAP_END)
                 return false;
 
-        offset = BITMAP_NUM_TO_OFFSET(b->next_entry);
-        rem = BITMAP_NUM_TO_REM(b->next_entry);
+        offset = BITMAP_NUM_TO_OFFSET(i->idx);
+        rem = BITMAP_NUM_TO_REM(i->idx);
         bitmask = 1 << rem;
 
         for (; offset < b->n_bitmaps; offset ++) {
@@ -172,7 +164,7 @@ bool bitmap_next(Bitmap *b, unsigned *n) {
                         for (; bitmask; bitmask <<= 1, rem ++) {
                                 if (b->bitmaps[offset] & bitmask) {
                                         *n = BITMAP_OFFSET_TO_NUM(offset, rem);
-                                        b->next_entry = *n + 1;
+                                        i->idx = *n + 1;
 
                                         return true;
                                 }
@@ -183,7 +175,7 @@ bool bitmap_next(Bitmap *b, unsigned *n) {
                 bitmask = 1;
         }
 
-        b->next_entry = BITMAP_END;
+        i->idx = BITMAP_END;
 
         return false;
 }
index 92bee51..2874bc9 100644 (file)
@@ -22,6 +22,7 @@
 ***/
 
 #include "macro.h"
+#include "hashmap.h"
 
 typedef struct Bitmap Bitmap;
 
@@ -37,13 +38,12 @@ bool bitmap_isset(Bitmap *b, unsigned n);
 bool bitmap_isclear(Bitmap *b);
 void bitmap_clear(Bitmap *b);
 
-void bitmap_rewind(Bitmap *b);
-bool bitmap_next(Bitmap *b, unsigned *n);
+bool bitmap_iterate(Bitmap *b, Iterator *i, unsigned *n);
 
 bool bitmap_equal(Bitmap *a, Bitmap *b);
 
-#define BITMAP_FOREACH(n, b) \
-        for (bitmap_rewind(b); bitmap_next((b), &(n)); )
+#define BITMAP_FOREACH(n, b, i) \
+        for ((i).idx = 0; bitmap_iterate((b), &(i), (unsigned*)&(n)); )
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(Bitmap*, bitmap_free);
 
index e44d392..b1cde4a 100644 (file)
@@ -536,6 +536,7 @@ fail:
 }
 
 static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
+        Iterator i;
         uint8_t window = 0;
         uint8_t len = 0;
         uint8_t bitmaps[32] = {};
@@ -548,7 +549,7 @@ static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
 
         saved_size = p->size;
 
-        BITMAP_FOREACH(n, types) {
+        BITMAP_FOREACH(n, types, i) {
                 uint8_t entry;
 
                 assert(n <= 0xffff);
index e9907ea..859b3f7 100644 (file)
@@ -527,10 +527,11 @@ static int format_timestamp_dns(char *buf, size_t l, time_t sec) {
 static char *format_types(Bitmap *types) {
         _cleanup_strv_free_ char **strv = NULL;
         _cleanup_free_ char *str = NULL;
+        Iterator i;
         unsigned type;
         int r;
 
-        BITMAP_FOREACH(type, types) {
+        BITMAP_FOREACH(type, types, i) {
                 if (dns_type_to_string(type)) {
                         r = strv_extend(&strv, strdup(dns_type_to_string(type)));
                         if (r < 0)
index 304888b..77db784 100644 (file)
@@ -21,6 +21,7 @@
 
 int main(int argc, const char *argv[]) {
         _cleanup_bitmap_free_ Bitmap *b = NULL;
+        Iterator it;
         unsigned n = (unsigned) -1, i = 0;
 
         b = bitmap_new();
@@ -61,7 +62,7 @@ int main(int argc, const char *argv[]) {
         assert_se(bitmap_set(b, 1) == 0);
         assert_se(bitmap_set(b, 256) == 0);
 
-        BITMAP_FOREACH(n, b) {
+        BITMAP_FOREACH(n, b, it) {
                 assert_se(n == i);
                 if (i == 0)
                         i = 1;
@@ -75,7 +76,7 @@ int main(int argc, const char *argv[]) {
 
         i = 0;
 
-        BITMAP_FOREACH(n, b) {
+        BITMAP_FOREACH(n, b, it) {
                 assert_se(n == i);
                 if (i == 0)
                         i = 1;