Skip to content

Commit

Permalink
perf: Speedup reference resolving
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dygalo <[email protected]>
  • Loading branch information
Stranger6667 committed Oct 4, 2024
1 parent 62506bd commit d9ae90f
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 21 deletions.
6 changes: 3 additions & 3 deletions crates/jsonschema-referencing/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl<T> List<T> {
self.head.is_none()
}
#[must_use]
pub fn push_front(&self, value: T) -> Self {
pub fn push_front(&self, value: Arc<T>) -> Self {
List {
head: Some(Arc::new(Node {
value,
Expand All @@ -52,7 +52,7 @@ impl<T> List<T> {

#[derive(Debug)]
pub(crate) struct Node<T> {
value: T,
value: Arc<T>,
next: Option<Arc<Node<T>>>,
}

Expand All @@ -68,7 +68,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
self.current.map(|current| {
let value = &current.value;
self.current = current.next.as_ref();
value
&**value
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/jsonschema-referencing/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,12 @@ impl Registry {
/// Create a new [`Resolver`] for this registry with a known valid base URI.
#[must_use]
pub fn resolver(&self, base_uri: Uri<String>) -> Resolver {
Resolver::new(self, base_uri)
Resolver::new(self, Arc::new(base_uri))
}
#[must_use]
pub fn resolver_from_raw_parts(
&self,
base_uri: Uri<String>,
base_uri: Arc<Uri<String>>,
scopes: List<Uri<String>>,
) -> Resolver {
Resolver::from_parts(self, base_uri, scopes)
Expand Down
17 changes: 9 additions & 8 deletions crates/jsonschema-referencing/src/resolver.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::fmt;
use std::sync::Arc;

use fluent_uri::Uri;
use serde_json::Value;
Expand All @@ -11,7 +12,7 @@ use crate::{list::List, uri, Draft, Error, Registry, ResourceRef};
#[derive(Clone)]
pub struct Resolver<'r> {
pub(crate) registry: &'r Registry,
base_uri: Uri<String>,
base_uri: Arc<Uri<String>>,
scopes: List<Uri<String>>,
}

Expand Down Expand Up @@ -45,7 +46,7 @@ impl<'r> fmt::Debug for Resolver<'r> {

impl<'r> Resolver<'r> {
/// Create a new `Resolver` with the given registry and base URI.
pub(crate) fn new(registry: &'r Registry, base_uri: Uri<String>) -> Self {
pub(crate) fn new(registry: &'r Registry, base_uri: Arc<Uri<String>>) -> Self {
Self {
registry,
base_uri,
Expand All @@ -54,7 +55,7 @@ impl<'r> Resolver<'r> {
}
pub(crate) fn from_parts(
registry: &'r Registry,
base_uri: Uri<String>,
base_uri: Arc<Uri<String>>,
scopes: List<Uri<String>>,
) -> Self {
Self {
Expand All @@ -64,8 +65,8 @@ impl<'r> Resolver<'r> {
}
}
#[must_use]
pub fn base_uri(&self) -> Uri<&str> {
self.base_uri.borrow()
pub fn base_uri(&self) -> Arc<Uri<String>> {
self.base_uri.clone()
}
/// Resolve a reference to the resource it points to.
///
Expand All @@ -81,7 +82,7 @@ impl<'r> Resolver<'r> {
} else {
(reference, "")
};
let uri = uri::resolve_against(&self.base_uri.borrow(), uri)?;
let uri = Arc::new(uri::resolve_against(&self.base_uri.borrow(), uri)?);
(uri, fragment)
};

Expand Down Expand Up @@ -155,7 +156,7 @@ impl<'r> Resolver<'r> {
/// Returns an error if the resource id cannot be resolved against the base URI of this resolver.
pub fn in_subresource(&self, subresource: ResourceRef) -> Result<Self, Error> {
if let Some(id) = subresource.id() {
let base_uri = uri::resolve_against(&self.base_uri.borrow(), id)?;
let base_uri = Arc::new(uri::resolve_against(&self.base_uri.borrow(), id)?);
Ok(Resolver {
registry: self.registry,
base_uri,
Expand All @@ -169,7 +170,7 @@ impl<'r> Resolver<'r> {
pub fn dynamic_scope(&self) -> List<Uri<String>> {
self.scopes.clone()
}
fn evolve(&self, base_uri: Uri<String>) -> Resolver<'r> {
fn evolve(&self, base_uri: Arc<Uri<String>>) -> Resolver<'r> {
if !self.base_uri.as_str().is_empty()
&& (self.scopes.is_empty() || base_uri != self.base_uri)
{
Expand Down
11 changes: 6 additions & 5 deletions crates/jsonschema/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc};
const DEFAULT_SCHEME: &str = "json-schema";
pub(crate) const DEFAULT_ROOT_URL: &str = "json-schema:///";
type BaseUri = Uri<String>;
type ResolverComponents = (Arc<BaseUri>, List<BaseUri>, Resource);

/// Container for information required to build a tree.
///
Expand Down Expand Up @@ -123,7 +124,7 @@ impl<'a> Context<'a> {
if base_uri.scheme().as_str() == DEFAULT_SCHEME {
None
} else {
Some(base_uri.to_owned())
Some((*base_uri).clone())
}
}
fn is_known_keyword(&self, keyword: &str) -> bool {
Expand Down Expand Up @@ -186,11 +187,11 @@ impl<'a> Context<'a> {
&self,
reference: &str,
) -> Result<bool, referencing::Error> {
let uri = uri::resolve_against(&self.resolver.base_uri(), reference)?;
let uri = uri::resolve_against(&self.resolver.base_uri().borrow(), reference)?;
Ok(self.seen.borrow().contains(&uri))
}
pub(crate) fn mark_seen(&self, reference: &str) -> Result<(), referencing::Error> {
let uri = uri::resolve_against(&self.resolver.base_uri(), reference)?;
let uri = uri::resolve_against(&self.resolver.base_uri().borrow(), reference)?;
self.seen.borrow_mut().insert(uri);
Ok(())
}
Expand All @@ -204,7 +205,7 @@ impl<'a> Context<'a> {
&self,
reference: &str,
is_recursive: bool,
) -> Result<Option<(BaseUri, List<BaseUri>, Resource)>, ValidationError<'static>> {
) -> Result<Option<ResolverComponents>, ValidationError<'static>> {
let resolved = if reference == "#" {
// Known & simple recursive reference
// It may also use some additional logic from the `$recursiveAnchor` keyword
Expand All @@ -223,7 +224,7 @@ impl<'a> Context<'a> {
let mut base_uri = resolved.resolver().base_uri().to_owned();
let scopes = resolved.resolver().dynamic_scope();
if let Some(id) = resource.id() {
base_uri = uri::resolve_against(&base_uri.borrow(), id)?;
base_uri = Arc::new(uri::resolve_against(&base_uri.borrow(), id)?);
};
Ok(Some((base_uri, scopes, resource)))
}
Expand Down
6 changes: 3 additions & 3 deletions crates/jsonschema/src/keywords/ref_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub(crate) struct LazyRefValidator {
config: Arc<ValidationOptions>,
registry: Arc<Registry>,
scopes: List<Uri<String>>,
base_uri: Uri<String>,
base_uri: Arc<Uri<String>>,
draft: Draft,
inner: OnceCell<SchemaNode>,
}
Expand All @@ -73,9 +73,9 @@ impl LazyRefValidator {
let scopes = ctx.scopes();
let resolved = ctx.lookup_recursive_reference()?;
let resource = ctx.draft().create_resource(resolved.contents().clone());
let mut base_uri = resolved.resolver().base_uri().to_owned();
let mut base_uri = resolved.resolver().base_uri();
if let Some(id) = resource.id() {
base_uri = uri::resolve_against(&base_uri.borrow(), id)?;
base_uri = Arc::new(uri::resolve_against(&base_uri.borrow(), id)?);
};
Ok(Box::new(LazyRefValidator {
resource,
Expand Down

0 comments on commit d9ae90f

Please sign in to comment.