117 lines
2.3 KiB
Go
117 lines
2.3 KiB
Go
|
package srt
|
||
|
|
||
|
import (
|
||
|
"math"
|
||
|
"sort"
|
||
|
)
|
||
|
|
||
|
type Datum struct {
|
||
|
seq_num uint32
|
||
|
data []byte
|
||
|
next *Datum
|
||
|
}
|
||
|
|
||
|
type DatumLink struct {
|
||
|
queued int
|
||
|
root *Datum
|
||
|
end *Datum
|
||
|
}
|
||
|
|
||
|
type chains []*DatumLink
|
||
|
|
||
|
func (c chains) Len() (int) {
|
||
|
return len(c)
|
||
|
}
|
||
|
|
||
|
func (c chains) Swap(i, j int) {
|
||
|
c[i], c[j] = c[j], c[i]
|
||
|
}
|
||
|
|
||
|
func (c chains) Less(i, j int) (bool) {
|
||
|
x_1 := c[i].end.seq_num
|
||
|
x_2 := c[j].root.seq_num
|
||
|
serial_add_limit := uint32(math.Pow(2, 30))
|
||
|
if (x_1 < x_2 && x_2 - x_1 < serial_add_limit) || (x_1 > x_2 && x_1 - x_2 > serial_add_limit) {
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
type DatumStorage struct {
|
||
|
main *DatumLink
|
||
|
offshoots chains
|
||
|
}
|
||
|
|
||
|
func (buffer *DatumLink) NewDatum(pkt *Packet) {
|
||
|
datum := new(Datum)
|
||
|
datum.seq_num = pkt.header_info.(*DataHeader).seq_num
|
||
|
datum.data = pkt.cif.([]byte)
|
||
|
|
||
|
buffer.queued += 1
|
||
|
buffer.end.next = datum
|
||
|
buffer.end = datum
|
||
|
}
|
||
|
|
||
|
func NewDatumLink(pkt *Packet) (*DatumLink) {
|
||
|
buffer := new(DatumLink)
|
||
|
root_datum := new(Datum)
|
||
|
root_datum.seq_num = pkt.header_info.(*DataHeader).seq_num
|
||
|
root_datum.data = pkt.cif.([]byte)
|
||
|
|
||
|
buffer.root = root_datum
|
||
|
buffer.end = root_datum
|
||
|
buffer.queued = 1
|
||
|
return buffer
|
||
|
}
|
||
|
|
||
|
func NewDatumStorage(packet *Packet) (*DatumStorage) {
|
||
|
storage := new(DatumStorage)
|
||
|
storage.main = NewDatumLink(packet)
|
||
|
return storage
|
||
|
}
|
||
|
|
||
|
func (storage *DatumStorage) NewDatum(pkt *Packet) {
|
||
|
prev_num := (pkt.header_info.(*DataHeader).seq_num - 1) % uint32(math.Pow(2, 31))
|
||
|
if storage.main.end.seq_num == prev_num {
|
||
|
storage.main.NewDatum(pkt)
|
||
|
} else {
|
||
|
for _, v := range storage.offshoots {
|
||
|
if v.end.seq_num == prev_num {
|
||
|
v.NewDatum(pkt)
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (buffer *DatumLink) Link(buffer_next *DatumLink) {
|
||
|
buffer.end.next = buffer_next.root
|
||
|
buffer.end = buffer_next.end
|
||
|
buffer.queued += buffer_next.queued
|
||
|
}
|
||
|
|
||
|
func check_append_serial_next(buffer *DatumLink, buffer_next *DatumLink) (bool) {
|
||
|
seq_1 := buffer.end.seq_num
|
||
|
seq_2 := (seq_1 + 1) % uint32(math.Pow(2, 31))
|
||
|
if seq_1 == seq_2 {
|
||
|
buffer.Link(buffer_next)
|
||
|
return true
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func (storage *DatumStorage) Relink() {
|
||
|
sort.Sort(storage.offshoots)
|
||
|
buffer := storage.main
|
||
|
i := 0
|
||
|
for i < len(storage.offshoots) {
|
||
|
if check_append_serial_next(buffer, storage.offshoots[i]) {
|
||
|
storage.offshoots = append(storage.offshoots[:i], storage.offshoots[i + 1:]...)
|
||
|
} else {
|
||
|
buffer = storage.offshoots[i]
|
||
|
i++
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|