A compressed bitmap class in C++.
The class EWAHBoolArray is a compressed bitset data structure.
It supports several word sizes by a template parameter (16-bit, 32-bit, 64-bit).
You should expect the 64-bit word-size to provide better performance, but
higher memory usage, while a 32-bit word-size might compress a bit better,
at the expense of some performance.
The library also provides a basic BoolArray class which can serve as a traditional
bitmap.
EWAH is used to accelerate the distributed version control system Git.
The Java counterpart of this library (JavaEWAH) is part of Apache Hive and its derivatives (e.g., Apache Spark) and Eclipse JGit. It has been used in production systems for many years. It is part of major Linux distributions.
This library is used by Hustle – A column oriented, embarrassingly distributed relational event database, by the The yt Project and by the fuzzing tool VUzzer.
Sets are a fundamental abstraction in
software. They can be implemented in various
ways, as hash sets, as trees, and so forth.
In databases and search engines, sets are often an integral
part of indexes. For example, we may need to maintain a set
of all documents or rows (represented by numerical identifier)
that satisfy some property. Besides adding or removing
elements from the set, we need fast functions
to compute the intersection, the union, the difference between sets, and so on.
To implement a set
of integers, a particularly appealing strategy is the
bitmap (also called bitset or bit vector). Using n bits,
we can represent any set made of the integers from the range
[0,n): it suffices to set the ith bit is set to one if integer i is present in the set.
Commodity processors use words of W=32 or W=64 bits. By combining many such words, we can
support large values of n. Intersections, unions and differences can then be implemented
as bitwise AND, OR and ANDNOT operations.
More complicated set functions can also be implemented as bitwise operations.
When the bitset approach is applicable, it can be orders of
magnitude faster than other possible implementation of a set (e.g., as a hash set)
while using several times less memory.
An uncompressed BitSet can use a lot of memory. For example, if you take a BitSet
and set the bit at position 1,000,000 to true and you have just over 100kB. That’s over 100kB
to store the position of one bit. This is wasteful even if you do not care about memory:
suppose that you need to compute the intersection between this BitSet and another one
that has a bit at position 1,000,001 to true, then you need to go through all these zeroes,
whether you like it or not. That can become very wasteful.
This being said, there are definitively cases where attempting to use compressed bitmaps is wasteful.
For example, if you have a small universe size. E.g., your bitmaps represent sets of integers
from [0,n) where n is small (e.g., n=64 or n=128). If you can use an BitSet and
it does not blow up your memory usage, then compressed bitmaps are probably not useful
to you. In fact, if you do not need compression, then a BitSet offers remarkable speed.
One of the downsides of a compressed bitmap like those provided by EWAHBoolArray is slower random access:
checking whether a bit is set to true in a compressed bitmap takes longer.
EWAH is part of a larger family of compressed bitmaps that are run-length-encoded
bitmaps. They identify long runs of 1s or 0s and they represent them with a marker word.
If you have a local mix of 1s and 0, you use an uncompressed word.
There are many formats in this family beside EWAH:
There are other alternatives however. For example, the Roaring
format is not a run-length-encoded hybrid. It provides faster random access
than even EWAH.
Please see our main header file:
https://github.com/lemire/EWAHBoolArray/blob/master/include/ewah/ewah.h
You may also consult our Web documentation.
The EWAHBoolArray project is under a dual license (Apache/MIT).
Users of the library may choose one or the other license.
None. (Will work under MacOS, Windows or Linux.)
Compilers tested: clang++, g++, Intel compiler, Microsoft Visual Studio
It works on x64 processors as well as on 32-bit ARM processors.
Versions 0.5 and above assume that the compiler supports the C++11 standard.
cmake -B build
cmake --build build
cd build
ctest --test-dir build
To build with at least Visual Studio 2017 directly in the IDE:
Visual C++ tools for CMake
optional component when installing the C++ Development Workload within Visual Studio.File > Open > Folder...
to open the CRoaring folder.CMakeLists.txt
in the parent directory within Solution Explorer
and select Build
to build the project.Select Startup Item...
menu and choose one of the tests. Run the test by pressing the button to the left of the dropdown. #include "ewah.h"
using namespace ewah;
typedef EWAHBoolArray<uint32_t> bitmap;
bitmap bitset1 =
bitmap::bitmapOf(9, 1, 2, 1000, 1001, 1002, 1003, 1007, 1009, 100000);
std::cout << "first bitset : " << bitset1 << std::endl;
bitmap bitset2 = bitmap::bitmapOf(5, 1, 3, 1000, 1007, 100000);
std::cout << "second bitset : " << bitset2 << std::endl;
bitmap bitset3 = bitmap::bitmapOf(3, 10, 11, 12);
std::cout << "third bitset : " << bitset3 << std::endl;
bitmap orbitset = bitset1 | bitset2;
bitmap andbitset = bitset1 & bitset2;
bitmap xorbitset = bitset1 ^ bitset2;
bitmap andnotbitset = bitset1 - bitset2;
Please see examples/example.cpp
.
For an example with tabular data, please see example2.cpp
.
Please see
Dimitrios Vasilas wrote a wrapper for JavaScript.
You can install it by typing:
npm install -g node-gyp
npm install node-bitmap-ewah
Josh Ferguson wrote a wrapper for Ruby.
The implementation is packaged and installable as a ruby gem.
You can install it by typing:
gem install ewah-bitset
We provide read and write functions.
We do not correct for the endianess. If you use both little endian and big endian machines, you should
be careful. Thankfully, big endian hardware is vanishingly rare.
When loading data from an untrusted source, we recommend that you use hashes to validate the content.