Module buffer
The buffer
module returns a dynamically resizable buffer which is solely
for optional use by methods of the net.box module
or the msgpack module.
Ordinarily the net.box
methods return a Lua table.
If a buffer
option is used, then the net.box
methods return a
raw MsgPack string.
This saves time on the server, if the client application has
its own routine for decoding raw MsgPack strings.
The buffer uses four pointers to manage its capacity:
buf
– a pointer to the beginning of the bufferrpos
– a pointer to the beginning of the range; available for reading data (“read position”)wpos
– a pointer to the end of the range; available for reading data, and to the beginning of the range for writing new data (“write position”)epos
– a pointer to the end of the range; available for writing new data (“end position”)
-
buffer.
ibuf
()¶ Create a new buffer.
Example:
In this example we will show that using buffer allows you to keep the data in the format that you get from the server. So if you get the data only for sending it somewhere else, buffer fastens this a lot.
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)
The result of the final request looks like this:
tarantool> msgpack.decode_unchecked(ibuf.rpos) --- - {48: [['ABCDE', 12345]]} - 'cdata<char *>: 0x7f97ba10c041' ...
Note
Before Tarantool version 1.7.7, the function to use for this case is
msgpack.ibuf_decode(ibuf.rpos)
. Starting with Tarantool version 1.7.7,ibuf_decode
is deprecated.
-
object
buffer_object
¶ -
buffer_object:
alloc
(size)¶ Allocate
size
bytes forbuffer_object
.Parameters: - size (
number
) – memory in bytes to allocate
Return: wpos
- size (
-
buffer_object:
capacity
()¶ Return the capacity of the
buffer_object
.Return: epos - buf
-
buffer_object:
checksize
(size)¶ Check if
size
bytes are available for reading inbuffer_object
.Parameters: - size (
number
) – memory in bytes to check
Return: rpos
- size (
-
buffer_object:
pos
()¶ Return the size of the range occupied by data.
Return: rpos - buf
-
buffer_object:
read
(size)¶ Read
size
bytes from buffer.
-
buffer_object:
recycle
()¶ Clear the memory slots allocated by
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:
reset
()¶ Clear the memory slots used by
buffer_object
. This method allows to keep the buffer but remove data from it. It is useful when you want to use the buffer further.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:
reserve
(size)¶ Reserve memory for
buffer_object
. Check if there is enough memory to writesize
bytes afterwpos
. If not,epos
shifts untilsize
bytes will be available.
-
buffer_object:
size
()¶ Return a range, available for reading data.
Return: wpos - rpos
-
buffer_object:
unused
()¶ Return a range for writing data.
Return: epos - wpos
-
Module buffer and skip_header
The example in the previous section
tarantool> msgpack.decode_unchecked(ibuf.rpos)
---
- {48: [['ABCDE', 12345]]}
- 'cdata<char *>: 0x7f97ba10c041'
...
showed that, ordinarily, the response from net.box includes a header –
48 (hexadecimal 30) that is the key
for IPROTO_DATA. But in some situations, for example when passing the buffer to
a C function that expects a MsgPack byte array without a header, the header can
be skipped. This is done by specifying skip_header=true
as an option to
conn.space.space-name:select{…} or
conn.space.space-name:insert{…} or
conn.space.space-name:replace{…} or
conn.space.space-name:update{…} or
conn.space.space-name:upsert{…} or
conn.space.space-name:delete{…}.
The default is skip_header=false
.
Now here is the end of the same example, except that skip_header=true
is used.
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)
The result of the final request looks like this:
tarantool> msgpack.decode_unchecked(ibuf.rpos)
---
- [['ABCDE', 12345]]
- 'cdata<char *>: 0x7f8fd102803f'
...
Notice that the IPROTO_DATA header (48) is gone.
The result is still inside an array, as is clear from the fact that it is shown inside square brackets. It is possible to skip the array header too, with msgpack.decode_array_header().