hash-func: add generic hash_ops implementation for hashing paths
This is similar to string_hash_ops but operates one file system paths specifically. It will ensure that "/foo//bar" and "///foo/bar" are considered to be the same path for hashmap purposes. This makes use of the existing path_compare() API, and adds a matching hashing function for it. Note that relative and absolute paths will hash to different values, however whether the path is suffixed with a slash or not is not detected. This matches the existing path_compare() behaviour, and follows the logic that on Linux there can't be two different objects at path /foo/bar and /foo/bar/ either.
This commit is contained in:
@@ -137,6 +137,34 @@ static void test_iterated_cache(void) {
|
||||
assert_se(iterated_cache_free(c) == NULL);
|
||||
}
|
||||
|
||||
static void test_path_hashmap(void) {
|
||||
_cleanup_(hashmap_freep) Hashmap *h = NULL;
|
||||
|
||||
assert_se(h = hashmap_new(&path_hash_ops));
|
||||
|
||||
assert_se(hashmap_put(h, "foo", INT_TO_PTR(1)) >= 0);
|
||||
assert_se(hashmap_put(h, "/foo", INT_TO_PTR(2)) >= 0);
|
||||
assert_se(hashmap_put(h, "//foo", INT_TO_PTR(3)) == -EEXIST);
|
||||
assert_se(hashmap_put(h, "//foox/", INT_TO_PTR(4)) >= 0);
|
||||
assert_se(hashmap_put(h, "/foox////", INT_TO_PTR(5)) == -EEXIST);
|
||||
assert_se(hashmap_put(h, "foo//////bar/quux//", INT_TO_PTR(6)) >= 0);
|
||||
assert_se(hashmap_put(h, "foo/bar//quux/", INT_TO_PTR(8)) == -EEXIST);
|
||||
|
||||
assert_se(hashmap_get(h, "foo") == INT_TO_PTR(1));
|
||||
assert_se(hashmap_get(h, "foo/") == INT_TO_PTR(1));
|
||||
assert_se(hashmap_get(h, "foo////") == INT_TO_PTR(1));
|
||||
assert_se(hashmap_get(h, "/foo") == INT_TO_PTR(2));
|
||||
assert_se(hashmap_get(h, "//foo") == INT_TO_PTR(2));
|
||||
assert_se(hashmap_get(h, "/////foo////") == INT_TO_PTR(2));
|
||||
assert_se(hashmap_get(h, "/////foox////") == INT_TO_PTR(4));
|
||||
assert_se(hashmap_get(h, "/foox/") == INT_TO_PTR(4));
|
||||
assert_se(hashmap_get(h, "/foox") == INT_TO_PTR(4));
|
||||
assert_se(!hashmap_get(h, "foox"));
|
||||
assert_se(hashmap_get(h, "foo/bar/quux") == INT_TO_PTR(6));
|
||||
assert_se(hashmap_get(h, "foo////bar////quux/////") == INT_TO_PTR(6));
|
||||
assert_se(!hashmap_get(h, "/foo////bar////quux/////"));
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
test_hashmap_funcs();
|
||||
test_ordered_hashmap_funcs();
|
||||
@@ -147,4 +175,7 @@ int main(int argc, const char *argv[]) {
|
||||
test_trivial_compare_func();
|
||||
test_string_compare_func();
|
||||
test_iterated_cache();
|
||||
test_path_hashmap();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user