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 <ck_spinlock.h>
29 #include <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  * Pad to 8 byte boundary.
67  */
68  char pad[7];
69 } as_node_shm;
70 
71 /**
72  * @private
73  * Shared memory representation of map of namespace data partitions to nodes. 8 bytes.
74  */
75 typedef struct as_partition_shm_s {
76  /**
77  * @private
78  * Master node index offset.
79  */
80  uint32_t master;
81 
82  /**
83  * @private
84  * Prole node index offset.
85  */
86  uint32_t prole;
88 
89 /**
90  * @private
91  * Shared memory representation of map of namespace to data partitions. 32 bytes + partitions size.
92  */
93 typedef struct as_partition_table_shm_s {
94  /**
95  * @private
96  * Namespace name.
97  */
99 
100  /**
101  * @private
102  * Array of partitions for a given namespace.
103  */
104  as_partition_shm partitions[];
106 
107 /**
108  * @private
109  * Shared memory cluster map. The map contains fixed arrays of nodes and partition tables.
110  * Each partition table contains a fixed array of partitions. The shared memory segment will be
111  * sized on startup and never change afterwards. If the max nodes or max namespaces are reached,
112  * the tender client will ignore additional nodes/namespaces and log an error message that the
113  * corresponding array is full.
114  */
115 typedef struct as_cluster_shm_s {
116  /**
117  * @private
118  * Last time cluster was tended in milliseconds since epoch.
119  */
120  uint64_t timestamp;
121 
122  /**
123  * @private
124  * Cluster tend owner process id.
125  */
126  uint32_t owner_pid;
127 
128  /**
129  * @private
130  * Current size of nodes array.
131  */
132  uint32_t nodes_size;
133 
134  /**
135  * @private
136  * Maximum size of nodes array.
137  */
138  uint32_t nodes_capacity;
139 
140  /**
141  * @private
142  * Nodes generation count. Incremented whenever a node is added or removed from cluster.
143  */
144  uint32_t nodes_gen;
145 
146  /**
147  * @private
148  * Total number of data partitions used by cluster.
149  */
150  uint32_t n_partitions;
151 
152  /**
153  * @private
154  * Current size of partition tables array.
155  */
157 
158  /**
159  * @private
160  * Maximum size of partition tables array.
161  */
163 
164  /**
165  * @private
166  * Cluster offset to partition tables at the end of this structure.
167  */
169 
170  /**
171  * @private
172  * Bytes required to hold one partition_table.
173  */
175 
176  /**
177  * @private
178  * Spin lock for taking over from a dead cluster tender.
179  */
180  ck_spinlock_t take_over_lock;
181 
182  /**
183  * @private
184  * Shared memory master mutex lock. Used to determine cluster tend owner.
185  */
186  uint8_t lock;
187 
188  /**
189  * @private
190  * Has shared memory been fully initialized and populated.
191  */
192  uint8_t ready;
193 
194  /**
195  * @private
196  * Pad to 8 byte boundary.
197  */
198  char pad[6];
199 
200  /*
201  * @private
202  * Dynamically allocated node array.
203  */
204  as_node_shm nodes[];
205 
206  // This is where the dynamically allocated partition tables are located.
208 
209 /**
210  * @private
211  * Local data related to shared memory implementation.
212  */
213 typedef struct as_shm_info_s {
214  /**
215  * @private
216  * Pointer to cluster shared memory.
217  */
219 
220  /**
221  * @private
222  * Array of pointers to local nodes.
223  * Array index offsets are synchronized with shared memory node offsets.
224  */
226 
227  /**
228  * @private
229  * Shared memory identifier.
230  */
231  int shm_id;
232 
233  /**
234  * @private
235  * Take over shared memory cluster tending if the cluster hasn't been tended by this
236  * millisecond threshold.
237  */
239 
240  /**
241  * @private
242  * Is this process responsible for performing cluster tending.
243  */
244  volatile bool is_tend_master;
245 } as_shm_info;
246 
247 /******************************************************************************
248  * FUNCTIONS
249  ******************************************************************************/
250 
251 /**
252  * @private
253  * Create shared memory implementation of cluster.
254  */
255 as_status
256 as_shm_create(struct as_cluster_s* cluster, as_error* err, as_config* config);
257 
258 /**
259  * @private
260  * Destroy shared memory components.
261  */
262 void
263 as_shm_destroy(struct as_cluster_s* cluster);
264 
265 /**
266  * @private
267  * Add nodes to shared memory.
268  */
269 void
270 as_shm_add_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_add);
271 
272 /**
273  * @private
274  * Remove nodes from shared memory.
275  */
276 void
277 as_shm_remove_nodes(struct as_cluster_s* cluster, as_vector* /* <as_node*> */ nodes_to_remove);
278 
279 /**
280  * @private
281  * Update shared memory partition tables for given namespace.
282  */
283 void
284 as_shm_update_partitions(as_shm_info* shm_info, const char* ns, char* bitmap_b64, int64_t len, as_node* node, bool master);
285 
286 /**
287  * @private
288  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is
289  * used instead. as_nodes_release() must be called when done with node.
290  */
291 as_node*
292 as_shm_node_get(struct as_cluster_s* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica);
293 
294 /**
295  * @private
296  * Get shared memory partition tables array.
297  */
298 static inline as_partition_table_shm*
300 {
301  return (as_partition_table_shm*) ((char*)cluster_shm + cluster_shm->partition_tables_offset);
302 }
303 
304 /**
305  * @private
306  * Get partition table identified by index.
307  */
308 static inline as_partition_table_shm*
310 {
311  return (as_partition_table_shm*) ((char*)tables + (cluster_shm->partition_table_byte_size * index));
312 }
313 
314 /**
315  * @private
316  * Get next partition table in array.
317  */
318 static inline as_partition_table_shm*
320 {
321  return (as_partition_table_shm*) ((char*)table + cluster_shm->partition_table_byte_size);
322 }
323 
324 #ifdef __cplusplus
325 } // end extern "C"
326 #endif