diff --git a/headers/Containers/DualkeyMap.hpp b/headers/Containers/DualkeyMap.hpp index c93e06c..08dc49b 100644 --- a/headers/Containers/DualkeyMap.hpp +++ b/headers/Containers/DualkeyMap.hpp @@ -9,14 +9,12 @@ #ifndef GUARD_TOURMALINE_DUALKEYMAP_H #define GUARD_TOURMALINE_DUALKEYMAP_H #include "../Systems/Logging.hpp" -#include "Hashing.hpp" +#include "Concepts.hpp" #include #include -#include #include #include -#include #include #include #include @@ -31,12 +29,20 @@ template class DualkeyMap { public: + // Return Types + template + requires Either + using MultiQueryResult = + std::pair, + std::array, resultValueCount>>; using QueryResult = std::pair, std::reference_wrapper>, Value &>; using Entry = std::tuple; + // Construct/Destruct DualkeyMap() { hashList.reserve(baseReservation); } ~DualkeyMap() { // I'm sure there is a better way to do this @@ -47,6 +53,12 @@ public: } } + // No copying due to the container expected to be the sole + // owner of the data + DualkeyMap(const DualkeyMap &) = delete; + DualkeyMap &operator=(const DualkeyMap &) = delete; + + // Public controls Entry Insert(AKey firstKey, BKey secondKey, Value value) { DualkeyHash *hash = new DualkeyHash(std::move(firstKey), std::move(secondKey), std::move(value)); @@ -106,7 +118,7 @@ public: } break; - case 3: + case 3: // Both given if (firstKeyHash == hash->firstKeyHash && secondKeyHash == hash->secondKeyHash && firstKey.value() == hash->firstKey && @@ -123,6 +135,12 @@ public: return amountDeleted; } + [[nodiscard]] + std::size_t Count() { + return hashList.size() - graveyard.size(); + } + + // Queries [[nodiscard("Discarding an expensive query!")]] std::vector Query(std::optional firstKey, std::optional secondKey) { @@ -180,18 +198,18 @@ public: } template - requires(std::same_as || std::same_as) + requires Either [[nodiscard("Discarding a very expensive query!")]] int QueryWithAll(const Key (&keys)[keyCount]) { auto queryResults = queryWithMany(keys); - for (const auto &queryRecord : queryResults) { - Systems::Logging::Log( - std::format("Opposite = {}, found = {}", - reinterpret_cast(queryRecord.resultKey), - queryRecord.howManyFound), - "DKM", Systems::Logging::LogLevel::Info, - queryRecord.howManyFound == keyCount); + // You could very well use auto here but this helps + // with LSP hints + for (const unprocessedMultiQueryResult< + std::conditional_t, BKey, AKey>, + keyCount> &queryRecord : queryResults) { + if (queryRecord.howManyFound == keyCount) { + } } return 0; @@ -223,19 +241,10 @@ public: } } - [[nodiscard]] - std::size_t Count() { - return hashList.size() - graveyard.size(); - } - - // No copying due to the container expected to be the sole - // owner of the data - DualkeyMap(const DualkeyMap &) = delete; - DualkeyMap &operator=(const DualkeyMap &) = delete; - private: + // Interal data structures template - struct MultiQueryResult { + struct unprocessedMultiQueryResult { OppositeKey *resultKey = nullptr; std::size_t howManyFound = 1; std::array valueQueryResults; @@ -255,8 +264,13 @@ private: mutable Value value; }; + // Actual data + std::vector hashList; + std::stack graveyard; + + // Interal querying template - inline std::vector, BKey, AKey>, keyCount>> queryWithMany(const Key (&keys)[keyCount]) { constexpr bool searchingInFirstKey = std::is_same_v; @@ -286,7 +300,7 @@ private: uint64_t hashToCompare; Key *keyToCompare; std::conditional_t resultKey; - std::vector, keyCount>> queryResults; for (DualkeyHash *hash : hashList) { @@ -332,10 +346,6 @@ private: return queryResults; } - - // It makes more sense to store the individual hash - std::vector hashList; - std::stack graveyard; }; } // namespace Tourmaline::Containers #endif