/* Spa * * Copyright © 2020 Wim Taymans * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #define MAX_COUNT 100000 #define MAX_ITEMS 1000 static struct spa_dict_item items[MAX_ITEMS]; static char values[MAX_ITEMS][32]; static void gen_values(void) { uint32_t i, j, idx; static const char chars[] = "abcdefghijklmnopqrstuvwxyz.:*ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (i = 0; i < MAX_ITEMS; i++) { for (j = 0; j < 32; j++) { idx = random() % sizeof(chars); values[i][j] = chars[idx]; } idx = random() % 16; values[i][idx + 16] = 0; } } static void gen_dict(struct spa_dict *dict, uint32_t n_items) { uint32_t i, idx; for (i = 0; i < n_items; i++) { idx = random() % MAX_ITEMS; items[i] = SPA_DICT_ITEM_INIT(values[idx], values[idx]); } dict->items = items; dict->n_items = n_items; dict->flags = 0; } static void test_query(const struct spa_dict *dict) { uint32_t i, idx; const char *str; for (i = 0; i < MAX_COUNT; i++) { idx = random() % dict->n_items; str = spa_dict_lookup(dict, dict->items[idx].key); assert(spa_streq(str, dict->items[idx].value)); } } static void test_lookup(struct spa_dict *dict) { struct timespec ts; uint64_t t1, t2, t3, t4; clock_gettime(CLOCK_MONOTONIC, &ts); t1 = SPA_TIMESPEC_TO_NSEC(&ts); test_query(dict); clock_gettime(CLOCK_MONOTONIC, &ts); t2 = SPA_TIMESPEC_TO_NSEC(&ts); fprintf(stderr, "%d elapsed %"PRIu64" count %u = %"PRIu64"/sec\n", dict->n_items, t2 - t1, MAX_COUNT, MAX_COUNT * (uint64_t)SPA_NSEC_PER_SEC / (t2 - t1)); spa_dict_qsort(dict); clock_gettime(CLOCK_MONOTONIC, &ts); t3 = SPA_TIMESPEC_TO_NSEC(&ts); fprintf(stderr, "%d sort elapsed %"PRIu64"\n", dict->n_items, t3 - t2); clock_gettime(CLOCK_MONOTONIC, &ts); t3 = SPA_TIMESPEC_TO_NSEC(&ts); test_query(dict); clock_gettime(CLOCK_MONOTONIC, &ts); t4 = SPA_TIMESPEC_TO_NSEC(&ts); fprintf(stderr, "%d elapsed %"PRIu64" count %u = %"PRIu64"/sec %f speedup\n", dict->n_items, t4 - t3, MAX_COUNT, MAX_COUNT * (uint64_t)SPA_NSEC_PER_SEC / (t4 - t3), (double)(t2 - t1) / (t4 - t2)); } int main(int argc, char *argv[]) { struct spa_dict dict; spa_zero(dict); gen_values(); /* warmup */ gen_dict(&dict, 1000); test_query(&dict); gen_dict(&dict, 10); test_lookup(&dict); gen_dict(&dict, 20); test_lookup(&dict); gen_dict(&dict, 50); test_lookup(&dict); gen_dict(&dict, 100); test_lookup(&dict); gen_dict(&dict, 1000); test_lookup(&dict); return 0; }