mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-16 15:20:20 +01:00
span buffers: Simplified code by throwing away cases that cannot happen. Extended unit tests with more pattern to check.
This commit is contained in:
parent
269e63ea59
commit
4f49d114c6
|
@ -90,65 +90,33 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
|
||||||
}
|
}
|
||||||
|
|
||||||
head := s
|
head := s
|
||||||
for prev := s; s != nil; s = s.Next {
|
for ; s != nil && pos > s.To; s = s.Next {
|
||||||
switch {
|
next := s.Next
|
||||||
case pos < s.From: // before span
|
if pos == s.To+1 && value == s.Value { // directly neighbored
|
||||||
if pos == s.From-1 && value == s.Value { // directly neighbored
|
s.To = pos
|
||||||
s.From = pos
|
// Check if a gap has to be closed
|
||||||
// Check if a gap has to be closed.
|
if next != nil && next.From == s.To+1 && value == next.Value {
|
||||||
if prev.To == s.From-1 && value == prev.Value {
|
s.To = next.To
|
||||||
prev.To = s.To
|
s.Next = next.Next
|
||||||
prev.Next = s.Next
|
sp.Free(next)
|
||||||
sp.Free(s)
|
|
||||||
return head
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Extend prev?
|
return head
|
||||||
if prev.To == pos-1 && value == prev.Value {
|
}
|
||||||
prev.To = pos
|
// Extend next?
|
||||||
return head
|
if next != nil && pos == next.From-1 && value == next.Value {
|
||||||
}
|
next.From = pos
|
||||||
// New between prev and current.
|
return head
|
||||||
|
}
|
||||||
|
// Before next -> New between current and next
|
||||||
|
if next == nil || pos < next.From {
|
||||||
sn := sp.Alloc()
|
sn := sp.Alloc()
|
||||||
sn.From = pos
|
sn.From = pos
|
||||||
sn.To = pos
|
sn.To = pos
|
||||||
sn.Value = value
|
sn.Value = value
|
||||||
sn.Next = s
|
sn.Next = next
|
||||||
prev.Next = sn
|
s.Next = sn
|
||||||
return head
|
|
||||||
|
|
||||||
case pos > s.To: // after span
|
|
||||||
next := s.Next
|
|
||||||
if pos == s.To+1 && value == s.Value { // directly neighbored
|
|
||||||
s.To = pos
|
|
||||||
// Check if a gap has to be closed
|
|
||||||
if next != nil && next.From == s.To+1 && value == next.Value {
|
|
||||||
s.To = next.To
|
|
||||||
s.Next = next.Next
|
|
||||||
sp.Free(next)
|
|
||||||
}
|
|
||||||
return head
|
|
||||||
}
|
|
||||||
// Extend next?
|
|
||||||
if next != nil && pos == next.From-1 && value == next.Value {
|
|
||||||
next.From = pos
|
|
||||||
return head
|
|
||||||
}
|
|
||||||
// Before next -> New between current and next
|
|
||||||
if next == nil || pos < next.From {
|
|
||||||
sn := sp.Alloc()
|
|
||||||
sn.From = pos
|
|
||||||
sn.To = pos
|
|
||||||
sn.Value = value
|
|
||||||
sn.Next = next
|
|
||||||
s.Next = sn
|
|
||||||
return head
|
|
||||||
}
|
|
||||||
|
|
||||||
default: // pos in span -> do not modify.
|
|
||||||
return head
|
return head
|
||||||
}
|
}
|
||||||
prev = s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return head
|
return head
|
||||||
|
|
|
@ -9,26 +9,68 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSpans(t *testing.T) {
|
const spanItems = 3000
|
||||||
|
|
||||||
inp := make([]int32, 3000)
|
func TestSpans(t *testing.T) {
|
||||||
for i, n := 0, len(inp); i < n; i++ {
|
|
||||||
inp[i] = int32(i)
|
|
||||||
}
|
|
||||||
for i, n := 0, len(inp); i < n; i++ {
|
|
||||||
i1 := rand.Int31n(int32(n))
|
|
||||||
i2 := rand.Int31n(int32(n))
|
|
||||||
inp[i1], inp[i2] = inp[i2], inp[i1]
|
|
||||||
}
|
|
||||||
|
|
||||||
sp := NewSpanPool()
|
sp := NewSpanPool()
|
||||||
var s *Span
|
var s *Span
|
||||||
for i, n := 0, len(inp); i < n; i++ {
|
|
||||||
|
for i := 0; i < spanItems; i++ {
|
||||||
|
s = sp.Insert(s, int32(i), 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n := s.Len(); n != 1 {
|
||||||
|
t.Errorf("inc: Span length %d expected 1\n", n)
|
||||||
|
t.Errorf("spans: %s\n", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.FreeAll(s)
|
||||||
|
|
||||||
|
s = nil
|
||||||
|
for i := spanItems - 1; i >= 0; i-- {
|
||||||
|
s = sp.Insert(s, int32(i), 42)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n := s.Len(); n != 1 {
|
||||||
|
t.Errorf("dec: Span length %d expected 1\n", n)
|
||||||
|
t.Errorf("spans: %s\n", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.FreeAll(s)
|
||||||
|
|
||||||
|
s = nil
|
||||||
|
for i := 0; i < spanItems/2; i++ {
|
||||||
|
j := spanItems - 1 - i
|
||||||
|
s = sp.Insert(s, int32(i), 42)
|
||||||
|
s = sp.Insert(s, int32(j), 21)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n := s.Len(); n != 2 {
|
||||||
|
t.Errorf("two: Span length %d expected 2\n", n)
|
||||||
|
t.Errorf("spans: %s\n", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.FreeAll(s)
|
||||||
|
|
||||||
|
inp := make([]int32, spanItems)
|
||||||
|
for i := 0; i < spanItems; i++ {
|
||||||
|
inp[i] = int32(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < spanItems; i++ {
|
||||||
|
i1 := rand.Int31n(int32(spanItems))
|
||||||
|
i2 := rand.Int31n(int32(spanItems))
|
||||||
|
inp[i1], inp[i2] = inp[i2], inp[i1]
|
||||||
|
}
|
||||||
|
|
||||||
|
s = nil
|
||||||
|
for i := 0; i < spanItems; i++ {
|
||||||
s = sp.Insert(s, inp[i], 42)
|
s = sp.Insert(s, inp[i], 42)
|
||||||
}
|
}
|
||||||
|
|
||||||
if n := s.Len(); n != 1 {
|
if n := s.Len(); n != 1 {
|
||||||
t.Errorf("Span length %d expected 1\n", n)
|
t.Errorf("rand: Span length %d expected 1\n", n)
|
||||||
t.Errorf("spans: %s\n", s)
|
t.Errorf("spans: %s\n", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user