This source file includes following definitions.
- pdcon
- pddes
- pmix_hash_store
- pmix_hash_fetch
- pmix_hash_fetch_by_key
- pmix_hash_remove_data
- lookup_keyval
- lookup_proc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <src/include/pmix_config.h>
24
25 #include <src/include/pmix_stdint.h>
26 #include <src/include/hash_string.h>
27
28 #include <string.h>
29
30 #include "src/include/pmix_globals.h"
31 #include "src/class/pmix_hash_table.h"
32 #include "src/class/pmix_pointer_array.h"
33 #include "src/mca/bfrops/bfrops.h"
34 #include "src/util/error.h"
35 #include "src/util/output.h"
36
37 #include "src/util/hash.h"
38
39
40
41
42
43
44 typedef struct {
45
46 pmix_list_item_t super;
47
48
49 pmix_list_t data;
50 } pmix_proc_data_t;
51 static void pdcon(pmix_proc_data_t *p)
52 {
53 PMIX_CONSTRUCT(&p->data, pmix_list_t);
54 }
55 static void pddes(pmix_proc_data_t *p)
56 {
57 PMIX_LIST_DESTRUCT(&p->data);
58 }
59 static PMIX_CLASS_INSTANCE(pmix_proc_data_t,
60 pmix_list_item_t,
61 pdcon, pddes);
62
63 static pmix_kval_t* lookup_keyval(pmix_list_t *data,
64 const char *key);
65 static pmix_proc_data_t* lookup_proc(pmix_hash_table_t *jtable,
66 uint64_t id, bool create);
67
68 pmix_status_t pmix_hash_store(pmix_hash_table_t *table,
69 pmix_rank_t rank, pmix_kval_t *kin)
70 {
71 pmix_proc_data_t *proc_data;
72 uint64_t id;
73 pmix_kval_t *hv;
74
75 pmix_output_verbose(10, pmix_globals.debug_output,
76 "HASH:STORE rank %d key %s",
77 rank, (NULL == kin) ? "NULL KVAL" : kin->key);
78
79 if (NULL == kin) {
80 return PMIX_ERR_BAD_PARAM;
81 }
82
83 id = (uint64_t)rank;
84
85
86
87 if (NULL == (proc_data = lookup_proc(table, id, true))) {
88 return PMIX_ERR_OUT_OF_RESOURCE;
89 }
90
91
92 hv = lookup_keyval(&proc_data->data, kin->key);
93 if (NULL != hv) {
94
95
96 pmix_list_remove_item(&proc_data->data, &hv->super);
97 PMIX_RELEASE(hv);
98 }
99 PMIX_RETAIN(kin);
100 pmix_list_append(&proc_data->data, &kin->super);
101
102 return PMIX_SUCCESS;
103 }
104
105 pmix_status_t pmix_hash_fetch(pmix_hash_table_t *table, pmix_rank_t rank,
106 const char *key, pmix_value_t **kvs)
107 {
108 pmix_status_t rc = PMIX_SUCCESS;
109 pmix_proc_data_t *proc_data;
110 pmix_kval_t *hv;
111 uint64_t id;
112 char *node;
113 pmix_info_t *info;
114 size_t ninfo, n;
115 pmix_value_t *val;
116
117 pmix_output_verbose(10, pmix_globals.debug_output,
118 "HASH:FETCH rank %d key %s",
119 rank, (NULL == key) ? "NULL" : key);
120
121 id = (uint64_t)rank;
122
123
124
125
126
127
128 if (PMIX_RANK_UNDEF == rank) {
129 rc = pmix_hash_table_get_first_key_uint64(table, &id,
130 (void**)&proc_data, (void**)&node);
131 if (PMIX_SUCCESS != rc) {
132 pmix_output_verbose(10, pmix_globals.debug_output,
133 "HASH:FETCH proc data for rank %d not found",
134 rank);
135 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
136 }
137 }
138
139 while (PMIX_SUCCESS == rc) {
140 proc_data = lookup_proc(table, id, false);
141 if (NULL == proc_data) {
142 pmix_output_verbose(10, pmix_globals.debug_output,
143 "HASH:FETCH proc data for rank %d not found",
144 rank);
145 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
146 }
147
148
149
150 if (NULL == key) {
151
152
153 val = (pmix_value_t*)malloc(sizeof(pmix_value_t));
154 if (NULL == val) {
155 return PMIX_ERR_NOMEM;
156 }
157 val->type = PMIX_DATA_ARRAY;
158 val->data.darray = (pmix_data_array_t*)malloc(sizeof(pmix_data_array_t));
159 if (NULL == val->data.darray) {
160 PMIX_VALUE_RELEASE(val);
161 return PMIX_ERR_NOMEM;
162 }
163 val->data.darray->type = PMIX_INFO;
164 val->data.darray->size = 0;
165 val->data.darray->array = NULL;
166 ninfo = pmix_list_get_size(&proc_data->data);
167 PMIX_INFO_CREATE(info, ninfo);
168 if (NULL == info) {
169 PMIX_VALUE_RELEASE(val);
170 return PMIX_ERR_NOMEM;
171 }
172
173 n=0;
174 PMIX_LIST_FOREACH(hv, &proc_data->data, pmix_kval_t) {
175 pmix_strncpy(info[n].key, hv->key, PMIX_MAX_KEYLEN);
176 pmix_value_xfer(&info[n].value, hv->value);
177 ++n;
178 }
179 val->data.darray->size = ninfo;
180 val->data.darray->array = info;
181 *kvs = val;
182 return PMIX_SUCCESS;
183 } else {
184
185 hv = lookup_keyval(&proc_data->data, key);
186 if (NULL != hv) {
187
188 PMIX_BFROPS_COPY(rc, pmix_globals.mypeer,
189 (void**)kvs, hv->value, PMIX_VALUE);
190 if (PMIX_SUCCESS != rc) {
191 PMIX_ERROR_LOG(rc);
192 return rc;
193 }
194 break;
195 } else if (PMIX_RANK_UNDEF != rank) {
196 pmix_output_verbose(10, pmix_globals.debug_output,
197 "HASH:FETCH data for key %s not found", key);
198 return PMIX_ERR_NOT_FOUND;
199 }
200 }
201
202 rc = pmix_hash_table_get_next_key_uint64(table, &id,
203 (void**)&proc_data, node, (void**)&node);
204 if (PMIX_SUCCESS != rc) {
205 pmix_output_verbose(10, pmix_globals.debug_output,
206 "HASH:FETCH data for key %s not found", key);
207 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
208 }
209 }
210
211 return rc;
212 }
213
214 pmix_status_t pmix_hash_fetch_by_key(pmix_hash_table_t *table, const char *key,
215 pmix_rank_t *rank, pmix_value_t **kvs, void **last)
216 {
217 pmix_status_t rc = PMIX_SUCCESS;
218 pmix_proc_data_t *proc_data;
219 pmix_kval_t *hv;
220 uint64_t id;
221 char *node;
222 static const char *key_r = NULL;
223
224 if (key == NULL && (node = *last) == NULL) {
225 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
226 }
227
228 if (key == NULL && key_r == NULL) {
229 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
230 }
231
232 if (key) {
233 rc = pmix_hash_table_get_first_key_uint64(table, &id,
234 (void**)&proc_data, (void**)&node);
235 key_r = key;
236 } else {
237 rc = pmix_hash_table_get_next_key_uint64(table, &id,
238 (void**)&proc_data, node, (void**)&node);
239 }
240
241 pmix_output_verbose(10, pmix_globals.debug_output,
242 "HASH:FETCH BY KEY rank %d key %s",
243 (int)id, key_r);
244
245 if (PMIX_SUCCESS != rc) {
246 pmix_output_verbose(10, pmix_globals.debug_output,
247 "HASH:FETCH proc data for key %s not found",
248 key_r);
249 return PMIX_ERR_PROC_ENTRY_NOT_FOUND;
250 }
251
252
253 hv = lookup_keyval(&proc_data->data, key_r);
254 if (hv) {
255
256 PMIX_BFROPS_COPY(rc, pmix_globals.mypeer,
257 (void**)kvs, hv->value, PMIX_VALUE);
258 if (PMIX_SUCCESS != rc) {
259 PMIX_ERROR_LOG(rc);
260 return rc;
261 }
262 } else {
263 return PMIX_ERR_NOT_FOUND;
264 }
265
266 *rank = (int)id;
267 *last = node;
268
269 return PMIX_SUCCESS;
270 }
271
272 pmix_status_t pmix_hash_remove_data(pmix_hash_table_t *table,
273 pmix_rank_t rank, const char *key)
274 {
275 pmix_status_t rc = PMIX_SUCCESS;
276 pmix_proc_data_t *proc_data;
277 pmix_kval_t *kv;
278 uint64_t id;
279 char *node;
280
281 id = (uint64_t)rank;
282
283
284
285 if (PMIX_RANK_WILDCARD == rank) {
286 rc = pmix_hash_table_get_first_key_uint64(table, &id,
287 (void**)&proc_data, (void**)&node);
288 while (PMIX_SUCCESS == rc) {
289 if (NULL != proc_data) {
290 if (NULL == key) {
291 PMIX_RELEASE(proc_data);
292 } else {
293 PMIX_LIST_FOREACH(kv, &proc_data->data, pmix_kval_t) {
294 if (0 == strcmp(key, kv->key)) {
295 pmix_list_remove_item(&proc_data->data, &kv->super);
296 PMIX_RELEASE(kv);
297 break;
298 }
299 }
300 }
301 }
302 rc = pmix_hash_table_get_next_key_uint64(table, &id,
303 (void**)&proc_data, node, (void**)&node);
304 }
305 return PMIX_SUCCESS;
306 }
307
308
309 if (NULL == (proc_data = lookup_proc(table, id, false))) {
310
311 return PMIX_SUCCESS;
312 }
313
314
315 if (NULL == key) {
316 while (NULL != (kv = (pmix_kval_t*)pmix_list_remove_first(&proc_data->data))) {
317 PMIX_RELEASE(kv);
318 }
319
320 pmix_hash_table_remove_value_uint64(table, id);
321
322 PMIX_RELEASE(proc_data);
323 return PMIX_SUCCESS;
324 }
325
326
327 PMIX_LIST_FOREACH(kv, &proc_data->data, pmix_kval_t) {
328 if (0 == strcmp(key, kv->key)) {
329 pmix_list_remove_item(&proc_data->data, &kv->super);
330 PMIX_RELEASE(kv);
331 break;
332 }
333 }
334
335 return PMIX_SUCCESS;
336 }
337
338
339
340
341 static pmix_kval_t* lookup_keyval(pmix_list_t *data,
342 const char *key)
343 {
344 pmix_kval_t *kv;
345
346 PMIX_LIST_FOREACH(kv, data, pmix_kval_t) {
347 if (0 == strcmp(key, kv->key)) {
348 return kv;
349 }
350 }
351 return NULL;
352 }
353
354
355
356
357
358
359 static pmix_proc_data_t* lookup_proc(pmix_hash_table_t *jtable,
360 uint64_t id, bool create)
361 {
362 pmix_proc_data_t *proc_data = NULL;
363
364 pmix_hash_table_get_value_uint64(jtable, id, (void**)&proc_data);
365 if (NULL == proc_data && create) {
366
367 proc_data = PMIX_NEW(pmix_proc_data_t);
368 if (NULL == proc_data) {
369 pmix_output(0, "pmix:client:hash:lookup_pmix_proc: unable to allocate proc_data_t\n");
370 return NULL;
371 }
372 pmix_hash_table_set_value_uint64(jtable, id, proc_data);
373 }
374
375 return proc_data;
376 }