From 7197da21f6bcc1aaa5d1905228e0e2ec1caf3fa8 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Mon, 17 Jul 2023 16:54:35 +1000 Subject: Basic playlists for upcoming Beware under-testing and bugs. Just getting something barebones in so that I can do rN+1 bringup --- src/util/include/bloom_filter.hpp | 40 +++++++++++++++++++++++ src/util/include/lru_cache.hpp | 69 +++++++++++++++++++++++++++++++++++++++ src/util/include/random.hpp | 39 ++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 src/util/include/bloom_filter.hpp create mode 100644 src/util/include/lru_cache.hpp create mode 100644 src/util/include/random.hpp (limited to 'src/util/include') diff --git a/src/util/include/bloom_filter.hpp b/src/util/include/bloom_filter.hpp new file mode 100644 index 00000000..04b72e20 --- /dev/null +++ b/src/util/include/bloom_filter.hpp @@ -0,0 +1,40 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include +#include +#include + +namespace util { + +template +class BloomFilter { + public: + explicit BloomFilter(std::function hasher) + : hasher_(hasher), bits_() {} + + auto Insert(T val) -> void { + uint64_t hash = std::invoke(hasher_, val); + bits_[hash & 0xFFFF] = 1; + bits_[(hash >> 16) & 0xFFFF] = 1; + bits_[(hash >> 32) & 0xFFFF] = 1; + bits_[(hash >> 48) & 0xFFFF] = 1; + } + + auto Contains(T val) -> bool { + uint64_t hash = std::invoke(hasher_, val); + return bits_[hash & 0xFFFF] && bits_[(hash >> 16) & 0xFFFF] && + bits_[(hash >> 32) & 0xFFFF] && bits_[(hash >> 48) & 0xFFFF]; + } + + private: + std::function hasher_; + std::bitset<(1 << 16)> bits_; +}; + +} // namespace util diff --git a/src/util/include/lru_cache.hpp b/src/util/include/lru_cache.hpp new file mode 100644 index 00000000..8f955a07 --- /dev/null +++ b/src/util/include/lru_cache.hpp @@ -0,0 +1,69 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace util { + +/* + * Basic least recently used cache. Stores the `Size` most recently accessed + * entries in memory. + * + * Not safe for use from multiple tasks, but all operations are constant time. + */ +template +class LruCache { + public: + LruCache() : entries_(), key_to_it_() {} + + auto Put(K key, V val) -> void { + if (key_to_it_.contains(key)) { + // This key was already present. Overwrite by removing the previous + // value. + entries_.erase(key_to_it_[key]); + key_to_it_.erase(key); + } else if (entries_.size() >= Size) { + // Cache is full. Evict the last entry. + key_to_it_.erase(entries_.back().first); + entries_.pop_back(); + } + + // Add the new value. + entries_.push_front({key, val}); + key_to_it_[key] = entries_.begin(); + } + + auto Get(K key) -> std::optional { + if (!key_to_it_.contains(key)) { + return {}; + } + // Use splice() to move the entry to the front of the list. This approach + // doesn't invalidate any of the iterators in key_to_it_, and is constant + // time. + auto it = key_to_it_[key]; + entries_.splice(entries_.begin(), entries_, it); + return it->second; + } + + auto Clear() -> void { + entries_.clear(); + key_to_it_.clear(); + } + + private: + std::list> entries_; + std::unordered_map key_to_it_; +}; + +} // namespace util diff --git a/src/util/include/random.hpp b/src/util/include/random.hpp new file mode 100644 index 00000000..cd8ab1c6 --- /dev/null +++ b/src/util/include/random.hpp @@ -0,0 +1,39 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include + +#include "komihash.h" + +namespace util { + +class IRandom { + public: + virtual ~IRandom() {} + + virtual auto Next() -> std::uint64_t = 0; + virtual auto RangeInclusive(std::uint64_t lower, std::uint64_t upper) + -> std::uint64_t = 0; +}; + +extern IRandom* sRandom; + +class Random : public IRandom { + public: + Random(); + + auto Next() -> std::uint64_t override; + auto RangeInclusive(std::uint64_t lower, std::uint64_t upper) + -> std::uint64_t override; + + private: + std::uint64_t seed1_; + std::uint64_t seed2_; +}; + +} // namespace util -- cgit v1.2.3