diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-06-03 15:07:09 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-06-03 15:07:09 +0200 |
commit | 18a1d4ec5085690d16345a52f3e75d059c834195 (patch) | |
tree | eddcbab91006a80cfa604c802bb1fccdaae1103d /src/datacache/plugin_datacache_heap.c | |
parent | 2e619a454b7c78aa5f592debd6c8a31e7d7c1143 (diff) | |
download | gnunet-18a1d4ec5085690d16345a52f3e75d059c834195.tar.gz gnunet-18a1d4ec5085690d16345a52f3e75d059c834195.zip |
proper datacache expiration by proximity first
Diffstat (limited to 'src/datacache/plugin_datacache_heap.c')
-rw-r--r-- | src/datacache/plugin_datacache_heap.c | 90 |
1 files changed, 36 insertions, 54 deletions
diff --git a/src/datacache/plugin_datacache_heap.c b/src/datacache/plugin_datacache_heap.c index c32edf8e2..ad5e7834d 100644 --- a/src/datacache/plugin_datacache_heap.c +++ b/src/datacache/plugin_datacache_heap.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | #define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-heap", op, fn) | 32 | #define LOG_STRERROR_FILE(kind,op,fn) GNUNET_log_from_strerror_file (kind, "datacache-heap", op, fn) |
33 | 33 | ||
34 | 34 | #define NUM_HEAPS 24 | |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Context for all functions in this plugin. | 37 | * Context for all functions in this plugin. |
@@ -49,14 +49,9 @@ struct Plugin | |||
49 | struct GNUNET_CONTAINER_MultiHashMap *map; | 49 | struct GNUNET_CONTAINER_MultiHashMap *map; |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Heap for expirations. | 52 | * Heaps sorted by distance. |
53 | */ | 53 | */ |
54 | struct GNUNET_CONTAINER_Heap *heap; | 54 | struct GNUNET_CONTAINER_Heap *heaps[NUM_HEAPS]; |
55 | |||
56 | /** | ||
57 | * Heap from the plugin for "closest" values. | ||
58 | */ | ||
59 | struct GNUNET_CONTAINER_Heap *cheap; | ||
60 | 55 | ||
61 | }; | 56 | }; |
62 | 57 | ||
@@ -97,9 +92,9 @@ struct Value | |||
97 | unsigned int path_info_len; | 92 | unsigned int path_info_len; |
98 | 93 | ||
99 | /** | 94 | /** |
100 | * Am I the closest peer? Determines which heap we are in! | 95 | * How close is the hash to us? Determines which heap we are in! |
101 | */ | 96 | */ |
102 | int am_closest; | 97 | uint32_t distance; |
103 | 98 | ||
104 | /** | 99 | /** |
105 | * Type of the block. | 100 | * Type of the block. |
@@ -128,16 +123,6 @@ struct PutContext | |||
128 | const char *data; | 123 | const char *data; |
129 | 124 | ||
130 | /** | 125 | /** |
131 | * Heap from the plugin for "closest" values. | ||
132 | */ | ||
133 | struct GNUNET_CONTAINER_Heap *cheap; | ||
134 | |||
135 | /** | ||
136 | * Heap from the plugin. | ||
137 | */ | ||
138 | struct GNUNET_CONTAINER_Heap *heap; | ||
139 | |||
140 | /** | ||
141 | * Path information. | 126 | * Path information. |
142 | */ | 127 | */ |
143 | const struct GNUNET_PeerIdentity *path_info; | 128 | const struct GNUNET_PeerIdentity *path_info; |
@@ -195,8 +180,8 @@ put_cb (void *cls, | |||
195 | val->path_info_len, | 180 | val->path_info_len, |
196 | put_ctx->path_info_len); | 181 | put_ctx->path_info_len); |
197 | GNUNET_memcpy (val->path_info, | 182 | GNUNET_memcpy (val->path_info, |
198 | put_ctx->path_info, | 183 | put_ctx->path_info, |
199 | put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity)); | 184 | put_ctx->path_info_len * sizeof (struct GNUNET_PeerIdentity)); |
200 | GNUNET_CONTAINER_heap_update_cost (val->hn, | 185 | GNUNET_CONTAINER_heap_update_cost (val->hn, |
201 | val->discard_time.abs_value_us); | 186 | val->discard_time.abs_value_us); |
202 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 187 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -216,7 +201,7 @@ put_cb (void *cls, | |||
216 | * | 201 | * |
217 | * @param cls closure (our `struct Plugin`) | 202 | * @param cls closure (our `struct Plugin`) |
218 | * @param key key to store data under | 203 | * @param key key to store data under |
219 | * @param am_closest are we the closest peer? | 204 | * @param xor_distance how close is @a key to our PID? |
220 | * @param size number of bytes in @a data | 205 | * @param size number of bytes in @a data |
221 | * @param data data to store | 206 | * @param data data to store |
222 | * @param type type of the value | 207 | * @param type type of the value |
@@ -228,7 +213,7 @@ put_cb (void *cls, | |||
228 | static ssize_t | 213 | static ssize_t |
229 | heap_plugin_put (void *cls, | 214 | heap_plugin_put (void *cls, |
230 | const struct GNUNET_HashCode *key, | 215 | const struct GNUNET_HashCode *key, |
231 | int am_closest, | 216 | uint32_t xor_distance, |
232 | size_t size, | 217 | size_t size, |
233 | const char *data, | 218 | const char *data, |
234 | enum GNUNET_BLOCK_Type type, | 219 | enum GNUNET_BLOCK_Type type, |
@@ -241,8 +226,6 @@ heap_plugin_put (void *cls, | |||
241 | struct PutContext put_ctx; | 226 | struct PutContext put_ctx; |
242 | 227 | ||
243 | put_ctx.found = GNUNET_NO; | 228 | put_ctx.found = GNUNET_NO; |
244 | put_ctx.heap = plugin->heap; | ||
245 | put_ctx.cheap = plugin->cheap; | ||
246 | put_ctx.data = data; | 229 | put_ctx.data = data; |
247 | put_ctx.size = size; | 230 | put_ctx.size = size; |
248 | put_ctx.path_info = path_info; | 231 | put_ctx.path_info = path_info; |
@@ -256,12 +239,17 @@ heap_plugin_put (void *cls, | |||
256 | if (GNUNET_YES == put_ctx.found) | 239 | if (GNUNET_YES == put_ctx.found) |
257 | return 0; | 240 | return 0; |
258 | val = GNUNET_malloc (sizeof (struct Value) + size); | 241 | val = GNUNET_malloc (sizeof (struct Value) + size); |
259 | GNUNET_memcpy (&val[1], data, size); | 242 | GNUNET_memcpy (&val[1], |
243 | data, | ||
244 | size); | ||
260 | val->key = *key; | 245 | val->key = *key; |
261 | val->type = type; | 246 | val->type = type; |
262 | val->discard_time = discard_time; | 247 | val->discard_time = discard_time; |
263 | val->size = size; | 248 | val->size = size; |
264 | val->am_closest = am_closest; | 249 | if (xor_distance >= NUM_HEAPS) |
250 | val->distance = NUM_HEAPS - 1; | ||
251 | else | ||
252 | val->distance = xor_distance; | ||
265 | GNUNET_array_grow (val->path_info, | 253 | GNUNET_array_grow (val->path_info, |
266 | val->path_info_len, | 254 | val->path_info_len, |
267 | path_info_len); | 255 | path_info_len); |
@@ -272,9 +260,7 @@ heap_plugin_put (void *cls, | |||
272 | &val->key, | 260 | &val->key, |
273 | val, | 261 | val, |
274 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 262 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
275 | val->hn = GNUNET_CONTAINER_heap_insert (am_closest | 263 | val->hn = GNUNET_CONTAINER_heap_insert (plugin->heaps[val->distance], |
276 | ? plugin->cheap | ||
277 | : plugin->heap, | ||
278 | val, | 264 | val, |
279 | val->discard_time.abs_value_us); | 265 | val->discard_time.abs_value_us); |
280 | return size + OVERHEAD; | 266 | return size + OVERHEAD; |
@@ -392,9 +378,12 @@ heap_plugin_del (void *cls) | |||
392 | struct Plugin *plugin = cls; | 378 | struct Plugin *plugin = cls; |
393 | struct Value *val; | 379 | struct Value *val; |
394 | 380 | ||
395 | val = GNUNET_CONTAINER_heap_remove_root (plugin->heap); | 381 | for (unsigned int i=0;i<NUM_HEAPS;i++) |
396 | if (NULL == val) | 382 | { |
397 | val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap); | 383 | val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i]); |
384 | if (NULL != val) | ||
385 | break; | ||
386 | } | ||
398 | if (NULL == val) | 387 | if (NULL == val) |
399 | return GNUNET_SYSERR; | 388 | return GNUNET_SYSERR; |
400 | GNUNET_assert (GNUNET_YES == | 389 | GNUNET_assert (GNUNET_YES == |
@@ -547,8 +536,8 @@ libgnunet_plugin_datacache_heap_init (void *cls) | |||
547 | plugin = GNUNET_new (struct Plugin); | 536 | plugin = GNUNET_new (struct Plugin); |
548 | plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */ | 537 | plugin->map = GNUNET_CONTAINER_multihashmap_create (1024, /* FIXME: base on quota! */ |
549 | GNUNET_YES); | 538 | GNUNET_YES); |
550 | plugin->heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 539 | for (unsigned int i=0;i<NUM_HEAPS;i++) |
551 | plugin->cheap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 540 | plugin->heaps[i] = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |
552 | plugin->env = env; | 541 | plugin->env = env; |
553 | api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions); | 542 | api = GNUNET_new (struct GNUNET_DATACACHE_PluginFunctions); |
554 | api->cls = plugin; | 543 | api->cls = plugin; |
@@ -576,26 +565,19 @@ libgnunet_plugin_datacache_heap_done (void *cls) | |||
576 | struct Plugin *plugin = api->cls; | 565 | struct Plugin *plugin = api->cls; |
577 | struct Value *val; | 566 | struct Value *val; |
578 | 567 | ||
579 | while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heap))) | 568 | for (unsigned int i=0;i<NUM_HEAPS;i++) |
580 | { | 569 | { |
581 | GNUNET_assert (GNUNET_YES == | 570 | while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->heaps[i]))) |
582 | GNUNET_CONTAINER_multihashmap_remove (plugin->map, | 571 | { |
583 | &val->key, | 572 | GNUNET_assert (GNUNET_YES == |
584 | val)); | 573 | GNUNET_CONTAINER_multihashmap_remove (plugin->map, |
585 | GNUNET_free_non_null (val->path_info); | 574 | &val->key, |
586 | GNUNET_free (val); | 575 | val)); |
587 | } | 576 | GNUNET_free_non_null (val->path_info); |
588 | while (NULL != (val = GNUNET_CONTAINER_heap_remove_root (plugin->cheap))) | 577 | GNUNET_free (val); |
589 | { | 578 | } |
590 | GNUNET_assert (GNUNET_YES == | 579 | GNUNET_CONTAINER_heap_destroy (plugin->heaps[i]); |
591 | GNUNET_CONTAINER_multihashmap_remove (plugin->map, | ||
592 | &val->key, | ||
593 | val)); | ||
594 | GNUNET_free_non_null (val->path_info); | ||
595 | GNUNET_free (val); | ||
596 | } | 580 | } |
597 | GNUNET_CONTAINER_heap_destroy (plugin->heap); | ||
598 | GNUNET_CONTAINER_heap_destroy (plugin->cheap); | ||
599 | GNUNET_CONTAINER_multihashmap_destroy (plugin->map); | 581 | GNUNET_CONTAINER_multihashmap_destroy (plugin->map); |
600 | GNUNET_free (plugin); | 582 | GNUNET_free (plugin); |
601 | GNUNET_free (api); | 583 | GNUNET_free (api); |