00001
00080 #include "examples_common.h"
00081 #include <math.h>
00082
00086 typedef enum employee_dist_e_ {
00088 EMPLOYEE_DIST_E_UNIFORM,
00090 EMPLOYEE_DIST_E_ZIPF,
00092 EMPLOYEE_DIST_E_MAX,
00093 } employee_dist_e;
00094
00096 static const uint32_t default_employee_cnt = 1000;
00098 static const uint32_t default_run_cnt = 1;
00100 static const uint8_t default_verbosity = 0;
00102 static const employee_dist_e default_last_name_dist = EMPLOYEE_DIST_E_UNIFORM;
00104 static const double default_zipf_alpha = 1.0;
00105
00109 #define MAX_NAME_LEN 100
00110
00114 typedef struct employee_example_opts_st_ {
00116 uint32_t employee_cnt;
00118 uint32_t run_cnt;
00120 uint32_t seed;
00122 uint8_t verbosity;
00124 employee_dist_e last_name_dist;
00126 double zipf_alpha;
00127 } employee_example_opts_st;
00128
00130 static const char *first_names[] = {
00131 "Jacob", "Isabella", "Ethan", "Sophia", "Michael", "Emma", "Jayden",
00132 "Olivia", "William", "Ava", "Alexander", "Emily", "Noah", "Abigail",
00133 "Daniel", "Madison", "Aiden", "Chloe", "Anthony", "Mia", "Joshua",
00134 "Addison", "Mason", "Elizabeth", "Christopher", "Ella", "Andrew", "Natalie",
00135 "David", "Samantha", "Matthew", "Alexis", "Logan", "Lily", "Elijah",
00136 "Grace", "James", "Hailey", "Joseph", "Alyssa", "Gabriel", "Lillian",
00137 "Benjamin", "Hannah", "Ryan", "Avery", "Samuel", "Leah", "Jackson",
00138 "Nevaeh", "John", "Sofia", "Nathan", "Ashley", "Jonathan", "Anna",
00139 "Christian", "Brianna", "Liam", "Sarah", "Dylan", "Zoe", "Landon",
00140 "Victoria", "Caleb", "Gabriella", "Tyler", "Brooklyn", "Lucas", "Kaylee",
00141 "Evan", "Taylor", "Gavin", "Layla", "Nicholas", "Allison", "Isaac",
00142 "Evelyn", "Brayden", "Riley", "Luke", "Amelia", "Angel", "Khloe", "Brandon",
00143 "Makayla", "Jack", "Aubrey", "Isaiah", "Charlotte", "Jordan", "Savannah",
00144 "Owen", "Zoey", "Carter", "Bella", "Connor", "Kayla", "Justin", "Alexa"
00145 };
00146
00148 static const char *last_names[] = {
00149 "Smith", "Johnson", "Williams", "Jones", "Brown", "Davis", "Miller",
00150 "Wilson", "Moore", "Taylor", "Anderson", "Thomas", "Jackson", "White",
00151 "Harris", "Martin", "Thompson", "Garcia", "Martinez", "Robinson", "Clark",
00152 "Rodriguez", "Lewis", "Lee", "Walker", "Hall", "Allen", "Young",
00153 "Hernandez", "King", "Wright", "Lopez", "Hill", "Scott", "Green", "Adams",
00154 "Baker", "Gonzalez", "Nelson", "Carter", "Mitchell", "Perez", "Roberts",
00155 "Turner", "Phillips", "Campbell", "Parker", "Evans", "Edwards", "Collins",
00156 "Stewart", "Sanchez", "Morris", "Rogers", "Reed", "Cook", "Morgan", "Bell",
00157 "Murphy", "Bailey", "Rivera", "Cooper", "Richardson", "Cox", "Howard",
00158 "Ward", "Torres", "Peterson", "Gray", "Ramirez", "James", "Watson",
00159 "Brooks", "Kelly", "Sanders", "Price", "Bennett", "Wood", "Barnes", "Ross",
00160 "Henderson", "Coleman", "Jenkins", "Perry", "Powell", "Long", "Patterson",
00161 "Hughes", "Flores", "Washington", "Butler", "Simmons", "Foster", "Gonzales",
00162 "Bryant", "Alexander", "Russell", "Griffin", "Diaz", "Hayes"
00163 };
00164
00168 typedef struct employee_obj_st_ {
00170 uint32_t id;
00172 char first_name[MAX_NAME_LEN];
00174 char last_name[MAX_NAME_LEN];
00175 } employee_obj_st;
00176
00180 typedef struct employee_example_input_st_ {
00182 const employee_example_opts_st *opts;
00184 mkavl_tree_handle tree_h;
00185 } employee_example_input_st;
00186
00190 typedef struct employee_ctx_st_ {
00192 uint32_t nodes_walked;
00194 uint32_t match_cnt;
00195 } employee_ctx_st;
00196
00200 typedef struct employee_walk_ctx_st_ {
00202 char lookup_last_name[MAX_NAME_LEN];
00203 } employee_walk_ctx_st;
00204
00214 static uint32_t
00215 zipf (double alpha, uint32_t n)
00216 {
00217 static uint32_t cached_n = 0;
00218 static double cached_c = 0.0;
00219 double z;
00220 double sum_prob;
00221 double zipf_value;
00222 double c = 0.0;
00223 uint32_t i;
00224
00225 if (n != cached_n) {
00226 for (i = 1; i <= n; ++i) {
00227 c = (c + (1.0 / pow((double) i, alpha)));
00228 }
00229 cached_c = (1.0 / c);
00230 cached_n = n;
00231 }
00232 c = cached_c;
00233
00234
00235 z = ((double) rand() / RAND_MAX);
00236
00237
00238 sum_prob = 0;
00239 for (i = 1; i <= n; i++) {
00240 sum_prob = sum_prob + (c / pow((double) i, alpha));
00241 if (sum_prob >= z) {
00242 zipf_value = i;
00243 break;
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252 assert_abort((zipf_value >= 1) && (zipf_value <= n));
00253
00254 return (zipf_value);
00255 }
00256
00263 static void
00264 print_usage (bool do_exit, int32_t exit_val)
00265 {
00266 printf("\nExample of using mkavl for an employee DB\n\n");
00267 printf("Usage:\n");
00268 printf("-s <seed>\n"
00269 " The starting seed for the RNG (default=seeded by time()).\n");
00270 printf("-n <employees>\n"
00271 " The number of nodes to place in the trees (default=%u).\n",
00272 default_employee_cnt);
00273 printf("-r <runs>\n"
00274 " The number of runs to do (default=%u).\n",
00275 default_run_cnt);
00276 printf("-v <verbosity level>\n"
00277 " A higher number gives more output (default=%u).\n",
00278 default_verbosity);
00279 printf("-z\n"
00280 " Use Zipf distribution for last names (default=uniform).\n");
00281 printf("-a <Zipf alpha>\n"
00282 " If using a Zipf distribution, the alpha value to\n"
00283 " parameterize the distribution (default=%lf).\n",
00284 default_zipf_alpha);
00285 printf("-h\n"
00286 " Display this help message.\n");
00287 printf("\n");
00288
00289 if (do_exit) {
00290 exit(exit_val);
00291 }
00292 }
00293
00299 static void
00300 print_opts (employee_example_opts_st *opts)
00301 {
00302 if (NULL == opts) {
00303 return;
00304 }
00305
00306 printf("employee_example_opts: seed=%u, employee_cnt=%u, run_cnt=%u,\n"
00307 " verbosity=%u last_name_dist=%u\n"
00308 " zipf_alpha=%lf\n",
00309 opts->seed, opts->employee_cnt, opts->run_cnt, opts->verbosity,
00310 opts->last_name_dist, opts->zipf_alpha);
00311 }
00312
00320 static void
00321 parse_command_line (int argc, char **argv, employee_example_opts_st *opts)
00322 {
00323 int c;
00324 char *end_ptr;
00325 uint32_t val;
00326 double dval;
00327
00328 if (NULL == opts) {
00329 return;
00330 }
00331
00332 opts->employee_cnt = default_employee_cnt;
00333 opts->run_cnt = default_run_cnt;
00334 opts->verbosity = default_verbosity;
00335 opts->last_name_dist = default_last_name_dist;
00336 opts->zipf_alpha = default_zipf_alpha;
00337 opts->seed = (uint32_t) time(NULL);
00338
00339 while ((c = getopt(argc, argv, "n:r:v:s:hza:")) != -1) {
00340 switch (c) {
00341 case 'n':
00342 val = strtol(optarg, &end_ptr, 10);
00343 if ((end_ptr != optarg) && (0 == errno)) {
00344 opts->employee_cnt = val;
00345 }
00346 break;
00347 case 'r':
00348 val = strtol(optarg, &end_ptr, 10);
00349 if ((end_ptr != optarg) && (0 == errno)) {
00350 opts->run_cnt = val;
00351 }
00352 break;
00353 case 'v':
00354 val = strtol(optarg, &end_ptr, 10);
00355 if ((end_ptr != optarg) && (0 == errno)) {
00356 opts->verbosity = val;
00357 }
00358 break;
00359 case 's':
00360 val = strtol(optarg, &end_ptr, 10);
00361 if ((end_ptr != optarg) && (0 == errno)) {
00362 opts->seed = val;
00363 }
00364 break;
00365 case 'a':
00366 dval = strtod(optarg, &end_ptr);
00367 if ((end_ptr != optarg) && (0 == errno)) {
00368 opts->zipf_alpha = dval;
00369 }
00370 break;
00371 case 'z':
00372 opts->last_name_dist = EMPLOYEE_DIST_E_ZIPF;
00373 break;
00374 case 'h':
00375 case '?':
00376 default:
00377 print_usage(true, EXIT_SUCCESS);
00378 break;
00379 }
00380 }
00381
00382 if (optind < argc) {
00383 print_usage(true, EXIT_SUCCESS);
00384 }
00385
00386 if (0 == opts->employee_cnt) {
00387 printf("Error: employee count(%u) must be non-zero\n",
00388 opts->employee_cnt);
00389 print_usage(true, EXIT_SUCCESS);
00390 }
00391
00392 if (!(opts->zipf_alpha > 0.0)) {
00393 printf("Error: Zipf alpha(%lf) must be greater than 0.0\n",
00394 opts->zipf_alpha);
00395 print_usage(true, EXIT_SUCCESS);
00396 }
00397
00398 if (opts->verbosity >= 3) {
00399 print_opts(opts);
00400 }
00401 }
00402
00411 static int32_t
00412 employee_cmp_by_id (const void *item1, const void *item2, void *context)
00413 {
00414 const employee_obj_st *e1 = item1;
00415 const employee_obj_st *e2 = item2;
00416
00417 if ((NULL == e1) || (NULL == e2)) {
00418 abort();
00419 }
00420
00421 if (e1->id < e2->id) {
00422 return (-1);
00423 } else if (e1->id > e2->id) {
00424 return (1);
00425 }
00426
00427 return (0);
00428 }
00429
00438 static int32_t
00439 employee_cmp_by_last_name (const void *item1, const void *item2, void *context)
00440 {
00441 const employee_obj_st *e1 = item1;
00442 const employee_obj_st *e2 = item2;
00443 employee_ctx_st *ctx = (employee_ctx_st *) context;
00444 int32_t str_rc;
00445
00446 if ((NULL == e1) || (NULL == e2) || (NULL == ctx)) {
00447 abort();
00448 }
00449
00450 ++(ctx->nodes_walked);
00451
00452
00453
00454
00455
00456 str_rc = strncmp(e1->last_name, e2->last_name, sizeof(e1->last_name));
00457 if (0 != str_rc) {
00458 return (str_rc);
00459 }
00460
00461
00462 if (e1->id < e2->id) {
00463 return (-1);
00464 } else if (e1->id > e2->id) {
00465 return (1);
00466 }
00467
00468 return (0);
00469 }
00470
00474 typedef enum employee_example_key_e_ {
00476 EMPLOYEE_EXAMPLE_KEY_E_ID,
00478 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID,
00480 EMPLOYEE_EXAMPLE_KEY_E_MAX,
00481 } employee_example_key_e;
00482
00484 static mkavl_compare_fn cmp_fn_array[] = {
00485 employee_cmp_by_id,
00486 employee_cmp_by_last_name
00487 };
00488
00490 CT_ASSERT(NELEMS(cmp_fn_array) == EMPLOYEE_EXAMPLE_KEY_E_MAX);
00503 static bool
00504 generate_employee (employee_example_input_st *input, employee_obj_st **obj)
00505 {
00506 static uint32_t next_id = 1;
00507 employee_obj_st *local_obj;
00508 uint32_t first_name_idx, last_name_idx;
00509
00510 if (NULL == obj) {
00511 return (false);
00512 }
00513 *obj = NULL;
00514
00515 local_obj = calloc(1, sizeof(*local_obj));
00516 if (NULL == local_obj) {
00517 return (false);
00518 }
00519
00520 local_obj->id = next_id++;
00521 first_name_idx = (rand() % NELEMS(first_names));
00522 switch (input->opts->last_name_dist) {
00523 case EMPLOYEE_DIST_E_UNIFORM:
00524 last_name_idx = (rand() % NELEMS(last_names));
00525 break;
00526 case EMPLOYEE_DIST_E_ZIPF:
00527 last_name_idx = (zipf(input->opts->zipf_alpha, NELEMS(last_names)) - 1);
00528 break;
00529 default:
00530 abort();
00531 break;
00532 }
00533 my_strlcpy(local_obj->first_name, first_names[first_name_idx],
00534 sizeof(local_obj->first_name));
00535 my_strlcpy(local_obj->last_name, last_names[last_name_idx],
00536 sizeof(local_obj->last_name));
00537
00538 *obj = local_obj;
00539
00540 return (true);
00541 }
00542
00548 static void
00549 display_employee (employee_obj_st *obj)
00550 {
00551 if (NULL == obj) {
00552 return;
00553 }
00554
00555 printf("Employee(ID=%u, Name=\"%s %s\")\n", obj->id, obj->first_name,
00556 obj->last_name);
00557 }
00558
00566 static mkavl_rc_e
00567 free_employee (void *item, void *context)
00568 {
00569 if (NULL == item) {
00570 return (MKAVL_RC_E_EINVAL);
00571 }
00572
00573 free(item);
00574
00575 return (MKAVL_RC_E_SUCCESS);
00576 }
00577
00589 static void
00590 lookup_employees_by_last_name (employee_example_input_st *input,
00591 const char *last_name, uint32_t max_records,
00592 bool find_all, bool do_print)
00593 {
00594 employee_obj_st *found_item;
00595 employee_obj_st lookup_item = {0};
00596 uint32_t num_records = 0;
00597 mkavl_rc_e rc;
00598 employee_ctx_st *ctx = mkavl_get_tree_context(input->tree_h);
00599
00600 assert_abort(NULL != ctx);
00601
00602
00603 lookup_item.id = 0;
00604 my_strlcpy(lookup_item.last_name, last_name, sizeof(lookup_item.last_name));
00605
00606 rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_GE,
00607 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID, &lookup_item,
00608 (void **) &found_item);
00609 assert_abort(mkavl_rc_e_is_ok(rc));
00610
00611 while ((NULL != found_item) &&
00612 (0 == strncmp(last_name, found_item->last_name,
00613 sizeof(found_item->last_name))) &&
00614 (find_all || (num_records < max_records))) {
00615
00616 if (do_print) {
00617 printf("%2u. ", (num_records + 1));
00618 display_employee(found_item);
00619 }
00620
00621 rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_GT,
00622 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID, found_item,
00623 (void **) &found_item);
00624 assert_abort(mkavl_rc_e_is_ok(rc));
00625 ++num_records;
00626 }
00627
00628 ctx->match_cnt = num_records;
00629 }
00630
00640 static mkavl_rc_e
00641 last_name_walk_cb (void *item, void *tree_context, void *walk_context,
00642 bool *stop_walk)
00643 {
00644 employee_obj_st *e = item;
00645 employee_ctx_st *ctx = (employee_ctx_st *) tree_context;
00646 employee_walk_ctx_st *walk_ctx = (employee_walk_ctx_st *) walk_context;
00647
00648 if ((NULL == e) || (NULL == ctx) || (NULL == walk_ctx) ||
00649 (NULL == stop_walk)) {
00650 return (MKAVL_RC_E_EINVAL);
00651 }
00652 *stop_walk = false;
00653
00654 ++(ctx->nodes_walked);
00655 if (0 == strncmp(e->last_name, walk_ctx->lookup_last_name,
00656 sizeof(e->last_name))) {
00657 ++(ctx->match_cnt);
00658 }
00659
00660 return (MKAVL_RC_E_SUCCESS);
00661 }
00662
00668 static void
00669 run_employee_example (employee_example_input_st *input)
00670 {
00671 employee_obj_st *cur_item, *found_item;
00672 employee_obj_st lookup_item = {0};
00673 const uint32_t lookup_cnt = 10;
00674 const char *last_name_lookups[30];
00675 uint32_t match_cnt_array[NELEMS(last_name_lookups)] = {0};
00676 mkavl_rc_e mkavl_rc;
00677 bool bool_rc;
00678 uint32_t i, idx;
00679 uint32_t lookup_id;
00680 const char *new_last_name;
00681 char old_last_name[MAX_NAME_LEN];
00682 struct timeval tv;
00683 double t1, t2;
00684 double key_lookup_time, nonkey_lookup_time;
00685 uint32_t key_nodes_walked, nonkey_nodes_walked;
00686 employee_ctx_st ctx = {0};
00687 employee_walk_ctx_st walk_ctx = {{0}};
00688
00689 printf("\n");
00690
00691 mkavl_rc = mkavl_new(&(input->tree_h), cmp_fn_array, NELEMS(cmp_fn_array),
00692 &ctx, NULL);
00693 assert_abort(mkavl_rc_e_is_ok(mkavl_rc));
00694
00695 for (i = 0; i < input->opts->employee_cnt; ++i) {
00696 bool_rc = generate_employee(input, &cur_item);
00697 assert_abort((NULL != cur_item) && bool_rc);
00698
00699 if (input->opts->verbosity >= 3) {
00700 printf("Adding employee to DB:\n ");
00701 display_employee(cur_item);
00702 }
00703
00704 mkavl_rc = mkavl_add(input->tree_h, cur_item,
00705 (void **) &found_item);
00706 assert_abort((NULL == found_item) &&
00707 mkavl_rc_e_is_ok(mkavl_rc));
00708 }
00709
00710 printf("*** Testing functionality ***\n\n");
00711
00712 printf("Find %u employees by ID\n", lookup_cnt);
00713 for (i = 0; i < 10; ++i) {
00714 lookup_id = (1 + (rand() % input->opts->employee_cnt));
00715 lookup_item.id = lookup_id;
00716 mkavl_rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_EQUAL,
00717 EMPLOYEE_EXAMPLE_KEY_E_ID,
00718 &lookup_item,
00719 (void **) &found_item);
00720 assert_abort((NULL != found_item) &&
00721 mkavl_rc_e_is_ok(mkavl_rc));
00722 printf("Looking up ID %u: ", lookup_id);
00723 display_employee(found_item);
00724 }
00725 printf("\n");
00726
00727 idx = (rand() % NELEMS(last_names));
00728 printf("Finding up to first %u employees with last name %s\n",
00729 lookup_cnt, last_names[idx]);
00730 lookup_employees_by_last_name(input, last_names[idx], lookup_cnt,
00731 false, true);
00732
00733 printf("\n");
00734
00735 lookup_id = (1 + (rand() % input->opts->employee_cnt));
00736 lookup_item.id = lookup_id;
00737 mkavl_rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_EQUAL,
00738 EMPLOYEE_EXAMPLE_KEY_E_ID,
00739 &lookup_item,
00740 (void **) &found_item);
00741 assert_abort((NULL != found_item) &&
00742 mkavl_rc_e_is_ok(mkavl_rc));
00743 cur_item = found_item;
00744
00745 idx = (rand() % NELEMS(last_names));
00746 new_last_name = last_names[idx];
00747 my_strlcpy(old_last_name, cur_item->last_name, sizeof(old_last_name));
00748
00749 printf("Changing last name of %s %s (ID=%u) to %s\n",
00750 cur_item->first_name, cur_item->last_name, cur_item->id,
00751 new_last_name);
00752
00753 mkavl_rc = mkavl_remove_key_idx(input->tree_h,
00754 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID, cur_item,
00755 (void **) &found_item);
00756 assert_abort((NULL != found_item) &&
00757 mkavl_rc_e_is_ok(mkavl_rc));
00758 cur_item = found_item;
00759
00760 my_strlcpy(cur_item->last_name, new_last_name, sizeof(cur_item->last_name));
00761
00762 mkavl_rc = mkavl_add_key_idx(input->tree_h, EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID,
00763 cur_item, (void **) &found_item);
00764 assert_abort((NULL == found_item) &&
00765 mkavl_rc_e_is_ok(mkavl_rc));
00766
00767 lookup_item.id = cur_item->id;
00768 mkavl_rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_EQUAL,
00769 EMPLOYEE_EXAMPLE_KEY_E_ID,
00770 &lookup_item,
00771 (void **) &found_item);
00772 assert_abort((NULL != found_item) &&
00773 mkavl_rc_e_is_ok(mkavl_rc));
00774 printf("Lookup for ID %u: ", lookup_item.id);
00775 display_employee(found_item);
00776
00777 lookup_item.id = cur_item->id;
00778 my_strlcpy(lookup_item.last_name, cur_item->last_name,
00779 sizeof(lookup_item.last_name));
00780 mkavl_rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_EQUAL,
00781 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID,
00782 &lookup_item,
00783 (void **) &found_item);
00784 assert_abort((NULL != found_item) &&
00785 mkavl_rc_e_is_ok(mkavl_rc));
00786 printf("Lookup for last name \"%s\", ID %u:\n ", lookup_item.last_name,
00787 lookup_item.id);
00788 display_employee(found_item);
00789
00790 my_strlcpy(lookup_item.last_name, old_last_name,
00791 sizeof(lookup_item.last_name));
00792 mkavl_rc = mkavl_find(input->tree_h, MKAVL_FIND_TYPE_E_EQUAL,
00793 EMPLOYEE_EXAMPLE_KEY_E_LNAME_ID,
00794 &lookup_item,
00795 (void **) &found_item);
00796 assert_abort(mkavl_rc_e_is_ok(mkavl_rc));
00797 printf("Lookup for last name \"%s\", ID %u: ", old_last_name,
00798 lookup_item.id);
00799 if (NULL == found_item) {
00800 printf("not found");
00801 } else {
00802 display_employee(found_item);
00803 }
00804 printf("\n");
00805
00806 printf("\n");
00807
00808 printf("*** Testing performance ***\n\n");
00809
00810
00811 for (i = 0; i < NELEMS(last_name_lookups); ++i) {
00812 idx = (rand() % NELEMS(last_names));
00813 last_name_lookups[i] = last_names[idx];
00814 }
00815
00816
00817 gettimeofday(&tv, NULL);
00818 t1 = timeval_to_seconds(&tv);
00819 ctx.nodes_walked = 0;
00820
00821 for (i = 0; i < NELEMS(last_name_lookups); ++i) {
00822 lookup_employees_by_last_name(input, last_name_lookups[i], 0,
00823 true, false);
00824 match_cnt_array[i] = ctx.match_cnt;
00825 }
00826
00827 gettimeofday(&tv, NULL);
00828 t2 = timeval_to_seconds(&tv);
00829
00830 key_lookup_time = (t2 - t1);
00831 key_nodes_walked = ctx.nodes_walked;
00832
00833
00834 gettimeofday(&tv, NULL);
00835 t1 = timeval_to_seconds(&tv);
00836 ctx.nodes_walked = 0;
00837
00838 for (i = 0; i < NELEMS(last_name_lookups); ++i) {
00839 ctx.match_cnt = 0;
00840 my_strlcpy(walk_ctx.lookup_last_name, last_name_lookups[i],
00841 sizeof(walk_ctx.lookup_last_name));
00842 mkavl_rc = mkavl_walk(input->tree_h, last_name_walk_cb, &walk_ctx);
00843 assert_abort(mkavl_rc_e_is_ok(mkavl_rc));
00844 if (match_cnt_array[i] != ctx.match_cnt) {
00845 printf("ERROR: for name %s, keyed lookup found %u matches and "
00846 "non-key lookup found %u matches\n",
00847 last_name_lookups[i], match_cnt_array[i], ctx.match_cnt);
00848
00849 }
00850 }
00851
00852 gettimeofday(&tv, NULL);
00853 t2 = timeval_to_seconds(&tv);
00854
00855 nonkey_lookup_time = (t2 - t1);
00856 nonkey_nodes_walked = ctx.nodes_walked;
00857
00858 printf("Keyed lookup time: %.6lfs, Non-keyed lookup time: %.6lfs, "
00859 "Ratio: %.2lf\n", key_lookup_time, nonkey_lookup_time,
00860 (key_lookup_time / nonkey_lookup_time));
00861 printf("Keyed nodes compared: %u, Non-keyed nodes walked: %u, "
00862 "Ratio: %.2lf\n", key_nodes_walked, nonkey_nodes_walked,
00863 ((double) key_nodes_walked / nonkey_nodes_walked));
00864
00865 mkavl_rc = mkavl_delete(&(input->tree_h), free_employee, NULL);
00866 assert_abort(mkavl_rc_e_is_ok(mkavl_rc));
00867
00868 printf("\n");
00869 }
00870
00874 int
00875 main (int argc, char *argv[])
00876 {
00877 employee_example_opts_st opts;
00878 uint32_t cur_run, cur_seed;
00879 employee_example_input_st input = {0};
00880
00881 parse_command_line(argc, argv, &opts);
00882
00883 printf("\n");
00884 cur_seed = opts.seed;
00885 for (cur_run = 0; cur_run < opts.run_cnt; ++cur_run) {
00886
00887 printf("Doing run %u with seed %u\n", (cur_run + 1), cur_seed);
00888 srand(cur_seed);
00889
00890 input.opts = &opts;
00891 input.tree_h = NULL;
00892
00893 run_employee_example(&input);
00894
00895 ++cur_seed;
00896 }
00897
00898 printf("\n");
00899
00900 return (0);
00901 }