summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-08-29 14:16:39 -0400
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2009-08-29 14:16:39 -0400
commit5aef73cb7d023436f954906b84e61a58115a07f3 (patch)
treebb0bd42151164e6e2002d9fbf57a3c25a5c6daf3
parent0a355e891e40dbe3f20516b2175acaed43922a68 (diff)
A couple of hash bug fixes
-rw-r--r--hash.c66
-rw-r--r--watch.c133
2 files changed, 97 insertions, 102 deletions
diff --git a/hash.c b/hash.c
index 090552e..e7fb77a 100644
--- a/hash.c
+++ b/hash.c
@@ -8,14 +8,6 @@ struct hash_entry_t
nul_ptr_t value;
};
-
-enum
-{
- FREE,
- IN_USE,
- DEAD
-};
-
/* Expand the table when more than 1/HIGH_OCCUPATION is in use.
* Shrink the table when less than 1/LOW_OCCUPATION is in use
* When resizing the table, size it such that 1/DEFAULT_OCCUPATION is in use
@@ -91,6 +83,7 @@ insert_internal (nul_hash_t *hash, nul_ptr_t key, nul_ptr_t value)
entry = &(hash->entries[index]);
}
+ hash->n_items++;
entry->key = key;
entry->value = value;
}
@@ -111,6 +104,7 @@ rehash (nul_hash_t *hash)
hash->entries = nul_array_new (hash_entry_t);
hash->entries = nul_array_set_size (hash->entries, new_size);
hash->mask = new_size - 1;
+ hash->n_items = 0;
for (t = 0; t < new_size; ++t)
{
@@ -133,28 +127,6 @@ rehash (nul_hash_t *hash)
}
}
-nul_hash_t *
-nul_hash_new (nul_hash_func_t hash_func,
- nul_hash_equal_func_t equal_func,
- nul_free_func_t key_free_func,
- nul_free_func_t value_free_func)
-{
- nul_hash_t *hash = g_new (nul_hash_t, 1);
-
- hash->entries = NULL;
- hash->hash_func = hash_func;
- hash->equal_func = equal_func;
- hash->key_free_func = key_free_func;
- hash->value_free_func = value_free_func;
- hash->free_marker = random_pointer();
- hash->dead_marker = random_pointer();
- hash->n_items = 0;
-
- rehash (hash);
-
- return hash;
-}
-
static void
regenerate_markers (nul_hash_t *hash, nul_ptr_t value)
{
@@ -207,15 +179,40 @@ retry:
hash->free_marker = new_free_marker;
}
+nul_hash_t *
+nul_hash_new (nul_hash_func_t hash_func,
+ nul_hash_equal_func_t equal_func,
+ nul_free_func_t key_free_func,
+ nul_free_func_t value_free_func)
+{
+ nul_hash_t *hash = g_new (nul_hash_t, 1);
+
+ hash->hash_func = hash_func;
+ hash->equal_func = equal_func;
+ hash->key_free_func = key_free_func;
+ hash->value_free_func = value_free_func;
+ hash->free_marker = random_pointer();
+ hash->dead_marker = random_pointer();
+
+ hash->entries = NULL;
+ hash->n_items = 0;
+ hash->mask = 0;
+
+ rehash (hash);
+
+ return hash;
+}
+
static inline nul_bool_t
need_rehash (nul_hash_t *hash)
{
- int table_size = nul_array_len (hash->entries);
+ int table_size = hash->mask + 1;
int n_items = hash->n_items;
return
- n_items * HIGH_OCCUPATION > table_size ||
- MAX (n_items * LOW_OCCUPATION, MIN_SIZE) < table_size;
+ (n_items * HIGH_OCCUPATION > table_size ||
+ n_items * LOW_OCCUPATION < table_size) &&
+ table_size > MIN_SIZE;
}
void
@@ -223,7 +220,7 @@ nul_hash_insert (nul_hash_t *hash,
nul_ptr_t key,
nul_ptr_t value)
{
- if (value == hash->free_marker || value == hash->dead_marker)
+ if (G_UNLIKELY (value == hash->free_marker || value == hash->dead_marker))
regenerate_markers (hash, value);
insert_internal (hash, key, value);
@@ -252,7 +249,6 @@ find_entry (nul_hash_t *hash, nul_ptr_t key)
return NULL;
}
-
nul_ptr_t
nul_hash_lookup (nul_hash_t *hash,
nul_ptr_t key)
diff --git a/watch.c b/watch.c
index 9602f39..8e33e84 100644
--- a/watch.c
+++ b/watch.c
@@ -14,7 +14,7 @@
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
+ * License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
@@ -29,7 +29,7 @@ struct Watch
GSource source;
GPollFD poll_fd;
gboolean removed;
-
+
WatchCallback read_callback;
WatchCallback write_callback;
WatchCallback hangup_callback;
@@ -53,7 +53,7 @@ static Watch *
lookup_watch (gint fd)
{
init ();
-
+
return g_hash_table_lookup (watched_fds, &fd);
}
@@ -61,9 +61,9 @@ static void
internal_add_watch (Watch *watch)
{
gpointer fd = &(watch->poll_fd.fd);
-
+
init ();
-
+
g_hash_table_insert (watched_fds, fd, watch);
g_source_add_poll ((GSource *)watch, &(watch->poll_fd));
}
@@ -72,9 +72,9 @@ static void
internal_remove_watch (Watch *watch)
{
gpointer fd = &(watch->poll_fd.fd);
-
+
init ();
-
+
watch->removed = TRUE;
g_source_remove_poll ((GSource *)watch, &(watch->poll_fd));
g_hash_table_remove (watched_fds, fd);
@@ -85,12 +85,12 @@ watch_prepare (GSource *source,
gint *timeout)
{
Watch *watch = (Watch *)source;
-
+
*timeout = -1;
-
+
if (watch->poll_callback)
watch->poll_callback (watch->data);
-
+
return FALSE;
}
@@ -99,7 +99,7 @@ watch_check (GSource *source)
{
Watch *watch = (Watch *)source;
gint revents = watch->poll_fd.revents;
-
+
if (revents & (G_IO_NVAL))
{
/* This can happen if the user closes the file descriptor
@@ -109,22 +109,22 @@ watch_check (GSource *source)
g_source_unref (source);
return FALSE;
}
-
+
if ((revents & G_IO_HUP) && watch->hangup_callback)
return TRUE;
-
+
if ((revents & G_IO_IN) && watch->read_callback)
return TRUE;
-
+
if ((revents & G_IO_PRI) && watch->priority_callback)
return TRUE;
-
+
if ((revents & G_IO_ERR) && watch->error_callback)
return TRUE;
-
+
if ((revents & G_IO_OUT) && watch->write_callback)
return TRUE;
-
+
return FALSE;
}
@@ -136,31 +136,31 @@ watch_dispatch (GSource *source,
Watch *watch = (Watch *)source;
gint revents = watch->poll_fd.revents;
gboolean removed;
-
+
g_source_ref (source);
-
+
if (!watch->removed && (revents & G_IO_IN) && watch->read_callback)
watch->read_callback (watch->data);
-
+
if (!watch->removed && (revents & G_IO_PRI) && watch->priority_callback)
watch->priority_callback (watch->data);
-
+
if (!watch->removed && (revents & G_IO_OUT) && watch->write_callback)
watch->write_callback (watch->data);
-
+
if (!watch->removed && (revents & G_IO_ERR) && watch->error_callback)
watch->error_callback (watch->data);
-
+
if (!watch->removed && (revents & G_IO_HUP) && watch->hangup_callback)
watch->hangup_callback (watch->data);
-
+
removed = watch->removed;
-
+
g_source_unref (source);
-
+
if (removed)
return FALSE;
-
+
return TRUE;
}
@@ -173,32 +173,32 @@ static void
update_poll_mask (Watch *watch)
{
gint events = 0;
-
+
g_source_remove_poll ((GSource *)watch, &(watch->poll_fd));
-
+
if (watch->read_callback)
events |= G_IO_IN;
-
+
if (watch->write_callback)
events |= G_IO_OUT;
-
+
if (watch->priority_callback)
events |= G_IO_PRI;
-
+
if (watch->hangup_callback)
events |= G_IO_HUP;
-
+
if (watch->error_callback)
events |= G_IO_ERR;
-
+
watch->poll_fd.events = events;
-
+
g_source_add_poll ((GSource *)watch, &(watch->poll_fd));
}
void
nul_fd_add_watch (gint fd,
- gpointer data)
+ gpointer data)
{
static GSourceFuncs watch_funcs = {
watch_prepare,
@@ -208,26 +208,26 @@ nul_fd_add_watch (gint fd,
NULL,
};
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch == NULL);
-
- watch = (Watch *)g_source_new (&watch_funcs, sizeof (Watch));
+
+ watch = (Watch *)g_source_new (&watch_funcs, sizeof (Watch));
g_source_set_can_recurse ((GSource *)watch, TRUE);
g_source_attach ((GSource *)watch, NULL);
-
+
watch->poll_fd.fd = fd;
watch->poll_fd.events = 0;
watch->removed = FALSE;
-
+
watch->read_callback = NULL;
watch->write_callback = NULL;
watch->hangup_callback = NULL;
watch->error_callback = NULL;
watch->priority_callback = NULL;
-
+
watch->data = data;
-
+
internal_add_watch (watch);
}
@@ -235,7 +235,7 @@ gpointer
nul_fd_get_data (gint fd)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_val_if_fail (fd > 0, NULL);
g_return_val_if_fail (watch != NULL, NULL);
@@ -244,10 +244,10 @@ nul_fd_get_data (gint fd)
void
nul_fd_set_data (gint fd,
- gpointer data)
+ gpointer data)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
@@ -256,13 +256,13 @@ nul_fd_set_data (gint fd,
void
nul_fd_set_read_callback (gint fd,
- WatchCallback read_cb)
+ WatchCallback read_cb)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
-
+
if (watch->read_callback != read_cb)
{
watch->read_callback = read_cb;
@@ -272,13 +272,13 @@ nul_fd_set_read_callback (gint fd,
void
nul_fd_set_write_callback (gint fd,
- WatchCallback write_cb)
+ WatchCallback write_cb)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
-
+
if (watch->write_callback != write_cb)
{
watch->write_callback = write_cb;
@@ -288,13 +288,13 @@ nul_fd_set_write_callback (gint fd,
void
nul_fd_set_hangup_callback (gint fd,
- WatchCallback hangup_cb)
+ WatchCallback hangup_cb)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
-
+
if (watch->hangup_callback != hangup_cb)
{
watch->hangup_callback = hangup_cb;
@@ -304,13 +304,13 @@ nul_fd_set_hangup_callback (gint fd,
void
nul_fd_set_error_callback (gint fd,
- WatchCallback error_cb)
+ WatchCallback error_cb)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
-
+
if (watch->error_callback != error_cb)
{
watch->error_callback = error_cb;
@@ -320,13 +320,13 @@ nul_fd_set_error_callback (gint fd,
void
nul_fd_set_priority_callback (gint fd,
- WatchCallback priority_cb)
+ WatchCallback priority_cb)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
g_return_if_fail (watch != NULL);
-
+
if (watch->priority_callback != priority_cb)
{
watch->priority_callback = priority_cb;
@@ -336,7 +336,7 @@ nul_fd_set_priority_callback (gint fd,
void
nul_fd_set_poll_handler (gint fd,
- WatchCallback poll_cb)
+ WatchCallback poll_cb)
{
Watch *watch = lookup_watch (fd);
@@ -354,12 +354,12 @@ void
nul_fd_remove_watch (gint fd)
{
Watch *watch = lookup_watch (fd);
-
+
g_return_if_fail (fd > 0);
-
+
if (!watch)
return;
-
+
internal_remove_watch (watch);
g_source_unref ((GSource *)watch);
}
@@ -368,10 +368,9 @@ gboolean
nul_fd_is_watched (gint fd)
{
g_return_val_if_fail (fd > 0, FALSE);
-
+
if (lookup_watch (fd))
return TRUE;
else
return FALSE;
}
-