12 type intervalTreeNode struct {
17 type intervalTree []intervalTreeNode
20 intervals map[string][]interval
21 itrees map[string]intervalTree
25 func (m *mask) Add(seqname string, start, end int) {
26 if m.intervals == nil {
27 m.intervals = map[string][]interval{}
29 m.intervals[seqname] = append(m.intervals[seqname], interval{start, end})
32 func (m *mask) Freeze() {
33 m.itrees = map[string]intervalTree{}
34 for seqname, intervals := range m.intervals {
35 m.itrees[seqname] = m.freeze(intervals)
40 func (m *mask) Check(seqname string, start, end int) bool {
42 panic("bug: (*mask)Check() called before Freeze()")
44 return m.itrees[seqname].check(0, interval{start, end})
47 func (m *mask) freeze(in []interval) intervalTree {
51 sort.Slice(in, func(i, j int) bool {
52 return in[i].start < in[j].start
55 for itreesize < len(in) {
56 itreesize = itreesize * 2
58 itree := make(intervalTree, itreesize)
59 itree.importSlice(0, in)
60 for i := len(in); i < itreesize; i++ {
66 func (itree intervalTree) check(root int, q interval) bool {
67 return root < len(itree) &&
68 itree[root].maxend >= q.start &&
69 ((itree[root].interval.start <= q.end && itree[root].interval.end >= q.start) ||
70 itree.check(root*2+1, q) ||
71 itree.check(root*2+2, q))
74 func (itree intervalTree) importSlice(root int, in []interval) int {
76 node := intervalTreeNode{interval: in[mid], maxend: in[mid].end}
78 end := itree.importSlice(root*2+1, in[0:mid])
79 if end > node.maxend {
84 end := itree.importSlice(root*2+2, in[mid+1:])
85 if end > node.maxend {