mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-12-24 01:00:18 +01:00
Complete code of insert into span buffer. Looks complicated and needs testing.
This commit is contained in:
parent
d880983abc
commit
a82d20f14b
105
common/spans.go
105
common/spans.go
@ -59,6 +59,7 @@ func (sp *SpanPool) FreeAll(s *Span) {
|
|||||||
|
|
||||||
func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
|
func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
|
||||||
|
|
||||||
|
// No head -> create.
|
||||||
if s == nil {
|
if s == nil {
|
||||||
s = sp.Alloc()
|
s = sp.Alloc()
|
||||||
s.From = pos
|
s.From = pos
|
||||||
@ -71,10 +72,10 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
|
|||||||
if pos < s.From {
|
if pos < s.From {
|
||||||
// Same value and directly neighbored -> extend head.
|
// Same value and directly neighbored -> extend head.
|
||||||
if value == s.Value && pos == s.From-1 {
|
if value == s.Value && pos == s.From-1 {
|
||||||
s.From--
|
s.From = pos
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
// Disjunct -> create new.
|
// Disjunct -> create new head.
|
||||||
prev := sp.Alloc()
|
prev := sp.Alloc()
|
||||||
prev.From = pos
|
prev.From = pos
|
||||||
prev.To = pos
|
prev.To = pos
|
||||||
@ -83,7 +84,103 @@ func (sp *SpanPool) Insert(s *Span, pos, value int32) *Span {
|
|||||||
return prev
|
return prev
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement the more complicated cases.
|
head := s
|
||||||
|
for prev := s; s != nil; s = s.Next {
|
||||||
|
switch {
|
||||||
|
case pos < s.From: // before span
|
||||||
|
if pos == s.From-1 && value == s.Value { // directly neighbored
|
||||||
|
s.From = pos
|
||||||
|
// Check if a gap has to be closed.
|
||||||
|
if prev.To == s.From-1 && value == prev.Value {
|
||||||
|
prev.To = s.To
|
||||||
|
prev.Next = s.Next
|
||||||
|
sp.Free(s)
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Extend prev?
|
||||||
|
if prev.To == pos-1 && value == prev.Value {
|
||||||
|
prev.To = pos
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
// New between prev and current.
|
||||||
|
sn := sp.Alloc()
|
||||||
|
sn.From = pos
|
||||||
|
sn.To = pos
|
||||||
|
sn.Value = value
|
||||||
|
sn.Next = s
|
||||||
|
prev.Next = sn
|
||||||
|
return head
|
||||||
|
|
||||||
return nil
|
case pos > s.To: // after span
|
||||||
|
if pos == s.To+1 && value == s.Value { // directly neighbored
|
||||||
|
s.To = pos
|
||||||
|
// Check if a gap has to be closed
|
||||||
|
next := s.Next
|
||||||
|
if next != nil {
|
||||||
|
if next.From == s.To-1 && value == next.Value {
|
||||||
|
s.To = next.To
|
||||||
|
s.Next = next.Next
|
||||||
|
sp.Free(next)
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
// Extend next?
|
||||||
|
if pos == next.From-1 && value == next.Value {
|
||||||
|
next.From = pos
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
// Before next -> New between current and next
|
||||||
|
if pos < next.From {
|
||||||
|
sn := sp.Alloc()
|
||||||
|
sn.From = pos
|
||||||
|
sn.To = pos
|
||||||
|
sn.Value = value
|
||||||
|
sn.Next = next
|
||||||
|
s.Next = sn
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
} else { // No next -> new at tail
|
||||||
|
sn := sp.Alloc()
|
||||||
|
sn.From = pos
|
||||||
|
sn.To = pos
|
||||||
|
sn.Value = value
|
||||||
|
sn.Next = nil
|
||||||
|
s.Next = sn
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
} else { // Not directly connected and/or values do not match.
|
||||||
|
next := s.Next
|
||||||
|
if next != nil {
|
||||||
|
if pos == next.From-1 && value == next.Value {
|
||||||
|
next.From = pos
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
// Before next -> New between current and next
|
||||||
|
if pos < next.From {
|
||||||
|
sn := sp.Alloc()
|
||||||
|
sn.From = pos
|
||||||
|
sn.To = pos
|
||||||
|
sn.Value = value
|
||||||
|
sn.Next = next
|
||||||
|
s.Next = sn
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
} else { // No next -> new at tail
|
||||||
|
sn := sp.Alloc()
|
||||||
|
sn.From = pos
|
||||||
|
sn.To = pos
|
||||||
|
sn.Value = value
|
||||||
|
sn.Next = nil
|
||||||
|
s.Next = sn
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default: // pos in span -> do not modify.
|
||||||
|
return head
|
||||||
|
}
|
||||||
|
prev = s
|
||||||
|
}
|
||||||
|
|
||||||
|
return head
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user