/* Libvisual - The audio visualisation framework. * * Copyright (C) 2004, 2005, 2006 Dennis Smit * * Authors: Dennis Smit * * $Id: lv_hashlist.c,v 1.4 2006/01/22 13:23:37 synap Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include "lv_common.h" #include "lv_hashlist.h" static int hashlist_destroy (VisCollection *collection); static int hashlist_size (VisCollection *collection); static VisCollectionIter *hashlist_iter (VisCollection *collection); static int hashlist_destroy (VisCollection *collection) { VisHashlist *hashlist = VISUAL_HASHLIST (collection); VisListEntry *le = NULL; /* Destroy all entries in hashlist first */ while (visual_list_next (hashlist->list, &le) != NULL) { VisListEntry *prev = le; VisListEntry *next = le; visual_list_prev (hashlist->list, &prev); visual_list_next (hashlist->list, &next); visual_hashlist_remove_list_entry (hashlist, le); if (next == NULL) break; le = prev; } /* Destroy the rest */ if (hashlist->list != NULL) visual_object_unref (VISUAL_OBJECT (hashlist->list)); if (hashlist->index != NULL) visual_object_unref (VISUAL_OBJECT (hashlist->index)); hashlist->list = NULL; hashlist->index = NULL; return VISUAL_OK; } static int hashlist_size (VisCollection *collection) { VisHashlist *hashlist = VISUAL_HASHLIST (collection); return visual_collection_size (VISUAL_COLLECTION (hashlist->list)); } static VisCollectionIter *hashlist_iter (VisCollection *collection) { VisHashlist *hashlist = VISUAL_HASHLIST (collection); return visual_collection_get_iter (VISUAL_COLLECTION (hashlist->list)); } /** * @defgroup VisHashlist VisHashlist * @{ */ /** * Creates a new VisHashlist. * * @return A newly allocated VisHashlist. */ VisHashlist *visual_hashlist_new (VisCollectionDestroyerFunc destroyer, int size) { VisHashlist *hashlist; hashlist = visual_mem_new0 (VisHashlist, 1); visual_hashlist_init (hashlist, destroyer, size); /* Do the VisObject initialization */ visual_object_set_allocated (VISUAL_OBJECT (hashlist), TRUE); visual_object_ref (VISUAL_OBJECT (hashlist)); return hashlist; } int visual_hashlist_init (VisHashlist *hashlist, VisCollectionDestroyerFunc destroyer, int size) { visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); /* Do the VisObject initialization */ visual_object_clear (VISUAL_OBJECT (hashlist)); visual_object_set_dtor (VISUAL_OBJECT (hashlist), visual_collection_dtor); visual_object_set_allocated (VISUAL_OBJECT (hashlist), FALSE); /* Set the VisCollection data */ visual_collection_set_destroyer (VISUAL_COLLECTION (hashlist), destroyer); visual_collection_set_destroy_func (VISUAL_COLLECTION (hashlist), hashlist_destroy); visual_collection_set_size_func (VISUAL_COLLECTION (hashlist), hashlist_size); visual_collection_set_iter_func (VISUAL_COLLECTION (hashlist), hashlist_iter); /* Set the VisHashlist data */ visual_hashlist_set_size (hashlist, size); hashlist->list = visual_list_new (NULL); hashlist->index = visual_hashmap_new (NULL); /* FIXME create in set_limits, rehash if not NULL */ visual_hashmap_set_table_size (hashlist->index, size); /* <- also */ return VISUAL_OK; } int visual_hashlist_clear (VisHashlist *hashlist) { VisListEntry *le = NULL; visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); /* Destroy all entries in hashlist first */ while (visual_list_next (hashlist->list, &le) != NULL) visual_hashlist_remove_list_entry (hashlist, le); if (hashlist->index != NULL) visual_object_unref (VISUAL_OBJECT (hashlist->index)); hashlist->index = visual_hashmap_new (NULL); visual_hashmap_set_table_size (hashlist->index, hashlist->size); return VISUAL_OK; } int visual_hashlist_put (VisHashlist *hashlist, char *key, void *data) { VisHashlistEntry *hentry; VisListEntry *le; visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); visual_log_return_val_if_fail (key != NULL, -VISUAL_ERROR_NULL); visual_log_return_val_if_fail (data != NULL, -VISUAL_ERROR_NULL); le = visual_hashmap_get_string (hashlist->index, key); if (le != NULL) { hentry = le->data; hentry->data = data; } else { hentry = visual_mem_new0 (VisHashlistEntry, 1); hentry->key = key; hentry->data = data; visual_list_add (hashlist->list, hentry); le = hashlist->list->tail; visual_hashmap_put_string (hashlist->index, key, le); } return VISUAL_OK; } int visual_hashlist_remove (VisHashlist *hashlist, char *key) { VisListEntry *le; visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); visual_log_return_val_if_fail (key != NULL, -VISUAL_ERROR_NULL); le = visual_hashmap_get_string (hashlist->index, key); if (le != NULL) visual_hashlist_remove_list_entry (hashlist, le); return VISUAL_OK; } int visual_hashlist_remove_list_entry (VisHashlist *hashlist, VisListEntry *le) { VisCollectionDestroyerFunc destroyer; VisHashlistEntry *hentry; visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); visual_log_return_val_if_fail (le != NULL, -VISUAL_ERROR_LIST_ENTRY_NULL); hentry = le->data; visual_hashmap_remove_string (hashlist->index, hentry->key, FALSE); destroyer = visual_collection_get_destroyer (VISUAL_COLLECTION (hashlist)); if (destroyer != NULL) destroyer (hentry->data); visual_list_destroy (hashlist->list, &le); return VISUAL_OK; } void *visual_hashlist_get (VisHashlist *hashlist, char *key) { VisHashlistEntry *hentry; VisListEntry *le; visual_log_return_val_if_fail (hashlist != NULL, NULL); visual_log_return_val_if_fail (key != NULL, NULL); le = visual_hashmap_get_string (hashlist->index, key); if (le == NULL) return NULL; hentry = le->data; return hentry->data; } int visual_hashlist_get_size (VisHashlist *hashlist) { visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); return visual_collection_size (VISUAL_COLLECTION (hashlist->list)); } int visual_hashlist_set_size (VisHashlist *hashlist, int size) { visual_log_return_val_if_fail (hashlist != NULL, -VISUAL_ERROR_HASHLIST_NULL); /* FIXME limit size change, rehash the index */ hashlist->size = size; return VISUAL_OK; } VisList *visual_hashlist_get_list (VisHashlist *hashlist) { visual_log_return_val_if_fail (hashlist != NULL, NULL); return hashlist->list; } /** * @} */