mtsatellite/common/spans.go

90 lines
1.4 KiB
Go
Raw Normal View History

// Copyright 2014 by Sascha L. Teichmann
// Use of this source code is governed by the MIT license
// that can be found in the LICENSE file.
package common
const chunkSize = 1024
type Span struct {
Value int32
From int32
To int32
Next *Span
}
type SpanPool struct {
freeList *Span
}
func NewSpanPool() *SpanPool {
return &SpanPool{}
}
func (sp *SpanPool) Alloc() *Span {
if sp.freeList != nil {
next := sp.freeList
sp.freeList = next.Next
return next
}
spans := make([]Span, chunkSize)
for i := chunkSize - 1; i > 0; i-- {
spans[i].Next = sp.freeList
sp.freeList = &spans[i]
}
return &spans[0]
}
func (sp *SpanPool) Free(s *Span) {
if s != nil {
s.Next = sp.freeList
sp.freeList = s
}
}
func (sp *SpanPool) FreeAll(s *Span) {
if s == nil {
return
}
head, prev := s, s
for ; s != nil; s = s.Next {
prev = s
}
prev.Next = sp.freeList
sp.freeList = head
}
func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
if s == nil {
s = sp.Alloc()
s.From = pos
s.To = pos
s.Value = value
s.Next = nil
return s
}
if pos < s.From {
// Same value and directly neighbored -> extend head.
if value == s.Value && pos == s.From-1 {
s.From--
return s
}
// Disjunct -> create new.
prev := sp.Alloc()
prev.From = pos
prev.To = pos
prev.Value = value
prev.Next = s
return prev
}
// TODO: Implement the more complicated cases.
return nil
}