summaryrefslogtreecommitdiff
path: root/src/datastore/plugin_datastore_heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datastore/plugin_datastore_heap.c')
-rw-r--r--src/datastore/plugin_datastore_heap.c622
1 files changed, 304 insertions, 318 deletions
diff --git a/src/datastore/plugin_datastore_heap.c b/src/datastore/plugin_datastore_heap.c
index 30d271202..b7d73f0c4 100644
--- a/src/datastore/plugin_datastore_heap.c
+++ b/src/datastore/plugin_datastore_heap.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20 20
21/** 21/**
22 * @file datastore/plugin_datastore_heap.c 22 * @file datastore/plugin_datastore_heap.c
@@ -34,9 +34,7 @@
34/** 34/**
35 * A value that we are storing. 35 * A value that we are storing.
36 */ 36 */
37struct Value 37struct Value {
38{
39
40 /** 38 /**
41 * Key for the value. 39 * Key for the value.
42 */ 40 */
@@ -92,16 +90,13 @@ struct Value
92 * Type of 'data'. 90 * Type of 'data'.
93 */ 91 */
94 enum GNUNET_BLOCK_Type type; 92 enum GNUNET_BLOCK_Type type;
95
96}; 93};
97 94
98 95
99/** 96/**
100 * We organize 0-anonymity values in arrays "by type". 97 * We organize 0-anonymity values in arrays "by type".
101 */ 98 */
102struct ZeroAnonByType 99struct ZeroAnonByType {
103{
104
105 /** 100 /**
106 * We keep these in a DLL. 101 * We keep these in a DLL.
107 */ 102 */
@@ -137,8 +132,7 @@ struct ZeroAnonByType
137/** 132/**
138 * Context for all functions in this plugin. 133 * Context for all functions in this plugin.
139 */ 134 */
140struct Plugin 135struct Plugin {
141{
142 /** 136 /**
143 * Our execution environment. 137 * Our execution environment.
144 */ 138 */
@@ -173,7 +167,6 @@ struct Plugin
173 * Size of all values we're storing. 167 * Size of all values we're storing.
174 */ 168 */
175 unsigned long long size; 169 unsigned long long size;
176
177}; 170};
178 171
179 172
@@ -185,7 +178,7 @@ struct Plugin
185 * @return number of bytes used on disk 178 * @return number of bytes used on disk
186 */ 179 */
187static void 180static void
188heap_plugin_estimate_size (void *cls, unsigned long long *estimate) 181heap_plugin_estimate_size(void *cls, unsigned long long *estimate)
189{ 182{
190 struct Plugin *plugin = cls; 183 struct Plugin *plugin = cls;
191 184
@@ -197,8 +190,7 @@ heap_plugin_estimate_size (void *cls, unsigned long long *estimate)
197/** 190/**
198 * Closure for iterator for updating. 191 * Closure for iterator for updating.
199 */ 192 */
200struct UpdateContext 193struct UpdateContext {
201{
202 /** 194 /**
203 * Number of bytes in 'data'. 195 * Number of bytes in 'data'.
204 */ 196 */
@@ -240,25 +232,25 @@ struct UpdateContext
240 * @return GNUNET_YES (continue iteration), GNUNET_NO if value was found 232 * @return GNUNET_YES (continue iteration), GNUNET_NO if value was found
241 */ 233 */
242static int 234static int
243update_iterator (void *cls, 235update_iterator(void *cls,
244 const struct GNUNET_HashCode *key, 236 const struct GNUNET_HashCode *key,
245 void *val) 237 void *val)
246{ 238{
247 struct UpdateContext *uc = cls; 239 struct UpdateContext *uc = cls;
248 struct Value *value = val; 240 struct Value *value = val;
249 241
250 if (value->size != uc->size) 242 if (value->size != uc->size)
251 return GNUNET_YES; 243 return GNUNET_YES;
252 if (0 != memcmp (value->data, uc->data, uc->size)) 244 if (0 != memcmp(value->data, uc->data, uc->size))
253 return GNUNET_YES; 245 return GNUNET_YES;
254 uc->expiration = GNUNET_TIME_absolute_max (value->expiration, 246 uc->expiration = GNUNET_TIME_absolute_max(value->expiration,
255 uc->expiration); 247 uc->expiration);
256 if (value->expiration.abs_value_us != uc->expiration.abs_value_us) 248 if (value->expiration.abs_value_us != uc->expiration.abs_value_us)
257 { 249 {
258 value->expiration = uc->expiration; 250 value->expiration = uc->expiration;
259 GNUNET_CONTAINER_heap_update_cost (value->expire_heap, 251 GNUNET_CONTAINER_heap_update_cost(value->expire_heap,
260 value->expiration.abs_value_us); 252 value->expiration.abs_value_us);
261 } 253 }
262 /* Saturating adds, don't overflow */ 254 /* Saturating adds, don't overflow */
263 if (value->priority > UINT32_MAX - uc->priority) 255 if (value->priority > UINT32_MAX - uc->priority)
264 value->priority = UINT32_MAX; 256 value->priority = UINT32_MAX;
@@ -289,87 +281,88 @@ update_iterator (void *cls,
289 * @param cont_cls continuation closure 281 * @param cont_cls continuation closure
290 */ 282 */
291static void 283static void
292heap_plugin_put (void *cls, 284heap_plugin_put(void *cls,
293 const struct GNUNET_HashCode *key, 285 const struct GNUNET_HashCode *key,
294 bool absent, 286 bool absent,
295 uint32_t size, 287 uint32_t size,
296 const void *data, 288 const void *data,
297 enum GNUNET_BLOCK_Type type, 289 enum GNUNET_BLOCK_Type type,
298 uint32_t priority, 290 uint32_t priority,
299 uint32_t anonymity, 291 uint32_t anonymity,
300 uint32_t replication, 292 uint32_t replication,
301 struct GNUNET_TIME_Absolute expiration, 293 struct GNUNET_TIME_Absolute expiration,
302 PluginPutCont cont, 294 PluginPutCont cont,
303 void *cont_cls) 295 void *cont_cls)
304{ 296{
305 struct Plugin *plugin = cls; 297 struct Plugin *plugin = cls;
306 struct Value *value; 298 struct Value *value;
307 299
308 if (!absent) { 300 if (!absent)
309 struct UpdateContext uc;
310
311 uc.size = size;
312 uc.data = data;
313 uc.priority = priority;
314 uc.replication = replication;
315 uc.expiration = expiration;
316 uc.updated = false;
317 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue,
318 key,
319 &update_iterator,
320 &uc);
321 if (uc.updated)
322 { 301 {
323 cont (cont_cls, key, size, GNUNET_NO, NULL); 302 struct UpdateContext uc;
324 return; 303
304 uc.size = size;
305 uc.data = data;
306 uc.priority = priority;
307 uc.replication = replication;
308 uc.expiration = expiration;
309 uc.updated = false;
310 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->keyvalue,
311 key,
312 &update_iterator,
313 &uc);
314 if (uc.updated)
315 {
316 cont(cont_cls, key, size, GNUNET_NO, NULL);
317 return;
318 }
325 } 319 }
326 } 320 value = GNUNET_malloc(sizeof(struct Value) + size);
327 value = GNUNET_malloc (sizeof (struct Value) + size);
328 value->key = *key; 321 value->key = *key;
329 value->data = &value[1]; 322 value->data = &value[1];
330 value->expire_heap = GNUNET_CONTAINER_heap_insert (plugin->by_expiration, 323 value->expire_heap = GNUNET_CONTAINER_heap_insert(plugin->by_expiration,
331 value, 324 value,
332 expiration.abs_value_us); 325 expiration.abs_value_us);
333 value->replication_heap = GNUNET_CONTAINER_heap_insert (plugin->by_replication, 326 value->replication_heap = GNUNET_CONTAINER_heap_insert(plugin->by_replication,
334 value, 327 value,
335 replication); 328 replication);
336 value->expiration = expiration; 329 value->expiration = expiration;
337 if (0 == anonymity) 330 if (0 == anonymity)
338 {
339 struct ZeroAnonByType *zabt;
340
341 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
342 if (zabt->type == type)
343 break;
344 if (NULL == zabt)
345 {
346 zabt = GNUNET_new (struct ZeroAnonByType);
347 zabt->type = type;
348 GNUNET_CONTAINER_DLL_insert (plugin->zero_head,
349 plugin->zero_tail,
350 zabt);
351 }
352 if (zabt->array_size == zabt->array_pos)
353 { 331 {
354 GNUNET_array_grow (zabt->array, 332 struct ZeroAnonByType *zabt;
355 zabt->array_size, 333
356 zabt->array_size * 2 + 4); 334 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
335 if (zabt->type == type)
336 break;
337 if (NULL == zabt)
338 {
339 zabt = GNUNET_new(struct ZeroAnonByType);
340 zabt->type = type;
341 GNUNET_CONTAINER_DLL_insert(plugin->zero_head,
342 plugin->zero_tail,
343 zabt);
344 }
345 if (zabt->array_size == zabt->array_pos)
346 {
347 GNUNET_array_grow(zabt->array,
348 zabt->array_size,
349 zabt->array_size * 2 + 4);
350 }
351 value->zero_anon_offset = zabt->array_pos;
352 zabt->array[zabt->array_pos++] = value;
357 } 353 }
358 value->zero_anon_offset = zabt->array_pos;
359 zabt->array[zabt->array_pos++] = value;
360 }
361 value->size = size; 354 value->size = size;
362 value->priority = priority; 355 value->priority = priority;
363 value->anonymity = anonymity; 356 value->anonymity = anonymity;
364 value->replication = replication; 357 value->replication = replication;
365 value->type = type; 358 value->type = type;
366 GNUNET_memcpy (&value[1], data, size); 359 GNUNET_memcpy(&value[1], data, size);
367 GNUNET_CONTAINER_multihashmap_put (plugin->keyvalue, 360 GNUNET_CONTAINER_multihashmap_put(plugin->keyvalue,
368 &value->key, 361 &value->key,
369 value, 362 value,
370 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 363 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
371 plugin->size += size; 364 plugin->size += size;
372 cont (cont_cls, key, size, GNUNET_OK, NULL); 365 cont(cont_cls, key, size, GNUNET_OK, NULL);
373} 366}
374 367
375 368
@@ -381,47 +374,45 @@ heap_plugin_put (void *cls,
381 * @param value value to delete 374 * @param value value to delete
382 */ 375 */
383static void 376static void
384delete_value (struct Plugin *plugin, 377delete_value(struct Plugin *plugin,
385 struct Value *value) 378 struct Value *value)
386{ 379{
387 GNUNET_assert (GNUNET_YES == 380 GNUNET_assert(GNUNET_YES ==
388 GNUNET_CONTAINER_multihashmap_remove (plugin->keyvalue, 381 GNUNET_CONTAINER_multihashmap_remove(plugin->keyvalue,
389 &value->key, 382 &value->key,
390 value)); 383 value));
391 GNUNET_assert (value == GNUNET_CONTAINER_heap_remove_node (value->expire_heap)); 384 GNUNET_assert(value == GNUNET_CONTAINER_heap_remove_node(value->expire_heap));
392 GNUNET_assert (value == GNUNET_CONTAINER_heap_remove_node (value->replication_heap)); 385 GNUNET_assert(value == GNUNET_CONTAINER_heap_remove_node(value->replication_heap));
393 if (0 == value->anonymity) 386 if (0 == value->anonymity)
394 {
395 struct ZeroAnonByType *zabt;
396
397 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
398 if (zabt->type == value->type)
399 break;
400 GNUNET_assert (NULL != zabt);
401 zabt->array[value->zero_anon_offset] = zabt->array[--zabt->array_pos];
402 zabt->array[value->zero_anon_offset]->zero_anon_offset = value->zero_anon_offset;
403 if (0 == zabt->array_pos)
404 { 387 {
405 GNUNET_array_grow (zabt->array, 388 struct ZeroAnonByType *zabt;
406 zabt->array_size, 389
407 0); 390 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
408 GNUNET_CONTAINER_DLL_remove (plugin->zero_head, 391 if (zabt->type == value->type)
409 plugin->zero_tail, 392 break;
410 zabt); 393 GNUNET_assert(NULL != zabt);
411 GNUNET_free (zabt); 394 zabt->array[value->zero_anon_offset] = zabt->array[--zabt->array_pos];
395 zabt->array[value->zero_anon_offset]->zero_anon_offset = value->zero_anon_offset;
396 if (0 == zabt->array_pos)
397 {
398 GNUNET_array_grow(zabt->array,
399 zabt->array_size,
400 0);
401 GNUNET_CONTAINER_DLL_remove(plugin->zero_head,
402 plugin->zero_tail,
403 zabt);
404 GNUNET_free(zabt);
405 }
412 } 406 }
413 }
414 plugin->size -= value->size; 407 plugin->size -= value->size;
415 GNUNET_free (value); 408 GNUNET_free(value);
416} 409}
417 410
418 411
419/** 412/**
420 * Closure for iterator called during 'get_key'. 413 * Closure for iterator called during 'get_key'.
421 */ 414 */
422struct GetContext 415struct GetContext {
423{
424
425 /** 416 /**
426 * Lowest uid to consider. 417 * Lowest uid to consider.
427 */ 418 */
@@ -441,7 +432,6 @@ struct GetContext
441 * If true, return a random value 432 * If true, return a random value
442 */ 433 */
443 bool random; 434 bool random;
444
445}; 435};
446 436
447 437
@@ -454,25 +444,25 @@ struct GetContext
454 * @return GNUNET_YES (continue iteration), GNUNET_NO if result was found 444 * @return GNUNET_YES (continue iteration), GNUNET_NO if result was found
455 */ 445 */
456static int 446static int
457get_iterator (void *cls, 447get_iterator(void *cls,
458 const struct GNUNET_HashCode *key, 448 const struct GNUNET_HashCode *key,
459 void *val) 449 void *val)
460{ 450{
461 struct GetContext *gc = cls; 451 struct GetContext *gc = cls;
462 struct Value *value = val; 452 struct Value *value = val;
463 453
464 if ( (gc->type != GNUNET_BLOCK_TYPE_ANY) && 454 if ((gc->type != GNUNET_BLOCK_TYPE_ANY) &&
465 (gc->type != value->type) ) 455 (gc->type != value->type))
466 return GNUNET_OK; 456 return GNUNET_OK;
467 if (gc->random) 457 if (gc->random)
468 { 458 {
469 gc->value = value; 459 gc->value = value;
470 return GNUNET_NO; 460 return GNUNET_NO;
471 } 461 }
472 if ( (uint64_t) (intptr_t) value < gc->next_uid) 462 if ((uint64_t)(intptr_t)value < gc->next_uid)
473 return GNUNET_OK; 463 return GNUNET_OK;
474 if ( (NULL != gc->value) && 464 if ((NULL != gc->value) &&
475 (value > gc->value) ) 465 (value > gc->value))
476 return GNUNET_OK; 466 return GNUNET_OK;
477 gc->value = value; 467 gc->value = value;
478 return GNUNET_OK; 468 return GNUNET_OK;
@@ -493,13 +483,13 @@ get_iterator (void *cls,
493 * @param proc_cls closure for @a proc 483 * @param proc_cls closure for @a proc
494 */ 484 */
495static void 485static void
496heap_plugin_get_key (void *cls, 486heap_plugin_get_key(void *cls,
497 uint64_t next_uid, 487 uint64_t next_uid,
498 bool random, 488 bool random,
499 const struct GNUNET_HashCode *key, 489 const struct GNUNET_HashCode *key,
500 enum GNUNET_BLOCK_Type type, 490 enum GNUNET_BLOCK_Type type,
501 PluginDatumProcessor proc, 491 PluginDatumProcessor proc,
502 void *proc_cls) 492 void *proc_cls)
503{ 493{
504 struct Plugin *plugin = cls; 494 struct Plugin *plugin = cls;
505 struct GetContext gc; 495 struct GetContext gc;
@@ -509,34 +499,34 @@ heap_plugin_get_key (void *cls,
509 gc.random = random; 499 gc.random = random;
510 gc.type = type; 500 gc.type = type;
511 if (NULL == key) 501 if (NULL == key)
512 { 502 {
513 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, 503 GNUNET_CONTAINER_multihashmap_iterate(plugin->keyvalue,
514 &get_iterator, 504 &get_iterator,
515 &gc); 505 &gc);
516 } 506 }
517 else 507 else
518 { 508 {
519 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue, 509 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->keyvalue,
520 key, 510 key,
521 &get_iterator, 511 &get_iterator,
522 &gc); 512 &gc);
523 } 513 }
524 if (NULL == gc.value) 514 if (NULL == gc.value)
525 { 515 {
526 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 516 proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
527 return; 517 return;
528 } 518 }
529 GNUNET_assert (GNUNET_OK == 519 GNUNET_assert(GNUNET_OK ==
530 proc (proc_cls, 520 proc(proc_cls,
531 &gc.value->key, 521 &gc.value->key,
532 gc.value->size, 522 gc.value->size,
533 &gc.value[1], 523 &gc.value[1],
534 gc.value->type, 524 gc.value->type,
535 gc.value->priority, 525 gc.value->priority,
536 gc.value->anonymity, 526 gc.value->anonymity,
537 gc.value->replication, 527 gc.value->replication,
538 gc.value->expiration, 528 gc.value->expiration,
539 (uint64_t) (intptr_t) gc.value)); 529 (uint64_t)(intptr_t)gc.value));
540} 530}
541 531
542 532
@@ -552,45 +542,45 @@ heap_plugin_get_key (void *cls,
552 * @param proc_cls closure for proc 542 * @param proc_cls closure for proc
553 */ 543 */
554static void 544static void
555heap_plugin_get_replication (void *cls, 545heap_plugin_get_replication(void *cls,
556 PluginDatumProcessor proc, 546 PluginDatumProcessor proc,
557 void *proc_cls) 547 void *proc_cls)
558{ 548{
559 struct Plugin *plugin = cls; 549 struct Plugin *plugin = cls;
560 struct Value *value; 550 struct Value *value;
561 551
562 value = GNUNET_CONTAINER_heap_remove_root (plugin->by_replication); 552 value = GNUNET_CONTAINER_heap_remove_root(plugin->by_replication);
563 if (NULL == value) 553 if (NULL == value)
564 { 554 {
565 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 555 proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
566 return; 556 return;
567 } 557 }
568 if (value->replication > 0) 558 if (value->replication > 0)
569 { 559 {
570 value->replication--; 560 value->replication--;
571 value->replication_heap = GNUNET_CONTAINER_heap_insert (plugin->by_replication, 561 value->replication_heap = GNUNET_CONTAINER_heap_insert(plugin->by_replication,
572 value, 562 value,
573 value->replication); 563 value->replication);
574 } 564 }
575 else 565 else
576 { 566 {
577 /* need a better way to pick a random item, replication level is always 0 */ 567 /* need a better way to pick a random item, replication level is always 0 */
578 value->replication_heap = GNUNET_CONTAINER_heap_insert (plugin->by_replication, 568 value->replication_heap = GNUNET_CONTAINER_heap_insert(plugin->by_replication,
579 value, 569 value,
580 value->replication); 570 value->replication);
581 value = GNUNET_CONTAINER_heap_walk_get_next (plugin->by_replication); 571 value = GNUNET_CONTAINER_heap_walk_get_next(plugin->by_replication);
582 } 572 }
583 GNUNET_assert (GNUNET_OK == 573 GNUNET_assert(GNUNET_OK ==
584 proc (proc_cls, 574 proc(proc_cls,
585 &value->key, 575 &value->key,
586 value->size, 576 value->size,
587 &value[1], 577 &value[1],
588 value->type, 578 value->type,
589 value->priority, 579 value->priority,
590 value->anonymity, 580 value->anonymity,
591 value->replication, 581 value->replication,
592 value->expiration, 582 value->expiration,
593 (uint64_t) (intptr_t) value)); 583 (uint64_t)(intptr_t)value));
594} 584}
595 585
596 586
@@ -603,30 +593,30 @@ heap_plugin_get_replication (void *cls,
603 * @param proc_cls closure for proc 593 * @param proc_cls closure for proc
604 */ 594 */
605static void 595static void
606heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc, 596heap_plugin_get_expiration(void *cls, PluginDatumProcessor proc,
607 void *proc_cls) 597 void *proc_cls)
608{ 598{
609 struct Plugin *plugin = cls; 599 struct Plugin *plugin = cls;
610 struct Value *value; 600 struct Value *value;
611 601
612 value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration); 602 value = GNUNET_CONTAINER_heap_peek(plugin->by_expiration);
613 if (NULL == value) 603 if (NULL == value)
614 { 604 {
615 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 605 proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
616 return; 606 return;
617 } 607 }
618 if (GNUNET_NO == 608 if (GNUNET_NO ==
619 proc (proc_cls, 609 proc(proc_cls,
620 &value->key, 610 &value->key,
621 value->size, 611 value->size,
622 &value[1], 612 &value[1],
623 value->type, 613 value->type,
624 value->priority, 614 value->priority,
625 value->anonymity, 615 value->anonymity,
626 value->replication, 616 value->replication,
627 value->expiration, 617 value->expiration,
628 (uint64_t) (intptr_t) value)) 618 (uint64_t)(intptr_t)value))
629 delete_value (plugin, value); 619 delete_value(plugin, value);
630} 620}
631 621
632 622
@@ -642,45 +632,45 @@ heap_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
642 * @param proc_cls closure for proc 632 * @param proc_cls closure for proc
643 */ 633 */
644static void 634static void
645heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid, 635heap_plugin_get_zero_anonymity(void *cls, uint64_t next_uid,
646 enum GNUNET_BLOCK_Type type, 636 enum GNUNET_BLOCK_Type type,
647 PluginDatumProcessor proc, void *proc_cls) 637 PluginDatumProcessor proc, void *proc_cls)
648{ 638{
649 struct Plugin *plugin = cls; 639 struct Plugin *plugin = cls;
650 struct ZeroAnonByType *zabt; 640 struct ZeroAnonByType *zabt;
651 struct Value *value = NULL; 641 struct Value *value = NULL;
652 642
653 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next) 643 for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
654 {
655 if ( (type != GNUNET_BLOCK_TYPE_ANY) &&
656 (type != zabt->type) )
657 continue;
658 for (int i = 0; i < zabt->array_pos; ++i)
659 { 644 {
660 if ( (uint64_t) (intptr_t) zabt->array[i] < next_uid) 645 if ((type != GNUNET_BLOCK_TYPE_ANY) &&
661 continue; 646 (type != zabt->type))
662 if ( (NULL != value) &&
663 (zabt->array[i] > value) )
664 continue; 647 continue;
665 value = zabt->array[i]; 648 for (int i = 0; i < zabt->array_pos; ++i)
649 {
650 if ((uint64_t)(intptr_t)zabt->array[i] < next_uid)
651 continue;
652 if ((NULL != value) &&
653 (zabt->array[i] > value))
654 continue;
655 value = zabt->array[i];
656 }
666 } 657 }
667 }
668 if (NULL == value) 658 if (NULL == value)
669 { 659 {
670 proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); 660 proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
671 return; 661 return;
672 } 662 }
673 GNUNET_assert (GNUNET_OK == 663 GNUNET_assert(GNUNET_OK ==
674 proc (proc_cls, 664 proc(proc_cls,
675 &value->key, 665 &value->key,
676 value->size, 666 value->size,
677 &value[1], 667 &value[1],
678 value->type, 668 value->type,
679 value->priority, 669 value->priority,
680 value->anonymity, 670 value->anonymity,
681 value->replication, 671 value->replication,
682 value->expiration, 672 value->expiration,
683 (uint64_t) (intptr_t) value)); 673 (uint64_t)(intptr_t)value));
684} 674}
685 675
686 676
@@ -688,7 +678,7 @@ heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
688 * Drop database. 678 * Drop database.
689 */ 679 */
690static void 680static void
691heap_plugin_drop (void *cls) 681heap_plugin_drop(void *cls)
692{ 682{
693 /* nothing needs to be done */ 683 /* nothing needs to be done */
694} 684}
@@ -697,8 +687,7 @@ heap_plugin_drop (void *cls)
697/** 687/**
698 * Closure for the 'return_value' function. 688 * Closure for the 'return_value' function.
699 */ 689 */
700struct GetAllContext 690struct GetAllContext {
701{
702 /** 691 /**
703 * Function to call. 692 * Function to call.
704 */ 693 */
@@ -720,15 +709,15 @@ struct GetAllContext
720 * @return GNUNET_OK (continue to iterate) 709 * @return GNUNET_OK (continue to iterate)
721 */ 710 */
722static int 711static int
723return_value (void *cls, 712return_value(void *cls,
724 const struct GNUNET_HashCode *key, 713 const struct GNUNET_HashCode *key,
725 void *val) 714 void *val)
726{ 715{
727 struct GetAllContext *gac = cls; 716 struct GetAllContext *gac = cls;
728 717
729 gac->proc (gac->proc_cls, 718 gac->proc(gac->proc_cls,
730 key, 719 key,
731 1); 720 1);
732 return GNUNET_OK; 721 return GNUNET_OK;
733} 722}
734 723
@@ -741,28 +730,26 @@ return_value (void *cls,
741 * @param proc_cls closure for proc 730 * @param proc_cls closure for proc
742 */ 731 */
743static void 732static void
744heap_get_keys (void *cls, 733heap_get_keys(void *cls,
745 PluginKeyProcessor proc, 734 PluginKeyProcessor proc,
746 void *proc_cls) 735 void *proc_cls)
747{ 736{
748 struct Plugin *plugin = cls; 737 struct Plugin *plugin = cls;
749 struct GetAllContext gac; 738 struct GetAllContext gac;
750 739
751 gac.proc = proc; 740 gac.proc = proc;
752 gac.proc_cls = proc_cls; 741 gac.proc_cls = proc_cls;
753 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, 742 GNUNET_CONTAINER_multihashmap_iterate(plugin->keyvalue,
754 &return_value, 743 &return_value,
755 &gac); 744 &gac);
756 proc (proc_cls, NULL, 0); 745 proc(proc_cls, NULL, 0);
757} 746}
758 747
759 748
760/** 749/**
761 * Closure for iterator called during 'remove_key'. 750 * Closure for iterator called during 'remove_key'.
762 */ 751 */
763struct RemoveContext 752struct RemoveContext {
764{
765
766 /** 753 /**
767 * Value found. 754 * Value found.
768 */ 755 */
@@ -777,7 +764,6 @@ struct RemoveContext
777 * Data to remove. 764 * Data to remove.
778 */ 765 */
779 const void *data; 766 const void *data;
780
781}; 767};
782 768
783 769
@@ -790,16 +776,16 @@ struct RemoveContext
790 * @return GNUNET_YES (continue iteration), GNUNET_NO if result was found 776 * @return GNUNET_YES (continue iteration), GNUNET_NO if result was found
791 */ 777 */
792static int 778static int
793remove_iterator (void *cls, 779remove_iterator(void *cls,
794 const struct GNUNET_HashCode *key, 780 const struct GNUNET_HashCode *key,
795 void *val) 781 void *val)
796{ 782{
797 struct RemoveContext *rc = cls; 783 struct RemoveContext *rc = cls;
798 struct Value *value = val; 784 struct Value *value = val;
799 785
800 if (value->size != rc->size) 786 if (value->size != rc->size)
801 return GNUNET_YES; 787 return GNUNET_YES;
802 if (0 != memcmp (value->data, rc->data, rc->size)) 788 if (0 != memcmp(value->data, rc->data, rc->size))
803 return GNUNET_YES; 789 return GNUNET_YES;
804 rc->value = value; 790 rc->value = value;
805 return GNUNET_NO; 791 return GNUNET_NO;
@@ -817,12 +803,12 @@ remove_iterator (void *cls,
817 * @param cont_cls continuation closure for @a cont 803 * @param cont_cls continuation closure for @a cont
818 */ 804 */
819static void 805static void
820heap_plugin_remove_key (void *cls, 806heap_plugin_remove_key(void *cls,
821 const struct GNUNET_HashCode *key, 807 const struct GNUNET_HashCode *key,
822 uint32_t size, 808 uint32_t size,
823 const void *data, 809 const void *data,
824 PluginRemoveCont cont, 810 PluginRemoveCont cont,
825 void *cont_cls) 811 void *cont_cls)
826{ 812{
827 struct Plugin *plugin = cls; 813 struct Plugin *plugin = cls;
828 struct RemoveContext rc; 814 struct RemoveContext rc;
@@ -830,26 +816,26 @@ heap_plugin_remove_key (void *cls,
830 rc.value = NULL; 816 rc.value = NULL;
831 rc.size = size; 817 rc.size = size;
832 rc.data = data; 818 rc.data = data;
833 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue, 819 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->keyvalue,
834 key, 820 key,
835 &remove_iterator, 821 &remove_iterator,
836 &rc); 822 &rc);
837 if (NULL == rc.value) 823 if (NULL == rc.value)
838 { 824 {
839 cont (cont_cls, 825 cont(cont_cls,
840 key, 826 key,
841 size, 827 size,
842 GNUNET_NO, 828 GNUNET_NO,
843 NULL); 829 NULL);
844 return; 830 return;
845 } 831 }
846 delete_value (plugin, 832 delete_value(plugin,
847 rc.value); 833 rc.value);
848 cont (cont_cls, 834 cont(cont_cls,
849 key, 835 key,
850 size, 836 size,
851 GNUNET_OK, 837 GNUNET_OK,
852 NULL); 838 NULL);
853} 839}
854 840
855 841
@@ -860,7 +846,7 @@ heap_plugin_remove_key (void *cls,
860 * @return our "struct Plugin*" 846 * @return our "struct Plugin*"
861 */ 847 */
862void * 848void *
863libgnunet_plugin_datastore_heap_init (void *cls) 849libgnunet_plugin_datastore_heap_init(void *cls)
864{ 850{
865 struct GNUNET_DATASTORE_PluginEnvironment *env = cls; 851 struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
866 struct GNUNET_DATASTORE_PluginFunctions *api; 852 struct GNUNET_DATASTORE_PluginFunctions *api;
@@ -868,17 +854,17 @@ libgnunet_plugin_datastore_heap_init (void *cls)
868 unsigned long long esize; 854 unsigned long long esize;
869 855
870 if (GNUNET_OK != 856 if (GNUNET_OK !=
871 GNUNET_CONFIGURATION_get_value_number (env->cfg, 857 GNUNET_CONFIGURATION_get_value_number(env->cfg,
872 "datastore-heap", 858 "datastore-heap",
873 "HASHMAPSIZE", 859 "HASHMAPSIZE",
874 &esize)) 860 &esize))
875 esize = 128 * 1024; 861 esize = 128 * 1024;
876 plugin = GNUNET_new (struct Plugin); 862 plugin = GNUNET_new(struct Plugin);
877 plugin->env = env; 863 plugin->env = env;
878 plugin->keyvalue = GNUNET_CONTAINER_multihashmap_create (esize, GNUNET_YES); 864 plugin->keyvalue = GNUNET_CONTAINER_multihashmap_create(esize, GNUNET_YES);
879 plugin->by_expiration = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 865 plugin->by_expiration = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN);
880 plugin->by_replication = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); 866 plugin->by_replication = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MAX);
881 api = GNUNET_new (struct GNUNET_DATASTORE_PluginFunctions); 867 api = GNUNET_new(struct GNUNET_DATASTORE_PluginFunctions);
882 api->cls = plugin; 868 api->cls = plugin;
883 api->estimate_size = &heap_plugin_estimate_size; 869 api->estimate_size = &heap_plugin_estimate_size;
884 api->put = &heap_plugin_put; 870 api->put = &heap_plugin_put;
@@ -889,8 +875,8 @@ libgnunet_plugin_datastore_heap_init (void *cls)
889 api->drop = &heap_plugin_drop; 875 api->drop = &heap_plugin_drop;
890 api->get_keys = &heap_get_keys; 876 api->get_keys = &heap_get_keys;
891 api->remove_key = &heap_plugin_remove_key; 877 api->remove_key = &heap_plugin_remove_key;
892 GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "heap", 878 GNUNET_log_from(GNUNET_ERROR_TYPE_INFO, "heap",
893 _("Heap database running\n")); 879 _("Heap database running\n"));
894 return api; 880 return api;
895} 881}
896 882
@@ -904,14 +890,14 @@ libgnunet_plugin_datastore_heap_init (void *cls)
904 * @return GNUNET_OK (continue to iterate) 890 * @return GNUNET_OK (continue to iterate)
905 */ 891 */
906static int 892static int
907free_value (void *cls, 893free_value(void *cls,
908 const struct GNUNET_HashCode *key, 894 const struct GNUNET_HashCode *key,
909 void *val) 895 void *val)
910{ 896{
911 struct Plugin *plugin = cls; 897 struct Plugin *plugin = cls;
912 struct Value *value = val; 898 struct Value *value = val;
913 899
914 delete_value (plugin, value); 900 delete_value(plugin, value);
915 return GNUNET_OK; 901 return GNUNET_OK;
916} 902}
917 903
@@ -922,19 +908,19 @@ free_value (void *cls,
922 * @return always NULL 908 * @return always NULL
923 */ 909 */
924void * 910void *
925libgnunet_plugin_datastore_heap_done (void *cls) 911libgnunet_plugin_datastore_heap_done(void *cls)
926{ 912{
927 struct GNUNET_DATASTORE_PluginFunctions *api = cls; 913 struct GNUNET_DATASTORE_PluginFunctions *api = cls;
928 struct Plugin *plugin = api->cls; 914 struct Plugin *plugin = api->cls;
929 915
930 GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, 916 GNUNET_CONTAINER_multihashmap_iterate(plugin->keyvalue,
931 &free_value, 917 &free_value,
932 plugin); 918 plugin);
933 GNUNET_CONTAINER_multihashmap_destroy (plugin->keyvalue); 919 GNUNET_CONTAINER_multihashmap_destroy(plugin->keyvalue);
934 GNUNET_CONTAINER_heap_destroy (plugin->by_expiration); 920 GNUNET_CONTAINER_heap_destroy(plugin->by_expiration);
935 GNUNET_CONTAINER_heap_destroy (plugin->by_replication); 921 GNUNET_CONTAINER_heap_destroy(plugin->by_replication);
936 GNUNET_free (plugin); 922 GNUNET_free(plugin);
937 GNUNET_free (api); 923 GNUNET_free(api);
938 return NULL; 924 return NULL;
939} 925}
940 926