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
