GNUnet  0.10.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 {
41  struct GNUNET_HashCode key;
42 
46  const void *data;
47 
52 
57 
62 
67  unsigned int zero_anon_offset;
68 
72  uint32_t size;
73 
77  uint32_t priority;
78 
82  uint32_t anonymity;
83 
87  uint32_t replication;
88 
93 };
94 
95 
104 
109 
113  struct Value **array;
114 
118  unsigned int array_size;
119 
123  unsigned int array_pos;
124 
129 };
130 
131 
135 struct Plugin {
140 
145 
150 
155 
160 
165 
169  unsigned long long size;
170 };
171 
172 
180 static void
181 heap_plugin_estimate_size(void *cls, unsigned long long *estimate)
182 {
183  struct Plugin *plugin = cls;
184 
185  if (NULL != estimate)
186  *estimate = plugin->size;
187 }
188 
189 
193 struct UpdateContext {
197  uint32_t size;
198 
202  const void *data;
203 
207  uint32_t priority;
208 
212  uint32_t replication;
213 
218 
222  bool updated;
223 };
224 
225 
234 static int
235 update_iterator(void *cls,
236  const struct GNUNET_HashCode *key,
237  void *val)
238 {
239  struct UpdateContext *uc = cls;
240  struct Value *value = val;
241 
242  if (value->size != uc->size)
243  return GNUNET_YES;
244  if (0 != memcmp(value->data, uc->data, uc->size))
245  return GNUNET_YES;
247  uc->expiration);
249  {
250  value->expiration = uc->expiration;
252  value->expiration.abs_value_us);
253  }
254  /* Saturating adds, don't overflow */
255  if (value->priority > UINT32_MAX - uc->priority)
256  value->priority = UINT32_MAX;
257  else
258  value->priority += uc->priority;
259  if (value->replication > UINT32_MAX - uc->replication)
260  value->replication = UINT32_MAX;
261  else
262  value->replication += uc->replication;
263  uc->updated = true;
264  return GNUNET_NO;
265 }
266 
283 static void
284 heap_plugin_put(void *cls,
285  const struct GNUNET_HashCode *key,
286  bool absent,
287  uint32_t size,
288  const void *data,
289  enum GNUNET_BLOCK_Type type,
290  uint32_t priority,
291  uint32_t anonymity,
292  uint32_t replication,
294  PluginPutCont cont,
295  void *cont_cls)
296 {
297  struct Plugin *plugin = cls;
298  struct Value *value;
299 
300  if (!absent)
301  {
302  struct UpdateContext uc;
303 
304  uc.size = size;
305  uc.data = data;
306  uc.priority = priority;
308  uc.expiration = expiration;
309  uc.updated = false;
311  key,
313  &uc);
314  if (uc.updated)
315  {
316  cont(cont_cls, key, size, GNUNET_NO, NULL);
317  return;
318  }
319  }
320  value = GNUNET_malloc(sizeof(struct Value) + size);
321  value->key = *key;
322  value->data = &value[1];
324  value,
325  expiration.abs_value_us);
327  value,
328  replication);
329  value->expiration = expiration;
330  if (0 == anonymity)
331  {
332  struct ZeroAnonByType *zabt;
333 
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;
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;
353  }
354  value->size = size;
355  value->priority = priority;
356  value->anonymity = anonymity;
357  value->replication = replication;
358  value->type = type;
359  GNUNET_memcpy(&value[1], data, size);
361  &value->key,
362  value,
364  plugin->size += size;
365  cont(cont_cls, key, size, GNUNET_OK, NULL);
366 }
367 
368 
376 static void
378  struct Value *value)
379 {
382  &value->key,
383  value));
386  if (0 == value->anonymity)
387  {
388  struct ZeroAnonByType *zabt;
389 
390  for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
391  if (zabt->type == value->type)
392  break;
393  GNUNET_assert(NULL != zabt);
394  zabt->array[value->zero_anon_offset] = zabt->array[--zabt->array_pos];
396  if (0 == zabt->array_pos)
397  {
398  GNUNET_array_grow(zabt->array,
399  zabt->array_size,
400  0);
402  plugin->zero_tail,
403  zabt);
404  GNUNET_free(zabt);
405  }
406  }
407  plugin->size -= value->size;
408  GNUNET_free(value);
409 }
410 
411 
415 struct GetContext {
419  uint64_t next_uid;
420 
424  struct Value *value;
425 
429  enum GNUNET_BLOCK_Type type;
430 
434  bool random;
435 };
436 
437 
446 static int
447 get_iterator(void *cls,
448  const struct GNUNET_HashCode *key,
449  void *val)
450 {
451  struct GetContext *gc = cls;
452  struct Value *value = val;
453 
454  if ((gc->type != GNUNET_BLOCK_TYPE_ANY) &&
455  (gc->type != value->type))
456  return GNUNET_OK;
457  if (gc->random)
458  {
459  gc->value = value;
460  return GNUNET_NO;
461  }
462  if ((uint64_t)(intptr_t)value < gc->next_uid)
463  return GNUNET_OK;
464  if ((NULL != gc->value) &&
465  (value > gc->value))
466  return GNUNET_OK;
467  gc->value = value;
468  return GNUNET_OK;
469 }
470 
471 
485 static void
487  uint64_t next_uid,
488  bool random,
489  const struct GNUNET_HashCode *key,
490  enum GNUNET_BLOCK_Type type,
492  void *proc_cls)
493 {
494  struct Plugin *plugin = cls;
495  struct GetContext gc;
496 
497  gc.value = NULL;
498  gc.next_uid = next_uid;
499  gc.random = random;
500  gc.type = type;
501  if (NULL == key)
502  {
504  &get_iterator,
505  &gc);
506  }
507  else
508  {
510  key,
511  &get_iterator,
512  &gc);
513  }
514  if (NULL == gc.value)
515  {
516  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
517  return;
518  }
520  proc(proc_cls,
521  &gc.value->key,
522  gc.value->size,
523  &gc.value[1],
524  gc.value->type,
525  gc.value->priority,
526  gc.value->anonymity,
527  gc.value->replication,
528  gc.value->expiration,
529  (uint64_t)(intptr_t)gc.value));
530 }
531 
532 
544 static void
547  void *proc_cls)
548 {
549  struct Plugin *plugin = cls;
550  struct Value *value;
551 
553  if (NULL == value)
554  {
555  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
556  return;
557  }
558  if (value->replication > 0)
559  {
560  value->replication--;
562  value,
563  value->replication);
564  }
565  else
566  {
567  /* need a better way to pick a random item, replication level is always 0 */
569  value,
570  value->replication);
572  }
574  proc(proc_cls,
575  &value->key,
576  value->size,
577  &value[1],
578  value->type,
579  value->priority,
580  value->anonymity,
581  value->replication,
582  value->expiration,
583  (uint64_t)(intptr_t)value));
584 }
585 
586 
595 static void
597  void *proc_cls)
598 {
599  struct Plugin *plugin = cls;
600  struct Value *value;
601 
602  value = GNUNET_CONTAINER_heap_peek(plugin->by_expiration);
603  if (NULL == value)
604  {
605  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
606  return;
607  }
608  if (GNUNET_NO ==
609  proc(proc_cls,
610  &value->key,
611  value->size,
612  &value[1],
613  value->type,
614  value->priority,
615  value->anonymity,
616  value->replication,
617  value->expiration,
618  (uint64_t)(intptr_t)value))
619  delete_value(plugin, value);
620 }
621 
622 
634 static void
635 heap_plugin_get_zero_anonymity(void *cls, uint64_t next_uid,
636  enum GNUNET_BLOCK_Type type,
637  PluginDatumProcessor proc, void *proc_cls)
638 {
639  struct Plugin *plugin = cls;
640  struct ZeroAnonByType *zabt;
641  struct Value *value = NULL;
642 
643  for (zabt = plugin->zero_head; NULL != zabt; zabt = zabt->next)
644  {
645  if ((type != GNUNET_BLOCK_TYPE_ANY) &&
646  (type != zabt->type))
647  continue;
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  }
657  }
658  if (NULL == value)
659  {
660  proc(proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
661  return;
662  }
664  proc(proc_cls,
665  &value->key,
666  value->size,
667  &value[1],
668  value->type,
669  value->priority,
670  value->anonymity,
671  value->replication,
672  value->expiration,
673  (uint64_t)(intptr_t)value));
674 }
675 
676 
680 static void
682 {
683  /* nothing needs to be done */
684 }
685 
686 
695 
699  void *proc_cls;
700 };
701 
702 
711 static int
712 return_value(void *cls,
713  const struct GNUNET_HashCode *key,
714  void *val)
715 {
716  struct GetAllContext *gac = cls;
717 
718  gac->proc(gac->proc_cls,
719  key,
720  1);
721  return GNUNET_OK;
722 }
723 
724 
732 static void
733 heap_get_keys(void *cls,
735  void *proc_cls)
736 {
737  struct Plugin *plugin = cls;
738  struct GetAllContext gac;
739 
740  gac.proc = proc;
741  gac.proc_cls = proc_cls;
743  &return_value,
744  &gac);
745  proc(proc_cls, NULL, 0);
746 }
747 
748 
756  struct Value *value;
757 
761  uint32_t size;
762 
766  const void *data;
767 };
768 
769 
778 static int
779 remove_iterator(void *cls,
780  const struct GNUNET_HashCode *key,
781  void *val)
782 {
783  struct RemoveContext *rc = cls;
784  struct Value *value = val;
785 
786  if (value->size != rc->size)
787  return GNUNET_YES;
788  if (0 != memcmp(value->data, rc->data, rc->size))
789  return GNUNET_YES;
790  rc->value = value;
791  return GNUNET_NO;
792 }
793 
794 
805 static void
807  const struct GNUNET_HashCode *key,
808  uint32_t size,
809  const void *data,
810  PluginRemoveCont cont,
811  void *cont_cls)
812 {
813  struct Plugin *plugin = cls;
814  struct RemoveContext rc;
815 
816  rc.value = NULL;
817  rc.size = size;
818  rc.data = data;
820  key,
822  &rc);
823  if (NULL == rc.value)
824  {
825  cont(cont_cls,
826  key,
827  size,
828  GNUNET_NO,
829  NULL);
830  return;
831  }
832  delete_value(plugin,
833  rc.value);
834  cont(cont_cls,
835  key,
836  size,
837  GNUNET_OK,
838  NULL);
839 }
840 
841 
848 void *
850 {
853  struct Plugin *plugin;
854  unsigned long long esize;
855 
856  if (GNUNET_OK !=
858  "datastore-heap",
859  "HASHMAPSIZE",
860  &esize))
861  esize = 128 * 1024;
862  plugin = GNUNET_new(struct Plugin);
863  plugin->env = env;
868  api->cls = plugin;
870  api->put = &heap_plugin_put;
875  api->drop = &heap_plugin_drop;
876  api->get_keys = &heap_get_keys;
879  _("Heap database running\n"));
880  return api;
881 }
882 
883 
892 static int
893 free_value(void *cls,
894  const struct GNUNET_HashCode *key,
895  void *val)
896 {
897  struct Plugin *plugin = cls;
898  struct Value *value = val;
899 
900  delete_value(plugin, value);
901  return GNUNET_OK;
902 }
903 
904 
910 void *
912 {
914  struct Plugin *plugin = api->cls;
915 
917  &free_value,
918  plugin);
922  GNUNET_free(plugin);
923  GNUNET_free(api);
924  return NULL;
925 }
926 
927 /* 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:46
#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.
static struct GNUNET_ATS_SolverFunctions * plugin
Our solver.
#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".
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.