]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
758dd67e | 2 | |
dccca82b LP |
3 | #include <string.h> |
4 | ||
758dd67e | 5 | #include "hash-funcs.h" |
46e16b34 | 6 | #include "path-util.h" |
52be2b43 | 7 | #include "strv.h" |
758dd67e | 8 | |
25073e50 | 9 | void string_hash_func(const char *p, struct siphash *state) { |
758dd67e LP |
10 | siphash24_compress(p, strlen(p) + 1, state); |
11 | } | |
12 | ||
25073e50 | 13 | DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func); |
be327321 ZJS |
14 | DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(string_hash_ops_free, |
15 | char, string_hash_func, string_compare_func, free); | |
87da8784 ZJS |
16 | DEFINE_HASH_OPS_FULL(string_hash_ops_free_free, |
17 | char, string_hash_func, string_compare_func, free, | |
74bbc85c | 18 | void, free); |
52be2b43 YW |
19 | DEFINE_HASH_OPS_FULL(string_hash_ops_free_strv_free, |
20 | char, string_hash_func, string_compare_func, free, | |
21 | char*, strv_free); | |
758dd67e | 22 | |
25073e50 | 23 | void path_hash_func(const char *q, struct siphash *state) { |
353df443 | 24 | bool add_slash = false; |
46e16b34 LP |
25 | |
26 | assert(q); | |
27 | assert(state); | |
28 | ||
29 | /* Calculates a hash for a path in a way this duplicate inner slashes don't make a differences, and also | |
30 | * whether there's a trailing slash or not. This fits well with the semantics of path_compare(), which does | |
31 | * similar checks and also doesn't care for trailing slashes. Note that relative and absolute paths (i.e. those | |
32 | * which begin in a slash or not) will hash differently though. */ | |
33 | ||
353df443 YW |
34 | /* if path is absolute, add one "/" to the hash. */ |
35 | if (path_is_absolute(q)) | |
c01a5c05 | 36 | siphash24_compress_byte('/', state); |
46e16b34 LP |
37 | |
38 | for (;;) { | |
353df443 YW |
39 | const char *e; |
40 | int r; | |
41 | ||
42 | r = path_find_first_component(&q, true, &e); | |
43 | if (r == 0) | |
44 | return; | |
45 | ||
46 | if (add_slash) | |
47 | siphash24_compress_byte('/', state); | |
48 | ||
49 | if (r < 0) { | |
50 | /* if a component is invalid, then add remaining part as a string. */ | |
51 | string_hash_func(q, state); | |
52 | return; | |
53 | } | |
54 | ||
55 | /* Add this component to the hash. */ | |
56 | siphash24_compress(e, r, state); | |
57 | ||
58 | add_slash = true; | |
46e16b34 LP |
59 | } |
60 | } | |
61 | ||
6906ac9a | 62 | DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare); |
3fb2326f ZJS |
63 | DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(path_hash_ops_free, |
64 | char, path_hash_func, path_compare, free); | |
730b9c1e LP |
65 | DEFINE_HASH_OPS_FULL(path_hash_ops_free_free, |
66 | char, path_hash_func, path_compare, free, | |
67 | void, free); | |
46e16b34 | 68 | |
758dd67e | 69 | void trivial_hash_func(const void *p, struct siphash *state) { |
c01a5c05 | 70 | siphash24_compress_typesafe(p, state); |
758dd67e LP |
71 | } |
72 | ||
73 | int trivial_compare_func(const void *a, const void *b) { | |
a0edd02e | 74 | return CMP(a, b); |
758dd67e LP |
75 | } |
76 | ||
77 | const struct hash_ops trivial_hash_ops = { | |
78 | .hash = trivial_hash_func, | |
70b400d9 | 79 | .compare = trivial_compare_func, |
758dd67e LP |
80 | }; |
81 | ||
5e71868c YW |
82 | const struct hash_ops trivial_hash_ops_free = { |
83 | .hash = trivial_hash_func, | |
84 | .compare = trivial_compare_func, | |
85 | .free_key = free, | |
86 | }; | |
87 | ||
88 | const struct hash_ops trivial_hash_ops_free_free = { | |
89 | .hash = trivial_hash_func, | |
90 | .compare = trivial_compare_func, | |
91 | .free_key = free, | |
92 | .free_value = free, | |
93 | }; | |
94 | ||
25073e50 | 95 | void uint64_hash_func(const uint64_t *p, struct siphash *state) { |
c01a5c05 | 96 | siphash24_compress_typesafe(*p, state); |
758dd67e LP |
97 | } |
98 | ||
25073e50 YW |
99 | int uint64_compare_func(const uint64_t *a, const uint64_t *b) { |
100 | return CMP(*a, *b); | |
758dd67e LP |
101 | } |
102 | ||
25073e50 | 103 | DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func); |
758dd67e LP |
104 | |
105 | #if SIZEOF_DEV_T != 8 | |
25073e50 | 106 | void devt_hash_func(const dev_t *p, struct siphash *state) { |
c01a5c05 | 107 | siphash24_compress_typesafe(*p, state); |
758dd67e | 108 | } |
17488537 | 109 | #endif |
758dd67e | 110 | |
25073e50 | 111 | int devt_compare_func(const dev_t *a, const dev_t *b) { |
17488537 LP |
112 | int r; |
113 | ||
114 | r = CMP(major(*a), major(*b)); | |
115 | if (r != 0) | |
116 | return r; | |
117 | ||
118 | return CMP(minor(*a), minor(*b)); | |
758dd67e LP |
119 | } |
120 | ||
25073e50 | 121 | DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func); |