From 302168de1e43aec3d2d2dfe3fd6707b0f3f68300 Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Fri, 25 Jan 2013 10:55:49 +0000 Subject: [PATCH] separate hello cache as module --- src/testbed/Makefile.am | 3 +- src/testbed/gnunet-service-testbed.c | 124 +-------------- src/testbed/gnunet-service-testbed.h | 56 ++++--- src/testbed/gnunet-service-testbed_hc.c | 194 ++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 142 deletions(-) create mode 100644 src/testbed/gnunet-service-testbed_hc.c diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index f6e1d6972..841a7f992 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am @@ -38,7 +38,8 @@ noinst_PROGRAMS = \ gnunet_service_testbed_SOURCES = \ gnunet-service-testbed.c \ - gnunet-service-testbed.h + gnunet-service-testbed.h \ + gnunet-service-testbed_hc.c gnunet_service_testbed_LDADD = $(XLIB) \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/core/libgnunetcore.la \ diff --git a/src/testbed/gnunet-service-testbed.c b/src/testbed/gnunet-service-testbed.c index 282e5a4e8..d741b7fc1 100644 --- a/src/testbed/gnunet-service-testbed.c +++ b/src/testbed/gnunet-service-testbed.c @@ -24,7 +24,6 @@ * @author Sree Harsha Totakura */ -#include "platform.h" #include "gnunet-service-testbed.h" #include @@ -137,18 +136,6 @@ static struct ForwardedOperationContext *fopcq_head; */ static struct ForwardedOperationContext *fopcq_tail; -/** - * DLL head for least recently used hello cache entries; least recently used - * cache items are at the head - */ -static struct HelloCacheEntry *lru_hcache_head; - -/** - * DLL tail for least recently used hello cache entries; recently used cache - * items are at the tail - */ -static struct HelloCacheEntry *lru_hcache_tail; - /** * Array of hosts */ @@ -174,11 +161,6 @@ static struct Peer **peer_list; */ static struct GNUNET_CONTAINER_MultiHashMap *ss_map; -/** - * Hashmap to maintain HELLO cache - */ -static struct GNUNET_CONTAINER_MultiHashMap *hello_cache; - /** * The event mask for the events we listen from sub-controllers */ @@ -204,11 +186,6 @@ static unsigned int slave_list_size; */ static unsigned int peer_list_size; -/** - * The size of hello cache - */ -static unsigned int hello_cache_size; - /*********/ /* Tasks */ /*********/ @@ -224,87 +201,6 @@ static GNUNET_SCHEDULER_TaskIdentifier lcf_proc_task_id; static GNUNET_SCHEDULER_TaskIdentifier shutdown_task_id; -/** - * Looks up in the hello cache and returns the HELLO of the given peer - * - * @param id the peer identity of the peer whose HELLO has to be looked up - * @return the HELLO message; NULL if not found - */ -static const struct GNUNET_MessageHeader * -hello_cache_lookup (const struct GNUNET_PeerIdentity *id) -{ - struct HelloCacheEntry *entry; - - if (NULL == hello_cache) - return NULL; - entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey); - if (NULL == entry) - return NULL; - GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); - GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry); - return entry->hello; -} - - -/** - * Removes the given hello cache centry from hello cache and frees its resources - * - * @param entry the entry to remove - */ -static void -hello_cache_remove (struct HelloCacheEntry *entry) -{ - GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (hello_cache, - &entry->key, - entry)); - GNUNET_free (entry->hello); - GNUNET_free (entry); -} - - -/** - * Caches the HELLO of the given peer. Updates the HELLO if it was already - * cached before - * - * @param id the peer identity of the peer whose HELLO has to be cached - * @param hello the HELLO message - */ -static void -hello_cache_add (const struct GNUNET_PeerIdentity *id, - const struct GNUNET_MessageHeader *hello) -{ - struct HelloCacheEntry *entry; - - if (NULL == hello_cache) - return; - entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey); - if (NULL == entry) - { - entry = GNUNET_malloc (sizeof (struct HelloCacheEntry)); - memcpy (&entry->key, &id->hashPubKey, sizeof (struct GNUNET_HashCode)); - if (GNUNET_CONTAINER_multihashmap_size (hello_cache) == hello_cache_size) - { - GNUNET_assert (NULL != lru_hcache_head); - hello_cache_remove (lru_hcache_head); - } - GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put - (hello_cache, - &entry->key, - entry, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); - } - else - { - GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); - GNUNET_free (entry->hello); - } - entry->hello = GNUNET_copy_message (hello); - GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry); -} - - /** * Function called to notify a client about the connection begin ready to queue * more data. "buf" will be NULL and "size" zero if the connection was closed @@ -2496,7 +2392,7 @@ hello_update_cb (void *cls, const struct GNUNET_MessageHeader *hello) LOG_DEBUG ("0x%llx: Received HELLO of %s\n", occ->op_id, GNUNET_i2s (&occ->peer_identity)); occ->hello = GNUNET_malloc (msize); - hello_cache_add (&occ->peer_identity, hello); + TESTBED_hello_cache_add (&occ->peer_identity, hello); memcpy (occ->hello, hello, msize); GNUNET_TRANSPORT_get_hello_cancel (occ->ghh); occ->ghh = NULL; @@ -2541,7 +2437,7 @@ core_startup_cb (void *cls, struct GNUNET_CORE_Handle *server, LOG_DEBUG ("0x%llx: Acquiring HELLO of peer %s\n", occ->op_id, GNUNET_i2s (&occ->peer_identity)); /* Lookup for HELLO in hello cache */ - if (NULL != (hello = hello_cache_lookup (&occ->peer_identity))) + if (NULL != (hello = TESTBED_hello_cache_lookup (&occ->peer_identity))) { LOG_DEBUG ("0x%llx: HELLO of peer %s found in cache\n", occ->op_id, GNUNET_i2s (&occ->peer_identity)); @@ -3429,16 +3325,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_free_non_null (hostname); GNUNET_CONFIGURATION_destroy (our_config); /* Free hello cache */ - if (NULL != hello_cache) - GNUNET_assert - (GNUNET_CONTAINER_multihashmap_size (hello_cache) <= hello_cache_size); - while (NULL != lru_hcache_head) - hello_cache_remove (lru_hcache_head); - if (NULL != hello_cache) - { - GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (hello_cache)); - GNUNET_CONTAINER_multihashmap_destroy (hello_cache); - } + TESTBED_cache_clear (); } @@ -3516,16 +3403,13 @@ testbed_run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", "HELLO_CACHE_SIZE", &num)); - hello_cache_size = (unsigned int) num; + TESTBED_cache_init ((unsigned int) num); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", "HOSTNAME", &hostname)); our_config = GNUNET_CONFIGURATION_dup (cfg); GNUNET_SERVER_add_handlers (server, message_handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); ss_map = GNUNET_CONTAINER_multihashmap_create (5, GNUNET_NO); - if (1 < hello_cache_size) - hello_cache = GNUNET_CONTAINER_multihashmap_create (hello_cache_size / 2, - GNUNET_YES); shutdown_task_id = GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_SCHEDULER_PRIORITY_IDLE, diff --git a/src/testbed/gnunet-service-testbed.h b/src/testbed/gnunet-service-testbed.h index 1ddc89540..4fa137780 100644 --- a/src/testbed/gnunet-service-testbed.h +++ b/src/testbed/gnunet-service-testbed.h @@ -24,6 +24,7 @@ * @author Sree Harsha Totakura */ +#include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_testbed_service.h" #include "gnunet_transport_service.h" @@ -783,28 +784,41 @@ struct LCFContextQueue /** - * Hello cache entry + * Looks up in the hello cache and returns the HELLO of the given peer + * + * @param id the peer identity of the peer whose HELLO has to be looked up + * @return the HELLO message; NULL if not found */ -struct HelloCacheEntry -{ - /** - * DLL next ptr for least recently used hello cache entries - */ - struct HelloCacheEntry *next; +const struct GNUNET_MessageHeader * +TESTBED_hello_cache_lookup (const struct GNUNET_PeerIdentity *id); + +/** + * Caches the HELLO of the given peer. Updates the HELLO if it was already + * cached before + * + * @param id the peer identity of the peer whose HELLO has to be cached + * @param hello the HELLO message + */ +void +TESTBED_hello_cache_add (const struct GNUNET_PeerIdentity *id, + const struct GNUNET_MessageHeader *hello); + + +/** + * Initializes the cache + * + * @param size the size of the cache + */ +void +TESTBED_cache_init (unsigned int size); + + +/** + * Clear cache + */ +void +TESTBED_cache_clear (); - /** - * DLL prev ptr for least recently used hello cache entries - */ - struct HelloCacheEntry *prev; - /** - * The key for this entry - */ - struct GNUNET_HashCode key; - - /** - * The HELLO message - */ - struct GNUNET_MessageHeader *hello; -}; +/* End of gnunet-service-testbed.h */ diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c new file mode 100644 index 000000000..569dc18f8 --- /dev/null +++ b/src/testbed/gnunet-service-testbed_hc.c @@ -0,0 +1,194 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file testbed/gnunet-service-testbed_hc.h + * @brief testbed cache implementation + * @author Sree Harsha Totakura + */ + +#include "gnunet-service-testbed.h" + +/** + * Hello cache entry + */ +struct HelloCacheEntry +{ + /** + * DLL next ptr for least recently used hello cache entries + */ + struct HelloCacheEntry *next; + + /** + * DLL prev ptr for least recently used hello cache entries + */ + struct HelloCacheEntry *prev; + + /** + * The key for this entry + */ + struct GNUNET_HashCode key; + + /** + * The HELLO message + */ + struct GNUNET_MessageHeader *hello; +}; + +/** + * Hashmap to maintain HELLO cache + */ +static struct GNUNET_CONTAINER_MultiHashMap *hello_cache; + +/** + * DLL head for least recently used hello cache entries; least recently used + * cache items are at the head + */ +static struct HelloCacheEntry *lru_hcache_head; + +/** + * DLL tail for least recently used hello cache entries; recently used cache + * items are at the tail + */ +static struct HelloCacheEntry *lru_hcache_tail; + +/** + * The size of HELLO cache + */ +static unsigned int hello_cache_size; + + +/** + * Looks up in the hello cache and returns the HELLO of the given peer + * + * @param id the peer identity of the peer whose HELLO has to be looked up + * @return the HELLO message; NULL if not found + */ +const struct GNUNET_MessageHeader * +TESTBED_hello_cache_lookup (const struct GNUNET_PeerIdentity *id) +{ + struct HelloCacheEntry *entry; + + if (NULL == hello_cache) + return NULL; + entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey); + if (NULL == entry) + return NULL; + GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); + GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry); + return entry->hello; +} + + +/** + * Removes the given hello cache centry from hello cache and frees its resources + * + * @param entry the entry to remove + */ +static void +TESTBED_hello_cache_remove (struct HelloCacheEntry *entry) +{ + GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (hello_cache, + &entry->key, + entry)); + GNUNET_free (entry->hello); + GNUNET_free (entry); +} + + +/** + * Caches the HELLO of the given peer. Updates the HELLO if it was already + * cached before + * + * @param id the peer identity of the peer whose HELLO has to be cached + * @param hello the HELLO message + */ +void +TESTBED_hello_cache_add (const struct GNUNET_PeerIdentity *id, + const struct GNUNET_MessageHeader *hello) +{ + struct HelloCacheEntry *entry; + + if (NULL == hello_cache) + return; + entry = GNUNET_CONTAINER_multihashmap_get (hello_cache, &id->hashPubKey); + if (NULL == entry) + { + entry = GNUNET_malloc (sizeof (struct HelloCacheEntry)); + memcpy (&entry->key, &id->hashPubKey, sizeof (struct GNUNET_HashCode)); + if (GNUNET_CONTAINER_multihashmap_size (hello_cache) == hello_cache_size) + { + GNUNET_assert (NULL != lru_hcache_head); + TESTBED_hello_cache_remove (lru_hcache_head); + } + GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put + (hello_cache, + &entry->key, + entry, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); + } + else + { + GNUNET_CONTAINER_DLL_remove (lru_hcache_head, lru_hcache_tail, entry); + GNUNET_free (entry->hello); + } + entry->hello = GNUNET_copy_message (hello); + GNUNET_CONTAINER_DLL_insert_tail (lru_hcache_head, lru_hcache_tail, entry); +} + + +/** + * Initializes the cache + * + * @param size the size of the cache + */ +void +TESTBED_cache_init (unsigned int size) +{ + if (0 == size) + return; + hello_cache_size = size; + if (size > 1) + size = size / 2; + hello_cache = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_YES); +} + + +/** + * Clear cache + */ +void +TESTBED_cache_clear () +{ + if (NULL != hello_cache) + GNUNET_assert + (GNUNET_CONTAINER_multihashmap_size (hello_cache) <= hello_cache_size); + while (NULL != lru_hcache_head) + TESTBED_hello_cache_remove (lru_hcache_head); + if (NULL != hello_cache) + { + GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (hello_cache)); + GNUNET_CONTAINER_multihashmap_destroy (hello_cache); + } +} + +/* end of gnunet-service-testbed_hc.c */ -- 2.25.1