source: mainline/uspace/app/hbench/env.c

Last change on this file was 0db0df2, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 months ago

Hash table improvements

Implement hash_table_foreach macro, analogous to list_foreach.

Remove superfluous argument to hash_table_find_next().
(If the user needs to recheck the part of the list already
checked by hash_table_find(), they can just rerun that function.)

Add hash argument to hash_table_ops_t::key_equal.
The big change here is that users with big keys can store the hash
value alongside key in their entries, and for the low low cost of
sizeof(size_t) bytes eliminate a bunch of expensive key comparisons.

Also added a hash function for strings and arbitrary data.
Found this one by asking ChatGPT, because the latency of accesses
to my book collection is currently a couple of hours.

+ Some drive-by unused #include removal.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * Copyright (c) 2019 Vojtech Horky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup hbench
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <adt/hash.h>
37#include <stdlib.h>
38#include <stdio.h>
39#include <str.h>
40#include "hbench.h"
41
42typedef struct {
43 ht_link_t link;
44
45 size_t hash;
46 char *key;
47 char *value;
48} param_t;
49
50static size_t param_hash(const ht_link_t *item)
51{
52 param_t *param = hash_table_get_inst(item, param_t, link);
53 return param->hash;
54}
55
56static size_t param_key_hash(const void *key)
57{
58 return hash_string(key);
59}
60
61static bool param_key_equal(const void *key, size_t hash, const ht_link_t *item)
62{
63 param_t *param = hash_table_get_inst(item, param_t, link);
64
65 if (param->hash != hash)
66 return false;
67
68 const char *key_str = key;
69 return str_cmp(param->key, key_str) == 0;
70}
71
72static bool param_equal(const ht_link_t *link_a, const ht_link_t *link_b)
73{
74 param_t *a = hash_table_get_inst(link_a, param_t, link);
75 param_t *b = hash_table_get_inst(link_b, param_t, link);
76
77 return a->hash == b->hash && str_cmp(a->key, b->key) == 0;
78}
79
80static void param_remove(ht_link_t *item)
81{
82 param_t *param = hash_table_get_inst(item, param_t, link);
83 free(param->key);
84 free(param->value);
85}
86
87static const hash_table_ops_t param_hash_table_ops = {
88 .hash = param_hash,
89 .key_hash = param_key_hash,
90 .key_equal = param_key_equal,
91 .equal = param_equal,
92 .remove_callback = param_remove
93};
94
95errno_t bench_env_init(bench_env_t *env)
96{
97 bool ok = hash_table_create(&env->parameters, 0, 0, &param_hash_table_ops);
98 if (!ok) {
99 return ENOMEM;
100 }
101
102 env->run_count = DEFAULT_RUN_COUNT;
103 env->minimal_run_duration_nanos = MSEC2NSEC(DEFAULT_MIN_RUN_DURATION_MSEC);
104
105 return EOK;
106}
107
108void bench_env_cleanup(bench_env_t *env)
109{
110 hash_table_destroy(&env->parameters);
111}
112
113errno_t bench_env_param_set(bench_env_t *env, const char *key, const char *value)
114{
115 param_t *param = malloc(sizeof(param_t));
116 if (param == NULL) {
117 return ENOMEM;
118 }
119
120 param->key = str_dup(key);
121 param->value = str_dup(value);
122 param->hash = hash_string(key);
123
124 if ((param->key == NULL) || (param->value == NULL)) {
125 free(param->key);
126 free(param->value);
127 free(param);
128
129 return ENOMEM;
130 }
131
132 hash_table_insert(&env->parameters, &param->link);
133
134 return EOK;
135}
136
137const char *bench_env_param_get(bench_env_t *env, const char *key, const char *default_value)
138{
139 ht_link_t *item = hash_table_find(&env->parameters, key);
140
141 if (item == NULL) {
142 return default_value;
143 }
144
145 param_t *param = hash_table_get_inst(item, param_t, link);
146 return param->value;
147}
148
149/** @}
150 */
Note: See TracBrowser for help on using the repository browser.