Модуль buffer
Модуль buffer возвращает буфер, допускающий динамическое изменение
размера, который используется только в качестве опции для методов
модуля net.box или модуля msgpack.
Как правило, модуль net.box возвращает Lua-таблицу. Если используется
опция buffer, то методы модуля net.box возвращают неформатированную
строку строку MsgPack. Это экономит время работы
на сервере, если в клиентском приложении есть собственная процедура
декодирования MsgPack-строк.
Буфер использует четыре указателя для управления его мощностью:
buf– указатель на начало буфераrpos– указатель на начало диапазона, доступного для чтения данных ("позиция чтения")wpos– указатель на конец диапазона, доступного для чтения данных, и на начало диапазона для записи новых данных ("позиция записи")epos– указатель на конец диапазона, доступного для записи новых данных ("конечная позиция")
Создать новый буфер.
Пример:
В этом примере мы покажем, что использование буфера позволит вам сохранить данные в том же формате, в котором они пришли с сервера. Так что если получить данные с сервера нужно только для отправки куда-то дальше, то с буфером это будет гораздо быстрее.
box.cfg{listen = 3301}buffer = require('buffer')net_box = require('net.box')msgpack = require('msgpack')box.schema.space.create('tester')box.space.tester:create_index('primary')box.space.tester:insert({1, 'ABCDE', 12345})box.schema.user.create('usr1', {password = 'pwd1'})box.schema.user.grant('usr1', 'read,write,execute', 'space', 'tester')ibuf = buffer.ibuf()conn = net_box.connect('usr1:pwd1@localhost:3301')conn.space.tester:select({}, {buffer=ibuf})msgpack.decode_unchecked(ibuf.rpos)
Результат последнего запроса выглядит следующим образом:
tarantool> msgpack.decode_unchecked(ibuf.rpos)---- {48: [['ABCDE', 12345]]}- 'cdata<char *>: 0x7f97ba10c041'...
Аллоцировать size байтов для buffer_object.
Параметры:
size(number) — объем памяти в байтах для аллокации
Возвращает
wpos
Вернуть мощность buffer_object.
Возвращает
epos - buf
Проверить, доступно ли size байтов для чтения из buffer_object.
size(number) — объем памяти в байтах для проверки
Возвращает
rpos
Вернуть размер участка, занятого данными.
Возвращает
rpos - buf
Прочитать size байтов из буфера.
Очистить слоты памяти, выделенные для buffer_object'а.
tarantool> ibuf:recycle()---...tarantool> ibuf.buf, ibuf.rpos, ibuf.wpos, ibuf.epos---- 'cdata<char *>: NULL'- 'cdata<char *>: NULL'- 'cdata<char *>: NULL'- 'cdata<char *>: NULL'...
Очистить слоты памяти, использованные buffer_object. Этот метод позволяет сохранить буфер, но убрать из него все данные.
Это полезно, если вы собираетесь использовать буфер дальше.
tarantool> ibuf:reset()---...tarantool> ibuf.buf, ibuf.rpos, ibuf.wpos, ibuf.epos---- 'cdata<char *>: 0x010cc28030'- 'cdata<char *>: 0x010cc28030'- 'cdata<char *>: 0x010cc28030'- 'cdata<char *>: 0x010cc2c000'...
Зарезервировать память для buffer_object. Проверить, достаточно ли
памяти, чтобы записать size байтов после wpos. Если нет, epos
будет сдвигаться, пока size байтов не будет доступно.
Вернуть участок, доступный для чтения данных.
Возвращает
wpos - rpos
Вернуть участок, доступный для записи данных.
Возвращает
epos - wpos
В примере из предыдущего раздела
tarantool> msgpack.decode_unchecked(ibuf.rpos)---- {48: [['ABCDE', 12345]]}- 'cdata<char *>: 0x7f97ba10c041'...
было показано, что обычно net.box ответ включает в себя заголовок – 48
(в шестнадцатиричной системе – 30), который является
ключом для IPROTO_DATA. Но в
некоторых ситуациях, например, при передаче буфера в функцию C, которая
ожидает массив байт MsgPack без заголовка, заголовок можно пропустить.
Это делается путем указания skip_header=true в качестве опции
conn.space.space-name:select{...} или
conn.space.space-name:insert{...} или
conn.space.space-name:replace{...} или
conn.space.space-name:update{...} или
conn.space.space-name:upsert{...} или
conn.space.space-name:delete{...}. По умолчанию skip_header=false.
Ниже приведен конец того же примера, но с использованием skip_header=true.
ibuf = buffer.ibuf()conn = net_box.connect('usr1:pwd1@localhost:3301')conn.space.tester:select({}, {buffer=ibuf, skip_header=true})msgpack.decode_unchecked(ibuf.rpos)
Результат последнего запроса выглядит следующим образом:
tarantool> msgpack.decode_unchecked(ibuf.rpos)---- {48: [['ABCDE', 12345]]}- 'cdata<char *>: 0x7f97ba10c041'...
Заметьте, что заголовок IPROTO_DATA (48) ушел.
Результат остается внутри массива, что видно из того, что он заключен в
квадратные скобки. Пропустить заголовок массива можно и функцией
msgpack.decode_array_header().