1package sheet23// overlapping calls fn with each formula one of whose ranges shares a4// cell with r, as readers does for one cell; a formula may come more5// than once. It walks r's columns or the indexed ones, whichever are6// fewer.7func (x *rangeIndex) overlapping(r Rect, fn func(Addr)) {8 if r.From == r.To {9 x.readers(r.From, fn)10 return11 }12 if r.To.Col-r.From.Col < len(x.byCol) {13 for c := r.From.Col; c <= r.To.Col; c++ {14 if iv := x.byCol[c]; iv != nil {15 iv.overlap(r, fn)16 }17 }18 } else {19 for c, iv := range x.byCol {20 if c >= r.From.Col && c <= r.To.Col {21 iv.overlap(r, fn)22 }23 }24 }25 x.wide.overlap(r, fn)26}2728// overlap calls fn with the users of every range sharing a cell with r.29func (iv *intervals) overlap(r Rect, fn func(Addr)) {30 if len(iv.users) == 0 {31 return32 }33 if iv.sorted == nil {34 iv.build()35 }36 iv.queryRect(0, len(iv.sorted), r, fn)37}3839// queryRect is query for the rows of r rather than one row.40func (iv *intervals) queryRect(lo, hi int, r Rect, fn func(Addr)) {41 for lo < hi {42 mid := (lo + hi) / 243 if iv.maxEnd[mid] < r.From.Row {44 return // nothing below reaches r's rows45 }46 iv.queryRect(lo, mid, r, fn)47 g := iv.sorted[mid]48 if g.From.Row > r.To.Row {49 return // this and everything after start below r50 }51 if _, over := intersectRect(g, r); over {52 for u := range iv.users[g] {53 fn(u)54 }55 }56 lo = mid + 157 }58}