Last active
November 3, 2016 16:15
-
-
Save R-omk/551dd0b77b563c3919c77a3f534810e4 to your computer and use it in GitHub Desktop.
tarantool get c function, get tuple with selected fields only remote:call('get' , 'spacename', fieldbitMask, 'key1')
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "module.h" | |
#include "msgpuck.h" | |
int get(box_function_ctx_t *ctx, const char *args, const char *args_end) { | |
// primary index is 0 | |
uint32_t index_id = 0; | |
uint32_t arg_count = mp_decode_array(&args); | |
uint32_t space_name_len; | |
const char *space_name; | |
// space name | |
space_name = mp_decode_str(&args, &space_name_len); | |
// space id | |
uint32_t space_id = box_space_id_by_name(space_name, space_name_len); | |
if (space_id == BOX_ID_NIL) { | |
box_error_raise(ER_PROC_C, "space not found"); | |
return -1; | |
} | |
// read field bitmask | |
uint64_t bitmask = mp_decode_uint(&args); | |
uint32_t key_len; | |
const char *key; | |
box_tuple_t *tuple = NULL; | |
// get primary text key | |
key = mp_decode_str(&args, &key_len); | |
//load tuple by key | |
uint32_t len = mp_sizeof_array(1) + | |
mp_sizeof_str(key_len); | |
char *begin = (char *) box_txn_alloc(len); | |
if (begin == NULL) { | |
return -1; | |
} | |
char *end = NULL; | |
end = mp_encode_array(begin, 1); | |
end = mp_encode_str(end, key, key_len); | |
if (box_index_get(space_id, index_id, begin, end, &tuple) == -1) { | |
return -1; | |
} | |
if (tuple == NULL) { | |
return 0; | |
} | |
// tuple size | |
size_t tuple_bsize = box_tuple_bsize(tuple); | |
// buffer for msgpack from original tuple | |
char *orig_tuple_buf = (char *) box_txn_alloc(tuple_bsize); | |
// buffer for new tuple | |
char *new_tuple_buf = (char *) box_txn_alloc(tuple_bsize); | |
if (orig_tuple_buf == NULL || new_tuple_buf == NULL) { | |
return -1; | |
} | |
// write tuple to buffer | |
if (box_tuple_to_buf(tuple, orig_tuple_buf, tuple_bsize) == -1) { | |
return -1; | |
} | |
// read original msgpack | |
const char *orig_tuple_buf_cursor = orig_tuple_buf; | |
uint32_t field_count = mp_decode_array(&orig_tuple_buf_cursor); | |
const char *lastpos = orig_tuple_buf_cursor; | |
char *new_tuple_buf_cursor = new_tuple_buf; | |
uint32_t field_pos = 0; | |
uint32_t real_field_count = 0; | |
for (; field_pos < field_count; field_pos++) { | |
if (bitmask & (1 << field_pos)) { | |
real_field_count++; | |
} | |
} | |
// create msgpack array | |
new_tuple_buf_cursor = mp_encode_array(new_tuple_buf, real_field_count); | |
for (field_pos = 0; field_pos < field_count; field_pos++) { | |
// for next to calculate previous field size | |
mp_next(&orig_tuple_buf_cursor); | |
// write field to new tuple | |
if (bitmask & (1 << field_pos)) { | |
memcpy(new_tuple_buf_cursor, lastpos, orig_tuple_buf_cursor - lastpos); | |
new_tuple_buf_cursor = new_tuple_buf_cursor + (orig_tuple_buf_cursor - lastpos); | |
} | |
lastpos = orig_tuple_buf_cursor; | |
} | |
box_tuple_format_t *fmt = box_tuple_format_default(); | |
box_tuple_t *newtuple = box_tuple_new(fmt, new_tuple_buf, new_tuple_buf_cursor); | |
if (newtuple == NULL) return -1; | |
return box_return_tuple(ctx, newtuple); | |
} |
Author
R-omk
commented
Aug 25, 2016
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment