// 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 }