summaryrefslogtreecommitdiff
path: root/source/fud_hash.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/fud_hash.cpp')
-rw-r--r--source/fud_hash.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/source/fud_hash.cpp b/source/fud_hash.cpp
new file mode 100644
index 0000000..faa62ff
--- /dev/null
+++ b/source/fud_hash.cpp
@@ -0,0 +1,53 @@
+/*
+ * libfud
+ * Copyright 2025 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "fud_hash.hpp"
+
+namespace fud::detail {
+
+size_t djb2(const utf8* data, size_t length)
+{
+ /* Allegedly djb chose 5381 after testing showed fewer collisions and better avalanching: see
+ * https://stackoverflow.com/questions/10696223/reason-for-the-number-5381-in-the-djb-hash-function */
+ constexpr size_t hashInit = 5381;
+ constexpr size_t mulBy = 33;
+ size_t hash = hashInit;
+ if (data == nullptr) {
+ return hash;
+ }
+
+ for (size_t index = 0; index < length; ++index) {
+ hash = (hash * mulBy) ^ data[index];
+ }
+
+ return hash;
+}
+
+
+size_t DefaultHash<String>::operator()(const String& value, size_t seed) const
+{
+ static_cast<void>(seed);
+ return djb2(value.data(), value.length());
+}
+
+size_t DefaultHash<StringView>::operator()(const StringView& value, size_t seed) const
+{
+ static_cast<void>(seed);
+ return djb2(value.data(), value.length());
+}
+
+}