examples/employee_example.c
Go to the documentation of this file.
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     /* Insert industrial strength RNG method here */
00235     z = ((double) rand() / RAND_MAX);
00236 
00237     /* Map z to the value */
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     /* Equations below are for Pareto and bounded Pareto distributions */
00248     //r=(m * pow((1- z), (-1/a)));
00249     //r = pow((pow(l, a) / (z*pow((l/h), a) - z + 1)), (1.0/a));
00250 
00251     /* Assert that zipf_value is between 1 and N */
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      * Compare by last name first.  This ensures last names are grouped
00454      * together.
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     /* If the last name is the same, compare by employee ID which is unique */
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     /* Set ID to the minimum possible value */
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     /* Fill in last names to lookup */
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     /* Test keyed lookup */
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     /* Test non-keyed lookup */
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines