GNUnet  0.10.x
gnunet-service-testbed_cache.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2008--2013 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 
26 #include "gnunet-service-testbed.h"
27 
31 #ifdef LOG
32 #undef LOG
33 #endif
34 #define LOG(kind, ...) \
35  GNUNET_log_from(kind, "testbed-cache", __VA_ARGS__)
36 
37 
41 struct CacheEntry {
45  struct CacheEntry *next;
46 
50  struct CacheEntry *prev;
51 
56 
60  unsigned int peer_id;
61 };
62 
63 
68 
75 static struct CacheEntry *cache_head;
76 
83 static struct CacheEntry *cache_tail;
84 
88 static unsigned int cache_size;
89 
90 
98 static struct CacheEntry *
99 cache_lookup(unsigned int peer_id)
100 {
101  struct CacheEntry *entry;
102 
103  GNUNET_assert(NULL != cache);
104  entry = GNUNET_CONTAINER_multihashmap32_get(cache, peer_id);
105  if (NULL == entry)
106  return NULL;
107  GNUNET_CONTAINER_DLL_remove(cache_head, cache_tail, entry);
108  GNUNET_CONTAINER_DLL_insert_tail(cache_head, cache_tail, entry);
109  return entry;
110 }
111 
112 
118 static void
119 free_entry(struct CacheEntry *entry)
120 {
121  GNUNET_CONTAINER_DLL_remove(cache_head, cache_tail, entry);
122  GNUNET_free_non_null(entry->hello);
123  GNUNET_free(entry);
124 }
125 
126 
133 static struct CacheEntry *
134 add_entry(unsigned int peer_id)
135 {
136  struct CacheEntry *entry;
137 
138  GNUNET_assert(NULL != cache);
140  {
141  /* remove the LRU head */
142  entry = cache_head;
145  entry->peer_id,
146  entry));
147  free_entry(entry);
148  }
149  entry = GNUNET_new(struct CacheEntry);
150  entry->peer_id = peer_id;
153  (uint32_t)peer_id,
154  entry,
156  GNUNET_CONTAINER_DLL_insert_tail(cache_head, cache_tail, entry);
157  return entry;
158 }
159 
160 
171 static int
172 cache_clear_iterator(void *cls, uint32_t key, void *value)
173 {
174  struct CacheEntry *entry = value;
175 
176  GNUNET_assert(NULL != entry);
178  GNUNET_CONTAINER_multihashmap32_remove(cache, key, value));
179  free_entry(entry);
180  return GNUNET_YES;
181 }
182 
183 
187 void
189 {
190  if (NULL != cache)
191  {
195  cache = NULL;
196  }
197  cache_size = 0;
198  cache_head = NULL;
199  cache_tail = NULL;
200 }
201 
202 
208 void
209 GST_cache_init(unsigned int size)
210 {
211  if (0 == size)
212  return;
213  cache_size = size;
215 }
216 
217 
224 const struct GNUNET_MessageHeader *
225 GST_cache_lookup_hello(const unsigned int peer_id)
226 {
227  struct CacheEntry *entry;
228 
229  LOG_DEBUG("Looking up HELLO for peer %u\n", peer_id);
230  if (NULL == cache)
231  {
232  LOG_DEBUG("Caching disabled\n");
233  return NULL;
234  }
235  entry = cache_lookup(peer_id);
236  if (NULL == entry)
237  return NULL;
238  if (NULL != entry->hello)
239  LOG_DEBUG("HELLO found for peer %u\n", peer_id);
240  return entry->hello;
241 }
242 
243 
251 void
252 GST_cache_add_hello(const unsigned int peer_id,
253  const struct GNUNET_MessageHeader *hello)
254 {
255  struct CacheEntry *entry;
256 
257  if (NULL == cache)
258  return;
259  entry = cache_lookup(peer_id);
260  if (NULL == entry)
261  entry = add_entry(peer_id);
262  GNUNET_free_non_null(entry->hello);
263  entry->hello = GNUNET_copy_message(hello);
264 }
265 
266 /* end of gnunet-service-testbed_hc.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct CacheEntry * next
DLL next ptr for least recently used cache entries.
data structures shared amongst components of TESTBED service
static struct CacheEntry * cache_head
DLL head for least recently used cache entries; least recently used cache items are at the head...
int GNUNET_CONTAINER_multihashmap32_iterate(struct GNUNET_CONTAINER_MultiHashMap32 *map, GNUNET_CONTAINER_MulitHashMapIterator32Callback it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct CacheEntry * add_entry(unsigned int peer_id)
Creates a new cache entry and then puts it into the cache&#39;s hashtable.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
static void free_entry(struct CacheEntry *entry)
Free the resources occupied by a cache entry.
int GNUNET_CONTAINER_multihashmap32_put(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct CacheEntry * prev
DLL prev ptr for least recently used cache entries.
int GNUNET_CONTAINER_multihashmap32_remove(struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key, const void *value)
Remove the given key-value pair from the map.
, &#39; bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_...
static char * value
Value of the record to add/remove.
void * GNUNET_CONTAINER_multihashmap32_get(const struct GNUNET_CONTAINER_MultiHashMap32 *map, uint32_t key)
Given a key find a value in the map matching the key.
const struct GNUNET_MessageHeader * GST_cache_lookup_hello(const unsigned int peer_id)
Looks up in the hello cache and returns the HELLO of the given peer.
void GST_cache_init(unsigned int size)
Initializes the cache.
unsigned int GNUNET_CONTAINER_multihashmap32_size(const struct GNUNET_CONTAINER_MultiHashMap32 *map)
Get the number of key-value pairs in the map.
Internal representation of the hash map.
static int cache_clear_iterator(void *cls, uint32_t key, void *value)
Iterator over hash map entries.
struct GNUNET_CONTAINER_MultiHashMap32 * GNUNET_CONTAINER_multihashmap32_create(unsigned int len)
Create a 32-bit key multi hash map.
void GNUNET_CONTAINER_multihashmap32_destroy(struct GNUNET_CONTAINER_MultiHashMap32 *map)
Destroy a 32-bit key hash map.
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:66
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct CacheEntry * cache_tail
DLL tail for least recently used cache entries; recently used cache items are at the tail...
static struct GNUNET_CONTAINER_MultiHashMap32 * cache
Hashmap to maintain cache.
static unsigned int cache_size
Maximum number of elements to cache.
struct GNUNET_MessageHeader * hello
The HELLO message.
static struct CacheEntry * cache_lookup(unsigned int peer_id)
Looks up in the cache and returns the entry.
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GST_cache_add_hello(const unsigned int peer_id, const struct GNUNET_MessageHeader *hello)
Caches the HELLO of the given peer.
#define LOG_DEBUG(...)
Debug logging shorthand.
unsigned int peer_id
The id of the peer this entry corresponds to.
void GST_cache_clear()
Clear cache.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_MessageHeader * GNUNET_copy_message(const struct GNUNET_MessageHeader *msg)
Create a copy of the given message.