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
38 {
39 
43  struct GNUNET_HashCode key;
44 
48  const void *data;
49 
54 
59 
64 
69  unsigned int zero_anon_offset;
70 
74  uint32_t size;
75 
79  uint32_t priority;
80 
84  uint32_t anonymity;
85 
89  uint32_t replication;
90 
95 
96 };
97 
98 
103 {
104 
109 
114 
118  struct Value **array;
119 
123  unsigned int array_size;
124 
128  unsigned int array_pos;
129 
134 };
135 
136 
140 struct Plugin
141 {
146 
151 
156 
161 
166 
171 
175  unsigned long long size;
176 
177 };
178 
179 
187 static void
188 heap_plugin_estimate_size (void *cls, unsigned long long *estimate)
189 {
190  struct Plugin *plugin = cls;
191 
192  if (NULL != estimate)
193  *estimate = plugin->size;
194 }
195 
196 
200 struct UpdateContext
201 {
205  uint32_t size;
206 
210  const void *data;
211 
215  uint32_t priority;
216 
220  uint32_t replication;
221 
226 
230  bool updated;
231 };
232 
233 
242 static int
243 update_iterator (void *cls,
244  const struct GNUNET_HashCode *key,
245  void *val)
246 {
247  struct UpdateContext *uc = cls;
248  struct Value *value = val;
249 
250  if (value->size != uc->size)
251  return GNUNET_YES;
252  if (0 != memcmp (value->data, uc->data, uc->size))
253  return GNUNET_YES;
255  uc->expiration);
257  {
258  value->expiration = uc->expiration;
260  value->expiration.abs_value_us);
261  }
262  /* Saturating adds, don't overflow */
263  if (value->priority > UINT32_MAX - uc->priority)
264  value->priority = UINT32_MAX;
265  else
266  value->priority += uc->priority;
267  if (value->replication > UINT32_MAX - uc->replication)
268  value->replication = UINT32_MAX;
269  else
270  value->replication += uc->replication;
271  uc->updated = true;
272  return GNUNET_NO;
273 }
274 
291 static void
292 heap_plugin_put (void *cls,
293  const struct GNUNET_HashCode *key,
294  bool absent,
295  uint32_t size,
296  const void *data,
297  enum GNUNET_BLOCK_Type type,
298  uint32_t priority,
299  uint32_t anonymity,
300  uint32_t replication,
302  PluginPutCont cont,
303  void *cont_cls)
304 {
305  struct Plugin *plugin = cls;
306  struct Value *value;
307 
308  if (!absent) {
309  struct UpdateContext uc;
310 
311  uc.size = size;
312  uc.data = data;
313  uc.priority = priority;
315  uc.expiration = expiration;
316  uc.updated = false;
318  key,
320  &uc);
321  if (uc.updated)
322  {
323  cont (cont_cls, key, size, GNUNET_NO, NULL);
324  return;
325  }
326  }
327  value = GNUNET_malloc (sizeof (struct Value) + size);
328  value->key = *key;
329  value->data = &value[1];
331  value,
332  expiration.abs_value_us);
334  value,
335  replication);
336  value->expiration = expiration;
337  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;
349  plugin->zero_tail,
350  zabt);
351  }
352  if (zabt->array_size == zabt->array_pos)
353  {
354  GNUNET_array_grow (zabt->array,
355  zabt->array_size,
356  zabt->array_size * 2 + 4);
357  }
358  value->zero_anon_offset = zabt->array_pos;
359  zabt->array[zabt->array_pos++] = value;
360  }
361  value->size = size;
362  value->priority = priority;
363  value->anonymity = anonymity;
364  value->replication = replication;
365  value->type = type;
366  GNUNET_memcpy (&value[1], data, size);
368  &value->key,
369  value,
371  plugin->size += size;
372  cont (cont_cls, key, size, GNUNET_OK, NULL);
373 }
374 
375 
383 static void
385  struct Value *value)
386 {
389  &value->key,
390  value));
393  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];
403  if (0 == zabt->array_pos)
404  {
405  GNUNET_array_grow (zabt->array,
406  zabt->array_size,
407  0);
409  plugin->zero_tail,
410  zabt);
411  GNUNET_free (zabt);
412  }
413  }
414  plugin->size -= value->size;
415  GNUNET_free (value);
416 }
417 
418 
422 struct GetContext
423 {
424 
428  uint64_t next_uid;
429 
433  struct Value *value;
434 
438  enum GNUNET_BLOCK_Type type;
439 
443  bool random;
444 
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  value,
573  value->replication);
574  }
575  else
576  {
577  /* need a better way to pick a random item, replication level is always 0 */
579  value,
580  value->replication);
582  }
584  proc (proc_cls,
585  &value->key,
586  value->size,
587  &value[1],
588  value->type,
589  value->priority,
590  value->anonymity,
591  value->replication,
592  value->expiration,
593  (uint64_t) (intptr_t) value));
594 }
595 
596 
605 static void
607  void *proc_cls)
608 {
609  struct Plugin *plugin = cls;
610  struct Value *value;
611 
612  value = GNUNET_CONTAINER_heap_peek (plugin->by_expiration);
613  if (NULL == value)
614  {
615  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
616  return;
617  }
618  if (GNUNET_NO ==
619  proc (proc_cls,
620  &value->key,
621  value->size,
622  &value[1],
623  value->type,
624  value->priority,
625  value->anonymity,
626  value->replication,
627  value->expiration,
628  (uint64_t) (intptr_t) value))
629  delete_value (plugin, value);
630 }
631 
632 
644 static void
645 heap_plugin_get_zero_anonymity (void *cls, uint64_t next_uid,
646  enum GNUNET_BLOCK_Type type,
647  PluginDatumProcessor proc, void *proc_cls)
648 {
649  struct Plugin *plugin = cls;
650  struct ZeroAnonByType *zabt;
651  struct Value *value = NULL;
652 
653  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  {
660  if ( (uint64_t) (intptr_t) zabt->array[i] < next_uid)
661  continue;
662  if ( (NULL != value) &&
663  (zabt->array[i] > value) )
664  continue;
665  value = zabt->array[i];
666  }
667  }
668  if (NULL == value)
669  {
670  proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
671  return;
672  }
674  proc (proc_cls,
675  &value->key,
676  value->size,
677  &value[1],
678  value->type,
679  value->priority,
680  value->anonymity,
681  value->replication,
682  value->expiration,
683  (uint64_t) (intptr_t) value));
684 }
685 
686 
690 static void
691 heap_plugin_drop (void *cls)
692 {
693  /* nothing needs to be done */
694 }
695 
696 
701 {
706 
710  void *proc_cls;
711 };
712 
713 
722 static int
723 return_value (void *cls,
724  const struct GNUNET_HashCode *key,
725  void *val)
726 {
727  struct GetAllContext *gac = cls;
728 
729  gac->proc (gac->proc_cls,
730  key,
731  1);
732  return GNUNET_OK;
733 }
734 
735 
743 static void
744 heap_get_keys (void *cls,
746  void *proc_cls)
747 {
748  struct Plugin *plugin = cls;
749  struct GetAllContext gac;
750 
751  gac.proc = proc;
752  gac.proc_cls = proc_cls;
754  &return_value,
755  &gac);
756  proc (proc_cls, NULL, 0);
757 }
758 
759 
764 {
765 
769  struct Value *value;
770 
774  uint32_t size;
775 
779  const void *data;
780 
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;
882  api->cls = plugin;
884  api->put = &heap_plugin_put;
889  api->drop = &heap_plugin_drop;
890  api->get_keys = &heap_get_keys;
893  _("Heap database running\n"));
894  return api;
895 }
896 
897 
906 static int
907 free_value (void *cls,
908  const struct GNUNET_HashCode *key,
909  void *val)
910 {
911  struct Plugin *plugin = cls;
912  struct Value *value = val;
913 
914  delete_value (plugin, value);
915  return GNUNET_OK;
916 }
917 
918 
924 void *
926 {
928  struct Plugin *plugin = api->cls;
929 
931  &free_value,
932  plugin);
936  GNUNET_free (plugin);
937  GNUNET_free (api);
938  return NULL;
939 }
940 
941 /* 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
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;.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:208
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.
#define GNUNET_memcpy(dst, src, n)
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.
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.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_HashMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
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:80
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.
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.