diff options
Diffstat (limited to 'libglusterfs/src/rbthash.c')
| -rw-r--r-- | libglusterfs/src/rbthash.c | 96 |
1 files changed, 65 insertions, 31 deletions
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c index 33e80224a..0d7b9e521 100644 --- a/libglusterfs/src/rbthash.c +++ b/libglusterfs/src/rbthash.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2008-2009 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS 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 - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ @@ -116,13 +107,14 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, } - newtab = CALLOC (1, sizeof (*newtab)); + newtab = GF_CALLOC (1, sizeof (*newtab), + gf_common_mt_rbthash_table_t); if (!newtab) return NULL; - newtab->buckets = CALLOC (buckets, sizeof (struct rbthash_bucket)); + newtab->buckets = GF_CALLOC (buckets, sizeof (struct rbthash_bucket), + gf_common_mt_rbthash_bucket); if (!newtab->buckets) { - gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to allocate memory"); goto free_newtab; } @@ -140,6 +132,7 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, } LOCK_INIT (&newtab->tablelock); + INIT_LIST_HEAD (&newtab->list); newtab->numbuckets = buckets; ret = __rbthash_init_buckets (newtab, buckets); @@ -157,11 +150,11 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, free_buckets: if (ret == -1) - FREE (newtab->buckets); + GF_FREE (newtab->buckets); free_newtab: if (ret == -1) { - FREE (newtab); + GF_FREE (newtab); newtab = NULL; } @@ -185,12 +178,12 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen) } entry->data = data; - entry->key = CALLOC (keylen, sizeof (char)); + entry->key = GF_CALLOC (keylen, sizeof (char), gf_common_mt_char); if (!entry->key) { - gf_log (GF_RBTHASH, GF_LOG_ERROR, "Memory allocation failed"); goto free_entry; } + INIT_LIST_HEAD (&entry->list); memcpy (entry->key, key, keylen); entry->keylen = keylen; entry->keyhash = tbl->hashfunc (entry->key, entry->keylen); @@ -199,7 +192,7 @@ rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen) ret = 0; free_entry: if (ret == -1) { - mem_put (tbl->entrypool, entry); + mem_put (entry); entry = NULL; } @@ -215,20 +208,26 @@ rbthash_deinit_entry (rbthash_table_t *tbl, rbthash_entry_t *entry) if (!entry) return; - if (entry->key) - FREE (entry->key); + GF_FREE (entry->key); if (tbl) { if ((entry->data) && (tbl->dfunc)) tbl->dfunc (entry->data); - mem_put (tbl->entrypool, entry); + + LOCK (&tbl->tablelock); + { + list_del_init (&entry->list); + } + UNLOCK (&tbl->tablelock); + + mem_put (entry); } return; } -inline struct rbthash_bucket * +static inline struct rbthash_bucket * rbthash_entry_bucket (rbthash_table_t *tbl, rbthash_entry_t * entry) { int nbucket = 0; @@ -292,11 +291,17 @@ rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen) rbthash_deinit_entry (tbl, entry); } + LOCK (&tbl->tablelock); + { + list_add_tail (&entry->list, &tbl->list); + } + UNLOCK (&tbl->tablelock); + err: return ret; } -inline struct rbthash_bucket * +static inline struct rbthash_bucket * rbthash_key_bucket (rbthash_table_t *tbl, void *key, int keylen) { uint32_t keyhash = 0; @@ -374,9 +379,16 @@ rbthash_remove (rbthash_table_t *tbl, void *key, int keylen) if (!entry) return NULL; - FREE (entry->key); + GF_FREE (entry->key); dataref = entry->data; - mem_put (tbl->entrypool, entry); + + LOCK (&tbl->tablelock); + { + list_del_init (&entry->list); + } + UNLOCK (&tbl->tablelock); + + mem_put (entry); return dataref; } @@ -418,7 +430,29 @@ rbthash_table_destroy (rbthash_table_t *tbl) if (tbl->pool_alloced) mem_pool_destroy (tbl->entrypool); - FREE (tbl->buckets); - FREE (tbl); + GF_FREE (tbl->buckets); + GF_FREE (tbl); } + +void +rbthash_table_traverse (rbthash_table_t *tbl, rbt_traverse_t traverse, + void *mydata) +{ + rbthash_entry_t *entry = NULL; + + if ((tbl == NULL) || (traverse == NULL)) { + goto out; + } + + LOCK (&tbl->tablelock); + { + list_for_each_entry (entry, &tbl->list, list) { + traverse (entry->data, mydata); + } + } + UNLOCK (&tbl->tablelock); + +out: + return; +} |
