BITFIELD
BITFIELD
BITFIELD key [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>] <SET encoding offset value | INCRBY encoding offset increment> [GET encoding offset | [OVERFLOW <WRAP | SAT | FAIL>] <SET encoding offset value | INCRBY encoding offset increment> ...]]
- Доступно с версии:
- 3.2.0
- Сложность по времени:
- O(1) для каждого указанного подкоманды
- Категории ACL:
-
@write,@bitmap,@slow,
Команда обрабатывает строку Redis как массив битов и способна обращаться к определённым целочисленным полям различной разрядности и произвольным (необязательно выровненным) смещениям. Практически, с помощью этой команды можно, например, установить целое число со знаком 5 бит со смещением 1234 до определённого значения, получить целое число без знака 31 бит со смещением 4567. Аналогично, команда обрабатывает приращения и уменьшения указанных целых чисел, обеспечивая гарантированное и хорошо определённое поведение переполнения и недополнения, которое пользователь может настроить.
BITFIELD может работать с несколькими битами в одном вызове команды. Она принимает список операций для выполнения и возвращает массив ответов, где каждый массив соответствует соответствующей операции в списке аргументов.
Например, следующая команда увеличивает целое число со знаком 5 бит со смещением 100 и получает значение целого числа без знака 4 бит со смещением 0:
> BITFIELD mykey INCRBY i5 100 1 GET u4 0 1) (integer) 1 2) (integer) 0
Обратите внимание, что:
- Обращение к
GETбитам за пределами текущей длины строки (включая случай, когда ключ вообще не существует), приводит к выполнению операции как если бы отсутствующая часть состояла из битов, установленных в 0. - Обращение к
SETилиINCRBYбитам за пределами текущей длины строки увеличит строку, дополнив нулями, по мере необходимости, до минимальной длины, необходимой для самого дальнего из затронутых битов.
Поддерживаемые подкоманды и кодирование целых чисел
Ниже приведён список поддерживаемых команд.
-
GET
<encoding><offset>-- Возвращает указанное поле бита. -
SET
<encoding><offset><value>-- Устанавливает указанное поле бита и возвращает его старое значение. -
INCRBY
<encoding><offset><increment>-- Увеличивает или уменьшает (если задано отрицательное увеличение) указанное поле бита и возвращает новое значение.
Существует ещё одна подкоманда, которая только изменяет поведение последующих вызовов подкоманд INCRBY и SET путём установки поведения переполнения:
-
OVERFLOW
[WRAP|SAT|FAIL]
Где ожидается кодирование целого числа, оно может быть составлено путём добавления префикса i для целых чисел со знаком и u для целых чисел без знака с количеством битов нашего кодирования целого числа. Например, u8 — целое число без знака 8 бит, а i16 — целое число со знаком 16 бит.
Поддерживаемые кодирования достигают 64 бит для целых чисел со знаком и 63 бит для целых чисел без знака. Это ограничение для целых чисел без знака обусловлено тем, что в настоящее время протокол Redis не может возвращать целые числа без знака 64 бита в качестве ответов.
Биты и позиционные смещения
Существует два способа задания смещений в команде bitfield. Если указано число без префикса, оно используется просто как смещение бита со значением ноль внутри строки.
Однако, если смещение имеет префикс символа #, указанное смещение умножается на ширину кодирования целого числа, например:
BITFIELD mystring SET i8 #0 100 SET i8 #1 200
Установит первое целое число i8 со смещением 0 и второе со смещением 8. Таким образом, вам не нужно производить вычисления в вашем клиенте, если вам нужен простой массив целых чисел заданного размера.
Управление переполнением
Используя команду OVERFLOW пользователь может точно настроить поведение переполнения (или недополнения) приращения или уменьшения, указав одно из следующих поведений:
-
WRAP: переносить, как для целых чисел со знаком, так и без знака. В случае целых чисел без знака перенос — это выполнение операции по модулю максимального значения, которое может содержать целое число (поведение стандарта C). Для целых чисел со знаком перенос означает, что переполнения начинаются в сторону наименьшего отрицательного значения, а недополнения — в сторону наибольшего положительного, например, если целое число со знаком
i8установлено в значение 127, увеличение его на 1 даст-128. -
SAT: использует насыщающую арифметику, то есть при недополнении значение устанавливается в минимальное значение целого числа, а при переполнении — в максимальное значение целого числа. Например, увеличение целого числа
i8, начиная со значения 120 с приращением 10, приведёт к значению 127, а дальнейшие увеличения всегда будут сохранять значение на уровне 127. То же самое происходит при недополнении, но в сторону наименьшего отрицательного значения. - FAIL: в этом режиме ни одна операция не выполняется при обнаружении переполнения или недополнения. Соответствующее возвращаемое значение устанавливается в NULL для сигнализации состояния вызывающей стороне.
Обратите внимание, что каждое заявление OVERFLOW влияет только на команды INCRBY и SET, которые следуют за ним в списке подкоманд, до следующего заявления OVERFLOW.
По умолчанию используется WRAP, если не указано иное.
> BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1 1) (integer) 1 2) (integer) 1 > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1 1) (integer) 2 2) (integer) 2 > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1 1) (integer) 3 2) (integer) 3 > BITFIELD mykey incrby u2 100 1 OVERFLOW SAT incrby u2 102 1 1) (integer) 0 2) (integer) 3
Возвращаемое значение
Команда возвращает массив, при этом каждый элемент — соответствующий результат подкоманды, заданной на той же позиции. Подкоманды OVERFLOW не считаются генерирующими ответ.
Ниже приведён пример ситуации, когда OVERFLOW FAIL возвращает NULL.
> BITFIELD mykey OVERFLOW FAIL incrby u2 102 1 1) (nil)
Мотивации
Мотивация к этой команде заключается в том, что возможность хранить множество маленьких целых чисел как единый большой битовый массив (или сегментированных по нескольким ключам, чтобы избежать огромных ключей) является чрезвычайно эффективной с точки зрения памяти и открывает новые возможности применения Redis, особенно в области аналитики в реальном времени. Эти возможности поддерживаются способностью контролируемо задавать переполнение.
Интересный факт: проект Reddit's 2017 April fools' project r/place был создан с использованием команды Redis BITFIELD для создания представления в оперативной памяти совместной холщовой работы.
Учет производительности
Обычно BITFIELD — это быстрая команда, однако обратите внимание, что обращение к далёким битам в текущих коротких строках вызовет выделение памяти, которое может быть более дорогостоящим, чем выполнение команды над уже существующими битами.
Порядок битов
Представление, используемое BITFIELD рассматривает битовый массив как имеющий номер бита 0, являющимся наиболее значимым битом первого байта, и так далее. Таким образом, установка целого числа без знака 5 бит со значением 23 со смещением 7 в битовый массив, ранее установленный на все нули, даст следующее представление:
+--------+--------+ |00000001|01110000| +--------+--------+
Когда смещения и размеры целых чисел выровнены по границам байтов, это то же самое, что и big endian, однако, когда такого выравнивания нет, важно также понимать, как упорядочены биты внутри байта.
© 2006–2022 Salvatore Sanfilippo
Licensed under the Creative Commons Attribution-ShareAlike License 4.0.
https://redis.io/commands/bitfield/