Skip to content

Commit

Permalink
Optimization: update collect_annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
skryukov committed Oct 22, 2023
1 parent 7b28708 commit bd76ebf
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 30 deletions.
15 changes: 5 additions & 10 deletions lib/json_skooma/keywords/draft_2019_09/unevaluated_items.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,16 @@ class UnevaluatedItems < Base
if then else allOf anyOf oneOf not
]

LOOKUP_KEYWORDS = %w[items additionalItems unevaluatedItems].freeze

def evaluate(instance, result)
last_evaluated_item = -1

result.parent.collect_annotations(instance, "items") do |i|
result.parent.collect_annotations(instance, keys: LOOKUP_KEYWORDS) do |node|
i = node.annotation
next result.discard if i == true

last_evaluated_item = i if i > last_evaluated_item
end

result.parent.collect_annotations(instance, "additionalItems") do |i|
next result.discard if i == true
end

result.parent.collect_annotations(instance, "unevaluatedItems") do |i|
next result.discard if i == true
last_evaluated_item = i if node.key == "items" && i > last_evaluated_item
end

annotation = nil
Expand Down
18 changes: 7 additions & 11 deletions lib/json_skooma/keywords/unevaluated/unevaluated_items.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,21 @@ class UnevaluatedItems < Base
if then else allOf anyOf oneOf not
]

LOOKUP_KEYWORDS = %w[items unevaluatedItems prefixItems contains].freeze

def evaluate(instance, result)
contains_indices = Set.new
last_evaluated_item = -1

result.parent.collect_annotations(instance, "prefixItems") do |i|
next result.discard if i == true

last_evaluated_item = i if i > last_evaluated_item
end
result.parent.collect_annotations(instance, keys: LOOKUP_KEYWORDS) do |node|
next contains_indices += node.annotation if node.key == "contains"

result.parent.collect_annotations(instance, "items") do |i|
i = node.annotation
next result.discard if i == true
end

result.parent.collect_annotations(instance, "unevaluatedItems") do |i|
next result.discard if i == true
last_evaluated_item = i if node.key == "prefixItems" && i > last_evaluated_item
end

contains_indices = Set.new
result.parent.collect_annotations(instance, "contains") { |i| contains_indices += i }
annotation = nil
error = []

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ class UnevaluatedProperties < Base
if then else dependentSchemas allOf anyOf oneOf not
]

LOOKUP_KEYWORDS = %w[properties patternProperties additionalProperties unevaluatedProperties].freeze

def evaluate(instance, result)
evaluated_names = Set.new
result.parent.collect_annotations(instance, "properties") { |name| evaluated_names += name }
result.parent.collect_annotations(instance, "patternProperties") { |name| evaluated_names += name }
result.parent.collect_annotations(instance, "additionalProperties") { |name| evaluated_names += name }
result.parent.collect_annotations(instance, "unevaluatedProperties") { |name| evaluated_names += name }
result.parent.collect_annotations(instance, keys: LOOKUP_KEYWORDS) do |node|
evaluated_names += node.annotation
end

annotation = []
error = []
Expand Down
28 changes: 23 additions & 5 deletions lib/json_skooma/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,36 @@ def absolute_uri
schema.canonical_uri.dup.tap { |u| u.fragment = path.to_s }
end

def collect_annotations(instance = nil, key = nil)
def collect_annotations(instance, key: nil, keys: nil)
return if !valid? || discard?

if @annotation &&
(key.nil? || key == @key) &&
(instance.nil? || instance.path == @instance.path)
yield @annotation
(keys.nil? || keys.include?(@key)) &&
(instance.path == @instance.path)
yield self
end

children[instance.path]&.each_value do |child|
child.collect_annotations(instance, key) do |annotation|
yield annotation
child.collect_annotations(instance, key: key, keys: keys) do |node|
yield node
end
end
end

def collect_errors(instance, key: nil, keys: nil)
return if valid? || discard?

if @error &&
(key.nil? || key == @key) &&
(keys.nil? || keys.include?(@key)) &&
(instance.path == @instance.path)
yield self
end

children[instance.path]&.each_value do |child|
child.collect_errors(instance, key: key, keys: keys) do |node|
yield node
end
end
end
Expand Down

0 comments on commit bd76ebf

Please sign in to comment.