On a test cluster with three nodes and five hundred VDIs, the early exit optimisation introduced here reduces the time to find the size, used, and shared values from a specific VDI from around 3.4s (for naive grep of collie vdi list output) to around 2s, similar to a 'collie vdi object' command.
However, is it possible to make this and other VDI operations properly constant- or log-time in the number of VDIs instead of linear? Signed-off-by: Chris Webb <[email protected]> --- collie/collie.c | 58 +++++++++++++++++++++++++++++++++--------------------- 1 files changed, 35 insertions(+), 23 deletions(-) diff --git a/collie/collie.c b/collie/collie.c index 759d4c0..55fb5d6 100644 --- a/collie/collie.c +++ b/collie/collie.c @@ -365,6 +365,13 @@ static int parse_vdi(vdi_parser_func_t func, size_t size, void *data) return 0; } +struct get_vid_info { + char *name; + char *tag; + uint32_t vid; + uint32_t snapid; +}; + static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid, uint32_t flags, struct sheepdog_inode *i, void *data) { @@ -374,6 +381,10 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid, time_t ti; struct tm tm; char dbuf[128]; + struct get_vid_info *info = data; + + if (info && strcmp(name, info->name) != 0) + return; ti = i->ctime >> 32; if (raw_output) { @@ -399,21 +410,19 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid, size_to_str(my_objs * SD_DATA_OBJ_SIZE, my_objs_str, sizeof(my_objs_str)); size_to_str(cow_objs * SD_DATA_OBJ_SIZE, cow_objs_str, sizeof(cow_objs_str)); - if (!data || strcmp(name, data) == 0) { - if (raw_output) { - printf("%c ", is_current(i) ? '=' : 's'); - while (*name) { - if (isspace(*name) || *name == '\\') - putchar('\\'); - putchar(*name++); - } - printf(" %d %s %s %s %s %" PRIx32 "\n", snapid, - vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid); - } else { - printf("%c %-8s %5d %7s %7s %7s %s %7" PRIx32 "\n", - is_current(i) ? ' ' : 's', name, snapid, - vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid); + if (raw_output) { + printf("%c ", is_current(i) ? '=' : 's'); + while (*name) { + if (isspace(*name) || *name == '\\') + putchar('\\'); + putchar(*name++); } + printf(" %d %s %s %s %s %" PRIx32 "\n", snapid, + vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid); + } else { + printf("%c %-8s %5d %7s %7s %7s %s %7" PRIx32 "\n", + is_current(i) ? ' ' : 's', name, snapid, + vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid); } } @@ -480,13 +489,6 @@ static void cal_total_vdi_size(uint32_t vid, char *name, char * tag, *size += i->vdi_size; } -struct get_vid_info { - char *name; - char *tag; - uint32_t vid; - uint32_t snapid; -}; - static void get_oid(uint32_t vid, char *name, char *tag, uint32_t snapid, uint32_t flags, struct sheepdog_inode *i, void *data) { @@ -721,13 +723,23 @@ static struct subcommand node_cmd[] = { static int vdi_list(int argc, char **argv) { + char *vdiname = argv[optind]; + if (!raw_output) { printf(" name id size used shared creation time vdi id\n"); printf("------------------------------------------------------------------\n"); } - parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL); - return EXIT_SUCCESS; + if (vdiname) { + struct get_vid_info info; + memset(&info, 0, sizeof(info)); + info.name = vdiname; + parse_vdi(print_vdi_list, SD_INODE_SIZE, &info); + return EXIT_SUCCESS; + } else { + parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL); + return EXIT_SUCCESS; + } } static int vdi_tree(int argc, char **argv) -- 1.7.4.1 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
