Module: Contrast::Agent::Assess::Property::Tagged
- Includes:
- Utils::Assess::TaggedUtils
- Included in:
- Contrast::Agent::Assess::Properties
- Defined in:
- lib/contrast/agent/assess/property/tagged.rb
Overview
This module serves to hold the functionality required for the management of our dataflow tags.
Instance Method Summary collapse
-
#delete_tags_at_ranges(ranges, shift: true) ⇒ Object
Remove all tags within the given ranges.
-
#remove_tags(range) ⇒ Object
Remove the tag ranges covering the given range and appends any trailing value that might exist after removal of range.
-
#shift_tags(ranges) ⇒ Object
Shift all the tags in this object by the given ranges.
- #shift_tags_comparison(comparison, add, tag, length, range) ⇒ Object
-
#shift_tags_for_deletion(range, shift) ⇒ Object
Shift the tag ranges covering the given range We assume this is for a deletion, meaning we have to move tags to the left.
-
#shift_tags_for_insertion(range) ⇒ Object
Shift the tag ranges covering the given range to account for new data being added.
-
#tags_remove_comparison(comparison, tag, remove, add, range) ⇒ Object
This method is for the tags comparison the idea is to move the whole case here.
-
#tracked? ⇒ Boolean
Is any tag present? Creating Tags is expensive and we check for Tags all the time on untracked things.
Methods included from Utils::Assess::TaggedUtils
#add_tag, #any_tags_between?, #cleanup_tags, #clear_tags, #delete_tags, #fetch_tag, #get_tags, #set_tags, #tag_keys, #tagged?, #tags_at, #tags_at_range
Instance Method Details
#delete_tags_at_ranges(ranges, shift: true) ⇒ Object
Remove all tags within the given ranges. This does not delete an entire tag if part of that tag is outside this range, meaning we may reduce sizes of tags or split them.
If shift is true, it is assumed the characters at those ranges were removed. If shift is false, it is assumed those ranges were replaced by the same number of characters and no shift is needed.
current tags: 0-15 range: 5-10 result: 0-5, 10-15
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 43 def ranges, shift: true return unless tracked? # Stage one - delete the tags w/o changing their # location. ranges.each do |range| (range) end return unless shift # the amount we've already removed from the string shift = 0 # Stage two - shift the tags to the left to account # for the sections that were deleted. ranges.each do |range| (range, shift) shift += (range.end - range.begin) end # Clean up and merge any touching tags Contrast::Utils::TagUtil.() end |
#remove_tags(range) ⇒ Object
Remove the tag ranges covering the given range and appends any trailing value that might exist after removal of range
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 84 def range return unless tracked? full_delete = [] .each_pair do |key, value| remove = [] add = [] value.each do |tag| comparison = tag.compare_range(range.begin, range.end) # ABOVE and BELOW are not affected by this check (comparison, tag, remove, add, range) end value.delete_if { |tag| remove.include?(tag) } Contrast::Utils::TagUtil.ordered_merge(value, add) full_delete << key if value.empty? end full_delete.each { |key| .delete(key) } end |
#shift_tags(ranges) ⇒ Object
Shift all the tags in this object by the given ranges. This method assumes the ranges are sorted, meaning the leftmost (lowest) range is first
current tags: 0-15 range: 5-10 result: 0-5, 10-20
73 74 75 76 77 78 79 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 73 def ranges return unless tracked? ranges.each do |range| (range) end end |
#shift_tags_comparison(comparison, add, tag, length, range) ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 175 def comparison, add, tag, length, range case comparison # part of the tag is being inserted on when Contrast::Agent::Assess::Tag::LOW_SPAN new_tag = tag.clone new_tag.update_start(range.begin) new_tag.shift(length) add << new_tag tag.update_end(range.begin) # the tag exists in the inserted range. it is partially shifted when Contrast::Agent::Assess::Tag::WITHIN tag.shift(length) # the tag spans the range. leave the part below alone when Contrast::Agent::Assess::Tag::WITHOUT # rubocop:disable Lint/DuplicateBranch new_tag = tag.clone new_tag.update_start(range.begin) new_tag.shift(length) add << new_tag tag.update_end(range.begin) when Contrast::Agent::Assess::Tag::HIGH_SPAN, Contrast::Agent::Assess::Tag::ABOVE # rubocop:disable Lint/DuplicateBranch tag.shift(length) end end |
#shift_tags_for_deletion(range, shift) ⇒ Object
Shift the tag ranges covering the given range We assume this is for a deletion, meaning we have to move tags to the left
132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 132 def range, shift return unless tracked? .each_value do |value| value.each do |tag| comparison = tag.compare_range(range.begin - shift, range.end - shift) # this is really the only thing we need to shift next unless comparison == Contrast::Agent::Assess::Tag::ABOVE length = range.end - range.begin tag.shift(0 - length) end end end |
#shift_tags_for_insertion(range) ⇒ Object
Shift the tag ranges covering the given range to account for new data being added. We assume this is for a insertion, meaning we have to move tags out of the range and to the right. For example, given current tags: 0-15 when we insert a range: 5-10 then the result is: 0-5, 10-20
Note that we disable Lint/DuplicateBranch in this branch in order list out all tag range cases in the proper order to make this easier to understand
160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 160 def range return unless tracked? .each_value do |value| add = [] value.each do |tag| comparison = tag.compare_range(range.begin, range.end) length = range.end - range.begin # BELOW is not affected by this check (comparison, add, tag, length, range) end Contrast::Utils::TagUtil.ordered_merge(value, add) end end |
#tags_remove_comparison(comparison, tag, remove, add, range) ⇒ Object
This method is for the tags comparison the idea is to move the whole case here
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 110 def comparison, tag, remove, add, range case comparison when Contrast::Agent::Assess::Tag::LOW_SPAN tag.update_end(range.begin) when Contrast::Agent::Assess::Tag::WITHIN remove << tag when Contrast::Agent::Assess::Tag::WITHOUT new_tag = tag.clone new_tag.update_start(range.end) add << new_tag tag.update_end(range.begin) when Contrast::Agent::Assess::Tag::HIGH_SPAN tag.update_start(range.end) end end |
#tracked? ⇒ Boolean
Is any tag present? Creating Tags is expensive and we check for Tags all the time on untracked things. ALWAYS!!! call this method before checking if an object has tags
23 24 25 |
# File 'lib/contrast/agent/assess/property/tagged.rb', line 23 def tracked? instance_variable_defined?(:@_tags) && .any? end |