Selaa lähdekoodia

refactor: change most storage methods to use unordered_map, unless they specifically require lower_bound/upper_bound

Sam Jaffe 1 kuukausi sitten
vanhempi
commit
33878e11da

+ 6 - 0
include/jvalidate/detail/anchor.h

@@ -63,3 +63,9 @@ private:
   static bool is_valid_char(char c) { return std::isalnum(c) || c == '_' || c == '.' || c == '-'; }
 };
 }
+
+template <> struct std::hash<jvalidate::detail::Anchor> {
+  auto operator()(jvalidate::detail::Anchor const & value) const {
+    return std::hash<std::string>()(static_cast<std::string const &>(value));
+  }
+};

+ 2 - 2
include/jvalidate/detail/dynamic_reference_context.h

@@ -28,7 +28,7 @@ namespace jvalidate::detail {
 class DynamicReferenceContext {
 private:
   std::deque<URI> sources_;
-  std::map<Anchor, std::deque<std::optional<Reference>>> data_;
+  std::unordered_map<Anchor, std::deque<std::optional<Reference>>> data_;
 
 public:
   /**
@@ -37,7 +37,7 @@ public:
    * parent reference and unregistering all of the anchors that are in context,
    * but not in this specific document.
    */
-  OnBlockExit scope(URI const & source, std::map<Anchor, Reference> const & frame) {
+  OnBlockExit scope(URI const & source, std::unordered_map<Anchor, Reference> const & frame) {
     // No-Op loading, for convenience
     if (frame.empty() && data_.empty()) {
       return nullptr;

+ 7 - 0
include/jvalidate/detail/pointer.h

@@ -181,6 +181,7 @@ public:
   iterator begin() const;
   iterator end() const;
 
+  explicit operator std::string const &() const { return value_; }
   friend std::ostream & operator<<(std::ostream & os, Pointer const & self) {
     return os << self.value_;
   }
@@ -294,3 +295,9 @@ inline auto Pointer::walk(Adapter auto document) const {
   return document;
 }
 }
+
+template <> struct std::hash<jvalidate::detail::Pointer> {
+  auto operator()(jvalidate::detail::Pointer const & value) const {
+    return std::hash<std::string>()(static_cast<std::string const &>(value));
+  }
+};

+ 3 - 3
include/jvalidate/detail/reference_manager.h

@@ -52,12 +52,12 @@ private:
 
   ReferenceCache references_;
 
-  std::map<schema::Version, Vocabulary<A>> vocabularies_;
-  std::map<URI, Vocabulary<A>> user_vocabularies_;
+  std::unordered_map<schema::Version, Vocabulary<A>> vocabularies_;
+  std::unordered_map<URI, Vocabulary<A>> user_vocabularies_;
 
   std::map<RootReference, A> roots_;
 
-  std::map<URI, std::map<Anchor, Reference>> dynamic_anchors_;
+  std::unordered_map<URI, std::unordered_map<Anchor, Reference>> dynamic_anchors_;
   DynamicReferenceContext active_dynamic_anchors_;
 
 public:

+ 2 - 2
include/jvalidate/document_cache.h

@@ -1,8 +1,8 @@
 #pragma once
 
-#include <map>
 #include <optional>
 #include <string>
+#include <unordered_map>
 
 #include <jvalidate/forward.h>
 #include <jvalidate/uri.h>
@@ -30,7 +30,7 @@ public:
 
 private:
   URIResolver<A> resolve_;
-  std::map<URI, value_type> cache_;
+  std::unordered_map<URI, value_type> cache_;
 
 public:
   /**

+ 6 - 0
include/jvalidate/uri.h

@@ -122,3 +122,9 @@ public:
   auto operator<=>(URI const & lhs) const = default;
 };
 }
+
+template <> struct std::hash<jvalidate::URI> {
+  auto operator()(jvalidate::URI const & value) const {
+    return std::hash<std::string>()(static_cast<std::string const &>(value));
+  }
+};

+ 10 - 7
include/jvalidate/validation_result.h

@@ -5,6 +5,7 @@
 #include <map>
 #include <ostream>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <variant>
 #include <vector>
@@ -40,15 +41,15 @@ public:
    */
   struct LocalResult {
     bool valid = true;
-    std::map<std::string, Annotation> errors;
-    std::map<std::string, Annotation> annotations;
+    std::unordered_map<std::string, Annotation> errors;
+    std::unordered_map<std::string, Annotation> annotations;
   };
 
   static auto indent(size_t depth) { return std::string(depth * 2, ' '); }
 
 private:
   bool valid_;
-  std::map<DocPointer, std::map<SchemaPointer, LocalResult>> results_;
+  std::unordered_map<DocPointer, std::unordered_map<SchemaPointer, LocalResult>> results_;
 
 public:
   /**
@@ -86,11 +87,14 @@ public:
    * }
    */
   friend std::ostream & operator<<(std::ostream & os, ValidationResult const & result) {
+    auto sorted = []<typename K, typename V>(std::unordered_map<K, V> const & container) {
+      return std::map<K, V const &>(container.begin(), container.end());
+    };
     char const * div = "\n";
     os << "{\n" << indent(1) << R"("valid": )" << (result.valid_ ? "true" : "false") << ',' << '\n';
     os << indent(1) << R"("details": [)";
-    for (auto const & [doc_path, by_schema] : result.results_) {
-      for (auto const & [schema_path, local] : by_schema) {
+    for (auto const & [doc_path, by_schema] : sorted(result.results_)) {
+      for (auto const & [schema_path, local] : sorted(by_schema)) {
         os << std::exchange(div, ",\n") << indent(2) << '{' << '\n';
         os << indent(3) << R"("valid": )" << (local.valid ? "true" : "false") << ',' << '\n';
         os << indent(3) << R"("evaluationPath": ")" << schema_path << '"' << ',' << '\n';
@@ -103,8 +107,7 @@ public:
     return os << '\n' << indent(1) << ']' << '\n' << '}';
   }
 
-  static void print(std::ostream & os, std::map<std::string, Annotation> const & named,
-                    std::string_view name, int const depth) {
+  static void print(std::ostream & os, auto const & named, std::string_view name, int const depth) {
     if (named.empty()) {
       return;
     }