From c391adad10f5f50ed07441b3eeb6d4702fbbcc90 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 11 Sep 2023 20:48:16 +0200 Subject: [PATCH] tag/Pool: move code from calc_hash() to util/djb_hash.cxx --- src/tag/Pool.cxx | 12 +++--------- src/util/djb_hash.cxx | 40 ++++++++++++++++++++++++++++++++++++++++ src/util/djb_hash.hxx | 25 +++++++++++++++++++++++++ src/util/meson.build | 1 + 4 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 src/util/djb_hash.cxx create mode 100644 src/util/djb_hash.hxx diff --git a/src/tag/Pool.cxx b/src/tag/Pool.cxx index b824bdf4a..bbd49cb56 100644 --- a/src/tag/Pool.cxx +++ b/src/tag/Pool.cxx @@ -4,7 +4,9 @@ #include "Pool.hxx" #include "Item.hxx" #include "util/Cast.hxx" +#include "util/djb_hash.hxx" #include "util/IntrusiveList.hxx" +#include "util/SpanCast.hxx" #include "util/VarSize.hxx" #include @@ -12,9 +14,6 @@ #include #include -#include -#include - Mutex tag_pool_lock; struct TagPoolItem { @@ -53,12 +52,7 @@ static std::array + +#include "djb_hash.hxx" + +#include + +[[gnu::always_inline]] [[gnu::hot]] +static constexpr std::size_t +djb_hash_update(std::size_t hash, std::byte b) noexcept +{ + return (hash * 33) ^ static_cast(b); +} + +[[gnu::hot]] +std::size_t +djb_hash(std::span src, std::size_t init) noexcept +{ + std::size_t hash = init; + + for (const auto i : src) + hash = djb_hash_update(hash, i); + + return hash; +} + +[[gnu::hot]] +std::size_t +djb_hash_string(const char *p, std::size_t init) noexcept +{ + assert(p != nullptr); + + std::size_t hash = init; + + while (*p != 0) + hash = djb_hash_update(hash, static_cast(*p++)); + + return hash; +} diff --git a/src/util/djb_hash.hxx b/src/util/djb_hash.hxx new file mode 100644 index 000000000..6eff57013 --- /dev/null +++ b/src/util/djb_hash.hxx @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright CM4all GmbH +// author: Max Kellermann + +/* + * Implementation of D. J. Bernstein's cdb hash function. + * http://cr.yp.to/cdb/cdb.txt + */ + +#pragma once + +#include +#include + +static constexpr std::size_t DJB_HASH_INIT = 5381; + +[[gnu::pure]] +std::size_t +djb_hash(std::span src, + std::size_t init=DJB_HASH_INIT) noexcept; + +[[gnu::pure]] +std::size_t +djb_hash_string(const char *p, + std::size_t init=DJB_HASH_INIT) noexcept; diff --git a/src/util/meson.build b/src/util/meson.build index 0e41fc20d..f68670fb3 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -24,6 +24,7 @@ util = static_library( 'ByteReverse.cxx', 'format.c', 'BitReverse.cxx', + 'djb_hash.cxx', 'Serial.cxx', include_directories: inc, )