Skip to content

Commit fcdb6c9

Browse files
committed
Improve #filter_out_boxes_fully_contained_in_others
`sorted_boxes` was first sorted, then used in an `#any?` check. In worst-case time complexity, this is just as (in)efficient as checking against the unsorted boxes. We can do better by sorting boxes by beginning ascending and ending descending. Algorithm explanation in comments.
1 parent 8afaade commit fcdb6c9

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

lib/super_diff/core/tiered_lines_elider.rb

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,22 @@ def box_groups_at_decreasing_indentation_levels_within(pane)
153153
end
154154

155155
def filter_out_boxes_fully_contained_in_others(boxes)
156-
sorted_boxes =
157-
boxes.sort_by do |box|
158-
[box.indentation_level, box.range.begin, box.range.end]
159-
end
160-
161-
boxes.reject do |box2|
162-
sorted_boxes.any? do |box1|
163-
!box1.equal?(box2) && box1.fully_contains?(box2)
164-
end
156+
# First, sorts boxes by beginning ascending, range descending. (Boxes may
157+
# never share beginnings, so the latter may be useless, but this is at least
158+
# sufficient if unnecessary.)
159+
#
160+
# Then, iterate through each box, keeping track of the farthest "end" of any
161+
# box seen so far. If the current box we are on ends before (or on) that farthest
162+
# end, we know there is some box earlier in the sequence that begins <= this one
163+
# (because of the prior sorting), and ends >= this one; that is, the current box
164+
# is fully contained, and we can filter it out.
165+
sorted = boxes.sort_by { |box| [box.range.begin, -box.range.end] }
166+
max_end = -1
167+
168+
sorted.reject do |box|
169+
contained = box.range.end <= max_end
170+
max_end = box.range.end if box.range.end > max_end
171+
contained
165172
end
166173
end
167174

0 commit comments

Comments
 (0)