int memcached_tuple_set(struct memcached_connection *con, const char *kpos, uint32_t klen, uint64_t expire, const char *vpos, uint32_t vlen, uint64_t cas, uint32_t flags) { (void )con; uint64_t time = fiber_time64(); uint32_t len = mp_sizeof_array(6) + mp_sizeof_str (klen) + mp_sizeof_uint (expire) + mp_sizeof_uint (time) + mp_sizeof_str (vlen) + mp_sizeof_uint (cas) + mp_sizeof_uint (flags); char *begin = (char *)box_txn_alloc(len); if (begin == NULL) { memcached_error_ENOMEM(len, "tuple"); return -1; } char *end = mp_encode_array(begin, 6); end = mp_encode_str (end, kpos, klen); end = mp_encode_uint (end, expire); end = mp_encode_uint (end, time); end = mp_encode_str (end, vpos, vlen); end = mp_encode_uint (end, cas); end = mp_encode_uint (end, flags); assert(end <= begin + len); return box_replace(con->cfg->space_id, begin, end, NULL); }
/* * For each UINT key in arguments create or increment counter in * box.space.test space. */ int multi_inc(box_function_ctx_t *ctx, const char *args, const char *args_end) { static const char *SPACE_NAME = "test"; static const char *INDEX_NAME = "primary"; uint32_t space_id = box_space_id_by_name(SPACE_NAME, strlen(SPACE_NAME)); uint32_t index_id = box_index_id_by_name(space_id, INDEX_NAME, strlen(INDEX_NAME)); if (space_id == BOX_ID_NIL || index_id == BOX_ID_NIL) { return box_error_raise(ER_PROC_C, "Can't find index %s in space %s", INDEX_NAME, SPACE_NAME); } say_debug("space_id = %u, index_id = %u", space_id, index_id); uint32_t arg_count = mp_decode_array(&args); box_txn_begin(); for (uint32_t i = 0; i < arg_count; i++) { /* Decode next argument */ if (mp_typeof(*args) != MP_UINT) return box_error_raise(ER_PROC_C, "Expected uint keys"); uint32_t key = mp_decode_uint(&args); (void) key; /* Prepare MsgPack key for search */ char key_buf[16]; char *key_end = key_buf; key_end = mp_encode_array(key_end, 1); key_end = mp_encode_uint(key_end, key); assert(key_end < key_buf + sizeof(key_buf)); /* Get current value from space */ uint64_t counter = 0; box_tuple_t *tuple; if (box_index_get(space_id, index_id, key_buf, key_end, &tuple) != 0) { return -1; /* error */ } else if (tuple != NULL) { const char *field = box_tuple_field(tuple, 1); if (field == NULL || mp_typeof(*field) != MP_UINT) return box_error_raise(ER_PROC_LUA, "Invalid tuple"); counter = mp_decode_uint(&field) + 1; } /* Replace value */ char tuple_buf[16]; char *tuple_end = tuple_buf; tuple_end = mp_encode_array(tuple_end, 2); tuple_end = mp_encode_uint(tuple_end, key); /* key */ tuple_end = mp_encode_uint(tuple_end, counter); /* counter */ assert(tuple_end <= tuple_buf + sizeof(tuple_buf)); if (box_replace(space_id, tuple_buf, tuple_end, NULL) != 0) return -1; } box_txn_commit(); return 0; }