aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/stllike/hash_fun.h
blob: 8fecc41b4c1aeb17ec27ed184aed8963832182d2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include <vespa/vespalib/stllike/string.h>

namespace vespalib {

template<typename K> struct hash {
    // specializations operate as functor for known key types
    size_t operator() (const K & v) const noexcept(noexcept(v.hash())) {
        return v.hash();
    }
};

template<> struct hash<char> {
    size_t operator() (char arg) const noexcept { return arg; }
};
template<> struct hash<signed char> {
    size_t operator() (signed char arg) const noexcept { return arg; }
};
template<> struct hash<short> {
    size_t operator() (short arg) const noexcept { return arg; }
};
template<> struct hash<int> {
    size_t operator() (int arg) const noexcept { return arg; }
};
template<> struct hash<long> {
    size_t operator() (long arg) const noexcept { return arg; }
};
template<> struct hash<long long> {
    size_t operator() (long long arg) const noexcept { return arg; }
};

template<> struct hash<unsigned char> {
    size_t operator() (unsigned char arg) const noexcept { return arg; }
};
template<> struct hash<unsigned short> {
    size_t operator() (unsigned short arg) const noexcept { return arg; }
};
template<> struct hash<unsigned int> {
    size_t operator() (unsigned int arg) const noexcept { return arg; }
};
template<> struct hash<unsigned long> {
    size_t operator() (unsigned long arg) const noexcept { return arg; }
};
template<> struct hash<unsigned long long> {
    size_t operator() (unsigned long long arg) const noexcept { return arg; }
};

template<> struct hash<float> {
    union U { float f; uint32_t i; };
    size_t operator() (float arg) const noexcept { U t; t.f = arg; return t.i; }
};
template<> struct hash<double> {
    union U { double f; uint64_t i; };
    size_t operator() (double arg) const noexcept { U t; t.f = arg; return t.i; }
};

template<typename T> struct hash<T *> {
    size_t operator() (const T * arg) const noexcept { return size_t(arg); }
};
template<typename T> struct hash<const T *> {
    size_t operator() (const T * arg) const noexcept { return size_t(arg); }
};

namespace xxhash {

uint64_t xxh3_64(uint64_t value) noexcept;
uint64_t xxh3_64(const void *str, size_t sz) noexcept;

}

// reuse old string hash function
size_t hashValue(const char *str) noexcept;
inline size_t hashValue(const void *buf, size_t sz) noexcept {
    return xxhash::xxh3_64(buf, sz);
}

struct hash_strings {
    size_t operator() (const vespalib::string & arg) const noexcept { return hashValue(arg.data(), arg.size()); }
    size_t operator() (vespalib::stringref arg) const noexcept { return hashValue(arg.data(), arg.size()); }
    size_t operator() (const char * arg) const noexcept { return hashValue(arg); }
    size_t operator() (const std::string& arg) const noexcept { return hashValue(arg.data(), arg.size()); }
};

template<> struct hash<const char *> : hash_strings { };
template<> struct hash<vespalib::stringref> : public hash_strings { };
template<> struct hash<vespalib::string> : hash_strings {};
template<> struct hash<std::string> : hash_strings {};

template<typename V> struct size {
    size_t operator() (const V & arg) const noexcept { return arg.size(); }
};

template<typename V> struct zero {
    size_t operator() (const V & ) const noexcept { return 0; }
};

} // namespace vespalib