|
| 1 | +let rec find_first_aux arr test low high = |
| 2 | + if low = high then high |
| 3 | + else ( |
| 4 | + let mid = (low + high) / 2 in |
| 5 | + let diff = test mid in |
| 6 | + if diff >= 0. then find_first_aux arr test low mid |
| 7 | + else find_first_aux arr test (mid + 1) high |
| 8 | + ) |
| 9 | + |
| 10 | +(* Binary search. Return the index of the first element where [test i] is true. |
| 11 | + If [test] isn't true for any element, returns the length of the array. |
| 12 | + Assumes that if [test i] then it's true for all later entries. *) |
| 13 | +let find_first ?(start = 0) arr test = |
| 14 | + find_first_aux arr test start (Array.length arr) |
| 15 | + |
1 | 16 | module type CANVAS = sig |
2 | 17 | type context |
3 | 18 |
|
@@ -217,12 +232,16 @@ module Make (C : CANVAS) = struct |
217 | 232 |
|
218 | 233 | let iter_gc_spans v fn ring = |
219 | 234 | let arr = ring.Layout.Ring.events in |
220 | | - (* todo: binary search *) |
221 | | - for i = 0 to Array.length arr - 1 do |
| 235 | + let time i = fst arr.(i) in |
| 236 | + let start = max 0 (find_first arr (fun i -> time i -. v.View.start_time) - 1) in |
| 237 | + let stop_time = View.time_of_x v v.width in |
| 238 | + let stop = find_first arr (fun i -> time i -. stop_time) ~start in |
| 239 | + for i = start to min stop (Array.length arr - 1) do |
222 | 240 | let time, e = arr.(i) in |
223 | 241 | fn (time, e) |
224 | 242 | done; |
225 | | - fn (v.View.layout.duration, []) |
| 243 | + if stop = Array.length arr then |
| 244 | + fn (v.View.layout.duration, []) |
226 | 245 |
|
227 | 246 | let render_gc_events v cr (ring : Layout.Ring.t) layer = |
228 | 247 | let y = y_of_row v ring.y in |
|
0 commit comments