All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_command.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2016 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_bin.h>
20 #include <aerospike/as_buffer.h>
21 #include <aerospike/as_cluster.h>
22 #include <aerospike/as_key.h>
24 #include <aerospike/as_proto.h>
25 #include <aerospike/as_record.h>
26 #include <citrusleaf/cf_byte_order.h>
27 #include <citrusleaf/cf_digest.h>
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /******************************************************************************
34  * MACROS
35  *****************************************************************************/
36 
37 // Field IDs
38 #define AS_FIELD_NAMESPACE 0
39 #define AS_FIELD_SETNAME 1
40 #define AS_FIELD_KEY 2
41 #define AS_FIELD_DIGEST 4
42 #define AS_FIELD_DIGEST_ARRAY 6
43 #define AS_FIELD_TASK_ID 7
44 #define AS_FIELD_SCAN_OPTIONS 8
45 #define AS_FIELD_INDEX_RANGE 22
46 #define AS_FIELD_INDEX_FILTER 23
47 #define AS_FIELD_INDEX_LIMIT 24
48 #define AS_FIELD_INDEX_ORDER 25
49 #define AS_FIELD_INDEX_TYPE 26
50 #define AS_FIELD_UDF_PACKAGE_NAME 30
51 #define AS_FIELD_UDF_FUNCTION 31
52 #define AS_FIELD_UDF_ARGLIST 32
53 #define AS_FIELD_UDF_OP 33
54 #define AS_FIELD_QUERY_BINS 40
55 #define AS_FIELD_BATCH_INDEX 41
56 
57 // Message info1 bits
58 #define AS_MSG_INFO1_READ (1 << 0) // contains a read operation
59 #define AS_MSG_INFO1_GET_ALL (1 << 1) // get all bins, period
60 // (Note: Bit 2 is unused.)
61 #define AS_MSG_INFO1_BATCH_INDEX (1 << 3) // batch read
62 #define AS_MSG_INFO1_XDR (1 << 4) // operation is being performed by XDR
63 #define AS_MSG_INFO1_GET_NOBINDATA (1 << 5) // do not get information about bins and its data
64 #define AS_MSG_INFO1_CONSISTENCY_ALL (1 << 6) // read consistency level - bit 0
65 // (Note: Bit 7 is unused.)
66 
67 // Message info2 bits
68 #define AS_MSG_INFO2_WRITE (1 << 0) // contains a write semantic
69 #define AS_MSG_INFO2_DELETE (1 << 1) // delete record
70 #define AS_MSG_INFO2_GENERATION (1 << 2) // pay attention to the generation
71 #define AS_MSG_INFO2_GENERATION_GT (1 << 3) // apply write if new generation >= old, good for restore
72 // (Note: Bit 4 is unused.)
73 #define AS_MSG_INFO2_CREATE_ONLY (1 << 5) // write record only if it doesn't exist
74 // (Note: Bit 6 is unused.)
75 // (Note: Bit 7 is unused.)
76 
77 // Message info3 bits
78 #define AS_MSG_INFO3_LAST (1 << 0) // this is the last of a multi-part message
79 #define AS_MSG_INFO3_COMMIT_MASTER (1 << 1) // write commit level - bit 0
80 // (Note: Bit 2 is unused.)
81 #define AS_MSG_INFO3_UPDATE_ONLY (1 << 3) // update existing record only, do not create new record
82 #define AS_MSG_INFO3_CREATE_OR_REPLACE (1 << 4) // completely replace existing record, or create new record
83 #define AS_MSG_INFO3_REPLACE_ONLY (1 << 5) // completely replace existing record, do not create new record
84 // (Note: Bit 6 is unused.)
85 // (Note: Bit 7 is unused.)
86 
87 // Transaction message
88 #define AS_MESSAGE_VERSION 2L
89 #define AS_MESSAGE_TYPE 3L
90 #define AS_COMPRESSED_MESSAGE_TYPE 4L
91 
92 // Info message
93 #define AS_INFO_MESSAGE_VERSION 2L
94 #define AS_INFO_MESSAGE_TYPE 1L
95 
96 // Misc
97 #define AS_HEADER_SIZE 30
98 #define AS_FIELD_HEADER_SIZE 5
99 #define AS_OPERATION_HEADER_SIZE 8
100 
101 #define AS_STACK_BUF_SIZE (1024 * 16)
102 
103 /**
104  * @private
105  * Macros use these stand-ins for cf_malloc() / cf_free(), so that
106  * instrumentation properly substitutes them.
107  */
108 
109 static inline void*
110 local_malloc(size_t size)
111 {
112  return cf_malloc(size);
113 }
114 
115 static inline void
116 local_free(void* memory)
117 {
118  return cf_free(memory);
119 }
120 
121 /**
122  * @private
123  * Allocate command buffer on stack or heap depending on given size.
124  */
125 #define as_command_init(_sz) (_sz > AS_STACK_BUF_SIZE) ? (uint8_t*)local_malloc(_sz) : (uint8_t*)alloca(_sz)
126 
127 /**
128  * @private
129  * Free command buffer.
130  */
131 #define as_command_free(_buf, _sz) if (_sz > AS_STACK_BUF_SIZE) {local_free(_buf);}
132 
133 /******************************************************************************
134  * TYPES
135  *****************************************************************************/
136 
137 /**
138  * @private
139  * Node map data used in as_command_execute().
140  */
141 typedef struct as_command_node_s {
143  const char* ns;
144  const uint8_t* digest;
146  bool write;
148 
149 /**
150  * @private
151  * Data used in as_command_parse_result().
152  */
153 typedef struct as_command_parse_result_data_s {
157 
158 /**
159  * @private
160  * Parse results callback used in as_command_execute().
161  */
162 typedef as_status (*as_parse_results_fn) (as_error* err, int fd, uint64_t deadline_ms, void* user_data);
163 
164 /******************************************************************************
165  * FUNCTIONS
166  ******************************************************************************/
167 
168 /**
169  * @private
170  * Calculate size of command header plus key fields.
171  */
172 size_t
173 as_command_key_size(as_policy_key policy, const as_key* key, uint16_t* n_fields);
174 
175 /**
176  * @private
177  * Calculate size of string field.
178  */
179 static inline size_t
181 {
182  return strlen(value) + AS_FIELD_HEADER_SIZE;
183 }
184 
185 /**
186  * @private
187  * Calculate size of field structure given field value size.
188  */
189 static inline size_t
191 {
192  return size + AS_FIELD_HEADER_SIZE;
193 }
194 
195 /**
196  * @private
197  * Calculate size of as_val field.
198  */
199 size_t
200 as_command_value_size(as_val* val, as_buffer* buffer);
201 
202 /**
203  * @private
204  * Calculate size of bin name and value combined.
205  */
206 static inline size_t
207 as_command_bin_size(const as_bin* bin, as_buffer* buffer)
208 {
209  return strlen(bin->name) + as_command_value_size((as_val*)bin->valuep, buffer) + 8;
210 }
211 
212 /**
213  * @private
214  * Calculate size of bin name. Return error is bin name greater than 14 characters.
215  */
216 static inline as_status
217 as_command_bin_name_size(as_error* err, const char* name, size_t* size)
218 {
219  size_t s = strlen(name);
220 
221  if (s > AS_BIN_NAME_MAX_LEN) {
222  return as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name too long: %s", name);
223  }
224  (*size) += s + AS_OPERATION_HEADER_SIZE;
225  return AEROSPIKE_OK;
226 }
227 
228 /**
229  * @private
230  * Calculate size of string operation.
231  */
232 static inline size_t
234 {
235  return strlen(value) + AS_OPERATION_HEADER_SIZE;
236 }
237 
238 /**
239  * @private
240  * Write command header for all commands.
241  */
242 uint8_t*
243 as_command_write_header(uint8_t* cmd, uint8_t read_attr, uint8_t write_attr,
244  as_policy_commit_level commit_level, as_policy_consistency_level consistency,
245  as_policy_exists exists, as_policy_gen gen_policy, uint32_t gen, uint32_t ttl,
246  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins);
247 
248 /**
249  * @private
250  * Write command header for read commands only.
251  */
252 static inline uint8_t*
253 as_command_write_header_read(uint8_t* cmd, uint8_t read_attr, as_policy_consistency_level consistency,
254  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins)
255 {
256  if (consistency == AS_POLICY_CONSISTENCY_LEVEL_ALL) {
257  read_attr |= AS_MSG_INFO1_CONSISTENCY_ALL;
258  }
259 
260  cmd[8] = 22;
261  cmd[9] = read_attr;
262  memset(&cmd[10], 0, 12);
263  *(uint32_t*)&cmd[22] = cf_swap_to_be32(timeout_ms);
264  *(uint16_t*)&cmd[26] = cf_swap_to_be16(n_fields);
265  *(uint16_t*)&cmd[28] = cf_swap_to_be16(n_bins);
266  return cmd + AS_HEADER_SIZE;
267 }
268 
269 /**
270  * @private
271  * Write field header.
272  */
273 static inline uint8_t*
274 as_command_write_field_header(uint8_t* p, uint8_t id, uint32_t size)
275 {
276  *(uint32_t*)p = cf_swap_to_be32(size+1);
277  p += 4;
278  *p++ = id;
279  return p;
280 }
281 
282 /**
283  * @private
284  * Write string field.
285  */
286 static inline uint8_t*
287 as_command_write_field_string(uint8_t* begin, uint8_t id, const char* val)
288 {
289  uint8_t* p = begin + AS_FIELD_HEADER_SIZE;
290 
291  // Copy string, but do not transfer null byte.
292  while (*val) {
293  *p++ = *val++;
294  }
295  as_command_write_field_header(begin, id, (uint32_t)(p - begin - AS_FIELD_HEADER_SIZE));
296  return p;
297 }
298 
299 /**
300  * @private
301  * Write uint64_t field.
302  */
303 static inline uint8_t*
304 as_command_write_field_uint64(uint8_t* p, uint8_t id, uint64_t val)
305 {
306  p = as_command_write_field_header(p, id, sizeof(uint64_t));
307  *(uint64_t*)p = cf_swap_to_be64(val);
308  return p + sizeof(uint64_t);
309 }
310 
311 /**
312  * @private
313  * Write as_buffer field.
314  */
315 static inline uint8_t*
316 as_command_write_field_buffer(uint8_t* p, uint8_t id, as_buffer* buffer)
317 {
318  p = as_command_write_field_header(p, id, buffer->size);
319  memcpy(p, buffer->data, buffer->size);
320  return p + buffer->size;
321 }
322 
323 /**
324  * @private
325  * Write digest field.
326  */
327 static inline uint8_t*
329 {
331  memcpy(p, val->value, AS_DIGEST_VALUE_SIZE);
332  return p + AS_DIGEST_VALUE_SIZE;
333 }
334 
335 /**
336  * @private
337  * Write key structure.
338  */
339 uint8_t*
340 as_command_write_key(uint8_t* p, as_policy_key policy, const as_key* key);
341 
342 /**
343  * @private
344  * Write bin header and bin name.
345  */
346 static inline uint8_t*
347 as_command_write_bin_name(uint8_t* cmd, const char* name)
348 {
349  uint8_t* p = cmd + AS_OPERATION_HEADER_SIZE;
350 
351  // Copy string, but do not transfer null byte.
352  while (*name) {
353  *p++ = *name++;
354  }
355  uint8_t name_len = p - cmd - AS_OPERATION_HEADER_SIZE;
356  *(uint32_t*)cmd = cf_swap_to_be32((uint32_t)name_len + 4);
357  cmd += 4;
358  *cmd++ = AS_OPERATOR_READ;
359  *cmd++ = 0;
360  *cmd++ = 0;
361  *cmd++ = name_len;
362  return p;
363 }
364 
365 /**
366  * @private
367  * Write bin.
368  */
369 uint8_t*
370 as_command_write_bin(uint8_t* begin, uint8_t operation_type, const as_bin* bin, as_buffer* buffer);
371 
372 /**
373  * @private
374  * Finish writing command.
375  */
376 static inline size_t
377 as_command_write_end(uint8_t* begin, uint8_t* end)
378 {
379  uint64_t len = end - begin;
380  uint64_t proto = (len - 8) | (AS_MESSAGE_VERSION << 56) | (AS_MESSAGE_TYPE << 48);
381  *(uint64_t*)begin = cf_swap_to_be64(proto);
382  return len;
383 }
384 
385 /**
386  * @private
387  * Finish writing compressed command.
388  */
389 static inline size_t
390 as_command_compress_write_end(uint8_t* begin, uint8_t* end, uint64_t uncompressed_sz)
391 {
392  uint64_t len = end - begin;
393  uint64_t proto = (len - 8) | (AS_MESSAGE_VERSION << 56) | (AS_COMPRESSED_MESSAGE_TYPE << 48);
394  *(uint64_t*)begin = cf_swap_to_be64(proto);
395 
396  // TODO: We are not passing this in network byte order because of a mistake
397  // in the past. Should be fixed in unison with server code.
398  ((as_compressed_proto *)begin)->uncompressed_sz = uncompressed_sz;
399 
400  return len;
401 }
402 
403 /**
404  * @private
405  * Calculate max size the compressed command buffer.
406  */
407 size_t
408 as_command_compress_max_size(size_t cmd_sz);
409 
410 /**
411  * @private
412  * Compress command buffer.
413  */
414 as_status
415 as_command_compress(as_error* err, uint8_t* cmd, size_t cmd_sz, uint8_t* compressed_cmd, size_t* compressed_size);
416 
417 /**
418  * @private
419  * Send command to the server.
420  */
421 as_status
422 as_command_execute(as_cluster* cluster, as_error* err, as_command_node* cn, uint8_t* command, size_t command_len,
423  uint32_t timeout_ms, uint32_t retry,
424  as_parse_results_fn parse_results_fn, void* parse_results_data);
425 
426 /**
427  * @private
428  * Parse header of server response.
429  */
430 as_status
431 as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
432 
433 /**
434  * @private
435  * Parse server record. Used for reads.
436  */
437 as_status
438 as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
439 
440 /**
441  * @private
442  * Parse server success or failure result.
443  */
444 as_status
445 as_command_parse_success_failure(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
446 
447 /**
448  * @private
449  * Parse server success or failure bins.
450  */
451 as_status
452 as_command_parse_success_failure_bins(uint8_t** pp, as_error* err, as_msg* msg, as_val** value);
453 
454 /**
455  * @private
456  * Parse bins received from the server.
457  */
458 uint8_t*
459 as_command_parse_bins(as_record* rec, uint8_t* buf, uint32_t n_bins, bool deserialize);
460 
461 /**
462  * @private
463  * Parse user defined function error.
464  */
465 as_status
466 as_command_parse_udf_failure(uint8_t* p, as_error* err, as_msg* msg, as_status status);
467 
468 /**
469  * @private
470  * Skip over fields section in returned data.
471  */
472 uint8_t*
473 as_command_ignore_fields(uint8_t* p, uint32_t n_fields);
474 
475 /**
476  * @private
477  * Parse key fields received from server. Used for reads.
478  */
479 uint8_t*
480 as_command_parse_key(uint8_t* p, uint32_t n_fields, as_key* key);
481 
482 #ifdef __cplusplus
483 } // end extern "C"
484 #endif
#define AS_FIELD_DIGEST
Definition: as_command.h:41
uint64_t uncompressed_sz
Definition: as_proto.h:840
as_policy_key
Definition: as_policy.h:191
static uint8_t * as_command_write_field_uint64(uint8_t *p, uint8_t id, uint64_t val)
Definition: as_command.h:304
as_policy_replica
Definition: as_policy.h:263
as_policy_consistency_level
Definition: as_policy.h:286
static uint8_t * as_command_write_field_header(uint8_t *p, uint8_t id, uint32_t size)
Definition: as_command.h:274
as_bin_value * valuep
Definition: as_bin.h:94
as_status as_command_execute(as_cluster *cluster, as_error *err, as_command_node *cn, uint8_t *command, size_t command_len, uint32_t timeout_ms, uint32_t retry, as_parse_results_fn parse_results_fn, void *parse_results_data)
as_policy_commit_level
Definition: as_policy.h:309
as_status
Definition: as_status.h:30
static as_status as_command_bin_name_size(as_error *err, const char *name, size_t *size)
Definition: as_command.h:217
as_policy_gen
Definition: as_policy.h:163
as_policy_replica replica
Definition: as_command.h:145
#define AS_BIN_NAME_MAX_LEN
Definition: as_bin.h:43
#define AS_OPERATION_HEADER_SIZE
Definition: as_command.h:99
uint16_t n_fields
Definition: as_proto.h:848
static void local_free(void *memory)
Definition: as_command.h:116
static size_t as_command_string_operation_size(const char *value)
Definition: as_command.h:233
as_bin_name name
Definition: as_bin.h:82
#define AS_MESSAGE_VERSION
Definition: as_command.h:88
as_digest_value value
Definition: as_key.h:99
size_t as_command_value_size(as_val *val, as_buffer *buffer)
static size_t as_command_field_size(size_t size)
Definition: as_command.h:190
as_policy_exists
Definition: as_policy.h:227
Definition: as_bin.h:77
Definition: as_val.h:57
static uint8_t * as_command_write_field_digest(uint8_t *p, const as_digest *val)
Definition: as_command.h:328
static uint8_t * as_command_write_bin_name(uint8_t *cmd, const char *name)
Definition: as_command.h:347
#define AS_FIELD_HEADER_SIZE
Definition: as_command.h:98
as_status as_command_parse_success_failure(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
uint8_t * as_command_write_key(uint8_t *p, as_policy_key policy, const as_key *key)
as_proto proto
Definition: as_proto.h:839
#define AS_MESSAGE_TYPE
Definition: as_command.h:89
static void * local_malloc(size_t size)
Definition: as_command.h:110
as_status as_command_parse_udf_failure(uint8_t *p, as_error *err, as_msg *msg, as_status status)
#define AS_DIGEST_VALUE_SIZE
Definition: as_key.h:41
as_node * node
Definition: as_command.h:142
as_status as_command_parse_result(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
as_status as_command_parse_header(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
uint8_t * as_command_write_header(uint8_t *cmd, uint8_t read_attr, uint8_t write_attr, as_policy_commit_level commit_level, as_policy_consistency_level consistency, as_policy_exists exists, as_policy_gen gen_policy, uint32_t gen, uint32_t ttl, uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins)
#define AS_MSG_INFO1_CONSISTENCY_ALL
Definition: as_command.h:64
static uint8_t * as_command_write_field_buffer(uint8_t *p, uint8_t id, as_buffer *buffer)
Definition: as_command.h:316
uint8_t * as_command_ignore_fields(uint8_t *p, uint32_t n_fields)
static uint8_t * as_command_write_field_string(uint8_t *begin, uint8_t id, const char *val)
Definition: as_command.h:287
#define AS_HEADER_SIZE
Definition: as_command.h:97
uint8_t * as_command_parse_key(uint8_t *p, uint32_t n_fields, as_key *key)
const uint8_t * digest
Definition: as_command.h:144
const char * ns
Definition: as_command.h:143
static size_t as_command_string_field_size(const char *value)
Definition: as_command.h:180
as_status(* as_parse_results_fn)(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
Definition: as_command.h:162
static size_t as_command_write_end(uint8_t *begin, uint8_t *end)
Definition: as_command.h:377
size_t as_command_compress_max_size(size_t cmd_sz)
static size_t as_command_compress_write_end(uint8_t *begin, uint8_t *end, uint64_t uncompressed_sz)
Definition: as_command.h:390
as_status as_command_parse_success_failure_bins(uint8_t **pp, as_error *err, as_msg *msg, as_val **value)
uint8_t * as_command_write_bin(uint8_t *begin, uint8_t operation_type, const as_bin *bin, as_buffer *buffer)
Definition: as_key.h:199
size_t as_command_key_size(as_policy_key policy, const as_key *key, uint16_t *n_fields)
static uint8_t * as_command_write_header_read(uint8_t *cmd, uint8_t read_attr, as_policy_consistency_level consistency, uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins)
Definition: as_command.h:253
uint8_t * as_command_parse_bins(as_record *rec, uint8_t *buf, uint32_t n_bins, bool deserialize)
#define as_error_update(__err, __code, __fmt,...)
Definition: as_error.h:135
#define AS_COMPRESSED_MESSAGE_TYPE
Definition: as_command.h:90
static size_t as_command_bin_size(const as_bin *bin, as_buffer *buffer)
Definition: as_command.h:207
as_status as_command_compress(as_error *err, uint8_t *cmd, size_t cmd_sz, uint8_t *compressed_cmd, size_t *compressed_size)