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 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #include <aerospike/as_bin.h>
24 #include <aerospike/as_buffer.h>
25 #include <aerospike/as_cluster.h>
26 #include <aerospike/as_key.h>
28 #include <aerospike/as_proto.h>
29 #include <aerospike/as_record.h>
30 #include <citrusleaf/cf_byte_order.h>
31 #include <citrusleaf/cf_digest.h>
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 
56 // Message info1 bits
57 #define AS_MSG_INFO1_READ (1 << 0) // contains a read operation
58 #define AS_MSG_INFO1_GET_ALL (1 << 1) // get all bins, period
59 // (Note: Bit 2 is unused.)
60 // (Note: Bit 3 is unused.)
61 #define AS_MSG_INFO1_XDR (1 << 4) // operation is being performed by XDR
62 #define AS_MSG_INFO1_GET_NOBINDATA (1 << 5) // do not get information about bins and its data
63 #define AS_MSG_INFO1_CONSISTENCY_ALL (1 << 6) // read consistency level - bit 0
64 // (Note: Bit 7 is unused.)
65 
66 // Message info2 bits
67 #define AS_MSG_INFO2_WRITE (1 << 0) // contains a write semantic
68 #define AS_MSG_INFO2_DELETE (1 << 1) // delete record
69 #define AS_MSG_INFO2_GENERATION (1 << 2) // pay attention to the generation
70 #define AS_MSG_INFO2_GENERATION_GT (1 << 3) // apply write if new generation >= old, good for restore
71 // (Note: Bit 4 is unused.)
72 #define AS_MSG_INFO2_CREATE_ONLY (1 << 5) // write record only if it doesn't exist
73 // (Note: Bit 6 is unused.)
74 // (Note: Bit 7 is unused.)
75 
76 // Message info3 bits
77 #define AS_MSG_INFO3_LAST (1 << 0) // this is the last of a multi-part message
78 #define AS_MSG_INFO3_COMMIT_MASTER (1 << 1) // write commit level - bit 0
79 // (Note: Bit 2 is unused.)
80 #define AS_MSG_INFO3_UPDATE_ONLY (1 << 3) // update existing record only, do not create new record
81 #define AS_MSG_INFO3_CREATE_OR_REPLACE (1 << 4) // completely replace existing record, or create new record
82 #define AS_MSG_INFO3_REPLACE_ONLY (1 << 5) // completely replace existing record, do not create new record
83 // (Note: Bit 6 is unused.)
84 // (Note: Bit 7 is unused.)
85 
86 // Transaction message
87 #define AS_MESSAGE_VERSION 2L
88 #define AS_MESSAGE_TYPE 3L
89 
90 // Info message
91 #define AS_INFO_MESSAGE_VERSION 2L
92 #define AS_INFO_MESSAGE_TYPE 1L
93 
94 // Misc
95 #define AS_HEADER_SIZE 30
96 #define AS_FIELD_HEADER_SIZE 5
97 #define AS_OPERATION_HEADER_SIZE 8
98 
99 #define AS_STACK_BUF_SIZE (1024 * 16)
100 
101 /**
102  * @private
103  * Allocate command buffer on stack or heap depending on given size.
104  */
105 #define as_command_init(_sz) (_sz > AS_STACK_BUF_SIZE)? (uint8_t*)cf_malloc(_sz) : (uint8_t*)alloca(_sz)
106 
107 /**
108  * @private
109  * Free command buffer.
110  */
111 #define as_command_free(_buf, _sz) if (_sz > AS_STACK_BUF_SIZE) {cf_free(_buf);}
112 
113 /******************************************************************************
114  * TYPES
115  *****************************************************************************/
116 
117 /**
118  * @private
119  * Node map data used in as_command_execute().
120  */
121 typedef struct as_command_node_s {
124  const char* ns;
125  const cf_digest* digest;
127  bool write;
129 
130 /**
131  * @private
132  * Parse results callback used in as_command_execute().
133  */
134 typedef as_status (*as_parse_results_fn) (as_error* err, int fd, uint64_t deadline_ms, void* user_data);
135 
136 /******************************************************************************
137  * FUNCTIONS
138  ******************************************************************************/
139 
140 /**
141  * @private
142  * Calculate size of command header plus key fields.
143  */
144 static inline size_t
145 as_command_key_size(const as_key* key, uint16_t* n_fields)
146 {
147  *n_fields = 3;
148  return strlen(key->ns) + strlen(key->set) + sizeof(cf_digest) + 45;
149 }
150 
151 /**
152  * @private
153  * Calculate size of user key field.
154  */
155 size_t
156 as_command_user_key_size(const as_key* key);
157 
158 /**
159  * @private
160  * Calculate size of string field.
161  */
162 static inline size_t
164 {
165  return strlen(value) + AS_FIELD_HEADER_SIZE;
166 }
167 
168 /**
169  * @private
170  * Calculate size of field structure given field value size.
171  */
172 static inline size_t
174 {
175  return size + AS_FIELD_HEADER_SIZE;
176 }
177 
178 /**
179  * @private
180  * Calculate size of as_val field.
181  */
182 size_t
183 as_command_value_size(as_val* val, as_buffer* buffer);
184 
185 /**
186  * @private
187  * Calculate size of bin name and value combined.
188  */
189 static inline size_t
190 as_command_bin_size(const as_bin* bin, as_buffer* buffer)
191 {
192  return strlen(bin->name) + as_command_value_size((as_val*)bin->valuep, buffer) + 8;
193 }
194 
195 /**
196  * @private
197  * Calculate size of bin name. Return error is bin name greater than 14 characters.
198  */
199 static inline as_status
200 as_command_bin_name_size(as_error* err, const char* name, size_t* size)
201 {
202  size_t s = strlen(name);
203 
204  if (s > AS_BIN_NAME_MAX_LEN) {
205  return as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name too long: %s", name);
206  }
207  (*size) += s + AS_OPERATION_HEADER_SIZE;
208  return AEROSPIKE_OK;
209 }
210 
211 /**
212  * @private
213  * Calculate size of string operation.
214  */
215 static inline size_t
217 {
218  return strlen(value) + AS_OPERATION_HEADER_SIZE;
219 }
220 
221 /**
222  * @private
223  * Write command header for all commands.
224  */
225 uint8_t*
226 as_command_write_header(uint8_t* cmd, uint8_t read_attr, uint8_t write_attr,
227  as_policy_commit_level commit_level, as_policy_consistency_level consistency,
228  as_policy_exists exists, as_policy_gen gen_policy, uint32_t gen, uint32_t ttl,
229  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins);
230 
231 /**
232  * @private
233  * Write command header for read commands only.
234  */
235 static inline uint8_t*
236 as_command_write_header_read(uint8_t* cmd, uint8_t read_attr, as_policy_consistency_level consistency,
237  uint32_t timeout_ms, uint16_t n_fields, uint16_t n_bins)
238 {
239  if (consistency == AS_POLICY_CONSISTENCY_LEVEL_ALL) {
240  read_attr |= AS_MSG_INFO1_CONSISTENCY_ALL;
241  }
242 
243  cmd[8] = 22;
244  cmd[9] = read_attr;
245  memset(&cmd[10], 0, 12);
246  *(uint32_t*)&cmd[22] = cf_swap_to_be32(timeout_ms);
247  *(uint16_t*)&cmd[26] = cf_swap_to_be16(n_fields);
248  *(uint16_t*)&cmd[28] = cf_swap_to_be16(n_bins);
249  return cmd + AS_HEADER_SIZE;
250 }
251 
252 /**
253  * @private
254  * Write field header.
255  */
256 static inline uint8_t*
257 as_command_write_field_header(uint8_t* p, uint8_t id, uint32_t size)
258 {
259  *(uint32_t*)p = cf_swap_to_be32(size+1);
260  p += 4;
261  *p++ = id;
262  return p;
263 }
264 
265 /**
266  * @private
267  * Write string field.
268  */
269 static inline uint8_t*
270 as_command_write_field_string(uint8_t* begin, uint8_t id, const char* val)
271 {
272  uint8_t* p = begin + AS_FIELD_HEADER_SIZE;
273 
274  // Copy string, but do not transfer null byte.
275  while (*val) {
276  *p++ = *val++;
277  }
278  as_command_write_field_header(begin, id, (uint32_t)(p - begin - AS_FIELD_HEADER_SIZE));
279  return p;
280 }
281 
282 /**
283  * @private
284  * Write uint64_t field.
285  */
286 static inline uint8_t*
287 as_command_write_field_uint64(uint8_t* p, uint8_t id, uint64_t val)
288 {
289  p = as_command_write_field_header(p, id, sizeof(uint64_t));
290  *(uint64_t*)p = cf_swap_to_be64(val);
291  return p + sizeof(uint64_t);
292 }
293 
294 /**
295  * @private
296  * Write as_buffer field.
297  */
298 static inline uint8_t*
299 as_command_write_field_buffer(uint8_t* p, uint8_t id, as_buffer* buffer)
300 {
301  p = as_command_write_field_header(p, id, buffer->size);
302  memcpy(p, buffer->data, buffer->size);
303  return p + buffer->size;
304 }
305 
306 /**
307  * @private
308  * Write digest field.
309  */
310 static inline uint8_t*
312 {
314  memcpy(p, val->value, AS_DIGEST_VALUE_SIZE);
315  return p + AS_DIGEST_VALUE_SIZE;
316 }
317 
318 /**
319  * @private
320  * Write key structure.
321  */
322 static inline uint8_t*
323 as_command_write_key(uint8_t* p, const as_key* key)
324 {
328  return p;
329 }
330 
331 /**
332  * @private
333  * Write user defined key.
334  */
335 uint8_t*
336 as_command_write_user_key(uint8_t* begin, const as_key* key);
337 
338 /**
339  * @private
340  * Write bin header and bin name.
341  */
342 static inline uint8_t*
343 as_command_write_bin_name(uint8_t* cmd, const char* name)
344 {
345  uint8_t* p = cmd + AS_OPERATION_HEADER_SIZE;
346 
347  // Copy string, but do not transfer null byte.
348  while (*name) {
349  *p++ = *name++;
350  }
351  uint8_t name_len = p - cmd - AS_OPERATION_HEADER_SIZE;
352  *(uint32_t*)cmd = cf_swap_to_be32((uint32_t)name_len + 4);
353  cmd += 4;
354  *cmd++ = AS_OPERATOR_READ;
355  *cmd++ = 0;
356  *cmd++ = 0;
357  *cmd++ = name_len;
358  return p;
359 }
360 
361 /**
362  * @private
363  * Write bin.
364  */
365 uint8_t*
366 as_command_write_bin(uint8_t* begin, uint8_t operation_type, const as_bin* bin, as_buffer* buffer);
367 
368 /**
369  * @private
370  * Finish writing command.
371  */
372 static inline size_t
373 as_command_write_end(uint8_t* begin, uint8_t* end)
374 {
375  uint64_t len = end - begin;
376  uint64_t proto = (len - 8) | (AS_MESSAGE_VERSION << 56) | (AS_MESSAGE_TYPE << 48);
377  *(uint64_t*)begin = cf_swap_to_be64(proto);
378  return len;
379 }
380 
381 /**
382  * @private
383  * Send command to the server.
384  */
385 as_status
386 as_command_execute(as_error * err, as_command_node* cn, uint8_t* command, size_t command_len,
387  uint32_t timeout_ms, as_policy_retry retry,
388  as_parse_results_fn parse_results_fn, void* parse_results_data);
389 
390 /**
391  * @private
392  * Parse header of server response.
393  */
394 as_status
395 as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
396 
397 /**
398  * @private
399  * Parse server record. Used for reads.
400  */
401 as_status
402 as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
403 
404 /**
405  * @private
406  * Parse server success or failure result.
407  */
408 as_status
409 as_command_parse_success_failure(as_error* err, int fd, uint64_t deadline_ms, void* user_data);
410 
411 /**
412  * @private
413  * Parse server success or failure bins.
414  */
415 uint8_t*
416 as_command_parse_success_failure_bins(uint8_t* p, as_error* err, as_msg* msg, as_val** value);
417 
418 /**
419  * @private
420  * Parse bins received from the server.
421  */
422 uint8_t*
423 as_command_parse_bins(as_record* rec, uint8_t* buf, uint32_t n_bins, bool deserialize);
424 
425 /**
426  * @private
427  * Skip over fields section in returned data.
428  */
429 uint8_t*
430 as_command_ignore_fields(uint8_t* p, uint32_t n_fields);
431 
432 /**
433  * @private
434  * Parse key fields received from server. Used for reads.
435  */
436 uint8_t*
437 as_command_parse_key(uint8_t* p, uint32_t n_fields, as_key* key);
438 
439 #ifdef __cplusplus
440 } // end extern "C"
441 #endif
as_digest digest
Definition: as_key.h:232
static size_t as_command_key_size(const as_key *key, uint16_t *n_fields)
Definition: as_command.h:145
#define AS_FIELD_DIGEST
Definition: as_command.h:41
uint8_t * as_command_write_user_key(uint8_t *begin, const as_key *key)
static uint8_t * as_command_write_field_uint64(uint8_t *p, uint8_t id, uint64_t val)
Definition: as_command.h:287
as_policy_replica
Definition: as_policy.h:257
as_policy_consistency_level
Definition: as_policy.h:280
const cf_digest * digest
Definition: as_command.h:125
static uint8_t * as_command_write_field_header(uint8_t *p, uint8_t id, uint32_t size)
Definition: as_command.h:257
as_bin_value * valuep
Definition: as_bin.h:92
as_policy_commit_level
Definition: as_policy.h:303
as_status
Definition: as_status.h:30
#define AS_FIELD_SETNAME
Definition: as_command.h:39
static as_status as_command_bin_name_size(as_error *err, const char *name, size_t *size)
Definition: as_command.h:200
as_policy_gen
Definition: as_policy.h:157
as_policy_replica replica
Definition: as_command.h:126
#define AS_BIN_NAME_MAX_LEN
Definition: as_bin.h:42
as_policy_retry
Definition: as_policy.h:134
#define AS_OPERATION_HEADER_SIZE
Definition: as_command.h:97
uint16_t n_fields
Definition: as_proto.h:773
static size_t as_command_string_operation_size(const char *value)
Definition: as_command.h:216
as_bin_name name
Definition: as_bin.h:80
#define AS_MESSAGE_VERSION
Definition: as_command.h:87
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:173
as_policy_exists
Definition: as_policy.h:221
Definition: as_bin.h:75
Definition: as_val.h:55
static uint8_t * as_command_write_field_digest(uint8_t *p, const as_digest *val)
Definition: as_command.h:311
static uint8_t * as_command_write_bin_name(uint8_t *cmd, const char *name)
Definition: as_command.h:343
#define AS_FIELD_HEADER_SIZE
Definition: as_command.h:96
as_status as_command_parse_success_failure(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
as_proto proto
Definition: as_proto.h:764
size_t as_command_user_key_size(const as_key *key)
#define AS_MESSAGE_TYPE
Definition: as_command.h:88
#define AS_DIGEST_VALUE_SIZE
Definition: as_key.h:41
as_node * node
Definition: as_command.h:122
uint8_t * as_command_parse_success_failure_bins(uint8_t *p, as_error *err, as_msg *msg, as_val **value)
#define AS_FIELD_NAMESPACE
Definition: as_command.h:38
as_status as_command_parse_result(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
as_status as_command_execute(as_error *err, as_command_node *cn, uint8_t *command, size_t command_len, uint32_t timeout_ms, as_policy_retry retry, as_parse_results_fn parse_results_fn, void *parse_results_data)
as_status as_command_parse_header(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
as_namespace ns
Definition: as_key.h:210
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:63
static uint8_t * as_command_write_field_buffer(uint8_t *p, uint8_t id, as_buffer *buffer)
Definition: as_command.h:299
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:270
#define AS_HEADER_SIZE
Definition: as_command.h:95
uint8_t * as_command_parse_key(uint8_t *p, uint32_t n_fields, as_key *key)
const char * ns
Definition: as_command.h:124
static size_t as_command_string_field_size(const char *value)
Definition: as_command.h:163
as_set set
Definition: as_key.h:215
as_status(* as_parse_results_fn)(as_error *err, int fd, uint64_t deadline_ms, void *user_data)
Definition: as_command.h:134
static size_t as_command_write_end(uint8_t *begin, uint8_t *end)
Definition: as_command.h:373
static uint8_t * as_command_write_key(uint8_t *p, const as_key *key)
Definition: as_command.h:323
as_cluster * cluster
Definition: as_command.h:123
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
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:236
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:190