GNUnet  0.11.x
plugin_datastore_heap.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2012 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
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/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
30 #include "platform.h"
32 
33 
37 struct Value
38 {
42  struct GNUNET_HashCode key;
43 
47  const void *data;
48 
53 
58 
63 
68  unsigned int zero_anon_offset;
69 
73  uint32_t size;
74 
78  uint32_t priority;
79 
83  uint32_t anonymity;
84 
88  uint32_t replication;
89 
94 };
95 
96 
101 {
106 
111 
115  struct Value **array;
116 
120  unsigned int array_size;
121 
125  unsigned int array_pos;
126 
131 };
132 
133 
137 struct Plugin
138 {
143 
148 
153 
158 
163 
168 
172  unsigned long long size;
173 };
174 
175 
183 static void
184 heap_plugin_estimate_size (void *cls, unsigned long long *estimate)
185 {
186  struct Plugin *plugin = cls;
187 
188  if (NULL != estimate)
189  *estimate = plugin->size;
190 }
191 
192 
196 struct UpdateContext
197 {
201  uint32_t size;
202 
206  const void *data;
207 
211  uint32_t priority;
212 
216  uint32_t replication;
217 
222 
226  bool updated;
227 };
228 
229 
238 static int
239 update_iterator (void *cls,
240  const struct GNUNET_HashCode *key,
241  void *val)
242 {
243  struct UpdateContext *uc = cls;
244  struct Value *value = val;
245 
246  if (value->size != uc->size)
247  return GNUNET_YES;
248  if (0 != memcmp (value->data, uc->data, uc->size))
249  return GNUNET_YES;
251  uc->expiration);
253  {
254  value->expiration = uc->expiration;
256  value->expiration.abs_value_us);
257  }
258  /* Saturating adds, don't overflow */
259  if (value->priority > UINT32_MAX - uc->priority)
260  value->priority = UINT32_MAX;
261  else
262  value->priority += uc->priority;
263  if (value->replication > UINT32_MAX - uc->replication)
264  value->replication = UINT32_MAX;
265  else
266  value->replication += uc->replication;
267  uc->updated = true;
268  return GNUNET_NO;
269 }
270 
271 
288 static void
289 heap_plugin_put (void *cls,
290  const struct GNUNET_HashCode *key,
291  bool absent,
292  uint32_t size,
293  const void *data,
294  enum GNUNET_BLOCK_Type type,
295  uint32_t priority,
296  uint32_t anonymity,
297  uint32_t replication,
299  PluginPutCont cont,
300  void *cont_cls)
301 {
302  struct Plugin *plugin = cls;
303  struct Value *value;
304 
305  if (! absent)
306  {
307  struct UpdateContext uc;
308 
309  uc.size = size;
310  uc.data = data;
311  uc.priority = priority;
313  uc.expiration = expiration;
314  uc.updated = false;
316  key,
318  &uc);
319  if (uc.updated)
320  {
321  cont (cont_cls, key, size, GNUNET_NO, NULL);
322  return;
323  }
324  }
325  value = GNUNET_malloc (sizeof(struct Value) + size);
326  value->key = *key;
327  value->data = &value[1];
329  value,
330  expiration.abs_value_us);
332  plugin->by_replication,
333  value,
334  replication);
335  value->expiration = expiration;
336  if (0 == anonymity)
337  {
338  struct ZeroAnonByType *zabt;
339 
340  for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
341  if (zabt->type == type)
342  break;
343  if (NULL == zabt)
344  {
345  zabt = GNUNET_new (struct ZeroAnonByType);
346  zabt->type = type;
348  plugin->zero_tail,
349  zabt);
350  }
351  if (zabt->array_size == zabt->array_pos)
352  {
353  GNUNET_array_grow (zabt->array,
354  zabt->array_size,
355  zabt->array_size * 2 + 4);
356  }
357  value->zero_anon_offset = zabt->array_pos;
358  zabt->array[zabt->array_pos++] = value;
359  }
360  value->size = size;
361  value->priority = priority;
362  value->anonymity = anonymity;
363  value->replication = replication;
364  value->type = type;
365  GNUNET_memcpy (&value[1], data, size);
367  &value->key,
368  value,
370  plugin->size += size;
371  cont (cont_cls, key, size, GNUNET_OK, NULL);
372 }
373 
374 
382 static void
384  struct Value *value)
385 {
388  &value->key,
389  value));
391  value->expire_heap));
393  value->replication_heap));
394  if (0 == value->anonymity)
395  {
396  struct ZeroAnonByType *zabt;
397 
398  for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
399  if (zabt->type == value->type)
400  break;
401  GNUNET_assert (NULL != zabt);
402  zabt->array[value->zero_anon_offset] = zabt->array[--zabt->array_pos];
403  zabt->array[value->zero_anon_offset]->zero_anon_offset =
404  value->zero_anon_offset;
405  if (0 == zabt->array_pos)
406  {
407  GNUNET_array_grow (zabt->array,
408  zabt->array_size,
409  0);
411  plugin->zero_tail,
412  zabt);
413  GNUNET_free (zabt);
414  }
415  }
416  plugin->size -= value->size;
417  GNUNET_free (value);
418 }
419 
420 
424 struct GetContext
425 {
429  uint64_t next_uid;
430 
434  struct Value *value;
435 
439  enum GNUNET_BLOCK_Type type;
440 
444  bool random;
445 };
446 
447 
456 static int
457 get_iterator (void *cls,
458  const struct GNUNET_HashCode *key,
459  void *val)
460 {
461  struct GetContext *gc = cls;
462  struct Value *value = val;
463 
464  if ((gc->type != GNUNET_BLOCK_TYPE_ANY) &&
465  (gc->type != value->type))
466  return GNUNET_OK;
467  if (gc->random)
468  {
469  gc->value = value;
470  return GNUNET_NO;
471  }
472  if ((uint64_t) (intptr_t) value < gc->next_uid)
473  return GNUNET_OK;
474  if ((NULL != gc->value) &&
475  (value > gc->value))
476  return GNUNET_OK;
477  gc->value = value;
478  return GNUNET_OK;
479 }
480 
481 
495 static void
497  uint64_t next_uid,
498  bool random,
499  const struct GNUNET_HashCode *key,
500  enum GNUNET_BLOCK_Type type,
502  void *proc_cls)
503 {
504  struct Plugin *plugin = cls;
505  struct GetContext gc;
506 
507  gc.value = NULL;
508  gc.next_uid = next_uid;
509  gc.random = random;
510  gc.type = type;
511  if (NULL == key)
512  {
514  &get_iterator,
515  &gc);
516  }
517  else
518  {
520  key,
521  &get_iterator,
522  &gc);
523  }
524  if (NULL == gc.value)
525  {
526  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
527  return;
528  }
530  proc (proc_cls,
531  &gc.value->key,
532  gc.value->size,
533  &gc.value[1],
534  gc.value->type,
535  gc.value->priority,
536  gc.value->anonymity,
537  gc.value->replication,
538  gc.value->expiration,
539  (uint64_t) (intptr_t) gc.value));
540 }
541 
542 
554 static void
557  void *proc_cls)
558 {
559  struct Plugin *plugin = cls;
560  struct Value *value;
561 
563  if (NULL == value)
564  {
565  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
566  return;
567  }
568  if (value->replication > 0)
569  {
570  value->replication--;
572  plugin->by_replication,
573  value,
574  value->replication);
575  }
576  else
577  {
578  /* need a better way to pick a random item, replication level is always 0 */
580  plugin->by_replication,
581  value,
582  value->replication);
584  }
586  proc (proc_cls,
587  &value->key,
588  value->size,
589  &value[1],
590  value->type,
591  value->priority,
592  value->anonymity,
593  value->replication,
594  value->expiration,
595  (uint64_t) (intptr_t) value));
596 }
597 
598 
607 static void
609  void *proc_cls)
610 {
611  struct Plugin *plugin = cls;
612  struct Value *value;
613 
614  value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration);
615  if (NULL == value)
616  {
617  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
618  return;
619  }
620  if (GNUNET_NO ==
621  proc (proc_cls,
622  &value->key,
623  value->size,
624  &value[1],
625  value->type,
626  value->priority,
627  value->anonymity,
628  value->replication,
629  value->expiration,
630  (uint64_t) (intptr_t) value))
631  delete_value (plugin, value);
632 }
633 
634 
646 static void
647 heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
648  enum GNUNET_BLOCK_Type type,
649  PluginDatumProcessor proc, void *proc_cls)
650 {
651  struct Plugin *plugin = cls;
652  struct ZeroAnonByType *zabt;
653  struct Value *value = NULL;
654 
655  for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
656  {
657  if ((type != GNUNET_BLOCK_TYPE_ANY) &&
658  (type != zabt->type))
659  continue;
660  for (int i = 0; i < zabt->array_pos; ++i)
661  {
662  if ((uint64_t) (intptr_t) zabt->array[i] < next_uid)
663  continue;
664  if ((NULL != value) &&
665  (zabt->array[i] > value))
666  continue;
667  value = zabt->array[i];
668  }
669  }
670  if (NULL == value)
671  {
672  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
673  return;
674  }
676  proc (proc_cls,
677  &value->key,
678  value->size,
679  &value[1],
680  value->type,
681  value->priority,
682  value->anonymity,
683  value->replication,
684  value->expiration,
685  (uint64_t) (intptr_t) value));
686 }
687 
688 
692 static void
693 heap_plugin_drop (void *cls)
694 {
695  /* nothing needs to be done */
696 }
697 
698 
703 {
708 
712  void *proc_cls;
713 };
714 
715 
724 static int
725 return_value (void *cls,
726  const struct GNUNET_HashCode *key,
727  void *val)
728 {
729  struct GetAllContext *gac = cls;
730 
731  gac->proc (gac->proc_cls,
732  key,
733  1);
734  return GNUNET_OK;
735 }
736 
737 
745 static void
746 heap_get_keys (void *cls,
748  void *proc_cls)
749 {
750  struct Plugin *plugin = cls;
751  struct GetAllContext gac;
752 
753  gac.proc = proc;
754  gac.proc_cls = proc_cls;
756  &return_value,
757  &gac);
758  proc (proc_cls, NULL, 0);
759 }
760 
761 
766 {
770  struct Value *value;
771 
775  uint32_t size;
776 
780  const void *data;
781 };
782 
783 
792 static int
793 remove_iterator (void *cls,
794  const struct GNUNET_HashCode *key,
795  void *val)
796 {
797  struct RemoveContext *rc = cls;
798  struct Value *value = val;
799 
800  if (value->size != rc->size)
801  return GNUNET_YES;
802  if (0 != memcmp (value->data, rc->data, rc->size))
803  return GNUNET_YES;
804  rc->value = value;
805  return GNUNET_NO;
806 }
807 
808 
819 static void
821  const struct GNUNET_HashCode *key,
822  uint32_t size,
823  const void *data,
824  PluginRemoveCont cont,
825  void *cont_cls)
826 {
827  struct Plugin *plugin = cls;
828  struct RemoveContext rc;
829 
830  rc.value = NULL;
831  rc.size = size;
832  rc.data = data;
834  key,
836  &rc);
837  if (NULL == rc.value)
838  {
839  cont (cont_cls,
840  key,
841  size,
842  GNUNET_NO,
843  NULL);
844  return;
845  }
846  delete_value (plugin,
847  rc.value);
848  cont (cont_cls,
849  key,
850  size,
851  GNUNET_OK,
852  NULL);
853 }
854 
855 
862 void *
864 {
867  struct Plugin *plugin;
868  unsigned long long esize;
869 
870  if (GNUNET_OK !=
872  "datastore-heap",
873  "HASHMAPSIZE",
874  &esize))
875  esize = 128 * 1024;
876  plugin = GNUNET_new (struct Plugin);
877  plugin->env = env;
884  api->cls = plugin;
886  api->put = &heap_plugin_put;
891  api->drop = &heap_plugin_drop;
892  api->get_keys = &heap_get_keys;
895  _ ("Heap database running\n"));
896  return api;
897 }
898 
899 
908 static int
909 free_value (void *cls,
910  const struct GNUNET_HashCode *key,
911  void *val)
912 {
913  struct Plugin *plugin = cls;
914  struct Value *value = val;
915 
916  delete_value (plugin, value);
917  return GNUNET_OK;
918 }
919 
920 
926 void *
928 {
930  struct Plugin *plugin = api->cls;
931 
933  &free_value,
934  plugin);
938  GNUNET_free (plugin);
939  GNUNET_free (api);
940  return NULL;
941 }
942 
943 
944 /* end of plugin_datastore_heap.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
PluginGetKeys get_keys
Iterate over all keys in the database.
PluginPut put
Function to store an item in the datastore.
size_t size
Payload (actual payload follows this struct)
void GNUNET_CONTAINER_heap_update_cost(struct GNUNET_CONTAINER_HeapNode *node, GNUNET_CONTAINER_HeapCostType new_cost)
Updates the cost of any node in the tree.
int(* PluginDatumProcessor)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, uint64_t uid)
An processor over a set of items stored in the datastore.
PluginGetType get_zero_anonymity
Get datum (of the specified type) with anonymity level zero.
uint32_t size
Size of data.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
Closure for update_rel_sum() and update_abs_sum().
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
static void heap_plugin_put(void *cls, const struct GNUNET_HashCode *key, bool absent, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, uint32_t replication, struct GNUNET_TIME_Absolute expiration, PluginPutCont cont, void *cont_cls)
Store an item in the datastore.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
Any type of block, used as a wildcard when searching.
struct GNUNET_DATASTORE_PluginEnvironment * env
Our execution environment.
struct GNUNET_CONTAINER_HeapNode * GNUNET_CONTAINER_heap_insert(struct GNUNET_CONTAINER_Heap *heap, void *element, GNUNET_CONTAINER_HeapCostType cost)
Inserts a new element into the heap.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
static int get_iterator(void *cls, const struct GNUNET_HashCode *key, void *val)
Obtain the matching value with the lowest uid >= next_uid.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CONTAINER_MultiHashMap * keyvalue
Mapping from keys to &#39;struct Value&#39;s.
static void delete_value(struct Plugin *plugin, struct Value *value)
Delete the given value, removing it from the plugin&#39;s data structures.
static void heap_plugin_get_key(void *cls, uint64_t next_uid, bool random, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Get one of the results for a particular key in the datastore.
PluginRemoveKey remove_key
Function to remove an item from the database.
const void * data
Data to remove.
static struct GNUNET_FS_UnindexContext * uc
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
PluginEstimateSize estimate_size
Calculate the current on-disk size of the SQ store.
unsigned int array_size
Allocated size of the array.
unsigned int array_pos
First unused offset in &#39;array&#39;.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
PluginKeyProcessor proc
Function to call.
void(* PluginPutCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Put continuation.
uint64_t abs_value_us
The actual value.
uint32_t replication
Replication level for the value.
struct GNUNET_CONTAINER_Heap * by_expiration
Heap organized by minimum expiration time.
Internal representation of the hash map.
void * proc_cls
Closure for &#39;proc&#39;.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
PluginGetRandom get_replication
Function to get a random item with high replication score from the database, lowering the item&#39;s repl...
static int free_value(void *cls, const struct GNUNET_HashCode *key, void *val)
Callback invoked to free all value.
static void heap_plugin_get_replication(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for replication.
PluginDrop drop
Delete the database.
uint64_t next_uid
Lowest uid to consider.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
uint32_t priority
Priority of the value.
static char * value
Value of the record to add/remove.
enum GNUNET_BLOCK_Type type
Type of all of the values in &#39;array&#39;.
void(* PluginKeyProcessor)(void *cls, const struct GNUNET_HashCode *key, unsigned int count)
An processor over a set of keys stored in the datastore.
PluginGetRandom get_expiration
Function to get a random expired item or, if none are expired, either the oldest entry or one with a ...
struct GNUNET_DATACACHE_PluginEnvironment * env
Our execution environment.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
unsigned int zero_anon_offset
Offset of this value in the array of the &#39;struct ZeroAnonByType&#39;; only used if anonymity is zero...
void * libgnunet_plugin_datastore_heap_init(void *cls)
Entry point for the plugin.
void * GNUNET_CONTAINER_heap_peek(const struct GNUNET_CONTAINER_Heap *heap)
Get element stored at the root of heap.
struct Value * value
Value with lowest uid >= next_uid found so far.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
enum GNUNET_BLOCK_Type type
Type of the block.
void * libgnunet_plugin_datastore_heap_done(void *cls)
Exit point from the plugin.
struct GNUNET_CONTAINER_HeapNode * expire_heap
Entry for this value in the &#39;expire&#39; heap.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:317
struct Value * value
Value found.
int GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
static void heap_plugin_drop(void *cls)
Drop database.
struct Value ** array
Array of 0-anonymity items of the given type.
Handle to a node in a heap.
struct ZeroAnonByType * zero_tail
Tail of list of arrays containing zero-anonymity values by type.
enum GNUNET_BLOCK_Type type
Block type requested.
Heap with the minimum cost at the root.
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
A 512-bit hashcode.
void * GNUNET_CONTAINER_heap_walk_get_next(struct GNUNET_CONTAINER_Heap *heap)
Perform a random walk of the tree.
We organize 0-anonymity values in arrays "by type".
static char * plugin
Solver plugin name as string.
struct GNUNET_HashCode key
Key for the entry.
Node in the heap.
struct GNUNET_CONTAINER_HeapNode * replication_heap
Entry for this value in the &#39;replication&#39; heap.
static int remove_iterator(void *cls, const struct GNUNET_HashCode *key, void *val)
Obtain the matching value with the lowest uid >= next_uid.
bool random
If true, return a random value.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Closure for the &#39;return_value&#39; function.
static int return_value(void *cls, const struct GNUNET_HashCode *key, void *val)
Callback invoked to call callback on each value.
void(* PluginRemoveCont)(void *cls, const struct GNUNET_HashCode *key, uint32_t size, int status, const char *msg)
Remove continuation.
Closure for get_cb().
static void heap_plugin_estimate_size(void *cls, unsigned long long *estimate)
Get an estimate of how much space the database is currently using.
uint32_t replication
Replication level for the value.
int GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
const void * data
Pointer to the data.
void * cls
Closure to use for all of the following callbacks (except "next_request").
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
uint32_t size
Number of bytes in &#39;data&#39;.
struct ZeroAnonByType * prev
We keep these in a DLL.
Allow multiple values with the same key.
Entry in the hash map.
static void heap_plugin_get_zero_anonymity(void *cls, uint64_t next_uid, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls)
Call the given processor on an item with zero anonymity.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
unsigned long long size
Size of all values we&#39;re storing.
uint32_t priority
Priority of the value.
struct GNUNET_TIME_Absolute expiration
Expiration time for this value.
Handle for a plugin.
Definition: block.c:37
struct GNUNET_CONTAINER_Heap * by_replication
Heap organized by maximum replication value.
uint32_t anonymity
Anonymity level for the value.
Heap with the maximum cost at the root.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
struct GNUNET_TIME_Absolute expiration
Expiration time for this value.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
static void heap_get_keys(void *cls, PluginKeyProcessor proc, void *proc_cls)
Get all of the keys in the datastore.
struct ZeroAnonByType * zero_head
Head of list of arrays containing zero-anonymity values by type.
static void heap_plugin_remove_key(void *cls, const struct GNUNET_HashCode *key, uint32_t size, const void *data, PluginRemoveCont cont, void *cont_cls)
Remove a particular key in the datastore.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
const void * data
Pointer to the value&#39;s data (allocated at the end of this struct).
Closure for iterator called during &#39;remove_key&#39;.
#define GNUNET_log_from(kind, comp,...)
PluginGetKey get_key
Get a particular datum matching a given hash from the datastore.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_heap_remove_node(struct GNUNET_CONTAINER_HeapNode *node)
Removes a node from the heap.
uint32_t size
Number of bytes in &#39;data&#39;.
struct ZeroAnonByType * next
We keep these in a DLL.
static void heap_plugin_get_expiration(void *cls, PluginDatumProcessor proc, void *proc_cls)
Get a random item for expiration.
#define GNUNET_malloc(size)
Wrapper around malloc.
bool updated
True if the value was found and updated.
static int update_iterator(void *cls, const struct GNUNET_HashCode *key, void *val)
Update the matching value.
const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration to use.
#define GNUNET_free(ptr)
Wrapper around free.