Статьи

Узнавать о растровых изображениях

Несколько недель назад мы с Алистером работали над кодом, используемым для моделирования меток, которые узел прикрепил к нему в базе данных Neo4j.

Это работает так, что куски идентификаторов из 32 узлов представляются в виде 32-битного растрового изображения для каждой метки, где 1 для бита означает, что узел имеет метку, а 0 — что нет.

Например, допустим, у нас есть идентификаторы узлов 0-31, где 0 — старший бит, а 31 — младший бит. Если только узел 0 имеет метку, то это будет представлено как следующее значение:

1
2
java> int bitmap = 1 << 31;
int bitmap = -2147483648

Если мы представим, что 32 бита расположены рядом друг с другом, это будет выглядеть так :

2014-01-12_15-45-16

1
2
java> 0X80000000;
Integer res16 = -2147483648

Следующее, что мы хотим сделать, это выяснить, применена ли к узлу метка или нет. Мы можем сделать это, используя побитовое AND.

Например, чтобы проверить, установлен ли старший бит, мы напишем следующий код:

1
2
java> bitmap & (1 << 31);
Integer res10 = -2147483648

Это установлено так, как мы себе представляем. Теперь давайте проверим несколько битов, которые, как мы знаем, не установлены:

1
2
3
4
5
6
7
8
java> bitmap & (1 << 0);
Integer res11 = 0
 
java> bitmap & (1 << 1);
Integer res12 = 0
 
java> bitmap & (1 << 30);
Integer res13 = 0

Еще одна операция, которую мы можем захотеть сделать, — установить еще один бит в нашем существующем растровом изображении, для которого мы можем использовать побитовое ИЛИ.

Битовое включающее ИЛИ означает, что бит будет установлен, если либо значение имеет установленный бит, либо если оба установлены.

Давайте установим второй старший бит. и визуализировать этот расчет:

2014-01-12_15-45-161

Если мы оценим это, мы ожидаем, что будут установлены два старших бита:

1
2
java> bitmap |= (1 << 30);
Integer res14 = -1073741824

Теперь, если мы представим растровое изображение, мы увидим, что это действительно так:

2014-01-12_17-16-21

1
2
java> 0XC0000000;
Integer res15 = -1073741824

Следующая операция, которую мы хотим сделать, это сбросить бит, который мы уже установили, для которого мы можем использовать побитовое исключающее ИЛИ.

Исключительное ИЛИ означает, что бит останется установленным, только если в расчете есть комбинация (0 и 1) или (1 и 0). Если есть два 1 или 2, то это будет не установлено.

Давайте сбросим 2-й старший бит, чтобы у нас остался только верхний бит.

Если мы представим, что у нас есть следующий расчет:

2014-01-12_17-33-21

И если мы оценим это, мы вернемся к нашему исходному растровому изображению:

1
2
java> bitmap ^= (1 << 30);
Integer res2 = -2147483648

Я использовал Java REPL для оценки примеров кода в этой статье, и в этой статье очень четко объясняются операторы битового сдвига .

Версия растрового изображения Neo4j, описанная в этом посте, находится в классе BitmapFormat на github.

Ссылка: узнав о растровых изображениях от нашего партнера по JCG Марка Нидхэма в блоге Марка Нидхэма .