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