190 lines
4.2 KiB
Go
190 lines
4.2 KiB
Go
package binary
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/omniscale/imposm3/element"
|
|
)
|
|
|
|
func MarshalIdRefsBunch(idRefs []element.IdRefs) []byte {
|
|
buf := make([]byte, len(idRefs)*(4+1+6)+binary.MaxVarintLen64)
|
|
|
|
lastRef := int64(0)
|
|
lastId := int64(0)
|
|
nextPos := 0
|
|
|
|
nextPos += binary.PutUvarint(buf[nextPos:], uint64(len(idRefs)))
|
|
|
|
for _, idRef := range idRefs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, len(buf)*2)
|
|
copy(tmp, buf)
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutVarint(buf[nextPos:], idRef.Id-lastId)
|
|
lastId = idRef.Id
|
|
}
|
|
for _, idRef := range idRefs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, len(buf)*2)
|
|
copy(tmp, buf)
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutUvarint(buf[nextPos:], uint64(len(idRef.Refs)))
|
|
}
|
|
for _, idRef := range idRefs {
|
|
for _, ref := range idRef.Refs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, len(buf)*2)
|
|
copy(tmp, buf)
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutVarint(buf[nextPos:], ref-lastRef)
|
|
lastRef = ref
|
|
}
|
|
}
|
|
return buf[:nextPos]
|
|
}
|
|
|
|
func MarshalIdRefsBunch2(idRefs []element.IdRefs, buf []byte) []byte {
|
|
lastRef := int64(0)
|
|
lastId := int64(0)
|
|
nextPos := 0
|
|
|
|
estSize := len(idRefs)*(4+1+6) + binary.MaxVarintLen64
|
|
if cap(buf) < estSize {
|
|
buf = make([]byte, estSize)
|
|
} else {
|
|
// expand to full capacity
|
|
buf = buf[:cap(buf)]
|
|
}
|
|
|
|
nextPos += binary.PutUvarint(buf[nextPos:], uint64(len(idRefs)))
|
|
|
|
for _, idRef := range idRefs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, cap(buf)*2)
|
|
copy(tmp, buf[:nextPos])
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutVarint(buf[nextPos:], idRef.Id-lastId)
|
|
lastId = idRef.Id
|
|
}
|
|
for _, idRef := range idRefs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, cap(buf)*2)
|
|
copy(tmp, buf[:nextPos])
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutUvarint(buf[nextPos:], uint64(len(idRef.Refs)))
|
|
}
|
|
for _, idRef := range idRefs {
|
|
for _, ref := range idRef.Refs {
|
|
if len(buf)-nextPos < binary.MaxVarintLen64 {
|
|
tmp := make([]byte, cap(buf)*2)
|
|
copy(tmp, buf[:nextPos])
|
|
buf = tmp
|
|
}
|
|
nextPos += binary.PutVarint(buf[nextPos:], ref-lastRef)
|
|
lastRef = ref
|
|
}
|
|
}
|
|
return buf[:nextPos]
|
|
}
|
|
|
|
func UnmarshalIdRefsBunch(buf []byte) []element.IdRefs {
|
|
length, n := binary.Uvarint(buf)
|
|
if n <= 0 {
|
|
return nil
|
|
}
|
|
|
|
offset := n
|
|
|
|
idRefs := make([]element.IdRefs, length)
|
|
|
|
last := int64(0)
|
|
for i := 0; uint64(i) < length; i++ {
|
|
idRefs[i].Id, n = binary.Varint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
idRefs[i].Id += last
|
|
last = idRefs[i].Id
|
|
}
|
|
var numRefs uint64
|
|
for i := 0; uint64(i) < length; i++ {
|
|
numRefs, n = binary.Uvarint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
idRefs[i].Refs = make([]int64, numRefs)
|
|
}
|
|
last = 0
|
|
for idIdx := 0; uint64(idIdx) < length; idIdx++ {
|
|
for refIdx := 0; refIdx < len(idRefs[idIdx].Refs); refIdx++ {
|
|
idRefs[idIdx].Refs[refIdx], n = binary.Varint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
idRefs[idIdx].Refs[refIdx] += last
|
|
last = idRefs[idIdx].Refs[refIdx]
|
|
}
|
|
}
|
|
return idRefs
|
|
}
|
|
|
|
func UnmarshalIdRefsBunch2(buf []byte, idRefs []element.IdRefs) []element.IdRefs {
|
|
length, n := binary.Uvarint(buf)
|
|
if n <= 0 {
|
|
return nil
|
|
}
|
|
|
|
offset := n
|
|
|
|
if uint64(cap(idRefs)) < length {
|
|
idRefs = make([]element.IdRefs, length)
|
|
} else {
|
|
idRefs = idRefs[:length]
|
|
}
|
|
|
|
last := int64(0)
|
|
for i := 0; uint64(i) < length; i++ {
|
|
idRefs[i].Id, n = binary.Varint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
idRefs[i].Id += last
|
|
last = idRefs[i].Id
|
|
}
|
|
var numRefs uint64
|
|
for i := 0; uint64(i) < length; i++ {
|
|
numRefs, n = binary.Uvarint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
if uint64(cap(idRefs[i].Refs)) < numRefs {
|
|
idRefs[i].Refs = make([]int64, numRefs)
|
|
} else {
|
|
idRefs[i].Refs = idRefs[i].Refs[:numRefs]
|
|
}
|
|
}
|
|
last = 0
|
|
for idIdx := 0; uint64(idIdx) < length; idIdx++ {
|
|
for refIdx := 0; refIdx < len(idRefs[idIdx].Refs); refIdx++ {
|
|
idRefs[idIdx].Refs[refIdx], n = binary.Varint(buf[offset:])
|
|
if n <= 0 {
|
|
panic("no data")
|
|
}
|
|
offset += n
|
|
idRefs[idIdx].Refs[refIdx] += last
|
|
last = idRefs[idIdx].Refs[refIdx]
|
|
}
|
|
}
|
|
return idRefs
|
|
}
|