about summary refs log tree commit homepage
path: root/svc_dev.c
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2014-05-29 07:11:04 +0000
committerEric Wong <e@80x24.org>2014-05-29 07:14:02 +0000
commit19a0fde65d8905f31e4ffaea531da4cefb02c29e (patch)
treeb43868b362b696e801454def49492ecb4607257e /svc_dev.c
parent565f1d67f7ce95f1a34bbcd9c3d90c1bb058bf9c (diff)
downloadcmogstored-19a0fde65d8905f31e4ffaea531da4cefb02c29e.tar.gz
There are no apparent benefits at the moment, but theoretically
it can reduce the amount of allocations we do and improve locality.
Diffstat (limited to 'svc_dev.c')
-rw-r--r--svc_dev.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/svc_dev.c b/svc_dev.c
index ea41c11..3a87800 100644
--- a/svc_dev.c
+++ b/svc_dev.c
@@ -4,6 +4,7 @@
  */
 #include "cmogstored.h"
 #include "compat_memstream.h"
+#include "dev.h"
 
 /*
  * maps multiple "devXXX" directories to the device.
@@ -12,7 +13,7 @@
  */
 struct mog_devlist {
         dev_t st_dev;
-        Hash_table *by_mogdevid;
+        khash_t(by_mog_devid) *by_mogdevid;
 };
 
 static size_t devlist_hash(const void *x, size_t tablesize)
@@ -34,7 +35,7 @@ static void devlist_free(void *x)
 {
         struct mog_devlist *devlist = x;
 
-        hash_free(devlist->by_mogdevid);
+        kh_destroy(by_mog_devid, devlist->by_mogdevid);
         free(devlist);
 }
 
@@ -43,15 +44,7 @@ static struct mog_devlist * mog_devlist_new(dev_t st_dev)
         struct mog_devlist *devlist = xmalloc(sizeof(struct mog_devlist));
 
         devlist->st_dev = st_dev;
-        devlist->by_mogdevid = hash_initialize(7, NULL,
-                                               mog_dev_hash, mog_dev_cmp,
-
-                                               /*
-                                                * elements are freed when
-                                                * svc->by_mog_devid is freed
-                                                */
-                                               NULL);
-
+        devlist->by_mogdevid = kh_init(by_mog_devid);
         mog_oom_if_null(devlist->by_mogdevid);
 
         return devlist;
@@ -108,7 +101,8 @@ static int svc_scandev(struct mog_svc *svc, unsigned *nr, mog_scandev_cb cb)
                 size_t len = strlen(ent->d_name);
                 struct mog_dev *dev;
                 struct mog_devlist *devlist;
-                Hash_table *devhash;
+                khash_t(by_mog_devid) *devhash;
+                int ret;
 
                 if (len <= 3) continue;
                 if (memcmp("dev", ent->d_name, 3) != 0) continue;
@@ -126,14 +120,16 @@ static int svc_scandev(struct mog_svc *svc, unsigned *nr, mog_scandev_cb cb)
                 if (cb)
                         rc |= cb(dev, svc); /* mog_dev_mkusage */
 
-                switch (hash_insert_if_absent(devhash, dev, NULL)) {
+                kh_put(by_mog_devid, devhash, dev, &ret);
+                switch (ret) {
                 case 0:
                         /* do not free dev, it is in svc->by_mog_devid */
                         syslog(LOG_ERR,
                                "%s/%s seen twice in readdir (BUG?)",
                                svc->docroot, ent->d_name);
                         break;
-                case 1:
+                case 1: /* never-used bucket */
+                case 2: /* deleted bucket */
                         (*nr)++;
                         break;
                 default: mog_oom(); /* -1 */
@@ -164,9 +160,11 @@ static bool write_dev_stats(void *entry, void *filep)
 static bool write_devlist_stats(void *entry, void *filep)
 {
         struct mog_devlist *devlist = entry;
-        FILE **fp ;
+        FILE **fp;
+        struct mog_dev *dev;
+        khash_t(by_mog_devid) *h = devlist->by_mogdevid;
 
-        hash_do_for_each(devlist->by_mogdevid, write_dev_stats, filep);
+        mog_kh_foreach_key(h, dev, write_dev_stats(dev, filep));
         fp = filep;
 
         /* *filep becomes NULL on errors */
@@ -314,17 +312,25 @@ static void svc_rescale_warn_fix_capa(struct mog_svc *svc, unsigned ndev_new)
 
 static void mog_svc_dev_rescale_all(struct mog_svc *svc)
 {
+        struct mog_dev *dev;
+        khash_t(by_mog_devid) *h;
+
         /* iterate through each device of this svc */
         CHECK(int, 0, pthread_mutex_lock(&svc->by_mog_devid_lock));
-        hash_do_for_each(svc->by_mog_devid, mog_dev_user_rescale_i, svc);
+        h = svc->by_mog_devid;
+        mog_kh_foreach_key(h, dev, mog_dev_user_rescale_i(dev, svc));
         CHECK(int, 0, pthread_mutex_unlock(&svc->by_mog_devid_lock));
 }
 
 void mog_svc_dev_requeue_prepare(struct mog_svc *svc)
 {
+        struct mog_dev *dev;
+        khash_t(by_mog_devid) *h;
+
         /* iterate through each device of this svc */
         CHECK(int, 0, pthread_mutex_lock(&svc->by_mog_devid_lock));
-        hash_do_for_each(svc->by_mog_devid, mog_dev_requeue_prepare, svc);
+        h = svc->by_mog_devid;
+        mog_kh_foreach_key(h, dev, mog_dev_requeue_prepare(dev, svc));
         CHECK(int, 0, pthread_mutex_unlock(&svc->by_mog_devid_lock));
 }