This commit is contained in:
2026-06-09 08:16:16 +03:00
parent 964fe4b4a8
commit 7007b1b6fd
18 changed files with 1334 additions and 1026 deletions

View File

@@ -1,6 +1,7 @@
package enc
import (
"io"
"log"
"math"
@@ -47,32 +48,32 @@ type CumulativeDeltaCompressor struct {
}
// Після відновлення із снапшота
func NewCumulativeDeltaCompressor(buf []byte, payloadSize int, fracDigits byte) *CumulativeDeltaCompressor {
func NewCumulativeDeltaCompressor(buf []byte, fracDigits byte) *CumulativeDeltaCompressor {
var coef float64 = 1
if fracDigits > 0 {
coef = math.Pow(10, float64(fracDigits))
}
s := &CumulativeDeltaCompressor{
return &CumulativeDeltaCompressor{
buf: buf,
pos: payloadSize, // перший вільний байт
coef: coef,
}
}
func (s *CumulativeDeltaCompressor) RestoreState(payloadSize int) {
if payloadSize > 0 {
u64, _, err := bin.GetVarUint64(buf)
s.pos = payloadSize - 1 // завжди показує на h
// base value на початку
u64, _, err := bin.GetVarUint64(s.buf)
if err != nil {
log.Fatalf("bug: get base value: %s", err)
}
s.baseValue = float64(u64) / s.coef
s.pos--
s.h = s.buf[s.pos]
var n int
s.lastDelta, n, err = bin.ReverseGetVarUint64(s.buf[:s.pos])
s.lastDelta, _, err = bin.ReverseGetVarUint64(s.buf[:s.pos-1])
if err != nil {
log.Fatalf("bug: get last delta: %s", err)
}
s.pos -= n
}
return s
}
// func (s *CumulativeDeltaCompressor) Size() int {
@@ -80,83 +81,73 @@ func NewCumulativeDeltaCompressor(buf []byte, payloadSize int, fracDigits byte)
// }
func (s *CumulativeDeltaCompressor) Evaluate(value float64) (compressionWay int, requiredSpace int) {
var (
delta = uint64((value-s.baseValue)*s.coef + eps)
)
delta := uint64((value-s.baseValue)*s.coef + eps) // fix - if delta 0, no eps
requiredSpace = s.pos
// fix - requiredSpace - all space
if s.pos > 0 {
if s.h < 128 {
// run
if delta == s.lastDelta && s.h < 127 {
compressionWay = incrementRun
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // current delta
hSize
} else {
compressionWay = endSeries
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
hSize + // h - end of run
bin.CountVarUint64(uint64(delta)) + // new literal
hSize // new h
requiredSpace += bin.CountVarUint64(uint64(delta)) + hSize
}
} else {
// literal
if delta != s.lastDelta {
if s.h < 255 {
compressionWay = incrementLiteral
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
bin.CountVarUint64(uint64(delta)) + // new delta
hSize
requiredSpace += bin.CountVarUint64(uint64(delta))
} else {
compressionWay = endSeries
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
hSize + // h - end of literal
bin.CountVarUint64(uint64(delta)) + // new literal
hSize // new h
requiredSpace += bin.CountVarUint64(uint64(delta)) + hSize
}
} else {
compressionWay = startRun
if s.h > 128 {
requiredSpace += hSize // h - end of literal
requiredSpace += hSize // h - end of run
}
requiredSpace += bin.CountVarUint64(uint64(delta)) + // new delta
hSize // new h
}
}
} else {
// encode base value
compressionWay = addBaseValue
requiredSpace = bin.CountVarUint64(uint64(value*s.coef)) + // base value
bin.CountVarUint64(uint64(delta)) + // new delta
+hSize // new h
bin.CountVarUint64(0) + // new delta
hSize // new h
}
return
}
// pos завжди вказує на h
func (s *CumulativeDeltaCompressor) Compress(compressionWay int, value float64) {
delta := uint64((value-s.baseValue)*s.coef + eps)
switch compressionWay {
case incrementRun:
s.h++
case incrementLiteral:
// write previous delta and increment counter
n, _ := bin.ReversePutVarUint64(s.buf[s.pos:], uint64(s.lastDelta))
s.pos += n
s.lastDelta = delta
s.h++
case endSeries:
n, _ := bin.ReversePutVarUint64(s.buf[s.pos:], uint64(s.lastDelta))
// write previous delta and increment counter
n, _ := bin.ReversePutVarUint64(s.buf[s.pos:], delta)
s.pos += n
// write h - end of run
s.buf[s.pos] = s.h
s.pos++
// start new literal (length=1)
case endSeries:
s.lastDelta = delta
s.h = 128
n, _ := bin.ReversePutVarUint64(s.buf[s.pos:], delta)
s.pos += n
s.h = 128 // start new literal (length=1)
case startRun:
if s.h > 128 {
// write h - end of literal (because length > 1)
s.pos -= 1 + bin.CountVarUint64(s.lastDelta)
s.h--
s.buf[s.pos] = s.h
s.pos++
// run delta
n, _ := bin.ReversePutVarUint64(s.buf[s.pos:], delta)
s.pos += n
} else {
}
// start new run (length=2)
s.h = 0
@@ -165,10 +156,14 @@ func (s *CumulativeDeltaCompressor) Compress(compressionWay int, value float64)
n, _ := bin.PutVarUint64(s.buf[s.pos:], uint64(value*s.coef))
s.pos += n
s.baseValue = value
// start new literal (length=1)
s.lastDelta = 0
n, _ = bin.ReversePutVarUint64(s.buf[s.pos:], s.lastDelta)
s.pos += n
// start new literal (length=1)
s.h = 128
}
s.buf[s.pos] = s.h
}
func (s *CumulativeDeltaCompressor) DeleteLast() {
@@ -186,10 +181,11 @@ func (s *CumulativeDeltaCompressor) CaptureState() {
qb.Abort(qb.RepeatableLock, nil)
}
// позиція посувається вліво, отже може перескочити на попередній chunk
pos := s.pos - hSize - bin.CountVarUint64(s.lastDelta)
s.state = &CumulativeDeltaCapturedState{
H: s.h,
LastDelta: s.lastDelta,
Payload: s.buf[:s.pos],
Payload: s.buf[:pos],
}
}
@@ -205,31 +201,65 @@ func (s *CumulativeDeltaCompressor) Offset() int {
return 0
}
// Snapshot - для створення снапшота.
func (s *CumulativeDeltaCompressor) Snapshot() (left []byte, right []byte) {
func (s *CumulativeDeltaCompressor) Size() int {
if s.state == nil {
left = s.buf[:s.pos]
right = s.encodeTail(s.lastDelta, s.h)
return s.pos
} else {
left = s.state.Payload
right = s.encodeTail(s.state.LastDelta, s.state.H)
return len(s.state.Payload)
}
return
}
func (s *CumulativeDeltaCompressor) encodeTail(lastDelta uint64, h byte) []byte {
tail := make([]byte, 10) // max var uint64 + h
n, _ := bin.PutVarUint64(tail, lastDelta)
tail[n] = h
return tail[:n+1]
// Snapshot - для створення снапшота.
func (s *CumulativeDeltaCompressor) Payload() []byte {
if s.state == nil {
return s.buf[:s.pos]
} else {
return s.state.Payload
}
}
func (s *CumulativeDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
n, _ := bin.PutVarUint64(s.buf[s.pos:], s.lastDelta)
s.pos += n
s.buf[s.pos] = s.h
s.pos++
payloadSize = s.pos
func (s *CumulativeDeltaCompressor) WritePayloadTo(w io.Writer) (err error) {
if s.state == nil {
err = bin.WriteUint16(w, uint16(s.pos))
if err != nil {
return
}
_, err = w.Write(s.buf[:s.pos])
return
} else {
size := bin.CountVarUint64(s.state.LastDelta) + hSize + len(s.state.Payload)
err = bin.WriteUint16(w, uint16(size))
if err != nil {
return
}
_, err = w.Write(s.state.Payload)
if err != nil {
return
}
_, err = bin.WriteVarUint64(w, s.state.LastDelta)
if err != nil {
return
}
w.Write([]byte{
s.state.H,
})
return
}
}
// func (s *CumulativeDeltaCompressor) encodeTail(lastDelta uint64, h byte) []byte {
// tail := make([]byte, 10) // max var uint64 + h
// n, _ := bin.PutVarUint64(tail, lastDelta)
// tail[n] = h
// return tail[:n+1]
// }
func (s *CumulativeDeltaCompressor) Rotate(newbuf []byte) {
// n, _ := bin.PutVarUint64(s.buf[s.pos:], s.lastDelta)
// s.pos += n
// s.buf[s.pos] = s.h
// s.pos++
// payloadSize = s.pos
// УВАГА!
// state не чіпаємо
s.buf = newbuf
@@ -237,7 +267,14 @@ func (s *CumulativeDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
s.baseValue = 0
s.lastDelta = 0
s.h = 0
return
}
func (s *CumulativeDeltaCompressor) LastValue() float64 {
if s.state == nil {
return s.baseValue + float64(s.lastDelta)*s.coef
} else {
return s.baseValue + float64(s.state.LastDelta)*s.coef
}
}
func (s *CumulativeDeltaCompressor) CreateDecompressor() qb.ValueDecompressor {
@@ -259,10 +296,6 @@ func (s *CumulativeDeltaCompressor) CreateDecompressor() qb.ValueDecompressor {
})
}
func (s *CumulativeDeltaCompressor) Chunks() []byte {
return s.buf
}
// DECOMPRESSOR
type CumulativeDeltaDecompressor struct {

View File

@@ -165,11 +165,10 @@ func TestCumulativeDeltaCompressor(t *testing.T) {
var (
fracDigits byte = 1
buf = make([]byte, 8)
payloadSize = 0
compressionWay int
requiredSpace int
)
c := NewCumulativeDeltaCompressor(buf, payloadSize, fracDigits)
c := NewCumulativeDeltaCompressor(buf, fracDigits)
for _, num := range testCase.Nums {
compressionWay, requiredSpace = c.Evaluate(num)
c.Compress(compressionWay, num)
@@ -282,10 +281,9 @@ func TestCumulativeDeltaDecompressorFromState(t *testing.T) {
var (
fracDigits byte = 1
buf = make([]byte, 16)
payloadSize = 0
decodedNums []float64
)
c := NewCumulativeDeltaCompressor(buf, payloadSize, fracDigits)
c := NewCumulativeDeltaCompressor(buf, fracDigits)
for _, num := range testCase.Nums {
compressionWay, _ := c.Evaluate(num)
c.Compress(compressionWay, num)
@@ -526,11 +524,10 @@ func TestInstantDeltaCompressor(t *testing.T) {
var (
fracDigits byte = 1
buf = make([]byte, 8)
payloadSize = 0
compressionWay int
requiredSpace int
)
c := NewInstantDeltaCompressor(buf, payloadSize, fracDigits)
c := NewInstantDeltaCompressor(buf, fracDigits)
for _, num := range testCase.Nums {
compressionWay, requiredSpace = c.Evaluate(num)
c.Compress(compressionWay, num)
@@ -643,10 +640,9 @@ func TestInstantDeltaDecompressorFromState(t *testing.T) {
var (
fracDigits byte = 1
buf = make([]byte, 16)
payloadSize = 0
decodedNums []float64
)
c := NewInstantDeltaCompressor(buf, payloadSize, fracDigits)
c := NewInstantDeltaCompressor(buf, fracDigits)
for _, num := range testCase.Nums {
compressionWay, _ := c.Evaluate(num)
c.Compress(compressionWay, num)
@@ -847,7 +843,7 @@ func TestTimeDeltaCompressor(t *testing.T) {
compressionWay int
requiredSpace int
)
c := NewTimeDeltaCompressor(buf, 0)
c := NewTimeDeltaCompressor(buf)
for _, num := range testCase.Nums {
compressionWay, requiredSpace = c.Evaluate(num)
c.Compress(compressionWay, num)
@@ -963,7 +959,7 @@ func TestTimeDeltaDecompressorFromState(t *testing.T) {
buf = make([]byte, 16)
decodedNums []uint32
)
c := NewTimeDeltaCompressor(buf, 0)
c := NewTimeDeltaCompressor(buf)
for _, num := range testCase.Nums {
compressionWay, _ := c.Evaluate(num)
c.Compress(compressionWay, num)

View File

@@ -1,6 +1,7 @@
package enc
import (
"io"
"log"
"math"
@@ -18,32 +19,33 @@ type InstantDeltaCompressor struct {
state *InstantDeltaCapturedState
}
func NewInstantDeltaCompressor(buf []byte, payloadSize int, fracDigits byte) *InstantDeltaCompressor {
func NewInstantDeltaCompressor(buf []byte, fracDigits byte) *InstantDeltaCompressor {
var coef float64 = 1
if fracDigits > 0 {
coef = math.Pow(10, float64(fracDigits))
}
s := &InstantDeltaCompressor{
buf: buf,
pos: payloadSize,
coef: coef,
}
return s
}
func (s *InstantDeltaCompressor) RestoreState(payloadSize int) {
if payloadSize > 0 {
u64, _, err := bin.GetVarInt64(buf)
s.pos = payloadSize - 1 // завжди показує на h
// base value на початку
u64, _, err := bin.GetVarUint64(s.buf)
if err != nil {
log.Fatalf("bug: get base value: %s", err)
}
s.baseValue = float64(u64) / s.coef
s.pos--
s.h = s.buf[s.pos]
var n int
s.lastDelta, n, err = bin.ReverseGetVarInt64(s.buf[:s.pos])
s.lastDelta, _, err = bin.ReverseGetVarInt64(s.buf[:s.pos-1])
if err != nil {
log.Fatalf("bug: get last delta: %s", err)
}
s.pos -= n
}
return s
}
// func (s *InstantDeltaCompressor) Size() int {
@@ -184,31 +186,60 @@ func (s *InstantDeltaCompressor) Offset() int {
return 0
}
// Snapshot - для створення снапшота.
func (s *InstantDeltaCompressor) Snapshot() (left []byte, right []byte) {
func (s *InstantDeltaCompressor) Size() int {
if s.state == nil {
left = s.buf[:s.pos]
right = s.encodeTail(s.lastDelta, s.h)
return s.pos
} else {
left = s.state.Payload
right = s.encodeTail(s.state.LastDelta, s.state.H)
return len(s.state.Payload)
}
return
}
func (s *InstantDeltaCompressor) encodeTail(lastDelta int64, h byte) []byte {
tail := make([]byte, 10) // max var uint64 + h
n, _ := bin.PutVarInt64(tail, lastDelta)
tail[n] = h
return tail[:n+1]
// Snapshot - для створення снапшота.
func (s *InstantDeltaCompressor) Payload() []byte {
if s.state == nil {
return s.buf[:s.pos]
} else {
return s.state.Payload
}
}
func (s *InstantDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
n, _ := bin.PutVarInt64(s.buf[s.pos:], s.lastDelta)
s.pos += n
s.buf[s.pos] = s.h
s.pos++
payloadSize = s.pos
func (s *InstantDeltaCompressor) WritePayloadTo(w io.Writer) (err error) {
if s.state == nil {
err = bin.WriteUint16(w, uint16(s.pos))
if err != nil {
return
}
_, err = w.Write(s.buf[:s.pos])
return
} else {
size := bin.CountVarInt64(s.state.LastDelta) + hSize + len(s.state.Payload)
err = bin.WriteUint16(w, uint16(size))
if err != nil {
return
}
_, err = w.Write(s.state.Payload)
if err != nil {
return
}
_, err = bin.WriteVarInt64(w, s.state.LastDelta)
if err != nil {
return
}
w.Write([]byte{
s.state.H,
})
return
}
}
// func (s *InstantDeltaCompressor) encodeTail(lastDelta int64, h byte) []byte {
// tail := make([]byte, 10) // max var uint64 + h
// n, _ := bin.PutVarInt64(tail, lastDelta)
// tail[n] = h
// return tail[:n+1]
// }
func (s *InstantDeltaCompressor) Rotate(newbuf []byte) {
// УВАГА!
// state не чіпаємо
s.buf = newbuf
@@ -216,7 +247,14 @@ func (s *InstantDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
s.baseValue = 0
s.lastDelta = 0
s.h = 0
return
}
func (s *InstantDeltaCompressor) LastValue() float64 {
if s.state == nil {
return s.baseValue + float64(s.lastDelta)*s.coef
} else {
return s.baseValue + float64(s.state.LastDelta)*s.coef
}
}
func (s *InstantDeltaCompressor) CreateDecompressor() qb.ValueDecompressor {

View File

@@ -1,6 +1,7 @@
package enc
import (
"io"
"log"
bin "gordenko.dev/dima/bin/little"
@@ -27,125 +28,125 @@ type TimeDeltaCompressor struct {
state *TimeDeltaCapturedState
}
// Кодує значення справа наліво футнкціями TailPut*. Читає значення зліва направо функціями Get*
func NewTimeDeltaCompressor(buf []byte, payloadSize int) *TimeDeltaCompressor {
s := &TimeDeltaCompressor{
// Початкове створення, коли даних немає
// Створення після page filled, коли одразу є початкове значення
// Відновлення стану із снапшота. LastTimestamp передаю окермо від payload,
// а lastDelta і h треба прочитати із payload (якщо є)
// Кодує значення справа наліво функціями TailPut*. Читає значення зліва направо функціями Get*
func NewTimeDeltaCompressor(buf []byte) *TimeDeltaCompressor {
return &TimeDeltaCompressor{
buf: buf,
pos: len(buf) - payloadSize,
}
}
func (s *TimeDeltaCompressor) RestoreState(payloadSize int, lastTimestamp uint32) {
if payloadSize > 0 {
var err error
s.lastUnixtime, err = bin.GetUint32(s.buf[s.pos:])
if err != nil {
log.Fatalf("bug: get last unixtime: %s", err)
}
s.pos += 4
if s.pos < len(buf) {
s.lastUnixtime = lastTimestamp
s.pos = len(s.buf) - payloadSize
if payloadSize > 4 {
s.h = s.buf[s.pos]
s.pos++
u64, n, err := bin.GetVarUint64(s.buf[s.pos:])
u64, _, err := bin.GetVarUint64(s.buf[s.pos+1:])
if err != nil {
log.Fatalf("bug: get last delta: %s", err)
}
s.lastDelta = uint32(u64)
s.pos += n
}
}
return s
}
// func (s *TimeDeltaCompressor) Size() int {
// return len(s.buf) - s.pos
// }
// retrun
func (s *TimeDeltaCompressor) Evaluate(unixtime uint32) (compressionWay int, requiredSpace int) {
requiredSpace = 4 // last unixtime
if s.lastUnixtime > 0 {
requiredSpace = len(s.buf) - s.pos
if requiredSpace > 0 {
delta := unixtime - s.lastUnixtime
if s.lastDelta > 0 {
// 3rd value
if s.h < 128 {
// run
if delta == s.lastDelta && s.h < 127 {
compressionWay = incrementRun
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // current delta
hSize
} else {
compressionWay = endSeries
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
hSize + // h - end of run
bin.CountVarUint64(uint64(delta)) + // new literal
hSize // new h
requiredSpace += bin.CountVarUint64(uint64(delta)) + hSize
}
} else {
// literal
if delta != s.lastDelta {
if s.h < 255 {
compressionWay = incrementLiteral
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
bin.CountVarUint64(uint64(delta)) + // new delta
hSize
requiredSpace += bin.CountVarUint64(uint64(delta))
} else {
compressionWay = endSeries
requiredSpace += bin.CountVarUint64(uint64(s.lastDelta)) + // previous delta
hSize + // h - end of literal
bin.CountVarUint64(uint64(delta)) + // new literal
hSize // new h
requiredSpace += bin.CountVarUint64(uint64(delta)) + hSize
}
} else {
compressionWay = startRun
if s.h > 128 {
requiredSpace += hSize // h - end of literal
requiredSpace += hSize // h - end of run
}
requiredSpace += bin.CountVarUint64(uint64(delta)) + // new delta
hSize // new h
}
}
} else {
compressionWay = add1stDelta
requiredSpace += bin.CountVarUint64(uint64(delta)) + // new literal
hSize // new h
requiredSpace += bin.CountVarUint64(uint64(delta)) + hSize
}
} else {
compressionWay = addUnixtime
requiredSpace += 4
}
return
}
// pos вказує на h byte
func (s *TimeDeltaCompressor) Compress(compressionWay int, unixtime uint32) {
delta := unixtime - s.lastUnixtime
switch compressionWay {
case incrementRun:
s.h++
s.buf[s.pos] = s.h
case incrementLiteral:
// write previous delta and increment counter
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(s.lastDelta))
s.pos -= n
s.lastDelta = delta
s.h++
case endSeries:
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(s.lastDelta))
// тому що перезаписую h
s.pos++
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(delta))
s.pos -= n
// write h - end of run
s.pos--
s.buf[s.pos] = s.h
case endSeries:
// start new literal (length=1)
s.lastDelta = delta
s.h = 128
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(delta))
s.pos -= n
s.pos--
s.buf[s.pos] = s.h
case startRun:
if s.h > 128 {
// write h - end of literal (because length > 1)
s.h--
s.pos += bin.CountVarUint64(uint64(s.lastDelta)) // забираю останню дельту у literal
s.buf[s.pos] = s.h // write h - end of literal (because length > 1)
s.pos--
// run delta
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(delta))
s.pos -= n
// для h
s.pos--
s.buf[s.pos] = s.h
}
// start new run (length=2)
s.h = 0
s.buf[s.pos] = s.h
case add1stDelta:
// start new literal (length=1)
s.lastDelta = delta
s.h = 128
n, _ := bin.TailPutVarUint64(s.buf[:s.pos], uint64(delta))
s.pos -= n
s.pos--
s.buf[s.pos] = s.h
case addUnixtime:
s.pos -= 4
bin.PutUint32(s.buf[s.pos:], unixtime)
}
// 1st value or update after every update
// do not write immediatelly because of update after every update
@@ -184,6 +185,14 @@ func (s *TimeDeltaCompressor) ForgetCapturedState() {
s.state = nil
}
// коли сторінка заповнена і відправляється в txlog, since замінюю на until
func (s *TimeDeltaCompressor) ReplaceSinceWithUntil() uint32 {
pos := len(s.buf) - 4
since, _ := bin.GetUint32(s.buf[pos:])
bin.PutUint32(s.buf[pos:], s.lastUnixtime)
return since
}
// fix
func (s *TimeDeltaCompressor) Offset() int {
// if s.state != nil {
@@ -192,35 +201,64 @@ func (s *TimeDeltaCompressor) Offset() int {
return 0
}
// Snapshot - для створення снапшота.
func (s *TimeDeltaCompressor) Snapshot() (left []byte, right []byte) {
func (s *TimeDeltaCompressor) Size() int {
if s.state == nil {
left = s.encodeTail(s.lastUnixtime, s.lastDelta, s.h)
right = s.buf[s.pos:]
return len(s.buf) - s.pos
} else {
left = s.encodeTail(s.state.LastUnixtime, s.state.LastDelta, s.state.H)
right = s.state.Payload
return len(s.state.Payload)
}
return
}
func (s *TimeDeltaCompressor) encodeTail(lastUnixtime, lastDelta uint32, h byte) []byte {
tail := make([]byte, 9)
bin.PutUint32(tail, lastUnixtime)
tail[4] = h
n, _ := bin.PutVarUint64(tail[5:], uint64(lastDelta))
return tail[:n+5]
// Snapshot - для створення снапшота.
// FIX - encode firstUnixtime in 1st 4 bytes
//
// while page not completed - has first unixtime, after - last unixtime
func (s *TimeDeltaCompressor) Payload() []byte {
if s.state == nil {
return s.buf[s.pos:]
} else {
return s.state.Payload
}
}
func (s *TimeDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
var n int
n, _ = bin.TailPutVarUint64(s.buf[:s.pos], uint64(s.lastDelta))
s.pos -= n
s.pos--
s.buf[s.pos] = s.h
n, _ = bin.TailPutVarUint64(s.buf[:s.pos], uint64(s.lastUnixtime))
s.pos -= n
payloadSize = len(s.buf) - s.pos
func (s *TimeDeltaCompressor) WritePayloadTo(w io.Writer) (err error) {
if s.state == nil {
err = bin.WriteUint16(w, uint16(s.pos))
if err != nil {
return
}
_, err = w.Write(s.buf[:s.pos])
return
} else {
size := bin.CountVarUint64(uint64(s.state.LastDelta)) + hSize + len(s.state.Payload)
err = bin.WriteUint16(w, uint16(size))
if err != nil {
return
}
_, err = w.Write(s.state.Payload)
if err != nil {
return
}
_, err = bin.WriteVarUint64(w, uint64(s.state.LastDelta))
if err != nil {
return
}
w.Write([]byte{
s.state.H,
})
return
}
}
// func (s *TimeDeltaCompressor) encodeTail(lastUnixtime, lastDelta uint32, h byte) []byte {
// tail := make([]byte, 9)
// bin.PutUint32(tail, lastUnixtime)
// tail[4] = h
// n, _ := bin.PutVarUint64(tail[5:], uint64(lastDelta))
// return tail[:n+5]
// }
func (s *TimeDeltaCompressor) Rotate(newbuf []byte) {
// УВАГА!
// state не чіпаємо
s.buf = newbuf
@@ -228,7 +266,6 @@ func (s *TimeDeltaCompressor) Rotate(newbuf []byte) (payloadSize int) {
s.lastUnixtime = 0
s.lastDelta = 0
s.h = 0
return
}
func (s *TimeDeltaCompressor) CreateDecompressor() qb.TimestampDecompressor {
@@ -252,8 +289,8 @@ func (s *TimeDeltaCompressor) CreateDecompressor() qb.TimestampDecompressor {
})
}
func (s *TimeDeltaCompressor) Chunks() []byte {
return s.buf
func (s *TimeDeltaCompressor) LastTimestamp() uint32 {
return s.lastUnixtime
}
// DECOMPRESSOR