1 // Copyright (C) The Lightning Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
11 type interval struct {
16 type intervalTreeNode struct {
21 type intervalTree []intervalTreeNode
24 intervals map[string][]interval
25 itrees map[string]intervalTree
29 func (m *mask) Add(seqname string, start, end int) {
31 panic("bug: (*mask)Add() called after Freeze()")
33 if m.intervals == nil {
34 m.intervals = map[string][]interval{}
36 m.intervals[seqname] = append(m.intervals[seqname], interval{start, end})
39 func (m *mask) Freeze() {
40 m.itrees = map[string]intervalTree{}
41 for seqname, intervals := range m.intervals {
42 m.itrees[seqname] = m.freeze(intervals)
47 func (m *mask) Check(seqname string, start, end int) bool {
49 panic("bug: (*mask)Check() called before Freeze()")
51 return m.itrees[seqname].check(0, interval{start, end})
54 func (m *mask) Len() int {
59 for _, intervals := range m.intervals {
65 func (m *mask) freeze(in []interval) intervalTree {
69 sort.Slice(in, func(i, j int) bool {
70 return in[i].start < in[j].start
73 for itreesize < len(in) {
74 itreesize = itreesize * 2
76 itree := make(intervalTree, itreesize)
77 for i := 0; i < itreesize; i++ {
80 itree.importSlice(0, in)
84 func (itree intervalTree) check(root int, q interval) bool {
85 return root < len(itree) &&
86 itree[root].maxend >= q.start &&
87 ((itree[root].interval.start <= q.end && itree[root].interval.end >= q.start) ||
88 itree.check(root*2+1, q) ||
89 itree.check(root*2+2, q))
92 func (itree intervalTree) importSlice(root int, in []interval) int {
94 node := intervalTreeNode{interval: in[mid], maxend: in[mid].end}
96 end := itree.importSlice(root*2+1, in[0:mid])
97 if end > node.maxend {
102 end := itree.importSlice(root*2+2, in[mid+1:])
103 if end > node.maxend {