GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
plugin_datacache_heap.c File Reference

heap-only implementation of a database backend for the datacache More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_datacache_plugin.h"
Include dependency graph for plugin_datacache_heap.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
 
struct  Value
 Entry in the hash map. More...
 
struct  PutContext
 Closure for put_cb(). More...
 
struct  GetContext
 Closure for get_cb(). More...
 
struct  GetClosestContext
 Closure for find_closest(). More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "datacache-heap", __VA_ARGS__)
 
#define LOG_STRERROR_FILE(kind, op, fn)
 
#define NUM_HEAPS   24
 
#define OVERHEAD   (sizeof(struct Value) + 64)
 

Functions

static enum GNUNET_GenericReturnValue put_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
 Function called during PUT to detect if an equivalent block already exists.
 
static ssize_t heap_plugin_put (void *cls, uint32_t xor_distance, const struct GNUNET_DATACACHE_Block *block)
 Store an item in the datastore.
 
static enum GNUNET_GenericReturnValue get_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
 Function called during GET to find matching blocks.
 
static unsigned int heap_plugin_get (void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
 Iterate over the results for a particular key in the datastore.
 
static enum GNUNET_GenericReturnValue heap_plugin_del (void *cls)
 Delete the entry with the lowest expiration value from the datacache right now.
 
static enum GNUNET_GenericReturnValue find_closest (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static unsigned int heap_plugin_get_closest (void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
 Iterate over the results that are "close" to a particular key in the datacache.
 
void * libgnunet_plugin_datacache_heap_init (void *cls)
 Entry point for the plugin.
 
void * libgnunet_plugin_datacache_heap_done (void *cls)
 Exit point from the plugin.
 

Detailed Description

heap-only implementation of a database backend for the datacache

Author
Christian Grothoff

Definition in file plugin_datacache_heap.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "datacache-heap", __VA_ARGS__)

Definition at line 30 of file plugin_datacache_heap.c.

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  op,
  fn 
)
Value:
"datacache-heap", \
op, fn)
static struct GNUNET_ARM_Operation * op
Current operation.
Definition gnunet-arm.c:143
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 32 of file plugin_datacache_heap.c.

41{
46
51
55 struct GNUNET_CONTAINER_Heap *heaps[NUM_HEAPS];
56};
57
58
62struct Value
63{
68
73
78
82 uint32_t distance;
83
84};
85
86
87#define OVERHEAD (sizeof(struct Value) + 64)
88
89
93struct PutContext
94{
98 const struct GNUNET_DATACACHE_Block *block;
99
103 bool found;
104};
105
106
117put_cb (void *cls,
118 const struct GNUNET_HashCode *key,
119 void *value)
120{
121 struct PutContext *put_ctx = cls;
122 struct Value *val = value;
123
124 if ((val->block.data_size == put_ctx->block->data_size) &&
125 (val->block.type == put_ctx->block->type) &&
126 (0 == memcmp (val->block.data,
127 put_ctx->block->data,
128 put_ctx->block->data_size)))
129 {
130 put_ctx->found = true;
133 put_ctx->block->expiration_time);
134 /* replace old path with new path */
135 GNUNET_free (val->put_path);
136 val->put_path = GNUNET_memdup (put_ctx->block->put_path,
137 put_ctx->block->put_path_length
138 * sizeof (struct GNUNET_DHT_PathElement));
139 val->block.put_path = val->put_path;
144 "Got same value for key %s and type %u (size %u vs %u)\n",
145 GNUNET_h2s (key),
146 (unsigned int) val->block.type,
147 (unsigned int) val->block.data_size,
148 (unsigned int) put_ctx->block->data_size);
149 return GNUNET_NO;
150 }
151 return GNUNET_YES;
152}
153
154
163static ssize_t
164heap_plugin_put (void *cls,
165 uint32_t xor_distance,
166 const struct GNUNET_DATACACHE_Block *block)
167{
168 struct Plugin *plugin = cls;
169 struct Value *val;
170 struct PutContext put_ctx = {
171 .block = block,
172 .found = false
173 };
174
176 "Storing %u bytes under key %s with path length %u\n",
177 (unsigned int) block->data_size,
178 GNUNET_h2s (&block->key),
181 &block->key,
182 &put_cb,
183 &put_ctx);
184 if (GNUNET_YES == put_ctx.found)
185 return 0;
186 val = GNUNET_malloc (sizeof(struct Value)
187 + block->data_size);
188 GNUNET_memcpy (&val[1],
189 block->data,
191 val->block = *block;
192 val->block.data = &val[1];
193 if (xor_distance >= NUM_HEAPS)
194 val->distance = NUM_HEAPS - 1;
195 else
196 val->distance = xor_distance;
197 if (0 != block->put_path_length)
198 {
199 val->put_path
202 * sizeof (struct GNUNET_DHT_PathElement));
203 val->block.put_path = val->put_path;
204 }
206 &val->block.key,
207 val,
210 plugin->heaps[val->distance],
211 val,
213 return val->block.data_size + OVERHEAD;
214}
215
216
220struct GetContext
221{
226
230 void *iter_cls;
231
235 unsigned int cnt;
236
241};
242
243
254get_cb (void *cls,
255 const struct GNUNET_HashCode *key,
256 void *value)
257{
258 struct GetContext *get_ctx = cls;
259 struct Value *val = value;
261
262 if ( (get_ctx->type != val->block.type) &&
263 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
264 {
266 "Result for key %s does not match block type %d\n",
267 GNUNET_h2s (key),
268 get_ctx->type);
269 return GNUNET_OK;
270 }
272 {
274 "Result for key %s is expired\n",
275 GNUNET_h2s (key));
276 return GNUNET_OK;
277 }
279 "Found result for key %s\n",
280 GNUNET_h2s (key));
281 if (NULL != get_ctx->iter)
282 ret = get_ctx->iter (get_ctx->iter_cls,
283 &val->block);
284 else
285 ret = GNUNET_YES;
286 get_ctx->cnt++;
287 return ret;
288}
289
290
302static unsigned int
303heap_plugin_get (void *cls,
304 const struct GNUNET_HashCode *key,
307 void *iter_cls)
308{
309 struct Plugin *plugin = cls;
310 struct GetContext get_ctx;
311
312 get_ctx.type = type;
313 get_ctx.iter = iter;
314 get_ctx.iter_cls = iter_cls;
315 get_ctx.cnt = 0;
317 key,
318 &get_cb,
319 &get_ctx);
320 return get_ctx.cnt;
321}
322
323
332heap_plugin_del (void *cls)
333{
334 struct Plugin *plugin = cls;
335 struct Value *val;
336
337 for (unsigned int i = 0; i < NUM_HEAPS; i++)
338 {
340 if (NULL != val)
341 break;
342 }
343 if (NULL == val)
344 return GNUNET_SYSERR;
347 &val->block.key,
348 val));
349 plugin->env->delete_notify (plugin->env->cls,
350 &val->block.key,
351 val->block.data_size + OVERHEAD);
352 GNUNET_free (val->put_path);
353 GNUNET_free (val);
354 return GNUNET_OK;
355}
356
357
362{
363 struct Value **values;
364
365 const struct GNUNET_HashCode *key;
366
368
369 unsigned int num_results;
370
371};
372
373
375find_closest (void *cls,
376 const struct GNUNET_HashCode *key,
377 void *value)
378{
379 struct GetClosestContext *gcc = cls;
380 struct Value *val = value;
381 unsigned int j;
382
383 if (1 != GNUNET_CRYPTO_hash_cmp (key,
384 gcc->key))
385 return GNUNET_OK; /* useless */
386 if ( (val->block.type != gcc->type) &&
387 (GNUNET_BLOCK_TYPE_ANY != gcc->type) )
388 return GNUNET_OK; /* useless */
389 j = gcc->num_results;
390 for (unsigned int i = 0; i < gcc->num_results; i++)
391 {
392 if (NULL == gcc->values[i])
393 {
394 j = i;
395 break;
396 }
397 if (1 ==
399 key))
400 {
401 j = i;
402 break;
403 }
404 }
405 if (j == gcc->num_results)
406 return GNUNET_OK;
407 gcc->values[j] = val;
408 return GNUNET_OK;
409}
410
411
426static unsigned int
427heap_plugin_get_closest (void *cls,
428 const struct GNUNET_HashCode *key,
430 unsigned int num_results,
432 void *iter_cls)
433{
434 struct Plugin *plugin = cls;
435 struct Value *values[num_results];
436 struct GetClosestContext gcc = {
437 .values = values,
438 .type = type,
439 .num_results = num_results * 2,
440 .key = key
441 };
442
445 &gcc);
446 for (unsigned int i = 0; i < num_results * 2; i++)
447 {
448 if (NULL == values[i])
449 return i;
450 if ( (NULL != iter) &&
451 (GNUNET_SYSERR ==
452 iter (iter_cls,
453 &values[i]->block)) )
454 {
456 "Ending iteration (client error)\n");
457 return i;
458 }
459 }
460 return num_results * 2;
461}
462
463void *
465
472void *
474{
477 struct Plugin *plugin;
478
479 plugin = GNUNET_new (struct Plugin);
480 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */
481 GNUNET_YES);
482 for (unsigned int i = 0; i < NUM_HEAPS; i++)
485 plugin->env = env;
487 api->cls = plugin;
488 api->get = &heap_plugin_get;
489 api->put = &heap_plugin_put;
490 api->del = &heap_plugin_del;
491 api->get_closest = &heap_plugin_get_closest;
493 _ ("Heap datacache running\n"));
494 return api;
495}
496
497void *
499
506void *
508{
510 struct Plugin *plugin = api->cls;
511 struct Value *val;
512
513 for (unsigned int i = 0; i < NUM_HEAPS; i++)
514 {
515 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i])))
516 {
519 &val->block.key,
520 val));
521 GNUNET_free (val->put_path);
522 GNUNET_free (val);
523 }
525 }
528 GNUNET_free (api);
529 return NULL;
530}
531
532
533/* end of plugin_datacache_heap.c */
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static int ret
Final status code.
Definition gnunet-arm.c:93
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_CONTAINER_MultiHashMap * values
Collection of all values (represented with ValueSet).
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
enum GNUNET_GenericReturnValue(* GNUNET_DATACACHE_Iterator)(void *cls, const struct GNUNET_DATACACHE_Block *block)
An iterator over a set of items stored in the datacache.
int GNUNET_CRYPTO_hash_cmp(const struct GNUNET_HashCode *h1, const struct GNUNET_HashCode *h2)
Compare function for HashCodes, producing a total ordering of all hashcodes.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
enum GNUNET_GenericReturnValue 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.
enum GNUNET_GenericReturnValue 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.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void * GNUNET_CONTAINER_heap_remove_root(struct GNUNET_CONTAINER_Heap *heap)
Remove root of the heap.
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.
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.
struct GNUNET_CONTAINER_Heap * GNUNET_CONTAINER_heap_create(enum GNUNET_CONTAINER_HeapOrder order)
Create a new heap.
void GNUNET_CONTAINER_heap_destroy(struct GNUNET_CONTAINER_Heap *heap)
Destroys the heap.
@ GNUNET_CONTAINER_HEAP_ORDER_MIN
Heap with the minimum cost at the root.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_memdup(buf, size)
Allocate and initialize a block of memory.
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:368
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition time.c:671
static struct GNUNET_CONTAINER_MultiPeerMap * map
Peermap of PeerIdentities to "struct PeerEntry" (for fast lookup).
Definition peer.c:63
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static enum GNUNET_GenericReturnValue get_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during GET to find matching blocks.
void * libgnunet_plugin_datacache_heap_init(void *cls)
Entry point for the plugin.
#define OVERHEAD
static enum GNUNET_GenericReturnValue put_cb(void *cls, const struct GNUNET_HashCode *key, void *value)
Function called during PUT to detect if an equivalent block already exists.
static unsigned int heap_plugin_get(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results for a particular key in the datastore.
static unsigned int heap_plugin_get_closest(void *cls, const struct GNUNET_HashCode *key, enum GNUNET_BLOCK_Type type, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls)
Iterate over the results that are "close" to a particular key in the datacache.
static enum GNUNET_GenericReturnValue find_closest(void *cls, const struct GNUNET_HashCode *key, void *value)
#define NUM_HEAPS
void * libgnunet_plugin_datacache_heap_done(void *cls)
Exit point from the plugin.
static enum GNUNET_GenericReturnValue heap_plugin_del(void *cls)
Delete the entry with the lowest expiration value from the datacache right now.
static ssize_t heap_plugin_put(void *cls, uint32_t xor_distance, const struct GNUNET_DATACACHE_Block *block)
Store an item in the datastore.
#define LOG(kind,...)
void * cls
Closure for all of the callbacks.
Handle to a node in a heap.
Internal representation of the hash map.
Information about a block stored in the datacache.
const struct GNUNET_DHT_PathElement * put_path
PUT path taken by the block, array of peer identities.
enum GNUNET_BLOCK_Type type
Type of the block.
const void * data
Actual block data.
struct GNUNET_HashCode key
Key of the block.
size_t data_size
Number of bytes in data.
unsigned int put_path_length
Length of the put_path array.
struct GNUNET_TIME_Absolute expiration_time
When does the block expire?
The datastore service will pass a pointer to a struct of this type as the first and only argument to ...
void * cls
Closure to use for callbacks.
struct returned by the initialization function of the plugin
void * cls
Closure to pass to all plugin functions.
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
A 512-bit hashcode.
void * cls
Closure to pass to start_testcase.
uint64_t abs_value_us
The actual value.
Closure for find_closest().
enum GNUNET_BLOCK_Type type
const struct GNUNET_HashCode * key
Closure for get_cb().
void * iter_cls
Closure for iter.
enum GNUNET_BLOCK_Type type
Block type requested.
GNUNET_DATACACHE_Iterator iter
Function to call for each result.
unsigned int cnt
Number of results found.
Handle for a plugin.
Definition block.c:38
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition block.c:47
Closure for put_cb().
const struct GNUNET_DATACACHE_Block * block
Block data.
bool found
Value to set to true if an equivalent block was found.
Entry in the hash map.
struct GNUNET_CONTAINER_HeapNode * hn
Corresponding node in the heap.
struct GNUNET_DATACACHE_Block block
Block data.
struct GNUNET_DHT_PathElement * put_path
Put path as a non-const pointer.
uint32_t distance
How close is the hash to us? Determines which heap we are in!

◆ NUM_HEAPS

#define NUM_HEAPS   24

Definition at line 36 of file plugin_datacache_heap.c.

◆ OVERHEAD

#define OVERHEAD   (sizeof(struct Value) + 64)

Definition at line 88 of file plugin_datacache_heap.c.

Function Documentation

◆ put_cb()

static enum GNUNET_GenericReturnValue put_cb ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Function called during PUT to detect if an equivalent block already exists.

Parameters
clsthe struct PutContext
keythe key for the value(s)
valuean existing value
Returns
GNUNET_YES if not found (to continue to iterate)

Definition at line 118 of file plugin_datacache_heap.c.

121{
122 struct PutContext *put_ctx = cls;
123 struct Value *val = value;
124
125 if ((val->block.data_size == put_ctx->block->data_size) &&
126 (val->block.type == put_ctx->block->type) &&
127 (0 == memcmp (val->block.data,
128 put_ctx->block->data,
129 put_ctx->block->data_size)))
130 {
131 put_ctx->found = true;
134 put_ctx->block->expiration_time);
135 /* replace old path with new path */
136 GNUNET_free (val->put_path);
137 val->put_path = GNUNET_memdup (put_ctx->block->put_path,
138 put_ctx->block->put_path_length
139 * sizeof (struct GNUNET_DHT_PathElement));
140 val->block.put_path = val->put_path;
145 "Got same value for key %s and type %u (size %u vs %u)\n",
146 GNUNET_h2s (key),
147 (unsigned int) val->block.type,
148 (unsigned int) val->block.data_size,
149 (unsigned int) put_ctx->block->data_size);
150 return GNUNET_NO;
151 }
152 return GNUNET_YES;
153}

References GNUNET_TIME_Absolute::abs_value_us, Value::block, PutContext::block, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, GNUNET_DATACACHE_Block::expiration_time, PutContext::found, GNUNET_CONTAINER_heap_update_cost(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_h2s(), GNUNET_log, GNUNET_memdup, GNUNET_NO, GNUNET_TIME_absolute_max(), GNUNET_YES, Value::hn, key, GNUNET_DATACACHE_Block::put_path, Value::put_path, GNUNET_DATACACHE_Block::put_path_length, GNUNET_DATACACHE_Block::type, and value.

Referenced by heap_plugin_put().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ heap_plugin_put()

static ssize_t heap_plugin_put ( void *  cls,
uint32_t  xor_distance,
const struct GNUNET_DATACACHE_Block block 
)
static

Store an item in the datastore.

Parameters
clsclosure (our struct Plugin)
xor_distancehow close is key to our PID?
blockdata to store
Returns
0 if duplicate, -1 on error, number of bytes used otherwise

Definition at line 165 of file plugin_datacache_heap.c.

168{
169 struct Plugin *plugin = cls;
170 struct Value *val;
171 struct PutContext put_ctx = {
172 .block = block,
173 .found = false
174 };
175
177 "Storing %u bytes under key %s with path length %u\n",
178 (unsigned int) block->data_size,
179 GNUNET_h2s (&block->key),
182 &block->key,
183 &put_cb,
184 &put_ctx);
185 if (GNUNET_YES == put_ctx.found)
186 return 0;
187 val = GNUNET_malloc (sizeof(struct Value)
188 + block->data_size);
189 GNUNET_memcpy (&val[1],
190 block->data,
192 val->block = *block;
193 val->block.data = &val[1];
194 if (xor_distance >= NUM_HEAPS)
195 val->distance = NUM_HEAPS - 1;
196 else
197 val->distance = xor_distance;
198 if (0 != block->put_path_length)
199 {
200 val->put_path
203 * sizeof (struct GNUNET_DHT_PathElement));
204 val->block.put_path = val->put_path;
205 }
207 &val->block.key,
208 val,
211 plugin->heaps[val->distance],
212 val,
214 return val->block.data_size + OVERHEAD;
215}

References GNUNET_TIME_Absolute::abs_value_us, Value::block, PutContext::block, GNUNET_DATACACHE_Block::data, GNUNET_DATACACHE_Block::data_size, Value::distance, GNUNET_DATACACHE_Block::expiration_time, PutContext::found, GNUNET_CONTAINER_heap_insert(), GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_memdup, GNUNET_YES, Value::hn, GNUNET_DATACACHE_Block::key, NUM_HEAPS, OVERHEAD, plugin, put_cb(), GNUNET_DATACACHE_Block::put_path, Value::put_path, and GNUNET_DATACACHE_Block::put_path_length.

Referenced by libgnunet_plugin_datacache_heap_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_cb()

static enum GNUNET_GenericReturnValue get_cb ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Function called during GET to find matching blocks.

Only matches by type.

Parameters
clsthe struct GetContext
keythe key for the value(s)
valuean existing value
Returns
GNUNET_YES to continue to iterate

Definition at line 255 of file plugin_datacache_heap.c.

258{
259 struct GetContext *get_ctx = cls;
260 struct Value *val = value;
262
263 if ( (get_ctx->type != val->block.type) &&
264 (GNUNET_BLOCK_TYPE_ANY != get_ctx->type) )
265 {
267 "Result for key %s does not match block type %d\n",
268 GNUNET_h2s (key),
269 get_ctx->type);
270 return GNUNET_OK;
271 }
273 {
275 "Result for key %s is expired\n",
276 GNUNET_h2s (key));
277 return GNUNET_OK;
278 }
280 "Found result for key %s\n",
281 GNUNET_h2s (key));
282 if (NULL != get_ctx->iter)
283 ret = get_ctx->iter (get_ctx->iter_cls,
284 &val->block);
285 else
286 ret = GNUNET_YES;
287 get_ctx->cnt++;
288 return ret;
289}

References Value::block, GetContext::cnt, GNUNET_DATACACHE_Block::expiration_time, GNUNET_BLOCK_TYPE_ANY, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_OK, GNUNET_TIME_absolute_is_past(), GNUNET_YES, GetContext::iter, GetContext::iter_cls, key, ret, GNUNET_DATACACHE_Block::type, GetContext::type, and value.

Referenced by heap_plugin_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ heap_plugin_get()

static unsigned int heap_plugin_get ( void *  cls,
const struct GNUNET_HashCode key,
enum GNUNET_BLOCK_Type  type,
GNUNET_DATACACHE_Iterator  iter,
void *  iter_cls 
)
static

Iterate over the results for a particular key in the datastore.

Parameters
clsclosure (our struct Plugin)
key
typeentries of which type are relevant?
itermaybe NULL (to just count)
iter_clsclosure for iter
Returns
the number of results found

Definition at line 304 of file plugin_datacache_heap.c.

309{
310 struct Plugin *plugin = cls;
311 struct GetContext get_ctx;
312
313 get_ctx.type = type;
314 get_ctx.iter = iter;
315 get_ctx.iter_cls = iter_cls;
316 get_ctx.cnt = 0;
318 key,
319 &get_cb,
320 &get_ctx);
321 return get_ctx.cnt;
322}

References GetContext::cnt, get_cb(), GNUNET_CONTAINER_multihashmap_get_multiple(), GetContext::iter, GetContext::iter_cls, key, plugin, type, and GetContext::type.

Referenced by libgnunet_plugin_datacache_heap_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ heap_plugin_del()

static enum GNUNET_GenericReturnValue heap_plugin_del ( void *  cls)
static

Delete the entry with the lowest expiration value from the datacache right now.

Parameters
clsclosure (our struct Plugin)
Returns
GNUNET_OK on success, GNUNET_SYSERR on error

Definition at line 333 of file plugin_datacache_heap.c.

334{
335 struct Plugin *plugin = cls;
336 struct Value *val;
337
338 for (unsigned int i = 0; i < NUM_HEAPS; i++)
339 {
341 if (NULL != val)
342 break;
343 }
344 if (NULL == val)
345 return GNUNET_SYSERR;
348 &val->block.key,
349 val));
350 plugin->env->delete_notify (plugin->env->cls,
351 &val->block.key,
352 val->block.data_size + OVERHEAD);
353 GNUNET_free (val->put_path);
354 GNUNET_free (val);
355 return GNUNET_OK;
356}

References Value::block, GNUNET_TESTING_PluginFunctions::cls, GNUNET_DATACACHE_Block::data_size, GNUNET_assert, GNUNET_CONTAINER_heap_remove_root(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, GNUNET_DATACACHE_Block::key, NUM_HEAPS, OVERHEAD, plugin, and Value::put_path.

Referenced by libgnunet_plugin_datacache_heap_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_closest()

static enum GNUNET_GenericReturnValue find_closest ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 376 of file plugin_datacache_heap.c.

379{
380 struct GetClosestContext *gcc = cls;
381 struct Value *val = value;
382 unsigned int j;
383
384 if (1 != GNUNET_CRYPTO_hash_cmp (key,
385 gcc->key))
386 return GNUNET_OK; /* useless */
387 if ( (val->block.type != gcc->type) &&
388 (GNUNET_BLOCK_TYPE_ANY != gcc->type) )
389 return GNUNET_OK; /* useless */
390 j = gcc->num_results;
391 for (unsigned int i = 0; i < gcc->num_results; i++)
392 {
393 if (NULL == gcc->values[i])
394 {
395 j = i;
396 break;
397 }
398 if (1 ==
400 key))
401 {
402 j = i;
403 break;
404 }
405 }
406 if (j == gcc->num_results)
407 return GNUNET_OK;
408 gcc->values[j] = val;
409 return GNUNET_OK;
410}

References Value::block, GNUNET_BLOCK_TYPE_ANY, GNUNET_CRYPTO_hash_cmp(), GNUNET_OK, key, GNUNET_DATACACHE_Block::key, GetClosestContext::key, GetClosestContext::num_results, GNUNET_DATACACHE_Block::type, GetClosestContext::type, value, and GetClosestContext::values.

Referenced by heap_plugin_get_closest().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ heap_plugin_get_closest()

static unsigned int heap_plugin_get_closest ( void *  cls,
const struct GNUNET_HashCode key,
enum GNUNET_BLOCK_Type  type,
unsigned int  num_results,
GNUNET_DATACACHE_Iterator  iter,
void *  iter_cls 
)
static

Iterate over the results that are "close" to a particular key in the datacache.

"close" is defined as numerically larger than key (when interpreted as a circular address space), with small distance.

Parameters
clsclosure (internal context for the plugin)
keyarea of the keyspace to look into
typedesired block type for the replies
num_resultsnumber of results that should be returned to iter
itermaybe NULL (to just count)
iter_clsclosure for iter
Returns
the number of results found

Definition at line 428 of file plugin_datacache_heap.c.

434{
435 struct Plugin *plugin = cls;
436 struct Value *values[num_results];
437 struct GetClosestContext gcc = {
438 .values = values,
439 .type = type,
440 .num_results = num_results * 2,
441 .key = key
442 };
443
446 &gcc);
447 for (unsigned int i = 0; i < num_results * 2; i++)
448 {
449 if (NULL == values[i])
450 return i;
451 if ( (NULL != iter) &&
452 (GNUNET_SYSERR ==
453 iter (iter_cls,
454 &values[i]->block)) )
455 {
457 "Ending iteration (client error)\n");
458 return i;
459 }
460 }
461 return num_results * 2;
462}

References find_closest(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_SYSERR, key, LOG, GetClosestContext::num_results, plugin, type, values, and GetClosestContext::values.

Referenced by libgnunet_plugin_datacache_heap_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ libgnunet_plugin_datacache_heap_init()

void * libgnunet_plugin_datacache_heap_init ( void *  cls)

Entry point for the plugin.

Parameters
clsclosure (the struct GNUNET_DATACACHE_PluginEnvironmnet)
Returns
the plugin's closure (our struct Plugin)

Definition at line 474 of file plugin_datacache_heap.c.

475{
478 struct Plugin *plugin;
479
480 plugin = GNUNET_new (struct Plugin);
481 plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */
482 GNUNET_YES);
483 for (unsigned int i = 0; i < NUM_HEAPS; i++)
486 plugin->env = env;
488 api->cls = plugin;
489 api->get = &heap_plugin_get;
490 api->put = &heap_plugin_put;
491 api->del = &heap_plugin_del;
492 api->get_closest = &heap_plugin_get_closest;
494 _ ("Heap datacache running\n"));
495 return api;
496}

References _, Plugin::api, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_DATACACHE_PluginEnvironment::cls, env, GNUNET_CONTAINER_heap_create(), GNUNET_CONTAINER_HEAP_ORDER_MIN, GNUNET_CONTAINER_multihashmap_create(), GNUNET_ERROR_TYPE_INFO, GNUNET_new, GNUNET_YES, heap_plugin_del(), heap_plugin_get(), heap_plugin_get_closest(), heap_plugin_put(), LOG, NUM_HEAPS, and plugin.

Here is the call graph for this function:

◆ libgnunet_plugin_datacache_heap_done()

void * libgnunet_plugin_datacache_heap_done ( void *  cls)

Exit point from the plugin.

Parameters
clsclosure (our "struct Plugin")
Returns
NULL

Definition at line 508 of file plugin_datacache_heap.c.

509{
511 struct Plugin *plugin = api->cls;
512 struct Value *val;
513
514 for (unsigned int i = 0; i < NUM_HEAPS; i++)
515 {
516 while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i])))
517 {
520 &val->block.key,
521 val));
522 GNUNET_free (val->put_path);
523 GNUNET_free (val);
524 }
526 }
529 GNUNET_free (api);
530 return NULL;
531}

References Plugin::api, Value::block, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_DATACACHE_PluginFunctions::cls, GNUNET_assert, GNUNET_CONTAINER_heap_destroy(), GNUNET_CONTAINER_heap_remove_root(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_YES, GNUNET_DATACACHE_Block::key, NUM_HEAPS, plugin, and Value::put_path.

Here is the call graph for this function: