All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_shm_cluster.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_config.h>
20 #include <aerospike/as_partition.h>
21 #include <citrusleaf/cf_queue.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 // Concurrency kit needs to be under extern "C" when compiling C++.
28 #include <aerospike/ck/ck_spinlock.h>
29 #include <aerospike/ck/ck_swlock.h>
30 
31 /******************************************************************************
32  * TYPES
33  *****************************************************************************/
34 
35 /**
36  * @private
37  * Shared memory representation of node. 48 bytes.
38  */
39 typedef struct as_node_shm_s {
40  /**
41  * @private
42  * Node name.
43  */
44  char name[AS_NODE_NAME_SIZE];
45 
46  /**
47  * @private
48  * Lightweight node read/write lock.
49  */
50  ck_swlock_t lock;
51 
52  /**
53  * @private
54  * Socket address.
55  */
56  struct sockaddr_in addr;
57 
58  /**
59  * @private
60  * Is node currently active.
61  */
62  uint8_t active;
63 
64  /**
65  * @private
66  * Does node support batch-index protocol?
67  */
68  uint8_t has_batch_index;
69 
70  /**
71  * @private
72  * Does node support replicas-all info protocol?
73  */
75 
76  /**
77  * @private
78  * Does node support floating point type?
79  */
80  uint8_t has_double;
81 
82  /**
83  * @private
84  * Does node support geospatial?
85  */
86  uint8_t has_geo;
87 
88  /**
89  * @private
90  * Pad to 8 byte boundary.
91  */
92  char pad[3];
93 } as_node_shm;
94 
95 /**
96  * @private
97  * Shared memory representation of map of namespace data partitions to nodes. 8 bytes.
98  */
99 typedef struct as_partition_shm_s {
100  /**
101  * @private
102  * Master node index offset.
103  */
104  uint32_t master;
105 
106  /**
107  * @private
108  * Prole node index offset.
109  */
110  uint32_t prole;
112 
113 /**
114  * @private
115  * Shared memory representation of map of namespace to data partitions. 32 bytes + partitions size.
116  */
117 typedef struct as_partition_table_shm_s {
118  /**
119  * @private
120  * Namespace name.
121  */
123 
124  /**
125  * @private
126  * Array of partitions for a given namespace.
127  */
128  as_partition_shm partitions[];
130 
131 /**
132  * @private
133  * Shared memory cluster map. The map contains fixed arrays of nodes and partition tables.
134  * Each partition table contains a fixed array of partitions. The shared memory segment will be
135  * sized on startup and never change afterwards. If the max nodes or max namespaces are reached,
136  * the tender client will ignore additional nodes/namespaces and log an error message that the
137  * corresponding array is full.
138  */
139 typedef struct as_cluster_shm_s {
140  /**
141  * @private
142  * Last time cluster was tended in milliseconds since epoch.
143  */
144  uint64_t timestamp;
145 
146  /**
147  * @private
148  * Cluster tend owner process id.
149  */
150  uint32_t owner_pid;
151 
152  /**
153  * @private
154  * Current size of nodes array.
155  */
156  uint32_t nodes_size;
157 
158  /**
159  * @private
160  * Maximum size of nodes array.
161  */
162  uint32_t nodes_capacity;
163 
164  /**
165  * @private
166  * Nodes generation count. Incremented whenever a node is added or removed from cluster.
167  */
168  uint32_t nodes_gen;
169 
170  /**
171  * @private
172  * Total number of data partitions used by cluster.
173  */
174  uint32_t n_partitions;
175 
176  /**
177  * @private
178  * Current size of partition tables array.
179  */
181 
182  /**
183  * @private
184  * Maximum size of partition tables array.
185  */
187 
188  /**
189  * @private
190  * Cluster offset to partition tables at the end of this structure.
191  */
193 
194  /**
195  * @private
196  * Bytes required to hold one partition_table.
197  */
199 
200  /**
201  * @private
202  * Spin lock for taking over from a dead cluster tender.
203  */
204  ck_spinlock_t take_over_lock;
205 
206  /**
207  * @private
208  * Shared memory master mutex lock. Used to determine cluster tend owner.
209  */
210  uint8_t lock;
211 
212  /**
213  * @private
214  * Has shared memory been fully initialized and populated.
215  */
216  uint8_t ready;
217 
218  /**
219  * @private
220  * Pad to 8 byte boundary.
221  */
222  char pad[6];
223 
224  /*
225  * @private
226  * Dynamically allocated node array.
227  */
228  as_node_shm nodes[];
229 
230  // This is where the dynamically allocated partition tables are located.
232 
233 /**
234  * @private
235  * Local data related to shared memory implementation.
236  */
237 typedef struct as_shm_info_s {
238  /**
239  * @private
240  * Pointer to cluster shared memory.
241  */
243 
244  /**
245  * @private
246  * Array of pointers to local nodes.
247  * Array index offsets are synchronized with shared memory node offsets.
248  */
250 
251  /**
252  * @private
253  * Shared memory identifier.
254  */
255  int shm_id;
256 
257  /**
258  * @private
259  * Take over shared memory cluster tending if the cluster hasn't been tended by this
260  * millisecond threshold.
261  */
263 
264  /**
265  * @private
266  * Is this process responsible for performing cluster tending.
267  */
268  volatile bool is_tend_master;
269 } as_shm_info;
270 
271 /******************************************************************************
272  * FUNCTIONS
273  ******************************************************************************/
274 
275 /**
276  * @private
277  * Create shared memory implementation of cluster.
278  */
279 as_status
280 as_shm_create(struct as_cluster_s* cluster, as_error* err, as_config* config);
281 
282 /**
283  * @private
284  * Destroy shared memory components.
285  */
286 void
287 as_shm_destroy(struct as_cluster_s* cluster);
288 
289 /**
290  * @private
291  * Add nodes to shared memory.
292  */
293 void
294 as_shm_add_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_add);
295 
296 /**
297  * @private
298  * Remove nodes from shared memory.
299  */
300 void
301 as_shm_remove_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_remove);
302 
303 /**
304  * @private
305  * Update shared memory partition tables for given namespace.
306  */
307 void
308 as_shm_update_partitions(as_shm_info* shm_info, const char* ns, char* bitmap_b64, int64_t len, as_node* node, bool master);
309 
310 /**
311  * @private
312  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is
313  * used instead. as_nodes_release() must be called when done with node.
314  */
315 as_node*
316 as_shm_node_get(struct as_cluster_s* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica);
317 
318 /**
319  * @private
320  * Get shared memory partition tables array.
321  */
322 static inline as_partition_table_shm*
324 {
325  return (as_partition_table_shm*) ((char*)cluster_shm + cluster_shm->partition_tables_offset);
326 }
327 
328 /**
329  * @private
330  * Get partition table identified by index.
331  */
332 static inline as_partition_table_shm*
334 {
335  return (as_partition_table_shm*) ((char*)tables + (cluster_shm->partition_table_byte_size * index));
336 }
337 
338 /**
339  * @private
340  * Get next partition table in array.
341  */
342 static inline as_partition_table_shm*
344 {
345  return (as_partition_table_shm*) ((char*)table + cluster_shm->partition_table_byte_size);
346 }
347 
348 #ifdef __cplusplus
349 } // end extern "C"
350 #endif
uint32_t partition_tables_size
uint8_t has_double
as_cluster_shm * cluster_shm
volatile bool is_tend_master
as_namespace ns
Definition: as_scan.h:359
as_policy_replica
Definition: as_policy.h:263
uint8_t has_replicas_all
void as_shm_remove_nodes(struct as_cluster_s *cluster, as_vector *nodes_to_remove)
as_status
Definition: as_status.h:30
uint32_t owner_pid
uint32_t takeover_threshold_ms
static as_partition_table_shm * as_shm_get_partition_table(as_cluster_shm *cluster_shm, as_partition_table_shm *tables, uint32_t index)
uint32_t n_partitions
uint8_t active
void as_shm_update_partitions(as_shm_info *shm_info, const char *ns, char *bitmap_b64, int64_t len, as_node *node, bool master)
uint8_t has_geo
#define AS_NODE_NAME_SIZE
Definition: as_node.h:38
as_node * as_shm_node_get(struct as_cluster_s *cluster, const char *ns, const uint8_t *digest, bool write, as_policy_replica replica)
uint32_t partition_tables_offset
void as_shm_destroy(struct as_cluster_s *cluster)
uint32_t partition_tables_capacity
as_status as_shm_create(struct as_cluster_s *cluster, as_error *err, as_config *config)
uint64_t timestamp
as_node ** local_nodes
uint32_t nodes_size
void as_shm_add_nodes(struct as_cluster_s *cluster, as_vector *nodes_to_add)
uint8_t has_batch_index
static as_partition_table_shm * as_shm_get_partition_tables(as_cluster_shm *cluster_shm)
uint32_t nodes_capacity
uint32_t nodes_gen
uint32_t partition_table_byte_size
#define AS_MAX_NAMESPACE_SIZE
Definition: as_partition.h:33
ck_spinlock_t take_over_lock
ck_swlock_t lock
static as_partition_table_shm * as_shm_next_partition_table(as_cluster_shm *cluster_shm, as_partition_table_shm *table)