/*
This file is part of GNUnet.
- (C) 2008, 2012 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2008, 2012 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
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.
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
/**
* @file util/container_multipeermap.c
idx_of (const struct GNUNET_CONTAINER_MultiPeerMap *map,
const struct GNUNET_PeerIdentity *key)
{
- GNUNET_assert (map != NULL);
- return (*(unsigned int *) key) % map->map_length;
+ unsigned int kx;
+
+ GNUNET_assert (NULL != map);
+ GNUNET_memcpy (&kx, key, sizeof (kx));
+ return kx % map->map_length;
}
sme = map->map[i].sme;
else
sme = p->next;
- ret++;
+ ret++;
}
else
{
struct BigMapEntry *bme;
while (NULL != (bme = old_map[i].bme))
- {
+ {
old_map[i].bme = bme->next;
idx = idx_of (map, &bme->key);
bme->next = new_map[idx].bme;
}
+/**
+ * @ingroup hashmap
+ * Call @a it on a random value from the map, or not at all
+ * if the map is empty. Note that this function has linear
+ * complexity (in the size of the map).
+ *
+ * @param map the map
+ * @param it function to call on a random entry
+ * @param it_cls extra argument to @a it
+ * @return the number of key value pairs processed, zero or one.
+ */
+unsigned int
+GNUNET_CONTAINER_multipeermap_get_random (const struct GNUNET_CONTAINER_MultiPeerMap *map,
+ GNUNET_CONTAINER_PeerMapIterator it,
+ void *it_cls)
+{
+ unsigned int off;
+ unsigned int idx;
+ union MapEntry me;
+
+ if (0 == map->size)
+ return 0;
+ if (NULL == it)
+ return 1;
+ off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ map->size);
+ for (idx = 0; idx < map->map_length; idx++)
+ {
+ me = map->map[idx];
+ if (map->use_small_entries)
+ {
+ struct SmallMapEntry *sme;
+ struct SmallMapEntry *nxt;
+
+ nxt = me.sme;
+ while (NULL != (sme = nxt))
+ {
+ nxt = sme->next;
+ if (0 == off)
+ {
+ if (GNUNET_OK != it (it_cls,
+ sme->key,
+ sme->value))
+ return GNUNET_SYSERR;
+ return 1;
+ }
+ off--;
+ }
+ }
+ else
+ {
+ struct BigMapEntry *bme;
+ struct BigMapEntry *nxt;
+
+ nxt = me.bme;
+ while (NULL != (bme = nxt))
+ {
+ nxt = bme->next;
+ if (0 == off)
+ {
+ if (GNUNET_OK != it (it_cls,
+ &bme->key, bme->value))
+ return GNUNET_SYSERR;
+ return 1;
+ }
+ off--;
+ }
+ }
+ }
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+}
+
+
/**
* Create an iterator for a multipeermap.
* The iterator can be used to retrieve all the elements in the multipeermap