Version:

Module buffer

Module buffer

The buffer module returns a dynamically resizable buffer which is solely for use as an option for methods of the net.box 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 MsgPack strings.

buffer.ibuf()
Return:a descriptor of a buffer.
Rtype:cdata

Example:

Assume a Tarantool server is listening on farhost:3301. Assume it has a space T with one tuple: 'ABCDE', 12345. In this example we start up a server on localhost:3302 and then use net.box routines to connect to farhost. Then we create a buffer, and use it as an option for a conn.space...select() call. The result will be in MsgPack format. To show this, we will use msgpack.decode_unchecked() on ibuf.rpos (the “read position” of the buffer). Thus we do not decode on the remote server, but we do decode on the local server.

box.cfg{listen=3302}
buffer = require('buffer')
ibuf = buffer.ibuf()
net_box = require('net.box')
conn = net_box.connect('farhost:3301')
buffer = require('buffer')
conn.space.T:select({},{buffer=ibuf})
msgpack = require('msgpack')
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.

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) 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 same example, except that skip_header=true is used.

box.cfg{listen=3302}
buffer = require('buffer')
ibuf = buffer.ibuf()
net_box = require('net.box')
conn = net_box.connect('farhost:3301')
buffer = require('buffer')
conn.space.T:select({},{buffer=ibuf, skip_header=true})
msgpack = require('msgpack')
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().