I'm in the process of implementing a counting Bloom filter. This data structure is defined as a bit-array and a "width" parameter, W.
The bit array stores unsigned integers, whose size is determined by W, into an array of uint64
s. Thus, it is expected that the integers' size will not be multiple of 8. For instance, W=4 (max value = 15) is a popular choice. Moreover, it is expected that the integers'size will not necessarily respect byte-boundaries. W=3, is also an acceptable value. The maximum size for W, however is 8.
Thus, a bit array with W=4 should be interpreted as such:
+----+----+----+----+----+----+----+----+----+----+----+----+----+----
| uint4 | uint4 | uint4 | ...
+----+----+----+----+----+----+----+----+----+----+----+----+----+----
Similarly, a bit array with W=2 should be interpreted as:
+----+----+----+----+----+----+----+----+----+----+----+----+----+----
| uint2 | uint2 | uint2 | uint2 | uint2 | uint2 | ...
+----+----+----+----+----+----+----+----+----+----+----+----+----+----
This data structure needs to support three distinct operations:
- Read the i-th uintW
- Increment the i-th uintW
- Decrement the i-th uintW
Decrementing a uintW below 0 is undefined behavior. Incrementing a uintW above its maximum value is also undefined behavior.
Questions
- Which algorithm can implement these operations on a bit array backed by an array of
uint64
s? - Is there a allocation-free and/or branch-free solution? The idea here is to have the most performant solution possible, since Bloom filters have a nasty habit of being called billions of times in tight loops.