X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fpeer.c;h=b637dc229c8dadc6dfaac0c4ef5b8486e0432e66;hb=03512957fb04969d08fb7eac0952a747aa9596ae;hp=96ac271c0097cb7f3e80d04a912b4276be8a1fd4;hpb=a36de9cd81b02e4454ffcfa10c709419700c590d;p=oweals%2Fgnunet.git diff --git a/src/util/peer.c b/src/util/peer.c index 96ac271c0..b637dc229 100644 --- a/src/util/peer.c +++ b/src/util/peer.c @@ -1,10 +1,10 @@ /* This file is part of GNUnet - (C) 2006, 2008, 2009 Christian Grothoff (and other contributing authors) + Copyright (C) 2006, 2008, 2009 GNUnet e.V. 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 + by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but @@ -23,10 +23,11 @@ * @brief peer-ID table that assigns integer IDs to peer-IDs to save memory * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_peer_lib.h" +#define LOG(kind,...) GNUNET_log_from (kind, "util-peer", __VA_ARGS__) + struct PeerEntry { @@ -51,14 +52,14 @@ struct PeerEntry /** * Table with our interned peer IDs. */ -static struct PeerEntry *table; +static struct PeerEntry **table; /** - * Hashmap of PeerIdentities to "struct PeerEntry" + * Peermap of PeerIdentities to "struct PeerEntry" * (for fast lookup). NULL until the library * is actually being used. */ -static struct GNUNET_CONTAINER_MultiHashMap *map; +static struct GNUNET_CONTAINER_MultiPeerMap *map; /** * Size of the "table". @@ -82,25 +83,19 @@ GNUNET_PEER_Id GNUNET_PEER_search (const struct GNUNET_PeerIdentity *pid) { struct PeerEntry *e; - long off; - if (pid == NULL) + if (NULL == pid) return 0; if (NULL == map) return 0; - off = (long) GNUNET_CONTAINER_multihashmap_get (map, &pid->hashPubKey); - e = (off == 0) ? NULL : &table[off]; - if (e != NULL) - { - GNUNET_assert (e->rc > 0); - return e->pid; - } - else - { - return 0; - } + e = GNUNET_CONTAINER_multipeermap_get (map, pid); + if (NULL == e) + return 0; + GNUNET_assert (e->rc > 0); + return e->pid; } + /** * Intern an peer identity. If the identity is already known, its * reference counter will be increased by one. @@ -114,80 +109,82 @@ GNUNET_PEER_intern (const struct GNUNET_PeerIdentity *pid) GNUNET_PEER_Id ret; struct PeerEntry *e; unsigned int i; - long off; - if (pid == NULL) + if (NULL == pid) return 0; if (NULL == map) - map = GNUNET_CONTAINER_multihashmap_create (32); - off = (long) GNUNET_CONTAINER_multihashmap_get (map, &pid->hashPubKey); - e = (off == 0) ? NULL : &table[off]; - if (e != NULL) - { - GNUNET_assert (e->rc > 0); - e->rc++; - return e->pid; - } + map = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); + e = GNUNET_CONTAINER_multipeermap_get (map, pid); + if (NULL != e) + { + GNUNET_assert (e->rc > 0); + e->rc++; + return e->pid; + } ret = free_list_start; if (ret == size) + { + GNUNET_array_grow (table, size, size + 16); + for (i = ret; i < size; i++) { - GNUNET_array_grow (table, size, size + 16); - for (i = ret; i < size; i++) - table[i].pid = i + 1; - } - if (ret == 0) - { - table[0].pid = 0; - table[0].rc = 1; - ret = 1; + table[i] = GNUNET_new (struct PeerEntry); + table[i]->pid = i + 1; } + } + if (0 == ret) + { + memset (&table[0]->id, 0, sizeof (struct GNUNET_PeerIdentity)); + table[0]->pid = 0; + table[0]->rc = 1; + ret = 1; + } GNUNET_assert (ret < size); - GNUNET_assert (table[ret].rc == 0); - free_list_start = table[ret].pid; - table[ret].id = *pid; - table[ret].rc = 1; - table[ret].pid = ret; + GNUNET_assert (0 == table[ret]->rc); + free_list_start = table[ret]->pid; + table[ret]->id = *pid; + table[ret]->rc = 1; + table[ret]->pid = ret; GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (map, - &pid->hashPubKey, - (void *) (long) ret, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + GNUNET_CONTAINER_multipeermap_put (map, + &table[ret]->id, + table[ret], + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); return ret; } /** * Decrement multiple RCs of peer identities by one. - * + * * @param ids array of PIDs to decrement the RCs of * @param count size of the ids array */ void -GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id * ids, unsigned int count) +GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id *ids, unsigned int count) { int i; GNUNET_PEER_Id id; - if (count == 0) + if (0 == count) return; for (i = count - 1; i >= 0; i--) + { + id = ids[i]; + if (0 == id) + continue; + GNUNET_assert (id < size); + GNUNET_assert (table[id]->rc > 0); + table[id]->rc--; + if (0 == table[id]->rc) { - id = ids[i]; - if (id == 0) - continue; - GNUNET_assert (id < size); - GNUNET_assert (table[id].rc > 0); - table[id].rc--; - if (table[id].rc == 0) - { - GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_remove (map, - &table[id].id.hashPubKey, - (void*) (long) id)); - table[id].pid = free_list_start; - free_list_start = id; - } + GNUNET_break (GNUNET_OK == + GNUNET_CONTAINER_multipeermap_remove (map, + &table[id]->id, + table[id])); + table[id]->pid = free_list_start; + free_list_start = id; } + } } @@ -200,21 +197,21 @@ GNUNET_PEER_decrement_rcs (const GNUNET_PEER_Id * ids, unsigned int count) void GNUNET_PEER_change_rc (GNUNET_PEER_Id id, int delta) { - if (id == 0) + if (0 == id) return; GNUNET_assert (id < size); - GNUNET_assert (table[id].rc > 0); - GNUNET_assert ((delta >= 0) || (table[id].rc >= -delta)); - table[id].rc += delta; - if (table[id].rc == 0) - { - GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_remove (map, - &table[id].id.hashPubKey, - (void*) (long) id)); - table[id].pid = free_list_start; - free_list_start = id; - } + GNUNET_assert (table[id]->rc > 0); + GNUNET_assert ((delta >= 0) || (table[id]->rc >= -delta)); + table[id]->rc += delta; + if (0 == table[id]->rc) + { + GNUNET_break (GNUNET_OK == + GNUNET_CONTAINER_multipeermap_remove (map, + &table[id]->id, + table[id])); + table[id]->pid = free_list_start; + free_list_start = id; + } } @@ -227,16 +224,31 @@ GNUNET_PEER_change_rc (GNUNET_PEER_Id id, int delta) void GNUNET_PEER_resolve (GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid) { - if (id == 0) - { - memset (pid, 0, sizeof (struct GNUNET_PeerIdentity)); - GNUNET_break (0); - return; - } + if (0 == id) + { + memset (pid, 0, sizeof (struct GNUNET_PeerIdentity)); + return; + } + GNUNET_assert (id < size); + GNUNET_assert (table[id]->rc > 0); + *pid = table[id]->id; +} + + +/** + * Convert an interned PID to a normal peer identity. + * + * @param id interned PID to convert + * @return pointer to peer identity, valid as long 'id' is valid + */ +const struct GNUNET_PeerIdentity * +GNUNET_PEER_resolve2 (GNUNET_PEER_Id id) +{ GNUNET_assert (id < size); - GNUNET_assert (table[id].rc > 0); - *pid = table[id].id; + GNUNET_assert (table[id]->rc > 0); + return &table[id]->id; } + /* end of peer.c */