123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package page_writer
- import (
- "math"
- )
- // ChunkWrittenInterval mark one written interval within one page chunk
- type ChunkWrittenInterval struct {
- StartOffset int64
- stopOffset int64
- TsNs int64
- prev *ChunkWrittenInterval
- next *ChunkWrittenInterval
- }
- func (interval *ChunkWrittenInterval) Size() int64 {
- return interval.stopOffset - interval.StartOffset
- }
- func (interval *ChunkWrittenInterval) isComplete(chunkSize int64) bool {
- return interval.stopOffset-interval.StartOffset == chunkSize
- }
- // ChunkWrittenIntervalList mark written intervals within one page chunk
- type ChunkWrittenIntervalList struct {
- head *ChunkWrittenInterval
- tail *ChunkWrittenInterval
- }
- func newChunkWrittenIntervalList() *ChunkWrittenIntervalList {
- list := &ChunkWrittenIntervalList{
- head: &ChunkWrittenInterval{
- StartOffset: -1,
- stopOffset: -1,
- },
- tail: &ChunkWrittenInterval{
- StartOffset: math.MaxInt64,
- stopOffset: math.MaxInt64,
- },
- }
- list.head.next = list.tail
- list.tail.prev = list.head
- return list
- }
- func (list *ChunkWrittenIntervalList) MarkWritten(startOffset, stopOffset, tsNs int64) {
- if startOffset >= stopOffset {
- return
- }
- interval := &ChunkWrittenInterval{
- StartOffset: startOffset,
- stopOffset: stopOffset,
- TsNs: tsNs,
- }
- list.addInterval(interval)
- }
- func (list *ChunkWrittenIntervalList) IsComplete(chunkSize int64) bool {
- return list.size() == 1 && list.head.next.isComplete(chunkSize)
- }
- func (list *ChunkWrittenIntervalList) WrittenSize() (writtenByteCount int64) {
- for t := list.head; t != nil; t = t.next {
- writtenByteCount += t.Size()
- }
- return
- }
- func (list *ChunkWrittenIntervalList) addInterval(interval *ChunkWrittenInterval) {
- //t := list.head
- //for ; t.next != nil; t = t.next {
- // if t.TsNs > interval.TsNs {
- // println("writes is out of order", t.TsNs-interval.TsNs, "ns")
- // }
- //}
- p := list.head
- for ; p.next != nil && p.next.stopOffset <= interval.StartOffset; p = p.next {
- }
- q := list.tail
- for ; q.prev != nil && q.prev.StartOffset >= interval.stopOffset; q = q.prev {
- }
- // left side
- // interval after p.next start
- if p.next.StartOffset < interval.StartOffset {
- t := &ChunkWrittenInterval{
- StartOffset: p.next.StartOffset,
- stopOffset: interval.StartOffset,
- TsNs: p.next.TsNs,
- }
- p.next = t
- t.prev = p
- t.next = interval
- interval.prev = t
- } else {
- p.next = interval
- interval.prev = p
- }
- // right side
- // interval ends before p.prev
- if interval.stopOffset < q.prev.stopOffset {
- t := &ChunkWrittenInterval{
- StartOffset: interval.stopOffset,
- stopOffset: q.prev.stopOffset,
- TsNs: q.prev.TsNs,
- }
- q.prev = t
- t.next = q
- interval.next = t
- t.prev = interval
- } else {
- q.prev = interval
- interval.next = q
- }
- }
- func (list *ChunkWrittenIntervalList) size() int {
- var count int
- for t := list.head; t != nil; t = t.next {
- count++
- }
- return count - 2
- }
|