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-2015 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 
91 // Info message
92 #define AS_INFO_MESSAGE_VERSION 2L
93 #define AS_INFO_MESSAGE_TYPE 1L
94 
95 // Misc
96 #define AS_HEADER_SIZE 30
97 #define AS_FIELD_HEADER_SIZE 5
98 #define AS_OPERATION_HEADER_SIZE 8
99 
100 #define AS_STACK_BUF_SIZE (1024 * 16)
101 
102 /**
103  * @private
104  * Allocate command buffer on stack or heap depending on given size.
105  */
106 #define as_command_init(_sz) (_sz > AS_STACK_BUF_SIZE)? (uint8_t*)cf_malloc(_sz) : (uint8_t*)alloca(_sz)
107 
108 /**
109  * @private
110  * Free command buffer.
111  */
112 #define as_command_free(_buf, _sz) if (_sz > AS_STACK_BUF_SIZE) {cf_free(_buf);}
113 
114 /******************************************************************************
115  * TYPES
116  *****************************************************************************/
117 
118 /**
119  * @private
120  * Node map data used in as_command_execute().
121  */
122 typedef struct as_command_node_s {
124  const char* ns;
125  const uint8_t* digest;
127  bool write;
129 
130 /**
131  * @private
132  * Data used in as_command_parse_result().
133  */
134 typedef struct as_command_parse_result_data_s {
138 
139 /**
140  * @private
141  * Parse results callback used in as_command_execute().
142  */
143 typedef as_status (*as_parse_results_fn) (as_error* err, int fd, uint64_t deadline_ms, void* user_data);
144 
145 /******************************************************************************
146  * FUNCTIONS
147  ******************************************************************************/
148 
149 /**
150  * @private
151  * Calculate size of command header plus key fields.
152  */
153 size_t
154 as_command_key_size(as_policy_key policy, const as_key* key, uint16_t* n_fields);
155 
156 /**
157  * @private
158  * Calculate size of string field.
159  */
160 static inline size_t
162 {
163  return strlen(value) + AS_FIELD_HEADER_SIZE;
164 }
165 
166 /**
167  * @private
168  * Calculate size of field structure given field value size.
169  */
170 static inline size_t
172 {
173  return size + AS_FIELD_HEADER_SIZE;
174 }
175 
176 /**
177  * @private
178  * Calculate size of as_val field.
179  */
180 size_t
181 as_command_value_size(as_val* val, as_buffer* buffer);
182 
183 /**
184  * @private
185  * Calculate size of bin name and value combined.
186  */
187 static inline size_t
188 as_command_bin_size(const as_bin* bin, as_buffer* buffer)
189 {
190  return strlen(bin->name) + as_command_value_size((as_val*)bin->valuep, buffer) + 8;
191 }
192 
193 /**
194  * @private
195  * Calculate size of bin name. Return error is bin name greater than 14 characters.
196  */
197 static inline as_status
198 as_command_bin_name_size(as_error* err, const char* name, size_t* size)
199 {
200  size_t s = strlen(name);
201 
202  if (s > AS_BIN_NAME_MAX_LEN) {
203  return as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name too long: %s", name);
204  }
205  (*size) += s + AS_OPERATION_HEADER_SIZE;
206  return AEROSPIKE_OK;
207 }
208 
209 /**
210  * @private
211  * Calculate size of string operation.
212  */
213 static inline size_t
215 {
216  return strlen(value) + AS_OPERATION_HEADER_SIZE;
217 }
218 
219 /**
220  * @private
221  * Write command header for all commands.
222  */
223 uint8_t*
224 as_command_write_header(uint8_t* cmd, uint8_t read_attr, uint8_t write_attr,
225  as_policy_commit_level commit_level, as_policy_consistency_level consistency,
226  as_policy_exists exists, as_policy_gen gen_policy, uint32_t gen, uint32_t ttl,
227  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins);
228 
229 /**
230  * @private
231  * Write command header for read commands only.
232  */
233 static inline uint8_t*
234 as_command_write_header_read(uint8_t* cmd, uint8_t read_attr, as_policy_consistency_level consistency,
235  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins)
236 {
237  if (consistency == AS_POLICY_CONSISTENCY_LEVEL_ALL) {
238  read_attr |= AS_MSG_INFO1_CONSISTENCY_ALL;
239  }
240 
241  cmd[8] = 22;
242  cmd[9] = read_attr;
243  memset(&cmd[10], 0, 12);
244  *(uint32_t*)&cmd[22] = cf_swap_to_be32(timeout_ms);
245  *(uint16_t*)&cmd[26] = cf_swap_to_be16(n_fields);
246  *(uint16_t*)&cmd[28] = cf_swap_to_be16(n_bins);
247  return cmd + AS_HEADER_SIZE;
248 }
249 
250 /**
251  * @private
252  * Write field header.
253  */
254 static inline uint8_t*
255 as_command_write_field_header(uint8_t* p, uint8_t id, uint32_t size)
256 {
257  *(uint32_t*)p = cf_swap_to_be32(size+1);
258  p += 4;
259  *p++ = id;
260  return p;
261 }
262 
263 /**
264  * @private
265  * Write string field.
266  */
267 static inline uint8_t*
268 as_command_write_field_string(uint8_t* begin, uint8_t id, const char* val)
269 {
270  uint8_t* p = begin + AS_FIELD_HEADER_SIZE;
271 
272  // Copy string, but do not transfer null byte.
273  while (*val) {
274  *p++ = *val++;
275  }
276  as_command_write_field_header(begin, id, (uint32_t)(p - begin - AS_FIELD_HEADER_SIZE));
277  return p;
278 }
279 
280 /**
281  * @private
282  * Write uint64_t field.
283  */
284 static inline uint8_t*
285 as_command_write_field_uint64(uint8_t* p, uint8_t id, uint64_t val)
286 {
287  p = as_command_write_field_header(p, id, sizeof(uint64_t));
288  *(uint64_t*)p = cf_swap_to_be64(val);
289  return p + sizeof(uint64_t);
290 }
291 
292 /**
293  * @private
294  * Write as_buffer field.
295  */
296 static inline uint8_t*
297 as_command_write_field_buffer(uint8_t* p, uint8_t id, as_buffer* buffer)
298 {
299  p = as_command_write_field_header(p, id, buffer->size);
300  memcpy(p, buffer->data, buffer->size);
301  return p + buffer->size;
302 }
303 
304 /**
305  * @private
306  * Write digest field.
307  */
308 static inline uint8_t*
310 {
312  memcpy(p, val->value, AS_DIGEST_VALUE_SIZE);
313  return p + AS_DIGEST_VALUE_SIZE;
314 }
315 
316 /**
317  * @private
318  * Write key structure.
319  */
320 uint8_t*
321 as_command_write_key(uint8_t* p, as_policy_key policy, const as_key* key);
322 
323 /**
324  * @private
325  * Write bin header and bin name.
326  */
327 static inline uint8_t*
328 as_command_write_bin_name(uint8_t* cmd, const char* name)
329 {
330  uint8_t* p = cmd + AS_OPERATION_HEADER_SIZE;
331 
332  // Copy string, but do not transfer null byte.
333  while (*name) {
334  *p++ = *name++;
335  }
336  uint8_t name_len = p - cmd - AS_OPERATION_HEADER_SIZE;
337  *(uint32_t*)cmd = cf_swap_to_be32((uint32_t)name_len + 4);
338  cmd += 4;
339  *cmd++ = AS_OPERATOR_READ;
340  *cmd++ = 0;
341  *cmd++ = 0;
342  *cmd++ = name_len;
343  return p;
344 }
345 
346 /**
347  * @private
348  * Write bin.
349  */
350 uint8_t*
351 as_command_write_bin(uint8_t* begin, uint8_t operation_type, const as_bin* bin, as_buffer* buffer);
352 
353 /**
354  * @private
355  * Finish writing command.
356  */
357 static inline size_t
358 as_command_write_end(uint8_t* begin, uint8_t* end)
359 {
360  uint64_t len = end - begin;
361  uint64_t proto = (len - 8) | (AS_MESSAGE_VERSION << 56) | (AS_MESSAGE_TYPE << 48);
362  *(uint64_t*)begin = cf_swap_to_be64(proto);
363  return len;
364 }
365 
366 /**
367  * @private
368  * Send command to the server.
369  */
370 as_status
371 as_command_execute(as_cluster* cluster, as_error * err, as_command_node* cn, uint8_t* command, size_t command_len,
372  uint32_t timeout_ms, uint32_t retry,
373  as_parse_results_fn parse_results_fn, void* parse_results_data);
374 
375 /**
376  * @private
377  * Parse header of server response.
378  */
379 as_status
380 as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
381 
382 /**
383  * @private
384  * Parse server record. Used for reads.
385  */
386 as_status
387 as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
388 
389 /**
390  * @private
391  * Parse server success or failure result.
392  */
393 as_status
394 as_command_parse_success_failure(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
395 
396 /**
397  * @private
398  * Parse server success or failure bins.
399  */
400 as_status
401 as_command_parse_success_failure_bins(uint8_t** pp, as_error* err, as_msg* msg, as_val** value);
402 
403 /**
404  * @private
405  * Parse bins received from the server.
406  */
407 uint8_t*
408 as_command_parse_bins(as_record* rec, uint8_t* buf, uint32_t n_bins, bool deserialize);
409 
410 /**
411  * @private
412  * Skip over fields section in returned data.
413  */
414 uint8_t*
415 as_command_ignore_fields(uint8_t* p, uint32_t n_fields);
416 
417 /**
418  * @private
419  * Parse key fields received from server. Used for reads.
420  */
421 uint8_t*
422 as_command_parse_key(uint8_t* p, uint32_t n_fields, as_key* key);
423 
424 #ifdef __cplusplus
425 } // end extern "C"
426 #endif
#define AS_FIELD_DIGEST
Definition: as_command.h:41
as_policy_key
Definition: as_policy.h:184
static uint8_t * as_command_write_field_uint64(uint8_t *p, uint8_t id, uint64_t val)
Definition: as_command.h:285
as_policy_replica
Definition: as_policy.h:256
as_policy_consistency_level
Definition: as_policy.h:279
static uint8_t * as_command_write_field_header(uint8_t *p, uint8_t id, uint32_t size)
Definition: as_command.h:255
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:302
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:198
as_policy_gen
Definition: as_policy.h:156
as_policy_replica replica
Definition: as_command.h:126
#define AS_BIN_NAME_MAX_LEN
Definition: as_bin.h:43
#define AS_OPERATION_HEADER_SIZE
Definition: as_command.h:98
uint16_t n_fields
Definition: as_proto.h:836
static size_t as_command_string_operation_size(const char *value)
Definition: as_command.h:214
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:171
as_policy_exists
Definition: as_policy.h:220
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:309
static uint8_t * as_command_write_bin_name(uint8_t *cmd, const char *name)
Definition: as_command.h:328
#define AS_FIELD_HEADER_SIZE
Definition: as_command.h:97
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:827
#define AS_MESSAGE_TYPE
Definition: as_command.h:89
#define AS_DIGEST_VALUE_SIZE
Definition: as_key.h:41
as_node * node
Definition: as_command.h:123
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:297
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:268
#define AS_HEADER_SIZE
Definition: as_command.h:96
uint8_t * as_command_parse_key(uint8_t *p, uint32_t n_fields, as_key *key)
const uint8_t * digest
Definition: as_command.h:125
const char * ns
Definition: as_command.h:124
static size_t as_command_string_field_size(const char *value)
Definition: as_command.h:161
as_status(* as_parse_results_fn)(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
Definition: as_command.h:143
static size_t as_command_write_end(uint8_t *begin, uint8_t *end)
Definition: as_command.h:358
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:234
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:134
static size_t as_command_bin_size(const as_bin *bin, as_buffer *buffer)
Definition: as_command.h:188