interval_list.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package filer
  2. import (
  3. "math"
  4. "sync"
  5. )
  6. type IntervalValue interface {
  7. SetStartStop(start, stop int64)
  8. Clone() IntervalValue
  9. }
  10. type Interval[T IntervalValue] struct {
  11. StartOffset int64
  12. StopOffset int64
  13. TsNs int64
  14. Value T
  15. Prev *Interval[T]
  16. Next *Interval[T]
  17. }
  18. func (interval *Interval[T]) Size() int64 {
  19. return interval.StopOffset - interval.StartOffset
  20. }
  21. // IntervalList mark written intervals within one page chunk
  22. type IntervalList[T IntervalValue] struct {
  23. head *Interval[T]
  24. tail *Interval[T]
  25. Lock sync.RWMutex
  26. }
  27. func NewIntervalList[T IntervalValue]() *IntervalList[T] {
  28. list := &IntervalList[T]{
  29. head: &Interval[T]{
  30. StartOffset: -1,
  31. StopOffset: -1,
  32. },
  33. tail: &Interval[T]{
  34. StartOffset: math.MaxInt64,
  35. StopOffset: math.MaxInt64,
  36. },
  37. }
  38. return list
  39. }
  40. func (list *IntervalList[T]) Front() (interval *Interval[T]) {
  41. return list.head.Next
  42. }
  43. func (list *IntervalList[T]) AppendInterval(interval *Interval[T]) {
  44. list.Lock.Lock()
  45. defer list.Lock.Unlock()
  46. if list.head.Next == nil {
  47. list.head.Next = interval
  48. }
  49. interval.Prev = list.tail.Prev
  50. if list.tail.Prev != nil {
  51. list.tail.Prev.Next = interval
  52. }
  53. list.tail.Prev = interval
  54. }
  55. func (list *IntervalList[T]) Overlay(startOffset, stopOffset, tsNs int64, value T) {
  56. if startOffset >= stopOffset {
  57. return
  58. }
  59. interval := &Interval[T]{
  60. StartOffset: startOffset,
  61. StopOffset: stopOffset,
  62. TsNs: tsNs,
  63. Value: value,
  64. }
  65. list.Lock.Lock()
  66. defer list.Lock.Unlock()
  67. list.overlayInterval(interval)
  68. }
  69. func (list *IntervalList[T]) InsertInterval(startOffset, stopOffset, tsNs int64, value T) {
  70. interval := &Interval[T]{
  71. StartOffset: startOffset,
  72. StopOffset: stopOffset,
  73. TsNs: tsNs,
  74. Value: value,
  75. }
  76. list.Lock.Lock()
  77. defer list.Lock.Unlock()
  78. value.SetStartStop(startOffset, stopOffset)
  79. list.insertInterval(interval)
  80. }
  81. func (list *IntervalList[T]) insertInterval(interval *Interval[T]) {
  82. prev := list.head
  83. next := prev.Next
  84. for interval.StartOffset < interval.StopOffset {
  85. if next == nil {
  86. // add to the end
  87. list.insertBetween(prev, interval, list.tail)
  88. break
  89. }
  90. // interval is ahead of the next
  91. if interval.StopOffset <= next.StartOffset {
  92. list.insertBetween(prev, interval, next)
  93. break
  94. }
  95. // interval is after the next
  96. if next.StopOffset <= interval.StartOffset {
  97. prev = next
  98. next = next.Next
  99. continue
  100. }
  101. // intersecting next and interval
  102. if interval.TsNs >= next.TsNs {
  103. // interval is newer
  104. if next.StartOffset < interval.StartOffset {
  105. // left side of next is ahead of interval
  106. t := &Interval[T]{
  107. StartOffset: next.StartOffset,
  108. StopOffset: interval.StartOffset,
  109. TsNs: next.TsNs,
  110. Value: next.Value.Clone().(T),
  111. }
  112. t.Value.SetStartStop(t.StartOffset, t.StopOffset)
  113. list.insertBetween(prev, t, interval)
  114. next.StartOffset = interval.StartOffset
  115. next.Value.SetStartStop(next.StartOffset, next.StopOffset)
  116. prev = t
  117. }
  118. if interval.StopOffset < next.StopOffset {
  119. // right side of next is after interval
  120. next.StartOffset = interval.StopOffset
  121. next.Value.SetStartStop(next.StartOffset, next.StopOffset)
  122. list.insertBetween(prev, interval, next)
  123. break
  124. } else {
  125. // next is covered
  126. prev.Next = interval
  127. next = next.Next
  128. }
  129. } else {
  130. // next is newer
  131. if interval.StartOffset < next.StartOffset {
  132. // left side of interval is ahead of next
  133. t := &Interval[T]{
  134. StartOffset: interval.StartOffset,
  135. StopOffset: next.StartOffset,
  136. TsNs: interval.TsNs,
  137. Value: interval.Value.Clone().(T),
  138. }
  139. t.Value.SetStartStop(t.StartOffset, t.StopOffset)
  140. list.insertBetween(prev, t, next)
  141. interval.StartOffset = next.StartOffset
  142. interval.Value.SetStartStop(interval.StartOffset, interval.StopOffset)
  143. }
  144. if next.StopOffset < interval.StopOffset {
  145. // right side of interval is after next
  146. interval.StartOffset = next.StopOffset
  147. interval.Value.SetStartStop(interval.StartOffset, interval.StopOffset)
  148. } else {
  149. // interval is covered
  150. break
  151. }
  152. }
  153. }
  154. }
  155. func (list *IntervalList[T]) insertBetween(a, interval, b *Interval[T]) {
  156. a.Next = interval
  157. b.Prev = interval
  158. if a != list.head {
  159. interval.Prev = a
  160. }
  161. if b != list.tail {
  162. interval.Next = b
  163. }
  164. }
  165. func (list *IntervalList[T]) overlayInterval(interval *Interval[T]) {
  166. //t := list.head
  167. //for ; t.Next != nil; t = t.Next {
  168. // if t.TsNs > interval.TsNs {
  169. // println("writes is out of order", t.TsNs-interval.TsNs, "ns")
  170. // }
  171. //}
  172. p := list.head
  173. for ; p.Next != nil && p.Next.StopOffset <= interval.StartOffset; p = p.Next {
  174. }
  175. q := list.tail
  176. for ; q.Prev != nil && q.Prev.StartOffset >= interval.StopOffset; q = q.Prev {
  177. }
  178. // left side
  179. // interval after p.Next start
  180. if p.Next != nil && p.Next.StartOffset < interval.StartOffset {
  181. t := &Interval[T]{
  182. StartOffset: p.Next.StartOffset,
  183. StopOffset: interval.StartOffset,
  184. TsNs: p.Next.TsNs,
  185. Value: p.Next.Value,
  186. }
  187. p.Next = t
  188. if p != list.head {
  189. t.Prev = p
  190. }
  191. t.Next = interval
  192. interval.Prev = t
  193. } else {
  194. p.Next = interval
  195. if p != list.head {
  196. interval.Prev = p
  197. }
  198. }
  199. // right side
  200. // interval ends before p.Prev
  201. if q.Prev != nil && interval.StopOffset < q.Prev.StopOffset {
  202. t := &Interval[T]{
  203. StartOffset: interval.StopOffset,
  204. StopOffset: q.Prev.StopOffset,
  205. TsNs: q.Prev.TsNs,
  206. Value: q.Prev.Value,
  207. }
  208. q.Prev = t
  209. if q != list.tail {
  210. t.Next = q
  211. }
  212. interval.Next = t
  213. t.Prev = interval
  214. } else {
  215. q.Prev = interval
  216. if q != list.tail {
  217. interval.Next = q
  218. }
  219. }
  220. }
  221. func (list *IntervalList[T]) Len() int {
  222. list.Lock.RLock()
  223. defer list.Lock.RUnlock()
  224. var count int
  225. for t := list.head; t != nil; t = t.Next {
  226. count++
  227. }
  228. return count - 1
  229. }