提交 26358d71 编写于 作者: Z Zoltan Varga 提交者: Ricardo Arango

Implement GHashTable iterators.

上级 b6ffea2b
......@@ -51,6 +51,12 @@ struct _GHashTable {
GDestroyNotify value_destroy_func, key_destroy_func;
};
typedef struct {
GHashTable *ht;
int slot_index;
Slot *slot;
} Iter;
static const guint prime_tbl[] = {
11, 19, 37, 73, 109, 163, 251, 367, 557, 823, 1237,
1861, 2777, 4177, 6247, 9371, 14057, 21089, 31627,
......@@ -458,6 +464,47 @@ g_hash_table_remove_all (GHashTable *hash)
rehash (hash);
}
void
g_hash_table_iter_init (GHashTableIter *it, GHashTable *hash_table)
{
Iter *iter = (Iter*)it;
memset (iter, 0, sizeof (Iter));
iter->ht = hash_table;
iter->slot_index = -1;
}
gboolean g_hash_table_iter_next (GHashTableIter *it, gpointer *key, gpointer *value)
{
Iter *iter = (Iter*)it;
GHashTable *hash = iter->ht;
g_assert (iter->slot_index != -2);
g_assert (sizeof (Iter) <= sizeof (GHashTableIter));
if (!iter->slot) {
while (TRUE) {
iter->slot_index ++;
if (iter->slot_index >= hash->table_size) {
iter->slot_index = -2;
return FALSE;
}
if (hash->table [iter->slot_index])
break;
}
iter->slot = hash->table [iter->slot_index];
}
if (key)
*key = iter->slot->key;
if (value)
*value = iter->slot->value;
iter->slot = iter->slot->next;
return TRUE;
}
gboolean
g_direct_equal (gconstpointer v1, gconstpointer v2)
{
......
......@@ -166,6 +166,14 @@ gchar* g_win32_getlocale(void);
* Hashtables
*/
typedef struct _GHashTable GHashTable;
typedef struct _GHashTableIter GHashTableIter;
/* Private, but needed for stack allocation */
struct _GHashTableIter
{
gpointer dummy [8];
};
typedef void (*GFunc) (gpointer data, gpointer user_data);
typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b);
typedef gint (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data);
......@@ -191,6 +199,9 @@ guint g_hash_table_foreach_remove (GHashTable *hash, GHRFunc func, gp
guint g_hash_table_foreach_steal (GHashTable *hash, GHRFunc func, gpointer user_data);
void g_hash_table_destroy (GHashTable *hash);
void g_hash_table_iter_init (GHashTableIter *iter, GHashTable *hash_table);
gboolean g_hash_table_iter_next (GHashTableIter *iter, gpointer *key, gpointer *value);
guint g_spaced_primes_closest (guint x);
#define g_hash_table_insert(h,k,v) g_hash_table_insert_replace ((h),(k),(v),FALSE)
......
......@@ -131,12 +131,40 @@ RESULT hash_grow (void)
return NULL;
}
RESULT hash_iter (void)
{
GHashTable *hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
GHashTableIter iter;
int i, sum, keys_sum, values_sum;
gpointer key, value;
sum = 0;
for (i = 0; i < 1000; i++) {
sum += i;
g_hash_table_insert (hash, GUINT_TO_POINTER (i), GUINT_TO_POINTER (i));
}
keys_sum = values_sum = 0;
g_hash_table_iter_init (&iter, hash);
while (g_hash_table_iter_next (&iter, &key, &value)) {
if (key != value)
return FAILED ("key != value");
keys_sum += GPOINTER_TO_UINT (key);
values_sum += GPOINTER_TO_UINT (value);
}
if (keys_sum != sum || values_sum != sum)
return FAILED ("Did not find all key-value pairs");
g_hash_table_destroy (hash);
return NULL;
}
static Test hashtable_tests [] = {
{"t1", hash_t1},
{"t2", hash_t2},
{"grow", hash_grow},
{"default", hash_default},
{"null_lookup", hash_null_lookup},
{"iter", hash_iter},
{NULL, NULL}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册