document_cache.h 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #pragma once
  2. #include <map>
  3. #include <optional>
  4. #include <jvalidate/detail/expect.h>
  5. #include <jvalidate/detail/pointer.h>
  6. #include <jvalidate/detail/reference.h>
  7. #include <jvalidate/forward.h>
  8. #include <jvalidate/uri.h>
  9. namespace jvalidate {
  10. template <Adapter A> class DocumentCache {
  11. public:
  12. using value_type = typename A::value_type;
  13. private:
  14. URIResolver<A> resolve_;
  15. std::map<URI, A> references_;
  16. std::map<URI, value_type> cache_;
  17. public:
  18. DocumentCache() = default;
  19. DocumentCache(URIResolver<A> const & resolve) : resolve_(resolve) {}
  20. void cache_reference(URI const & where, A const & handle) {
  21. EXPECT(references_.emplace(where, handle).second);
  22. }
  23. operator bool() const { return resolve_; }
  24. std::optional<A> try_load(detail::Reference const & ref) {
  25. if (auto it = references_.find(ref.uri()); it != references_.end()) {
  26. return ref.pointer().walk(it->second);
  27. }
  28. if (not resolve_) {
  29. return std::nullopt;
  30. }
  31. auto [it, created] = cache_.try_emplace(ref.uri());
  32. if (created && not resolve_(ref.uri(), it->second)) {
  33. cache_.erase(it);
  34. return std::nullopt;
  35. }
  36. return ref.pointer().walk(A(it->second));
  37. }
  38. };
  39. }