On 03/13/2012 10:10 AM, Li Wenpeng wrote: > From: levin li <[email protected]> > > Applied the object list cache to get_obj_list() which > walk through the rb-tree cache and 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 | 23 ++++------------------- > sheep/farm/farm.h | 1 + > sheep/farm/trunk.c | 14 ++++++++++++++ > sheep/sheep_priv.h | 1 + > sheep/simple_store.c | 50 > +++++++++++++++++++++++++++++++++++++++++++++----- > sheep/store.c | 38 ++++++++++---------------------------- > 6 files changed, 75 insertions(+), 52 deletions(-) > > diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c > index 1e073f0..6db7dab 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,13 @@ 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; > - > - nr_trunks = hdr.priv; > - for (i = 0; i < nr_trunks; i++, trunk_buf++) > - objlist[iocb->length++] = trunk_buf->oid; > + iocb->length = trunk_get_working_objlist(objlist); > > 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..a9a1bbf 100644 > --- a/sheep/farm/farm.h > +++ b/sheep/farm/farm.h > @@ -68,6 +68,7 @@ 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 int trunk_get_working_objlist(uint64_t *list); > > /* snap.c */ > extern int snap_init(void); > diff --git a/sheep/farm/trunk.c b/sheep/farm/trunk.c > index b9f0b3e..2949704 100644 > --- a/sheep/farm/trunk.c > +++ b/sheep/farm/trunk.c > @@ -379,3 +379,17 @@ void trunk_reset(void) > eprintf("%s\n", trunk_entry_active_nr ? "WARN: active_list not clean" : > "clean"); > } > + > +int trunk_get_working_objlist(uint64_t *list) > +{ > + int nr = 0; > + struct trunk_entry_incore *entry; > + > + pthread_mutex_lock(&active_list_lock); > + list_for_each_entry(entry, &trunk_active_list, active_list) { > + list[nr++] = entry->raw.oid; > + } > + pthread_mutex_unlock(&active_list_lock); > + > + return nr; > +} > diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h > index e93806e..c38022b 100644 > --- a/sheep/sheep_priv.h > +++ b/sheep/sheep_priv.h > @@ -299,6 +299,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 7cdad31..dd3c62d 100644 > --- a/sheep/simple_store.c > +++ b/sheep/simple_store.c > @@ -185,13 +185,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); > @@ -203,7 +202,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, "..")) > @@ -213,14 +211,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 17922b2..0069eaf 100644 > --- a/sheep/store.c > +++ b/sheep/store.c > @@ -177,41 +177,23 @@ 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 nr = 0; > int res = SD_RES_SUCCESS; > - int buf_len; > - char *buf; > + struct objlist_cache_entry *entry; > + struct rb_node *p; > > - /* 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; > + pthread_rwlock_rdlock(&obj_list_cache.lock); > + for (p = rb_first(&obj_list_cache.root); p; p = rb_next(p)) { > + entry = rb_entry(p, struct objlist_cache_entry, node); > + list[nr++] = entry->oid; > } > + pthread_rwlock_unlock(&obj_list_cache.lock); > > - for (i = 1; i <= hdr->tgt_epoch; i++) { > - struct siocb iocb = { 0 }; > - > - 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); > - } > -out: > - free(buf); > rsp->data_length = nr * sizeof(uint64_t); > - for (i = 0; i < nr; i++) { > - dprintf("oid %"PRIx64"\n", list[i]); > - } > + > return res; > } > > @@ -1720,7 +1702,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;
Tow (Object list cache) patches applied, thanks Yuan -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
