From e22df631c4428f8dea4d5784a8a7840d2f84c6be Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 22 Aug 2022 23:41:49 +0000 Subject: Generate runtime debug info with source locations --- pkg/libs/rangemap/rangemap.go | 67 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 5 deletions(-) (limited to 'pkg/libs/rangemap/rangemap.go') diff --git a/pkg/libs/rangemap/rangemap.go b/pkg/libs/rangemap/rangemap.go index 650deec..367483a 100644 --- a/pkg/libs/rangemap/rangemap.go +++ b/pkg/libs/rangemap/rangemap.go @@ -73,6 +73,54 @@ func (rm *RangeMap[D]) Set(from, to int, data D) { rm.ranges = newRanges } +func (rm *RangeMap[D]) Fill(from, to int, data D) { + if to < from { + return + } + + leftIndex := rm.entry(from) + rightIndex := rm.entry(to) + + for i := leftIndex; i <= rightIndex; i++ { + r := rm.ranges[i] + // Range is not inside fill zone or is already filled. + if r.from > to || (r.to < from && r.to != -1) || r.data != nil { + continue + } + + if r.from >= from && r.to <= to && r.to != -1 { + // The empty range is completely contained in the range to fill, overwrite it. + rm.ranges[i].data = &data + } else { + // The empty range is partially contained in the range to fill, split it. + rm.Set(max(r.from, from), min(r.to, to), data) + } + } +} + +func (rm *RangeMap[D]) AppendRanges(other RangeMap[D]) { + newRanges := make([]rangeEntry[D], 0, len(rm.ranges)+len(other.ranges)) + offset := rm.ranges[len(rm.ranges)-1].from + + // No need to copy the sentinel. + newRanges = append(newRanges, rm.ranges[:len(rm.ranges)-1]...) + + for _, otherEntry := range other.ranges { + to := otherEntry.to + offset + if otherEntry.to == -1 { + to = -1 // Sentinel not affected by offset. + } + + newRanges = append(newRanges, rangeEntry[D]{ + from: otherEntry.from + offset, + to: to, + data: otherEntry.data, + }) + } + + rm.ranges = newRanges +} + func (rm *RangeMap[D]) Get(i int) *D { return rm.ranges[rm.entry(i)].data } @@ -100,11 +148,6 @@ func (rm *RangeMap[D]) entry(i int) int { return 0 } - lastRange := rm.ranges[len(rm.ranges)-1] - if i >= lastRange.to && lastRange.to != -1 { - return len(rm.ranges) - 1 - } - left := 0 right := len(rm.ranges) - 1 for left <= right { @@ -127,3 +170,17 @@ type rangeEntry[D any] struct { to int data *D } + +func min(a, b int) int { + if a < b && a != -1 { + return a + } + return b +} + +func max(a, b int) int { + if a > b && b != -1 { + return a + } + return b +} -- cgit 1.4.1