From: levin li <[email protected]>

Applied the object list cache to get_obj_list() which
just return the cached list, instead of calling sd_store->get_objlist(),
make it much faster to get the object list.

Signed-off-by: levin li <[email protected]>
---
 sheep/farm/farm.c    |   30 +++++++++++-------------------
 sheep/farm/farm.h    |    2 ++
 sheep/farm/trunk.c   |   10 ++++++++++
 sheep/sheep_priv.h   |    1 +
 sheep/simple_store.c |   50 +++++++++++++++++++++++++++++++++++++++++++++-----
 sheep/store.c        |   37 ++++++++++---------------------------
 6 files changed, 79 insertions(+), 51 deletions(-)

diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c
index e130138..7befd56 100644
--- a/sheep/farm/farm.c
+++ b/sheep/farm/farm.c
@@ -12,6 +12,7 @@
  */
 
 #include <dirent.h>
+#include <pthread.h>
 
 #include "farm.h"
 #include "sheep_priv.h"
@@ -269,29 +270,20 @@ out:
 
 static int farm_get_objlist(struct siocb *iocb)
 {
-       struct sha1_file_hdr hdr;
-       struct trunk_entry *trunk_buf, *trunk_free = NULL;
-       unsigned char trunk_sha1[SHA1_LEN];
-       uint64_t nr_trunks, i;
        uint64_t *objlist = (uint64_t *)iocb->buf;
-       int ret = SD_RES_NO_TAG;
-
-       if (get_trunk_sha1(iocb->epoch, trunk_sha1, 0) < 0)
-               goto out;
-
-       trunk_free = trunk_buf = trunk_file_read(trunk_sha1, &hdr);
-       if (!trunk_buf)
-               goto out;
+       struct list_head *active_list = trunk_get_active_list();
+       pthread_mutex_t lock = trunk_get_active_list_lock();
+       struct trunk_entry_incore *entry;
 
-       nr_trunks = hdr.priv;
-       for (i = 0; i < nr_trunks; i++, trunk_buf++)
-               objlist[iocb->length++] = trunk_buf->oid;
+       pthread_mutex_lock(&lock);
+       list_for_each_entry(entry, active_list, active_list) {
+               objlist[iocb->length++] = entry->raw.oid;
+       }
+       pthread_mutex_unlock(&lock);
 
        dprintf("%"PRIu32"\n", iocb->length);
-       ret = SD_RES_SUCCESS;
-out:
-       free(trunk_free);
-       return ret;
+
+       return SD_RES_SUCCESS;
 }
 
 static void *retrieve_object_from_snap(uint64_t oid, int epoch)
diff --git a/sheep/farm/farm.h b/sheep/farm/farm.h
index 86aeadd..0ecf491 100644
--- a/sheep/farm/farm.h
+++ b/sheep/farm/farm.h
@@ -68,6 +68,8 @@ extern int trunk_update_entry(uint64_t oid);
 extern void trunk_reset(void);
 extern void trunk_put_entry(uint64_t oid);
 extern void trunk_get_entry(uint64_t oid);
+extern struct list_head *trunk_get_active_list(void);
+extern pthread_mutex_t trunk_get_active_list_lock(void);
 
 /* snap.c */
 extern int snap_init(void);
diff --git a/sheep/farm/trunk.c b/sheep/farm/trunk.c
index fabae8a..8631e32 100644
--- a/sheep/farm/trunk.c
+++ b/sheep/farm/trunk.c
@@ -378,3 +378,13 @@ void trunk_reset(void)
        eprintf("%s\n", trunk_entry_active_nr ? "WARN: active_list not clean" :
                                                "clean");
 }
+
+struct list_head *trunk_get_active_list(void)
+{
+       return &trunk_active_list;
+}
+
+pthread_mutex_t trunk_get_active_list_lock(void)
+{
+       return active_list_lock;
+}
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index db70c57..6fd838c 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -296,6 +296,7 @@ int read_object(struct sd_vnode *e,
 int remove_object(struct sd_vnode *e,
                  int vnodes, int zones, uint32_t node_version,
                  uint64_t oid, int nr);
+int merge_objlist(uint64_t *list1, int nr_list1, uint64_t *list2, int 
nr_list2);
 
 void del_sheep_fd(int fd);
 int get_sheep_fd(uint8_t *addr, uint16_t port, int node_idx, uint32_t epoch);
diff --git a/sheep/simple_store.c b/sheep/simple_store.c
index e1cfeca..b30f75f 100644
--- a/sheep/simple_store.c
+++ b/sheep/simple_store.c
@@ -184,13 +184,12 @@ static int simple_store_close(uint64_t oid, struct siocb 
*iocb)
        return SD_RES_SUCCESS;
 }
 
-static int simple_store_get_objlist(struct siocb *siocb)
+static int get_epoch_obj_list(int epoch, uint64_t *objlist, int *nr)
 {
        struct strbuf buf = STRBUF_INIT;
-       int epoch = siocb->epoch;
-       uint64_t *objlist = (uint64_t *)siocb->buf;
        DIR *dir;
        struct dirent *d;
+       int length = 0;
        int ret = SD_RES_SUCCESS;
 
        strbuf_addf(&buf, "%s%08u/", obj_path, epoch);
@@ -202,7 +201,6 @@ static int simple_store_get_objlist(struct siocb *siocb)
                ret = SD_RES_EIO;
                goto out;
        }
-
        while ((d = readdir(dir))) {
                uint64_t oid;
                if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
@@ -212,14 +210,56 @@ static int simple_store_get_objlist(struct siocb *siocb)
                if (oid == 0)
                        continue;
 
-               objlist[siocb->length++] = oid;
+               objlist[length++] = oid;
        }
        closedir(dir);
+       *nr = length;
 out:
        strbuf_release(&buf);
        return ret;
 }
 
+static int simple_store_get_objlist(struct siocb *siocb)
+{
+       uint64_t *objlist = (uint64_t*)siocb->buf;
+       uint64_t *buf;
+       int epoch, nr = 0, obj_nr = 0;
+       DIR *dir;
+       struct dirent *d;
+       int ret = SD_RES_SUCCESS, r;
+
+       dir = opendir(obj_path);
+       if (!dir) {
+               ret = SD_RES_EIO;
+               goto out;
+       }
+
+       buf = zalloc(1 << 22);
+       if (!buf) {
+               dprintf("no memory to allocate.\n");
+               ret = SD_RES_NO_MEM;
+               goto out;
+       }
+
+       while ((d = readdir(dir))) {
+               if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
+                       continue;
+               epoch = strtoul(d->d_name, NULL, 16);
+               if (epoch == 0)
+                       continue;
+
+               r = get_epoch_obj_list(epoch, buf, &obj_nr);
+               if (SD_RES_SUCCESS == r)
+                       nr = merge_objlist(objlist, nr, buf, obj_nr);
+       }
+       closedir(dir);
+
+       siocb->length = nr;
+       free(buf);
+out:
+       return ret;
+}
+
 static int simple_store_link(uint64_t oid, struct siocb *iocb, int tgt_epoch)
 {
        char old[PATH_MAX], new[PATH_MAX];
diff --git a/sheep/store.c b/sheep/store.c
index e90bf96..33e05a8 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -226,41 +226,24 @@ out:
        return ret;
 }
 
-static int merge_objlist(uint64_t *list1, int nr_list1,
-                        uint64_t *list2, int nr_list2);
-
 int get_obj_list(const struct sd_list_req *hdr, struct sd_list_rsp *rsp, void 
*data)
 {
        uint64_t *list = (uint64_t *)data;
        int i, nr = 0;
        int res = SD_RES_SUCCESS;
-       int buf_len;
-       char *buf;
-
-       /* FIXME: handle larger size */
-       buf_len = (1 << 22);
-       buf = zalloc(buf_len);
-       if (!buf) {
-               eprintf("failed to allocate memory\n");
-               res = SD_RES_NO_MEM;
-               goto out;
-       }
 
-       for (i = 1; i <= hdr->tgt_epoch; i++) {
-               struct siocb iocb = { 0 };
+       struct objlist_cache_entry *entry;
+       struct hlist_node *node;
 
-               iocb.buf = buf;
-               iocb.length = 0;
-               iocb.epoch = i;
-               sd_store->get_objlist(&iocb);
-               nr = merge_objlist(list, nr, (uint64_t *)iocb.buf, iocb.length);
+       pthread_rwlock_rdlock(&obj_list_cache.lock);
+       for (i = 0; i < obj_list_cache.hash_size; i++) {
+               hlist_for_each_entry(entry, node, obj_list_cache.hashtable + i, 
list)
+                       list[nr++] = entry->oid;
        }
-out:
-       free(buf);
+       pthread_rwlock_unlock(&obj_list_cache.lock);
+
        rsp->data_length = nr * sizeof(uint64_t);
-       for (i = 0; i < nr; i++) {
-               dprintf("oid %"PRIx64"\n", list[i]);
-       }
+
        return res;
 }
 
@@ -1733,7 +1716,7 @@ static int request_obj_list(struct sd_node *e, uint32_t 
epoch,
        return rsp->data_length / sizeof(uint64_t);
 }
 
-static int merge_objlist(uint64_t *list1, int nr_list1, uint64_t *list2, int 
nr_list2)
+int merge_objlist(uint64_t *list1, int nr_list1, uint64_t *list2, int nr_list2)
 {
        int i;
        int old_nr_list1 = nr_list1;
-- 
1.7.1

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to