diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-08-29 14:16:39 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2009-08-29 14:16:39 -0400 |
commit | 5aef73cb7d023436f954906b84e61a58115a07f3 (patch) | |
tree | bb0bd42151164e6e2002d9fbf57a3c25a5c6daf3 | |
parent | 0a355e891e40dbe3f20516b2175acaed43922a68 (diff) |
A couple of hash bug fixes
-rw-r--r-- | hash.c | 66 | ||||
-rw-r--r-- | watch.c | 133 |
2 files changed, 97 insertions, 102 deletions
@@ -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) @@ -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; } - |