|
| 1 | +# Roaring |
| 2 | + |
| 3 | +## Введение |
| 4 | + |
| 5 | +Битовые множства, также называемые битовыми картами (bitmaps), обычно используются в качестве быстрых структур данных. К сожалению, они могут использовать слишком много памяти. Для того, чтобы уменьшить занимаемую используется сжатие. |
| 6 | + |
| 7 | +Roaring bitmaps — это сжатые битовые карты, которые, как правило, превосходят обычные алгоритмы сжатия битовых карт, такие как WAH, EWAH или Concise. В некоторых случаях Roaring bitmaps могут быть в сотни раз быстрее, и они часто предлагают значительно лучшее сжатие. Они могут быть даже быстрее, чем несжатые битовые карты. |
| 8 | + |
| 9 | +## Реализация |
| 10 | + |
| 11 | +Работать с Roaring bitmap в YDB можно с помощью набора пользовательских функций UDF в модуле `Roaring`. Они предоставляют возможность работать с 32-битными Roaring bitmap. Для этого данные должны быть сериализованы в формате для 32-битных битовых масок, описанном в [спецификации](https://github.com/RoaringBitmap/RoaringFormatSpec?tab=readme-ov-file#standard-32-bit-roaring-bitmap). Это можно сделать с помощью функции, доступной в библиотеке Roaring bitmap. Такие библиотеки есть для многих языков, например, для [Go](https://github.com/RoaringBitmap/roaring). |
| 12 | + |
| 13 | +Сериализованную битовую маску приложение может сохранить в колонке с типом `String`. |
| 14 | + |
| 15 | +Для работы с Roaring bitmap данные из строкового типа необходимо десериализовать в тип [Resource<roaring_bitmap>](../../types/special.md). Для сохранения нужно проделать обратную операцию. После этого приложение сможет прочитать обновлённую битовую маску из YDB, и десериализовать её уже на своей стороне. |
| 16 | + |
| 17 | +## Доступные методы |
| 18 | + |
| 19 | +```yql |
| 20 | +Roaring::Deserialize(String{Flags:AutoMap})->Resource<roaring_bitmap> |
| 21 | +Roaring::FromUint32List(List<Uint32>{Flags:AutoMap})->Resource<roaring_bitmap> |
| 22 | +Roaring::Serialize(Resource<roaring_bitmap>{Flags:AutoMap})->String |
| 23 | +Roaring::Uint32List(Resource<roaring_bitmap>{Flags:AutoMap})->List<Uint32> |
| 24 | +
|
| 25 | +Roaring::Cardinality(Resource<roaring_bitmap>{Flags:AutoMap})->Uint32 |
| 26 | +
|
| 27 | +Roaring::Or(Resource<roaring_bitmap>{Flags:AutoMap}, Resource<roaring_bitmap>{Flags:AutoMap})->Resource<roaring_bitmap> |
| 28 | +Roaring::OrWithBinary(Resource<roaring_bitmap>{Flags:AutoMap}, String{Flags:AutoMap})->Resource<roaring_bitmap> |
| 29 | +
|
| 30 | +Roaring::And(Resource<roaring_bitmap>{Flags:AutoMap}, Resource<roaring_bitmap>{Flags:AutoMap})->Resource<roaring_bitmap> |
| 31 | +Roaring::AndWithBinary(Resource<roaring_bitmap>{Flags:AutoMap}, String{Flags:AutoMap})->Resource<roaring_bitmap> |
| 32 | +
|
| 33 | +Roaring::AndNot(Resource<roaring_bitmap>{Flags:AutoMap}, Resource<roaring_bitmap>{Flags:AutoMap})->Resource<roaring_bitmap> |
| 34 | +Roaring::AndNotWithBinary(Resource<roaring_bitmap>{Flags:AutoMap}, String{Flags:AutoMap})->Resource<roaring_bitmap> |
| 35 | +
|
| 36 | +Roaring::RunOptimize(Resource<roaring_bitmap>{Flags:AutoMap})->Resource<roaring_bitmap> |
| 37 | +``` |
| 38 | + |
| 39 | +## Сериализация и десериализация |
| 40 | + |
| 41 | +Для создания `Resource<roaring_bitmap>` доступны две функции `Deserialize` и `FromUint32List`. Вторая функция позволяет создавать Roaring bitmap из списков беззнаковых целых чисел, то есть без необходимости использовть библиотечный код Roaring bitmaps для создания бинарного представления. |
| 42 | + |
| 43 | +YDB не сохраняет данные с типом `Resource`, поэтому созданную битовую маску необходимо превратить в бинарное представление с помощью метода `Serialize`. |
| 44 | + |
| 45 | +Чтобы использовать результирующую битовую маску, например, в условии `WHERE` предусмотрен метод `Uint32List`, который возвращает список беззнаковых целых чисел из `Resource<roaring_bitmap>`. |
| 46 | + |
| 47 | + |
| 48 | +## Битовые операции |
| 49 | + |
| 50 | +В настоящий момент поддержаны три модфицирующих бинарных операции с битовыми масками: |
| 51 | +- `Or` |
| 52 | +- `And` |
| 53 | +- `AndNot` |
| 54 | + |
| 55 | +То, что операции являются модифицирующими означает, что они изменяют `Resource<roaring_bitmap>`, переданный в первом аргументе. У каждой из этих операций есть версия с суффиксом `WithBinary`, которая позволяет работать с бинарным представлением, не прибегая к его десериализации в тип `Resource<roaring_bitmap>`. Реализация этих методов всё равно вынуждена выполнить десериализацию для выполнения операции, но она не создаёт промежуточный `Resource` для экономии ресурсов. |
| 56 | + |
| 57 | +## Прочие операции |
| 58 | + |
| 59 | +Для получения кардинальности (количества бит, установленных в 1) предусмотрена функция `Cardinality`. |
| 60 | + |
| 61 | +После построения или модификации битовой маски её можно оптимизировать с помощью метода `RunOptimize`. Это связано с тем, что внутренний формат Roaring bitmap может использовать контейнеры с лучшим представлением для разных последовательностей бит. |
| 62 | + |
| 63 | +## Примеры |
| 64 | + |
| 65 | +```yql |
| 66 | +--!syntax_v1 |
| 67 | +$b = Roaring::FromUint32List(AsList(42)); |
| 68 | +$b = Roaring::Or($b, Roaring::FromUint32List(AsList(56))); |
| 69 | +
|
| 70 | +
|
| 71 | +SELECT Roaring::Uint32List($b) AS `Or`; -- [42, 56] |
| 72 | +``` |
| 73 | + |
| 74 | + |
| 75 | +```yql |
| 76 | +$b1 = Roaring::FromUint32List(AsList(10, 567, 42)); |
| 77 | +$b2 = Roaring::FromUint32List(AsList(42)); |
| 78 | +
|
| 79 | +$b2ser = Roaring::Serialize($b2); -- результат можно сохранить в колонку с типом String |
| 80 | +
|
| 81 | +SELECT Roaring::Cardinality(Roaring::AndWithBinary($b1, $b2ser)) AS Cardinality; -- 1 |
| 82 | +
|
| 83 | +SELECT Roaring::Uint32List(Roaring::And($b1, $b2)) AS `And`; -- [42] |
| 84 | +SELECT Roaring::Uint32List(Roaring::AndWithBinary($b1, $b2ser)) AS AndWithBinary; -- [42] |
| 85 | +``` |
| 86 | + |
| 87 | +```yql |
| 88 | +--!syntax_v1 |
| 89 | +
|
| 90 | +$b1 = Roaring::FromUint32List(AsList(10, 567, 42)); |
| 91 | +$b2 = Roaring::FromUint32List(AsList(42)); |
| 92 | +
|
| 93 | +$b2ser = Roaring::Serialize($b2); -- результат можно сохранить в колонку с типом String |
| 94 | +
|
| 95 | +SELECT Roaring::Cardinality(Roaring::AndNotWithBinary($b1, $b2ser)) AS Cardinality; -- 2 |
| 96 | +
|
| 97 | +SELECT Roaring::Uint32List(Roaring::AndNot($b1, $b2)) AS AndNot; -- [10,567] |
| 98 | +SELECT Roaring::Uint32List(Roaring::AndNotWithBinary($b1, $b2ser)) AS AndNotWithBinary; -- [10,567] |
| 99 | +``` |
0 commit comments