1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright 2010 Lennart Poettering
4 Copyright 2014 Michal Schmidt
9 #include "hash-funcs.h"
10 #include "path-util.h"
12 void string_hash_func(const void *p
, struct siphash
*state
) {
13 siphash24_compress(p
, strlen(p
) + 1, state
);
16 int string_compare_func(const void *a
, const void *b
) {
20 const struct hash_ops string_hash_ops
= {
21 .hash
= string_hash_func
,
22 .compare
= string_compare_func
25 void path_hash_func(const void *p
, struct siphash
*state
) {
32 /* Calculates a hash for a path in a way this duplicate inner slashes don't make a differences, and also
33 * whether there's a trailing slash or not. This fits well with the semantics of path_compare(), which does
34 * similar checks and also doesn't care for trailing slashes. Note that relative and absolute paths (i.e. those
35 * which begin in a slash or not) will hash differently though. */
38 if (n
> 0) { /* Eat up initial slashes, and add one "/" to the hash for all of them */
39 siphash24_compress(q
, 1, state
);
44 /* Determine length of next component */
46 if (n
== 0) /* Reached the end? */
49 /* Add this component to the hash and skip over it */
50 siphash24_compress(q
, n
, state
);
53 /* How many slashes follow this component? */
55 if (q
[n
] == 0) /* Is this a trailing slash? If so, we are at the end, and don't care about the slashes anymore */
58 /* We are not add the end yet. Hash exactly one slash for all of the ones we just encountered. */
59 siphash24_compress(q
, 1, state
);
64 int path_compare_func(const void *a
, const void *b
) {
65 return path_compare(a
, b
);
68 const struct hash_ops path_hash_ops
= {
69 .hash
= path_hash_func
,
70 .compare
= path_compare_func
73 void trivial_hash_func(const void *p
, struct siphash
*state
) {
74 siphash24_compress(&p
, sizeof(p
), state
);
77 int trivial_compare_func(const void *a
, const void *b
) {
78 return a
< b
? -1 : (a
> b
? 1 : 0);
81 const struct hash_ops trivial_hash_ops
= {
82 .hash
= trivial_hash_func
,
83 .compare
= trivial_compare_func
86 void uint64_hash_func(const void *p
, struct siphash
*state
) {
87 siphash24_compress(p
, sizeof(uint64_t), state
);
90 int uint64_compare_func(const void *_a
, const void *_b
) {
92 a
= *(const uint64_t*) _a
;
93 b
= *(const uint64_t*) _b
;
94 return a
< b
? -1 : (a
> b
? 1 : 0);
97 const struct hash_ops uint64_hash_ops
= {
98 .hash
= uint64_hash_func
,
99 .compare
= uint64_compare_func
102 #if SIZEOF_DEV_T != 8
103 void devt_hash_func(const void *p
, struct siphash
*state
) {
104 siphash24_compress(p
, sizeof(dev_t
), state
);
107 int devt_compare_func(const void *_a
, const void *_b
) {
109 a
= *(const dev_t
*) _a
;
110 b
= *(const dev_t
*) _b
;
111 return a
< b
? -1 : (a
> b
? 1 : 0);
114 const struct hash_ops devt_hash_ops
= {
115 .hash
= devt_hash_func
,
116 .compare
= devt_compare_func