Модуль ulid
Доступно с версии 3.6.0.
Модуль ulid реализует в Tarantool поддержку ULID – универсального уникального лексикографически сортируемого идентификатора (Universally Unique Lexicographically Sortable Identifier). ULID – это 128-битный идентификатор, состоящий из:
- 48-битной временной метки в миллисекундах от эпохи Unix;
- 80-битной случайной (энтропийной) части.
Строки ULID кодируются с использованием Crockford Base32 – компактного и удобного, человекочитаемого алфавита, который исключает визуально неоднозначные символы.
В бинарном виде ULID представлен 16-байтным значением в порядке байт big-endian. Это гарантирует, что лексикографический порядок бинарных ULID совпадает с их хронологическим порядком, как и требует спецификация ULID.
ULID обладают рядом полезных свойств. Такие идентификаторы:
- лексикографически сортируются по времени создания;
- полностью помещаются в 26 ASCII-символов;
- избегают визуально неоднозначных символов, таких как
I,L,OилиU; - имеют 128 бит общей уникальности – как UUID v4.
Tarantool использует монотонный генератор ULID. Это гарантирует, что несколько ULID, созданных в пределах одной миллисекунды, строго возрастают и сохраняют следующий порядок: для любых двух ULID, сгенерированных в одной и той же миллисекунде, созданный позже идентификатор будет больше созданного раньше.
Внутри монотонный генератор хранит последний ULID для текущей миллисекунды и инкрементирует 80-битную случайную часть для каждого следующего идентификатора. Переполнение случайной части возможно только после генерации 2^80 ULID в пределах одной миллисекунды, что практически невозможно в реальных условиях эксплуатации. Однако для строгого соответствия спецификации ULID и чтобы избежать тихого переполнения (wrap-around), реализация детектирует такое переполнение и завершает следующую попытку генерации ошибкой Lua (ULID random component overflow).
Чтобы использовать модуль, выполните команду ниже:
ulid = require('ulid')
Объекты ULID поддерживают полный набор операторов сравнения Lua:
==и~=– равенство и неравенство;<и<=– лексикографическое сравнение;>и>=– лексикографическое сравнение.
Сравнение основано на внутреннем 16-байтном представлении в порядке big-endian и соответствует спецификации ULID: монотонный генератор гарантирует, что порядок сравнения ULID совпадает с порядком их создания, включая одну и ту же миллисекунду.
Сравнение работает как между объектами ULID, так и между объектом ULID и строкой ULID:
u1 == u2сравнивает два объекта ULID напрямую;u1 == "01..."преобразует строку в ULID и сравнивает значения;u1 < "01..."или"01..." < u1преобразует строковый аргумент в ULID и выполняет лексикографическое сравнение.
Примеры:
tarantool> u1 = ulid.new()
tarantool> u2 = ulid.new()
tarantool> u1 < u2, u1 <= u2, u1 == u2, u1 ~= u2, u1 > u2, u1 >= u2
---
- true
- true
- false
- true
- false
- false
...
tarantool> u = ulid.new()
tarantool> s = u:str()
tarantool> u == s, u < s, u > s
---
- true
- false
- false
...
tarantool> u == "not-a-valid-ulid"
---
- false
...
tarantool> u < "not-a-valid-ulid"
---
- error: '[string "return u < "not-a-valid-ulid""]:1: incorrect value to convert to
ulid as 2 argument'
...
Ниже приведён список всех функций и элементов модуля ulid.
| Имя | Назначение |
|---|---|
| ulid.NULL | Объект c нулевым ULID |
| ulid.ulid() ulid.bin() ulid.str() |
Сокращения для создания нового значения ULID |
| ulid.new() | Создать новый объект ULID |
| ulid.fromstr() ulid.frombin() ulid_object:bin() ulid_object:str() |
Преобразование между строкой, бинарным видом и объектом ULID |
| ulid.is_ulid() ulid_object:isnil() |
Проверить тип ULID или нулевое значение |
-
ulid.NULL¶ Нулевой объект ULID – это идентификатор, содержащий 16 нулевых байт.
Return: нулевое значение ULID Rtype: cdata Пример:
tarantool> ulid.NULL --- - 00000000000000000000000000 ...
-
ulid.new()¶ Создать новый объект ULID.
Эта функция использует монотонный генератор, описанный в разделе Общие сведения. Несколько ULID, созданных в пределах одной миллисекунды, строго возрастают.
Return: новый объект ULID Rtype: cdata Пример:
tarantool> ulid.new() --- - 06DGE3YNDCM2PPWJT3SKTTRNZR ...
-
ulid.ulid()¶ Вызов модуля напрямую эквивалентен вызову
ulid.new().Метод
ulid()- это сокращение дляulid.new().Return: новый объект ULID (то же самое, что ulid.new())Rtype: cdata Пример:
tarantool> ulid() --- - 06DGE41G63GAZ6F0TV4WRSVCCW ...
-
ulid.str()¶ Создать новый ULID и вернуть его строковое представление.
Это сокращение для
ulid.new():str().Результат всегда имеет длину 26 символов и кодируется Crockford Base32.
Return: строка ULID Rtype: строка длиной 26 байт Пример:
tarantool> ulid.str() --- - 06DGE480BWZ6H5BKX0KS3Q8S2G ...
-
ulid.bin()¶ Создать новый ULID и вернуть его бинарное представление в виде строки длиной 16 байт.
Это сокращение для
ulid.new():bin().Return: ULID в бинарном виде Rtype: строка длиной 16 байт Пример:
tarantool> #ulid.bin() --- - 16 ...
-
ulid.fromstr(ulid_string)¶ Создать объект ULID из 26-символьной строки.
Входным значением должна быть корректная строка ULID, закодированная Crockford Base32. Если строка некорректна (неверная длина или недопустимые символы), возвращается
nil.Параметры: - ulid_string (
string) – ULID в виде 26-символьной строки
Return: преобразованный ULID или
nilRtype: cdata или
nilПример:
tarantool> u = ulid.fromstr('06DGE4FH80PHA28YZVV5Z473T4') tarantool> u --- - 06DGE4FH80PHA28YZVV5Z473T4 ...
- ulid_string (
-
ulid.frombin(ulid_bin)¶ Создать объект ULID из 16-байтной бинарной строки.
Параметры: - ulid_bin (
string) – ULID в виде 16-байтной бинарной строки
Return: преобразованный ULID
Rtype: cdata
Пример:
tarantool> u1 = ulid.new() tarantool> b = u1:bin() tarantool> u2 = ulid.frombin(b) tarantool> u1 == u2 --- - true ...
- ulid_bin (
-
ulid.is_ulid(value)¶ Проверить, является ли переданное значение объектом ULID (cdata).
Параметры: - value – значение любого типа
Return: true, если значение является ULID, иначеfalseRtype: boolean
Пример:
tarantool> ulid.is_ulid(ulid.new()) --- - true ... tarantool> ulid.is_ulid("string") --- - false ...
Объект ULID, который возвращает функции ulid.new(), ulid.fromstr() и ulid.frombin(), предоставляет следующие методы:
-
ulid_object:bin()¶ Вернуть ULID в виде 16-байтной бинарной строки.
Return: ULID в бинарном виде Rtype: строка длиной 16 байт Пример:
tarantool> u = ulid.new() tarantool> b = u:bin() tarantool> #b, b --- - 16 - "\x01\x9B\a\xAD==\x81u۶-\x93hPa\xAE" ...
-
ulid_object:str()¶ Вернуть ULID в виде 26-символьной строки.
Return: ULID в строковом виде Rtype: строка длиной 26 байт Объекты ULID также реализуют стандартный Lua-метаметод
__tostring. Это означает, что вызовtostring(u)для ULID-объектаuвозвращает то же значение, что иu:str(), а ULID-объекты автоматически преобразуются в своё 26-символьное строковое представление, когда это нужно в строковом контексте.Пример:
tarantool> u = ulid.new() tarantool> u:str(), tostring(u) --- - 06DGFBE3J07B7DB5A3JP4WQ9CM - 06DGFBE3J07B7DB5A3JP4WQ9CM ...
Базовое использование:
tarantool> u_obj = ulid.new()
tarantool> u_str = ulid.str()
tarantool> u_bin = ulid.bin()
tarantool> u_obj, u_str, u_bin
---
- 06DGE6SEZDCFFSFEAJFMC9YQAR
- 06DGE6T0DW0N2N6KMPVZ8SGE4W
- "\x01\x9B\a\eSz8\xBA\xB3\xC5\xCC\xFE\x18\xBB1\xD6"
...
Создание объекта ULID и просмотр его свойств:
tarantool> u = ulid()
---
...
tarantool> #u:bin(), #u:str(), type(u), u:isnil()
---
- 16
- 26
- cdata
- false
...
tarantool> tostring(u) == u:str()
---
- true
...
Преобразование между строковым и бинарным форматами:
tarantool> s = ulid.str()
tarantool> s
---
- 06DGE70CPFDV344XX43687N1SM
...
tarantool> u = ulid.fromstr(s)
tarantool> u:str() == s
---
- true
...
tarantool> b = u:bin()
tarantool> u2 = ulid.frombin(b)
tarantool> u2 == u
---
- true
...
Работа с ulid.NULL:
tarantool> ulid.NULL
---
- 00000000000000000000000000
...
tarantool> ulid.NULL:isnil()
---
- true
...
tarantool> ulid.new():isnil()
---
- false
...
Операторы сравнения:
tarantool> u1 = ulid.new()
tarantool> u2 = ulid.new()
tarantool> u1 < u2
---
- true
...
Проверка типов:
tarantool> u = ulid.new()
tarantool> ulid.is_ulid(u)
---
- true
...
tarantool> ulid.is_ulid("06DGE7RJK8QWJE27X5VVCC5VDW")
---
- false
...
Генерация множества ULID:
tarantool> for i = 1,5 do print(ulid.str()) end
---
06DGE7T8AJD6EDNJ3VQ2ZYB3R4
06DGE7T8AJD6EDNJ3VQ2ZYB3R8
06DGE7T8AJD6EDNJ3VQ2ZYB3RC
06DGE7T8AJD6EDNJ3VQ2ZYB3RG
06DGE7T8AJD6EDNJ3VQ2ZYB3RM
...