几周前,我和Alistair一起研究了用于对Neo4j数据库中节点已附加到其上的标签进行建模的代码。
这种工作方式是将32个节点ID的块表示为每个标签的32位位图 ,其中位1表示节点具有标签,而0表示没有标签。
例如,假设我们有节点ID 0-31,其中0是最高位,而31是最低位。 如果只有节点0具有标签,则将其表示为以下值:
java> int bitmap = 1 << 31;
int bitmap = -2147483648
如果我们想象32位彼此相邻放置,它将看起来像这样 :
java> 0X80000000;
Integer res16 = -2147483648
我们要做的下一件事是确定节点是否应用了标签。 我们可以通过按位与来实现。
例如,要检查是否设置了最高位,我们将编写以下代码:
java> bitmap & (1 << 31);
Integer res10 = -2147483648
正如我们所想象的那样。 现在让我们检查一下一些我们尚未设置的位:
java> bitmap & (1 << 0);
Integer res11 = 0java> bitmap & (1 << 1);
Integer res12 = 0java> bitmap & (1 << 30);
Integer res13 = 0
我们可能要执行的另一项操作是在现有位图上设置另一位,我们可以对其使用按位“或”运算。
按位“或”或“或”表示如果一个值设置了该位或两个值都设置了,则将置位。
让我们设置第二高的位。 并可视化该计算:
如果我们评估,我们期望设置两个最高位:
java> bitmap |= (1 << 30);
Integer res14 = -1073741824
现在,如果我们可视化位图,我们将看到确实如此:
java> 0XC0000000;
Integer res15 = -1073741824
我们要执行的下一个操作是取消设置已经设置的位,可以使用按位异或。
异或表示只有在计算中包含(0和1)或(1和0)的组合时,该位才保持设置。 如果有两个1或2 0,那么它将被取消设置。
让我们取消设置第二高的位,以便仅设置最高位。
如果我们直观地看到,我们将进行以下计算:
并且如果我们评估返回到原始位图:
java> bitmap ^= (1 << 30);
Integer res2 = -2147483648
我使用Java REPL评估了本文中的代码示例,并且本文非常清楚地解释了移位运算符 。
这篇文章中描述的Neo4j版本的位图位于github上的BitmapFormat类中。
翻译自: https://www.javacodegeeks.com/2014/01/learning-about-bitmaps.html