diff options
| -rw-r--r-- | libglusterfs/src/rbthash.c | 52 | ||||
| -rw-r--r-- | libglusterfs/src/rbthash.h | 5 | ||||
| -rw-r--r-- | xlators/performance/stat-prefetch/src/stat-prefetch.c | 78 | ||||
| -rw-r--r-- | xlators/performance/stat-prefetch/src/stat-prefetch.h | 7 | 
4 files changed, 118 insertions, 24 deletions
diff --git a/libglusterfs/src/rbthash.c b/libglusterfs/src/rbthash.c index 3b0f4ed4fcf..1c6294872b5 100644 --- a/libglusterfs/src/rbthash.c +++ b/libglusterfs/src/rbthash.c @@ -78,9 +78,20 @@ err:          return ret;  } +/* + * rbthash_table_init - Initialize a RBT based hash table + * @buckets - Number of buckets in the hash table + * @hfunc   - hashing function + * @dfunc   - destroyer for data in the RBT + * @expected_entries - Number of entries expected in RBT. Mutually exclusive + * with entrypool. + * @entrypool -  Memory pool in lieu of expected_entries. + */  rbthash_table_t * -rbthash_table_init (int buckets, rbt_hasher_t hfunc, rbt_data_destroyer_t dfunc) +rbthash_table_init (int buckets, rbt_hasher_t hfunc, +                    rbt_data_destroyer_t dfunc, unsigned long expected_entries, +                    struct mem_pool *entrypool)  {          rbthash_table_t         *newtab = NULL;          int                     ret = -1; @@ -90,6 +101,19 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, rbt_data_destroyer_t dfunc)                  return NULL;          } +        if (!entrypool && !expected_entries) { +                gf_log (GF_RBTHASH, GF_LOG_ERROR, +                        "Both mem-pool and expected entries not provided"); +                return NULL; +        } + +        if (entrypool && expected_entries) { +                gf_log (GF_RBTHASH, GF_LOG_ERROR, +                        "Both mem-pool and expected entries are provided"); +                return NULL; +        } + +          newtab = CALLOC (1, sizeof (*newtab));          if (!newtab)                  return NULL; @@ -100,10 +124,17 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, rbt_data_destroyer_t dfunc)                  goto free_newtab;          } -        newtab->entrypool =  mem_pool_new (rbthash_entry_t, GF_RBTHASH_MEMPOOL); -        if (!newtab->entrypool) { -                gf_log (GF_RBTHASH, GF_LOG_ERROR,"Failed to allocate mem-pool"); -                goto free_buckets; +        if (expected_entries) { +                newtab->entrypool = +                        mem_pool_new (rbthash_entry_t, expected_entries); +                if (!newtab->entrypool) { +                        gf_log (GF_RBTHASH, GF_LOG_ERROR, +                                "Failed to allocate mem-pool"); +                        goto free_buckets; +                } +                newtab->pool_alloced = _gf_true; +        } else { +                newtab->entrypool = entrypool;          }          LOCK_INIT (&newtab->tablelock); @@ -112,13 +143,16 @@ rbthash_table_init (int buckets, rbt_hasher_t hfunc, rbt_data_destroyer_t dfunc)          if (ret == -1) {                  gf_log (GF_RBTHASH, GF_LOG_ERROR, "Failed to init buckets"); -                mem_pool_destroy (newtab->entrypool); -        } else +                if (newtab->pool_alloced) +                        mem_pool_destroy (newtab->entrypool); +        } else {                  gf_log (GF_RBTHASH, GF_LOG_TRACE, "Inited hash table: buckets:"                          " %d", buckets); +        }          newtab->hashfunc = hfunc;          newtab->dfunc = dfunc; +  free_buckets:          if (ret == -1)                  FREE (newtab->buckets); @@ -132,7 +166,6 @@ free_newtab:          return newtab;  } -  rbthash_entry_t *  rbthash_init_entry (rbthash_table_t *tbl, void *data, void *key, int keylen)  { @@ -379,7 +412,8 @@ rbthash_table_destroy (rbthash_table_t *tbl)                  return;          rbthash_table_destroy_buckets (tbl); -        mem_pool_destroy (tbl->entrypool); +        if (tbl->pool_alloced) +                mem_pool_destroy (tbl->entrypool);          FREE (tbl->buckets);          FREE (tbl); diff --git a/libglusterfs/src/rbthash.h b/libglusterfs/src/rbthash.h index 5bfa6afd0ef..3f6d788f4cb 100644 --- a/libglusterfs/src/rbthash.h +++ b/libglusterfs/src/rbthash.h @@ -23,6 +23,7 @@  #include "locking.h"  #include "mem-pool.h"  #include "logging.h" +#include "common-utils.h"  #include <pthread.h> @@ -52,11 +53,13 @@ typedef struct rbthash_table {          struct rbthash_bucket   *buckets;          rbt_hasher_t            hashfunc;          rbt_data_destroyer_t    dfunc; +        gf_boolean_t            pool_alloced;  } rbthash_table_t;  extern rbthash_table_t *  rbthash_table_init (int buckets, rbt_hasher_t hfunc, -                    rbt_data_destroyer_t dfunc); +                    rbt_data_destroyer_t dfunc, unsigned long expected_entries, +                    struct mem_pool *entrypool);  extern int  rbthash_insert (rbthash_table_t *tbl, void *data, void *key, int keylen); diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c index 258d92c68ff..a9934bb1544 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.c +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c @@ -19,8 +19,8 @@  #include "stat-prefetch.h" -#define GF_SP_CACHE_BUCKETS 4096 - +#define GF_SP_CACHE_BUCKETS 1 +#define GF_SP_CACHE_ENTRIES_EXPECTED 1048576  sp_cache_t *  sp_cache_ref (sp_cache_t *cache) @@ -164,15 +164,25 @@ sp_hashfn (void *data, int len)  }  sp_cache_t * -sp_cache_init (void) +sp_cache_init (xlator_t *this)  { -        sp_cache_t *cache = NULL; +        sp_cache_t      *cache = NULL; +        sp_private_t    *priv = NULL; + +        priv = this->private; + +        if (!priv) +                goto out; + +        if (!priv->mem_pool) +                goto out; +          cache = CALLOC (1, sizeof (*cache));          if (cache) {                  cache->table = rbthash_table_init (GF_SP_CACHE_BUCKETS, -                                                   sp_hashfn, -                                                   free); +                                                   sp_hashfn, free, +                                                   0, priv->mem_pool);                  if (cache->table == NULL) {                          FREE (cache);                          cache = NULL; @@ -180,6 +190,7 @@ sp_cache_init (void)                  }                  LOCK_INIT (&cache->lock); +                cache->this = this;          }  out: @@ -202,18 +213,32 @@ sp_cache_remove_entry (sp_cache_t *cache, char *name, char remove_all)  {          int32_t          ret   = -1;          rbthash_table_t *table = NULL; +        xlator_t        *this; +        sp_private_t    *priv = NULL;          if ((cache == NULL) || ((name == NULL) && !remove_all)) {                  goto out;          } +        this = cache->this; + +        if (this == NULL) +                goto out; + +        if (this->private == NULL) +                goto out; + +        priv = this->private; +          LOCK (&cache->lock);          {                  if (remove_all) {                          table = cache->table;                          cache->table = rbthash_table_init (GF_SP_CACHE_BUCKETS,                                                             sp_hashfn, -                                                           free); +                                                           free, +                                                           0, +                                                           priv->mem_pool);                          if (cache->table == NULL) {                                  cache->table = table;                          } else { @@ -1001,16 +1026,21 @@ int32_t  sp_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  int32_t op_ret, int32_t op_errno, gf_dirent_t *entries)  { -        sp_local_t *local       = NULL; -        sp_cache_t *cache       = NULL; -        fd_t       *fd          = NULL; -        int32_t     ret         = 0; -        char        was_present = 1; +        sp_local_t      *local       = NULL; +        sp_cache_t      *cache       = NULL; +        fd_t            *fd          = NULL; +        int32_t         ret         = 0; +        char            was_present = 1; +        sp_private_t    *priv = NULL;          if (op_ret == -1) {                  goto out;          } +        if (!this->private) { +                goto out; +        } +          local = frame->local;          if (local == NULL) {                  goto out; @@ -1018,12 +1048,25 @@ sp_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          fd = local->fd; +        priv = this->private; + +        LOCK (&priv->lock); +        { +                if (!priv->mem_pool) +                        priv->mem_pool =  mem_pool_new (rbthash_entry_t, +                                                GF_SP_CACHE_ENTRIES_EXPECTED); +        } +        UNLOCK (&priv->lock); + +        if (!priv->mem_pool) +                goto out; +          LOCK (&fd->lock);          {                  cache = __sp_get_cache_fd (this, fd);                  if (cache == NULL) {                          was_present = 0; -                        cache = sp_cache_init (); +                        cache = sp_cache_init (this);                          if (cache == NULL) {                                  goto unlock;                          } @@ -4029,7 +4072,9 @@ sp_release (xlator_t *this, fd_t *fd)  int32_t   init (xlator_t *this)  { -        int32_t ret = -1; +        int32_t         ret = -1; +        sp_private_t    *priv = NULL; +          if (!this->children || this->children->next) {                  gf_log ("stat-prefetch",                          GF_LOG_ERROR, @@ -4038,6 +4083,11 @@ init (xlator_t *this)                  goto out;          } +        priv = CALLOC (1, sizeof(sp_private_t)); +        LOCK_INIT (&priv->lock); + +        this->private = priv; +          ret = 0;  out:          return ret; diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.h b/xlators/performance/stat-prefetch/src/stat-prefetch.h index 0e935330335..2a251e346c2 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.h +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.h @@ -44,6 +44,7 @@ struct sp_cache {          unsigned long    miss;          unsigned long    hits;          uint32_t         ref; +        xlator_t         *this;  };  typedef struct sp_cache sp_cache_t; @@ -77,6 +78,12 @@ struct sp_local {  };  typedef struct sp_local sp_local_t; +struct sp_private { +        struct mem_pool  *mem_pool; +        gf_lock_t        lock; +}; +typedef struct sp_private sp_private_t; +  void sp_local_free (sp_local_t *local);  | 
