]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
r13926@catbus: nickm | 2007-07-26 17:21:06 -0400
authorNick Mathewson <nickm@torproject.org>
Thu, 26 Jul 2007 21:26:53 +0000 (21:26 +0000)
committerNick Mathewson <nickm@torproject.org>
Thu, 26 Jul 2007 21:26:53 +0000 (21:26 +0000)
 Add a bit-array type with reasonably fast inline functions.

svn:r10938

src/common/container.h
src/or/test.c

index db5967208a05c1e5236a92ab8761da0f9093059f..a342b266708384c16985e8a16ee27d36f0386c0b 100644 (file)
@@ -267,5 +267,49 @@ void* strmap_remove_lc(strmap_t *map, const char *key);
     return digestmap_iter_done((digestmap_iter_t*)iter);                \
   }
 
+#if SIZEOF_INT == 4
+#define BITARRAY_SHIFT 5
+#define BITARRAY_MASK 31
+#elif SIZEOF_INT == 8
+#define BITARRAY_SHIFT 6
+#define BITARRAY_MASK 63
+#else
+#error "int is neither 4 nor 8 bites. I can't deal with that."
+#endif
+
+typedef unsigned int bitarray_t;
+/** Create a new bit array that can hold <b>n_bits</b> bits. */
+static INLINE bitarray_t *
+bitarray_init_zero(int n_bits)
+{
+  size_t sz = (n_bits+BITARRAY_MASK) & BITARRAY_MASK;
+  return tor_malloc_zero(sz*sizeof(unsigned int));
+}
+/** Free the bit array <b>ba</b>. */
+static INLINE void
+bitarray_free(bitarray_t *ba)
+{
+  tor_free(ba);
+}
+/** Set the <b>bit</b>th bit in <b>b</b> to 1. */
+static INLINE void
+bitarray_set(bitarray_t *b, int bit)
+{
+  b[bit >> BITARRAY_SHIFT] |= (1u << (bit & BITARRAY_MASK));
+}
+/** Set the <b>bit</b>th bit in <b>b</b> to 0. */
+static INLINE void
+bitarray_clear(bitarray_t *b, int bit)
+{
+  b[bit >> BITARRAY_SHIFT] &= ~ (1u << (bit & BITARRAY_MASK));
+}
+/** Return true iff <b>bit</b>th bit in <b>b</b> is nonzero.  NOTE: does
+ * not necessarily return 1 on true. */
+static INLINE unsigned int
+bitarray_is_set(bitarray_t *b, int bit)
+{
+  return b[bit >> BITARRAY_SHIFT] & (1u << (bit & BITARRAY_MASK));
+}
+
 #endif
 
index 2776fcbfc19385dd1e7ffee7c5ffab747535b067..147023a8de1deeec4a739df989cc9c7e285e151b 100644 (file)
@@ -1544,6 +1544,43 @@ test_smartlist(void)
   smartlist_free(sl);
 }
 
+static void
+test_bitarray(void)
+{
+  bitarray_t *ba;
+  int i, j, ok=1;
+
+  ba = bitarray_init_zero(1);
+  test_assert(! bitarray_is_set(ba, 0));
+  bitarray_set(ba, 0);
+  test_assert(bitarray_is_set(ba, 0));
+  bitarray_clear(ba, 0);
+  test_assert(! bitarray_is_set(ba, 0));
+  bitarray_free(ba);
+
+  ba = bitarray_init_zero(1023);
+  for (i = 1; i < 64; ) {
+    for (j = 0; j < 1023; ++j) {
+      if (j % i)
+        bitarray_set(ba, j);
+      else
+        bitarray_clear(ba, j);
+    }
+    for (j = 0; j < 1023; ++j) {
+      if (!bool_eq(bitarray_is_set(ba, j), j%i))
+        ok = 0;
+    }
+    test_assert(ok);
+    if (i < 7)
+      ++i;
+    else if (i == 28)
+      i = 32;
+    else
+      i += 7;
+  }
+  bitarray_free(ba);
+}
+
 /* stop threads running at once. */
 static tor_mutex_t *_thread_test_mutex = NULL;
 /* make sure that threads have to run at the same time. */
@@ -2990,6 +3027,8 @@ main(int c, char**v)
   test_util();
   puts("\n--smartlist");
   test_smartlist();
+  puts("\n--bitarray");
+  test_bitarray();
   puts("\n--mempool");
   test_mempool();
   puts("\n--strmap");