فهرست منبع

refactor: change Reference/RootReference maps to unordered_map as well

Sam Jaffe 1 ماه پیش
والد
کامیت
fa9c6edabc

+ 30 - 0
include/jvalidate/compat/hash.h

@@ -0,0 +1,30 @@
+#pragma once
+
+#include <cstddef>
+#include <cstdint>
+#include <utility> // IWYU pragma: keep std::hash
+
+// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers,readability-identifier-length)
+namespace jvalidate::compat {
+// Taken from boostorg/container_hash
+// https://github.com/boostorg/container_hash/blob/2698b43803c012601e6bb1a6116e83767b97986c/include/boost/container_hash/detail/hash_mix.hpp#L67-L81
+inline std::size_t hash_mix(std::size_t x) {
+  static_assert(sizeof(std::size_t) == 8);
+  constexpr static std::uint64_t m = 0xe9846af9b1a615d;
+
+  x ^= x >> 32;
+  x *= m;
+  x ^= x >> 32;
+  x *= m;
+  x ^= x >> 28;
+
+  return x;
+}
+
+// Taken from boostorg/container_hash
+// https://github.com/boostorg/container_hash/blob/2698b43803c012601e6bb1a6116e83767b97986c/include/boost/container_hash/hash.hpp#L474-L477
+template <class T> inline void hash_combine(std::size_t & seed, T const & v) {
+  seed = hash_mix(seed + 0x9e3779b9 + std::hash<T>()(v));
+}
+}
+// NOLINTEND(cppcoreguidelines-avoid-magic-numbers,readability-identifier-length)

+ 19 - 0
include/jvalidate/detail/reference.h

@@ -6,6 +6,7 @@
 #include <string_view>
 #include <utility>
 
+#include <jvalidate/compat/hash.h>
 #include <jvalidate/detail/anchor.h>
 #include <jvalidate/detail/expect.h>
 #include <jvalidate/detail/out.h>
@@ -158,3 +159,21 @@ public:
   auto operator<=>(Reference const &) const = default;
 };
 }
+
+template <> struct std::hash<jvalidate::detail::RootReference> {
+  auto operator()(jvalidate::detail::RootReference const & value) const {
+    std::size_t seed = 0;
+    jvalidate::compat::hash_combine(seed, value.uri());
+    jvalidate::compat::hash_combine(seed, value.anchor());
+    return seed;
+  }
+};
+
+template <> struct std::hash<jvalidate::detail::Reference> {
+  auto operator()(jvalidate::detail::Reference const & value) const {
+    std::size_t seed = 0;
+    jvalidate::compat::hash_combine(seed, value.root());
+    jvalidate::compat::hash_combine(seed, value.pointer());
+    return seed;
+  }
+};

+ 1 - 2
include/jvalidate/detail/reference_manager.h

@@ -1,7 +1,6 @@
 #pragma once
 
 #include <cstdlib>
-#include <map>
 #include <optional>
 #include <string>
 #include <string_view>
@@ -55,7 +54,7 @@ private:
   std::unordered_map<schema::Version, Vocabulary<A>> vocabularies_;
   std::unordered_map<URI, Vocabulary<A>> user_vocabularies_;
 
-  std::map<RootReference, A> roots_;
+  std::unordered_map<RootReference, A> roots_;
 
   std::unordered_map<URI, std::unordered_map<Anchor, Reference>> dynamic_anchors_;
   DynamicReferenceContext active_dynamic_anchors_;

+ 2 - 3
include/jvalidate/schema.h

@@ -1,6 +1,5 @@
 #pragma once
 
-#include <map>
 #include <memory>
 #include <optional>
 #include <stdexcept> // IWYU pragma: keep
@@ -122,11 +121,11 @@ private:
   // An owning cache of all created schemas. Avoids storing duplicates such as
   // the "always-true" schema, "always-false" schema, and schemas whose only
   // meaningful field is "$ref", "$recursiveRef", or "$dynamicRef".
-  std::map<detail::Reference, schema::Node> cache_;
+  std::unordered_map<detail::Reference, schema::Node> cache_;
 
   // A non-owning cache of all schemas, including duplcates where multiple
   // References map to the same underlying schema.
-  std::map<detail::Reference, schema::Node const *> alias_cache_;
+  std::unordered_map<detail::Reference, schema::Node const *> alias_cache_;
 
 public:
   /**