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