From 0e019118c2515feef9f8373de26e7f134238551b Mon Sep 17 00:00:00 2001 From: Dima Gordenko <1.e4.kc6@gmail.com> Date: Sat, 6 Jun 2026 15:36:27 +0300 Subject: [PATCH] wp --- chunkenc/chunkenc_test.go | 12 +- chunkenc/cumdelta.go | 38 ++--- chunkenc/insdelta.go | 38 ++--- chunkenc/time_delta.go | 293 +++++++++++++++++++++------------ chunkenc2/chunckenc.go | 3 - chunkenc2/cumdelta.go | 330 ------------------------------------- chunkenc2/insdelta.go | 345 -------------------------------------- chunkenc2/time_delta_delta.go | 374 ------------------------------------------ go.sum | 2 - 9 files changed, 229 insertions(+), 1206 deletions(-) delete mode 100644 chunkenc2/chunckenc.go delete mode 100644 chunkenc2/cumdelta.go delete mode 100644 chunkenc2/insdelta.go delete mode 100644 chunkenc2/time_delta_delta.go diff --git a/chunkenc/chunkenc_test.go b/chunkenc/chunkenc_test.go index c2bdd44..de78d6d 100644 --- a/chunkenc/chunkenc_test.go +++ b/chunkenc/chunkenc_test.go @@ -144,7 +144,7 @@ func TestCumdeltaBound(t *testing.T) { c.Append(191) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) ////////////////////////// c.Lock() @@ -155,7 +155,7 @@ func TestCumdeltaBound(t *testing.T) { c.Append(305) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) d := NewReverseCumulativeDeltaDecompressor(buf, c.Size(), fracDigits) d.RestoreFromEnd() @@ -205,7 +205,7 @@ func TestInsdeltaBound(t *testing.T) { c.Append(191) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) ////////////////////////// //bound := c.GetState() @@ -216,7 +216,7 @@ func TestInsdeltaBound(t *testing.T) { c.Append(305) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) d := NewReverseInstantDeltaDecompressor(buf, c.Size(), fracDigits) d.RestoreFromEnd() @@ -265,7 +265,7 @@ func TestInsdeltaBound2(t *testing.T) { c.Append(130) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) ////////////////////////// //bound := c.GetState() @@ -276,7 +276,7 @@ func TestInsdeltaBound2(t *testing.T) { c.Append(10) fmt.Printf("pos: %d\n", c.pos) - fmt.Printf("%d\n", buf.Chunks()[0]) + fmt.Printf("%d\n", c.Chunks()) d := NewReverseInstantDeltaDecompressor(buf, c.Size(), fracDigits) d.RestoreFromEnd() diff --git a/chunkenc/cumdelta.go b/chunkenc/cumdelta.go index 0f8e8b9..7d517d3 100644 --- a/chunkenc/cumdelta.go +++ b/chunkenc/cumdelta.go @@ -7,7 +7,6 @@ import ( bin "gordenko.dev/dima/bin/little" "gordenko.dev/dima/qb" - "gordenko.dev/dima/qb/conbuf" ) // COMPRESSOR REVERSE @@ -209,25 +208,26 @@ func (s *ReverseCumulativeDeltaCompressor) Offset() int { } func (s *ReverseCumulativeDeltaCompressor) Snapshot() ([]byte, int) { - if s.state == nil { - return s.buf, s.Size() - } - // ВАЖЛИВО! - // Треба відтворити стан останнього чанка - var ( - pos = s.state.Pos - chunk = make([]byte, conbuf.ChunkSize) - lastChunkIdx = len(s.state.Chunks) - 1 - qtyToCopy = pos % conbuf.ChunkSize - ) - copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) - chunks := append(s.state.Chunks[:lastChunkIdx], chunk) + // if s.state == nil { + // return s.buf, s.Size() + // } + // // ВАЖЛИВО! + // // Треба відтворити стан останнього чанка + // var ( + // pos = s.state.Pos + // chunk = make([]byte, conbuf.ChunkSize) + // lastChunkIdx = len(s.state.Chunks) - 1 + // qtyToCopy = pos % conbuf.ChunkSize + // ) + // copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) + // chunks := append(s.state.Chunks[:lastChunkIdx], chunk) - buf := conbuf.New(chunks) - pos += buf.ReversePutVarUint64(pos, s.state.LastDelta) - buf.SetByte(pos, s.state.H) - pos++ - return chunks, pos + // buf := conbuf.New(chunks) + // pos += buf.ReversePutVarUint64(pos, s.state.LastDelta) + // buf.SetByte(pos, s.state.H) + // pos++ + // return chunks, pos + return nil, 0 } func (s *ReverseCumulativeDeltaCompressor) CreateDecompressor(fracDigits byte) qb.ValueDecompressor { diff --git a/chunkenc/insdelta.go b/chunkenc/insdelta.go index 459963b..1f24445 100644 --- a/chunkenc/insdelta.go +++ b/chunkenc/insdelta.go @@ -7,7 +7,6 @@ import ( "gordenko.dev/dima/qb" "gordenko.dev/dima/qb/bin" - "gordenko.dev/dima/qb/conbuf" ) type ReverseInstantDeltaCompressor struct { @@ -181,25 +180,26 @@ func (s *ReverseInstantDeltaCompressor) Offset() int { } func (s *ReverseInstantDeltaCompressor) Snapshot() ([]byte, int) { - if s.state == nil { - return s.buf, s.Size() - } - // ВАЖЛИВО! - // Треба відтворити стан останнього чанка - var ( - pos = s.state.Pos - chunk = make([]byte, conbuf.ChunkSize) - lastChunkIdx = len(s.state.Chunks) - 1 - qtyToCopy = pos % conbuf.ChunkSize - ) - copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) - chunks := append(s.state.Chunks[:lastChunkIdx], chunk) + // if s.state == nil { + // return s.buf, s.Size() + // } + // // ВАЖЛИВО! + // // Треба відтворити стан останнього чанка + // var ( + // pos = s.state.Pos + // chunk = make([]byte, conbuf.ChunkSize) + // lastChunkIdx = len(s.state.Chunks) - 1 + // qtyToCopy = pos % conbuf.ChunkSize + // ) + // copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) + // chunks := append(s.state.Chunks[:lastChunkIdx], chunk) - buf := conbuf.New(chunks) - pos += buf.ReversePutVarInt64(pos, s.state.LastDelta) - buf.SetByte(pos, s.state.H) - pos++ - return chunks, pos + // buf := conbuf.New(chunks) + // pos += buf.ReversePutVarInt64(pos, s.state.LastDelta) + // buf.SetByte(pos, s.state.H) + // pos++ + // return chunks, pos + return nil, 0 } func (s *ReverseInstantDeltaCompressor) CreateDecompressor(fracDigits byte) qb.ValueDecompressor { diff --git a/chunkenc/time_delta.go b/chunkenc/time_delta.go index 6350321..636644e 100644 --- a/chunkenc/time_delta.go +++ b/chunkenc/time_delta.go @@ -7,7 +7,6 @@ import ( bin "gordenko.dev/dima/bin/little" "gordenko.dev/dima/pretty" "gordenko.dev/dima/qb" - "gordenko.dev/dima/qb/conbuf" ) /* @@ -35,22 +34,22 @@ func NewReverseTimeDeltaCompressor(buf []byte, size int) *ReverseTimeDeltaCompre buf: buf, pos: size, // перший вільний байт } - if size > 0 { - u64, n, err := bin.ReverseGetVarUint64(s.buf[:s.pos-1]) - if err != nil { - log.Fatalf("bug: get last unixtime: %s", err) - } - s.lastUnixtime = uint32(u64) - s.pos -= n - if s.pos > 0 { - s.h = s.buf[s.pos-1] - u64, s.lastDeltaSize, err = bin.ReverseGetVarUint64(s.buf[:s.pos-2]) - if err != nil { - log.Fatalf("bug: get last delta: %s", err) - } - s.lastDelta = uint32(u64) - } - } + // if size > 0 { + // u64, n, err := bin.ReverseGetVarUint64(s.buf[:s.pos-1]) + // if err != nil { + // log.Fatalf("bug: get last unixtime: %s", err) + // } + // s.lastUnixtime = uint32(u64) + // s.pos -= n + // if s.pos > 0 { + // s.h = s.buf[s.pos-1] + // u64, s.lastDeltaSize, err = bin.ReverseGetVarUint64(s.buf[:s.pos-2]) + // if err != nil { + // log.Fatalf("bug: get last delta: %s", err) + // } + // s.lastDelta = uint32(u64) + // } + // } return s } @@ -58,99 +57,176 @@ func (s *ReverseTimeDeltaCompressor) Size() int { return s.pos } -func (s *ReverseTimeDeltaCompressor) CalcRequiredSpace(value uint32) int { - return 0 -} +const hSize = 1 -func (s *ReverseTimeDeltaCompressor) Append(unixtime uint32) { +// retrun +func (s *ReverseTimeDeltaCompressor) CalcRequiredSpace(unixtime uint32) (code int, size int) { if s.lastUnixtime > 0 { - // base value - //s.pos += s.buf.PutVarUint64(s.pos, uint64(value*s.coef)) - //s.baseValue = value - //s.appendNewLiteral(0) - - //} else { delta := unixtime - s.lastUnixtime - if delta == s.lastDelta { + if s.lastDelta > 0 { + // 3rd value if s.h < 128 { - // run блок - отже треба збільшити лічильник - if s.h < 127 { - // increase counter - s.h++ - s.buf[s.pos-1] = s.h + // run + if delta == s.lastDelta && s.h < 127 { + code = incementRun } else { - // не можу збільшити - буде переповнення. Додаю новий literal блок - // counter overflow - s.appendNewLiteral(delta) + code = endOfSeries } } else { - // literal блок. - // Якщо в ньому лише одне значення - перетворюю його на run блок. - // Інакше забираю останнє значення із literal блока і додаю новий run блок. - q := s.h & 127 - if q == 0 { // 1 кодується як 0 - s.convertLiteralToRun() + // literal + if delta != s.lastDelta { + if s.h < 255 { + code = incementLiteral + } else { + code = endOfSeries + } } else { - // забираю останнє значення із literal блоку щоб зробити run блок - s.convertLastFromLiteralToRun() + code = startRun } } } else { - if s.h < 127 { // fix 128? - // end of run - s.appendNewLiteral(delta) - } else { - if s.h < 255 { - // encode value from pos - 1, then append h byte - s.appendDeltaToLiteral(delta) - } else { - // overflowed - encode new - s.appendNewLiteral(delta) - } + code = add1stDelta + } + } else { + code = addUnixtime + } + + if code != addUnixtime { + size = hSize + if code != incementRun { + size += bin.CountVarUint64(uint64(unixtime)) + if code == endOfSeries { + size += hSize + } else if code == startRun && s.h > 128 { + // need end of literal series + size += hSize } } + } else { + size = 4 } + return +} + +const ( + addUnixtime = 0 + incementRun = 1 + incementLiteral = 2 + endOfSeries = 3 + startRun = 4 + add1stDelta = 5 +) + +func (s *ReverseTimeDeltaCompressor) Append(code int, unixtime uint32) { + delta := unixtime - s.lastUnixtime + switch code { + case incementRun: + s.h++ + case incementLiteral: + // // white s.lastDelta + //s.lastDelta = delta + s.h++ + case endOfSeries: + // write h - end of series + s.lastDelta = delta + s.h = 128 // new literal (length=1) + case startRun: + if s.h > 128 { // + // write h - end literal series if length > 1 + } + // last literal convert to run (length=2) + // write delta + s.h = 0 // run, length=2 + + case add1stDelta: + s.lastDelta = delta + } + // 1st value s.lastUnixtime = unixtime } -func (s *ReverseTimeDeltaCompressor) convertLastFromLiteralToRun() { - // Зменшую кількість елементів в literal блоці - s.h-- - s.pos -= 1 + s.lastDeltaSize - s.buf[s.pos] = s.h // закриваю literal блок - s.pos++ - s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(s.lastDelta)) - s.pos += s.lastDeltaSize - s.h = 0 // run блок, довжини 2 - s.buf[s.pos] = s.h - s.pos++ -} +// func (s *ReverseTimeDeltaCompressor) Append(unixtime uint32) { +// if s.lastUnixtime > 0 { +// delta := unixtime - s.lastUnixtime +// if s.lastDelta > 0 { +// // 3rd value +// if s.h < 128 { +// // run +// if delta == s.lastDelta && s.h < 127 { +// s.h++ +// } else { +// //write h - end of run +// s.lastDelta = delta +// s.h = 128 // new literal (length=1) +// } +// } else { +// // literal +// if delta == s.lastDelta { +// if s.h > 128 { // +// // write h - end literal series if length > 1 +// } +// // last literal convert to run (length=2) +// // write delta +// s.h = 0 // run, length=2 +// } else { +// // white s.lastDelta +// if s.h < 255 { +// //s.lastDelta = delta +// s.h++ +// } else { +// // write h - end of literal +// s.lastDelta = delta +// s.h = 128 // new literal (length=1) +// } +// } +// } +// } else { +// // 2nd value +// s.lastDelta = delta +// } +// } +// // 1st value +// s.lastUnixtime = unixtime +// } -func (s *ReverseTimeDeltaCompressor) convertLiteralToRun() { - // Знімаю flagLiteral, а лічильник 0 дорівнює 2 елементам в серії. - s.h = 0 - s.buf[s.pos-1] = s.h -} +// func (s *ReverseTimeDeltaCompressor) convertLastFromLiteralToRun() { +// // Зменшую кількість елементів в literal блоці +// s.h-- +// s.pos -= 1 + s.lastDeltaSize +// s.buf[s.pos] = s.h // закриваю literal блок +// s.pos++ +// s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(s.lastDelta)) +// s.pos += s.lastDeltaSize +// s.h = 0 // run блок, довжини 2 +// s.buf[s.pos] = s.h +// s.pos++ +// } -func (s *ReverseTimeDeltaCompressor) appendDeltaToLiteral(delta uint32) { - s.h++ // збільшую к-сть дельт - s.lastDelta = delta - s.pos-- - s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(delta)) - s.pos += s.lastDeltaSize - s.buf[s.pos] = s.h - s.pos++ -} +// func (s *ReverseTimeDeltaCompressor) convertLiteralToRun() { +// // Знімаю flagLiteral, а лічильник 0 дорівнює 2 елементам в серії. +// s.h = 0 +// s.buf[s.pos-1] = s.h +// } -func (s *ReverseTimeDeltaCompressor) appendNewLiteral(delta uint32) { - //fmt.Println("appendNewLiteral", delta) - s.h = flagLiteral - s.lastDelta = delta - s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(delta)) - s.pos += s.lastDeltaSize - s.buf[s.pos] = flagLiteral // literal, length = 1 - s.pos++ -} +// func (s *ReverseTimeDeltaCompressor) appendDeltaToLiteral(delta uint32) { +// s.h++ // збільшую к-сть дельт +// s.lastDelta = delta +// s.pos-- +// s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(delta)) +// s.pos += s.lastDeltaSize +// s.buf[s.pos] = s.h +// s.pos++ +// } + +// func (s *ReverseTimeDeltaCompressor) appendNewLiteral(delta uint32) { +// //fmt.Println("appendNewLiteral", delta) +// s.h = flagLiteral +// s.lastDelta = delta +// s.lastDeltaSize, _ = bin.ReversePutVarUint64(s.buf[s.pos:], uint64(delta)) +// s.pos += s.lastDeltaSize +// s.buf[s.pos] = flagLiteral // literal, length = 1 +// s.pos++ +// } func (s *ReverseTimeDeltaCompressor) DeleteLast() { @@ -214,25 +290,26 @@ func (s *ReverseTimeDeltaCompressor) Offset() int { // fix - func (s *ReverseTimeDeltaCompressor) Snapshot() ([]byte, int) { - if s.state == nil { - return s.buf, s.Size() - } - // ВАЖЛИВО! - // Треба відтворити стан останнього чанка - var ( - pos = s.state.Pos - chunk = make([]byte, conbuf.ChunkSize) - lastChunkIdx = len(s.state.Chunks) - 1 - qtyToCopy = pos % conbuf.ChunkSize - ) - copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) - chunks := append(s.state.Chunks[:lastChunkIdx], chunk) + // if s.state == nil { + // return s.buf, s.Size() + // } + // // ВАЖЛИВО! + // // Треба відтворити стан останнього чанка + // var ( + // pos = s.state.Pos + // chunk = make([]byte, conbuf.ChunkSize) + // lastChunkIdx = len(s.state.Chunks) - 1 + // qtyToCopy = pos % conbuf.ChunkSize + // ) + // copy(chunk, s.state.Chunks[lastChunkIdx][:qtyToCopy]) + // chunks := append(s.state.Chunks[:lastChunkIdx], chunk) - buf := conbuf.New(chunks) - pos += buf.ReversePutVarUint64(pos, uint64(s.state.LastDelta)) - buf.SetByte(pos, s.state.H) - pos++ - return chunks, pos + // buf := conbuf.New(chunks) + // pos += buf.ReversePutVarUint64(pos, uint64(s.state.LastDelta)) + // buf.SetByte(pos, s.state.H) + // pos++ + // return chunks, pos + return nil, 0 } func (s *ReverseTimeDeltaCompressor) CreateDecompressor() qb.TimestampDecompressor { diff --git a/chunkenc2/chunckenc.go b/chunkenc2/chunckenc.go deleted file mode 100644 index 53e145e..0000000 --- a/chunkenc2/chunckenc.go +++ /dev/null @@ -1,3 +0,0 @@ -package chunkenc2 - -const eps = 0.000001 diff --git a/chunkenc2/cumdelta.go b/chunkenc2/cumdelta.go deleted file mode 100644 index f865849..0000000 --- a/chunkenc2/cumdelta.go +++ /dev/null @@ -1,330 +0,0 @@ -package chunkenc2 - -import ( - "fmt" - "math" - - "gordenko.dev/dima/qb/bin" - "gordenko.dev/dima/qb/conbuf" -) - -// REVERSE - -type ReverseCumulativeDeltaCompressor struct { - buf *conbuf.ContinuousBuffer - coef float64 - pos int - firstValue float64 - lastDelta uint64 - length uint16 - numIdx int -} - -func NewReverseCumulativeDeltaCompressor(buf *conbuf.ContinuousBuffer, size int, fracDigits byte) *ReverseCumulativeDeltaCompressor { - var coef float64 = 1 - if fracDigits > 0 { - coef = math.Pow(10, float64(fracDigits)) - } - s := &ReverseCumulativeDeltaCompressor{ - buf: buf, - pos: size, - coef: coef, - } - if size > 0 { - s.restoreState() - } - return s -} - -func (s *ReverseCumulativeDeltaCompressor) restoreState() { - u64, n, err := s.buf.GetVarUint64(0) - if err != nil { - panic(fmt.Sprintf("bug: get first value: %s", err)) - } - s.firstValue = float64(u64) / s.coef - - if s.pos > n { - pos := s.pos - 1 - idxOf8 := uint(8 - s.buf.GetByte(pos)) - pos-- - s8 := s.buf.GetByte(pos) - pos-- - - var n int - s.lastDelta, n, err = s.buf.ReverseGetVarUint64(pos) - if err != nil { - panic(fmt.Sprintf("bug: get last delta: %s", err)) - } - pos -= n - s.numIdx = pos + 1 - - var flag byte = 1 << idxOf8 - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(pos) - } - } -} - -func (s *ReverseCumulativeDeltaCompressor) Size() int { - return s.pos -} - -func (s *ReverseCumulativeDeltaCompressor) CalcRequiredSpace(value float64) int { - if s.pos == 0 { - n := bin.CalcVarUint64Length(uint64(value * s.coef)) - return n + 3 - } - delta := uint64((value-s.firstValue)*s.coef + eps) - if delta == s.lastDelta { - if s.length == 0 { - return 1 - } else { - newLength := s.length + 1 - if newLength < 130 { - return 0 - } else if newLength == 130 { - return 1 - } else { - if newLength < 32769 { - return 0 - } else { - n := bin.CalcVarUint64Length(delta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } - } - } - } else { - n := bin.CalcVarUint64Length(delta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } -} - -func (s *ReverseCumulativeDeltaCompressor) Append(value float64) { - if s.pos == 0 { - n := s.buf.PutVarUint64(s.pos, uint64(value*s.coef)) - s.pos += n - s.firstValue = value - s.encodeNewDelta(0, 0, 1) - } else { - delta := uint64((value-s.firstValue)*s.coef + eps) - if delta == s.lastDelta { - if s.length == 0 { - s.length = 2 - s.shiftOnePosToRight() - s.buf.SetByte(s.numIdx-1, 0) - s8q := s.buf.GetByte(s.pos - 1) - s.buf.SetFlag(s.pos-2, 1<<(8-s8q)) - } else { - s.length++ - if s.length < 130 { - s.buf.SetByte(s.numIdx-1, byte(s.length-2)) - } else if s.length == 130 { - s.shiftOnePosToRight() - s.encode2bLength() - } else { - if s.length < 32769 { - s.encode2bLength() - } else { - s.appendNewDelta(delta) - } - } - } - } else { - s.appendNewDelta(delta) - } - } -} - -func (s *ReverseCumulativeDeltaCompressor) appendNewDelta(delta uint64) { - s.length = 0 - - s8 := s.buf.GetByte(s.pos - 2) - s8q := s.buf.GetByte(s.pos - 1) - - if s8q == 8 { - s.pos -= 1 - s8 = 0 - s8q = 1 - } else { - s.pos -= 2 - s8q++ - } - - s.encodeNewDelta(delta, s8, s8q) -} - -func (s *ReverseCumulativeDeltaCompressor) encodeNewDelta(delta uint64, s8 byte, s8q byte) { - s.lastDelta = delta - s.numIdx = s.pos - n := s.buf.ReversePutVarUint64(s.pos, s.lastDelta) - s.pos += n - s.buf.SetByte(s.pos, s8) - s.pos++ - s.buf.SetByte(s.pos, s8q) - s.pos++ -} - -func (s *ReverseCumulativeDeltaCompressor) shiftOnePosToRight() { - s.buf.ShiftOnePosToRight(s.numIdx, s.pos) - s.pos++ - s.numIdx++ -} - -func (s *ReverseCumulativeDeltaCompressor) encode2bLength() { - num := s.length - 2 - s.buf.SetByte(s.numIdx-1, byte(num&127)|128) - s.buf.SetByte(s.numIdx-2, byte(num>>7)) -} - -func (s *ReverseCumulativeDeltaCompressor) DeleteLast() { - var ( - s8q = s.buf.GetByte(s.pos - 1) - s8 = s.buf.GetByte(s.pos - 2) - flag byte = 1 << uint(8-s8q) - ) - - if s.length > 0 { - if s.length == 2 { - s.length = 0 - s.buf.UnsetFlag(s.pos-2, flag) - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - } else if s.length < 130 { - s.length-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else if s.length == 130 { - s.length-- - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else { - s.length-- - s.encode2bLength() - } - } else { - if s8q > 1 { - s8q-- - flag = 1 << uint(8-s8q) - s.pos = s.numIdx + 2 - s.buf.SetByte(s.pos-2, s8) - s.buf.SetByte(s.pos-1, s8q) - } else { - s.pos = s.numIdx + 1 - s.buf.SetByte(s.pos-1, 8) - s8 = s.buf.GetByte(s.pos - 2) - flag = 1 - } - var ( - pos = s.pos - 3 - n int - err error - ) - s.lastDelta, n, err = s.buf.ReverseGetVarUint64(pos) - if err != nil { - panic(err) - } - s.numIdx = pos - n - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(s.numIdx - 1) - } - } -} - -type ReverseCumulativeDeltaDecompressor struct { - buf *conbuf.ContinuousBuffer - pos int - bound int - firstValue float64 - lastValue float64 - length uint16 - coef float64 - idxOf8 uint - s8 byte - step byte -} - -func NewReverseCumulativeDeltaDecompressor(buf *conbuf.ContinuousBuffer, size int, fracDigits byte) *ReverseCumulativeDeltaDecompressor { - var coef float64 = 1 - if fracDigits > 0 { - coef = math.Pow(10, float64(fracDigits)) - } - return &ReverseCumulativeDeltaDecompressor{ - buf: buf, - coef: coef, - pos: size, - } -} - -func (s *ReverseCumulativeDeltaDecompressor) NextValue() (value float64, done bool) { - if s.step > 0 { - if s.length > 0 { - s.length-- - return s.lastValue, false - } - if s.pos < s.bound { - return 0, true - } - if s.idxOf8 == 0 { - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - } - s.readVar() - if s.length > 0 { - s.length-- - } - return s.lastValue, false - } - u64, n, err := s.buf.GetVarUint64(0) - if err != nil { - panic(err) - } - s.firstValue = float64(u64) / s.coef - s.bound = n - s.pos-- - s.idxOf8 = uint(8 - s.buf.GetByte(s.pos)) - s.pos-- - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - s.readVar() - if s.length > 0 { - s.length-- - } - s.step = 1 - return s.lastValue, false -} - -func (s *ReverseCumulativeDeltaDecompressor) readVar() { - u64, n, err := s.buf.ReverseGetVarUint64(s.pos) - if err != nil { - panic(err) - } - s.pos -= n - s.lastValue = s.firstValue + float64(u64)/s.coef - - var flag byte = 1 << s.idxOf8 - if (s.s8 & flag) == flag { - s.length, n = s.buf.DecodeRunLength(s.pos) - s.pos -= n - } - if s.idxOf8 == 7 { - s.idxOf8 = 0 - } else { - s.idxOf8++ - } -} diff --git a/chunkenc2/insdelta.go b/chunkenc2/insdelta.go deleted file mode 100644 index 056b595..0000000 --- a/chunkenc2/insdelta.go +++ /dev/null @@ -1,345 +0,0 @@ -package chunkenc2 - -import ( - "fmt" - "math" - - "gordenko.dev/dima/qb/bin" - "gordenko.dev/dima/qb/conbuf" -) - -// REVERSE - -type ReverseInstantDeltaCompressor struct { - buf *conbuf.ContinuousBuffer - coef float64 - pos int - firstValue float64 - lastDelta int64 - length uint16 - numIdx int -} - -func NewReverseInstantDeltaCompressor(buf *conbuf.ContinuousBuffer, size int, fracDigits byte) *ReverseInstantDeltaCompressor { - var coef float64 = 1 - if fracDigits > 0 { - coef = math.Pow(10, float64(fracDigits)) - } - s := &ReverseInstantDeltaCompressor{ - buf: buf, - pos: size, - coef: coef, - } - if size > 0 { - s.restoreState() - } - return s -} - -func (s *ReverseInstantDeltaCompressor) restoreState() { - i64, n, err := s.buf.GetVarInt64(0) - if err != nil { - panic(fmt.Sprintf("bug: get first value: %s", err)) - } - s.firstValue = float64(i64) / s.coef - - if s.pos > n { - pos := s.pos - 1 - idxOf8 := uint(8 - s.buf.GetByte(pos)) - pos-- - s8 := s.buf.GetByte(pos) - pos-- - - var n int - s.lastDelta, n, err = s.buf.ReverseGetVarInt64(pos) - if err != nil { - panic(fmt.Sprintf("bug: get last delta: %s", err)) - } - pos -= n - s.numIdx = pos + 1 - var flag byte = 1 << idxOf8 - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(pos) - } - } -} - -func (s *ReverseInstantDeltaCompressor) Size() int { - return s.pos -} - -func (s *ReverseInstantDeltaCompressor) CalcRequiredSpace(value float64) int { - if s.pos == 0 { - n := bin.CalcVarInt64Length(int64(value * s.coef)) - return n + 3 - } - - tmp := (value - s.firstValue) * s.coef - if tmp > 0 { - tmp += eps - } else { - tmp -= eps - } - delta := int64(tmp) - - if delta == s.lastDelta { - if s.length == 0 { - return 1 - } else { - newLength := s.length + 1 - if newLength < 130 { - return 0 - } else if newLength == 130 { - return 1 - } else { - if newLength < 32769 { - return 0 - } else { - n := bin.CalcVarInt64Length(delta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } - } - } - } else { - n := bin.CalcVarInt64Length(delta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } -} - -// В начале буфера кодирую базовое значение. -func (s *ReverseInstantDeltaCompressor) Append(value float64) { - if s.pos == 0 { - n := s.buf.PutVarInt64(s.pos, int64(value*s.coef)) - s.pos += n - s.firstValue = value - s.encodeNewDelta(0, 0, 1) - } else { - tmp := (value - s.firstValue) * s.coef - if tmp > 0 { - tmp += eps - } else { - tmp -= eps - } - delta := int64(tmp) - - if delta == s.lastDelta { - if s.length == 0 { - s.length = 2 - s.shiftOnePosToRight() - s.buf.SetByte(s.numIdx-1, 0) - s8q := s.buf.GetByte(s.pos - 1) - s.buf.SetFlag(s.pos-2, 1<<(8-s8q)) - } else { - s.length++ - if s.length < 130 { - s.buf.SetByte(s.numIdx-1, byte(s.length-2)) - } else if s.length == 130 { - s.shiftOnePosToRight() - s.encode2bLength() - } else { - if s.length < 32769 { - s.encode2bLength() - } else { - s.appendNewDelta(delta) - } - } - } - } else { - s.appendNewDelta(delta) - } - } -} - -func (s *ReverseInstantDeltaCompressor) appendNewDelta(delta int64) { - s.length = 0 - - s8 := s.buf.GetByte(s.pos - 2) - s8q := s.buf.GetByte(s.pos - 1) - - if s8q == 8 { - s.pos -= 1 - s8 = 0 - s8q = 1 - } else { - s.pos -= 2 - s8q++ - } - s.encodeNewDelta(delta, s8, s8q) -} - -func (s *ReverseInstantDeltaCompressor) encodeNewDelta(delta int64, s8 byte, s8q byte) { - s.lastDelta = delta - s.numIdx = s.pos - n := s.buf.ReversePutVarInt64(s.pos, s.lastDelta) - s.pos += n - s.buf.SetByte(s.pos, s8) - s.pos++ - s.buf.SetByte(s.pos, s8q) - s.pos++ -} - -func (s *ReverseInstantDeltaCompressor) shiftOnePosToRight() { - s.buf.ShiftOnePosToRight(s.numIdx, s.pos) - s.pos++ - s.numIdx++ -} - -func (s *ReverseInstantDeltaCompressor) encode2bLength() { - num := s.length - 2 - s.buf.SetByte(s.numIdx-1, byte(num&127)|128) - s.buf.SetByte(s.numIdx-2, byte(num>>7)) -} - -func (s *ReverseInstantDeltaCompressor) DeleteLast() { - var ( - s8q = s.buf.GetByte(s.pos - 1) - s8 = s.buf.GetByte(s.pos - 2) - flag byte = 1 << uint(8-s8q) - ) - - if s.length > 0 { - if s.length == 2 { - s.length = 0 - s.buf.UnsetFlag(s.pos-2, flag) - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - } else if s.length < 130 { - s.length-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else if s.length == 130 { - s.length-- - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else { - s.length-- - s.encode2bLength() - } - } else { - if s8q > 1 { - s8q-- - flag = 1 << uint(8-s8q) - s.pos = s.numIdx + 2 - s.buf.SetByte(s.pos-2, s8) - s.buf.SetByte(s.pos-1, s8q) - } else { - s.pos = s.numIdx + 1 - s.buf.SetByte(s.pos-1, 8) - s8 = s.buf.GetByte(s.pos - 2) - flag = 1 - } - var ( - pos = s.pos - 3 - n int - err error - ) - s.lastDelta, n, err = s.buf.ReverseGetVarInt64(pos) - if err != nil { - panic(err) - } - s.numIdx = pos - n - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(s.numIdx - 1) - } - } -} - -type ReverseInstantDeltaDecompressor struct { - step byte - buf *conbuf.ContinuousBuffer - pos int - bound int - firstValue float64 - lastValue float64 - length uint16 - coef float64 - idxOf8 uint - s8 byte -} - -func NewReverseInstantDeltaDecompressor(buf *conbuf.ContinuousBuffer, size int, fracDigits byte) *ReverseInstantDeltaDecompressor { - var coef float64 = 1 - if fracDigits > 0 { - coef = math.Pow(10, float64(fracDigits)) - } - return &ReverseInstantDeltaDecompressor{ - buf: buf, - coef: coef, - pos: size, - } -} - -func (s *ReverseInstantDeltaDecompressor) NextValue() (value float64, done bool) { - if s.step > 0 { - if s.length > 0 { - s.length-- - return s.lastValue, false - } - if s.pos < s.bound { - return 0, true - } - - if s.idxOf8 == 0 { - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - } - s.readVar() - if s.length > 0 { - s.length-- - } - return s.lastValue, false - } - i64, n, err := s.buf.GetVarInt64(0) - if err != nil { - panic(err) - } - s.firstValue = float64(i64) / s.coef - s.bound = n - s.pos-- - s.idxOf8 = uint(8 - s.buf.GetByte(s.pos)) - s.pos-- - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - s.readVar() - if s.length > 0 { - s.length-- - } - s.step = 1 - return s.lastValue, false -} - -func (s *ReverseInstantDeltaDecompressor) readVar() { - i64, n, err := s.buf.ReverseGetVarInt64(s.pos) - if err != nil { - panic(err) - } - s.pos -= n - s.lastValue = s.firstValue + float64(i64)/s.coef - - var flag byte = 1 << s.idxOf8 - if (s.s8 & flag) == flag { - s.length, n = s.buf.DecodeRunLength(s.pos) - s.pos -= n - } - if s.idxOf8 == 7 { - s.idxOf8 = 0 - } else { - s.idxOf8++ - } -} diff --git a/chunkenc2/time_delta_delta.go b/chunkenc2/time_delta_delta.go deleted file mode 100644 index 76b0c49..0000000 --- a/chunkenc2/time_delta_delta.go +++ /dev/null @@ -1,374 +0,0 @@ -package chunkenc2 - -import ( - "fmt" - - "gordenko.dev/dima/qb/bin" - "gordenko.dev/dima/qb/conbuf" -) - -// REVERSE - -const ( - lastUnixtimeIdx = 0 - baseDeltaIdx = 4 -) - -type ReverseTimeDeltaOfDeltaCompressor struct { - buf *conbuf.ContinuousBuffer - pos int - baseDelta uint32 - lastUnixtime uint32 - lastDeltaOfDelta int64 - length uint16 - numIdx int -} - -func NewReverseTimeDeltaOfDeltaCompressor(buf *conbuf.ContinuousBuffer, size int) *ReverseTimeDeltaOfDeltaCompressor { - s := &ReverseTimeDeltaOfDeltaCompressor{ - buf: buf, - pos: size, - } - if size > 0 { - s.restoreState() - } - return s -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) restoreState() { - s.lastUnixtime = s.buf.GetUint32(lastUnixtimeIdx) - if s.pos > 4 { - u64, _, err := s.buf.GetVarUint64(baseDeltaIdx) - if err != nil { - panic(fmt.Sprintf("bug: get base delta: %s", err)) - } - s.baseDelta = uint32(u64) - - pos := s.pos - 1 - idxOf8 := uint(8 - s.buf.GetByte(pos)) - pos-- - s8 := s.buf.GetByte(pos) - pos-- - - var n int - s.lastDeltaOfDelta, n, err = s.buf.ReverseGetVarInt64(pos) - if err != nil { - panic(err) - } - pos -= n - s.numIdx = pos + 1 - var flag byte = 1 << idxOf8 - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(pos) - } - } -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) Size() int { - return s.pos -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) CalcRequiredSpace(unixtime uint32) int { - if s.pos == 0 { - return 4 - } - - if s.baseDelta == 0 { - baseDelta := unixtime - s.lastUnixtime - n := bin.CalcVarUint64Length(uint64(baseDelta)) - return n + 3 - } - - deltaOfDelta := int64(unixtime-s.lastUnixtime) - int64(s.baseDelta) - if deltaOfDelta == s.lastDeltaOfDelta { - if s.length == 0 { - return 1 - } else { - newLength := s.length + 1 - if newLength < 130 { - return 0 - } else if newLength == 130 { - return 1 - } else { - if newLength < 32769 { - return 0 - } else { - n := bin.CalcVarInt64Length(deltaOfDelta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } - } - } - } else { - n := bin.CalcVarInt64Length(deltaOfDelta) - n += 2 - s8q := s.buf.GetByte(s.pos - 1) - if s8q == 8 { - n -= 1 - } else { - n -= 2 - } - return n - } -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) Append(unixtime uint32) { - if s.pos == 0 { - s.lastUnixtime = unixtime - s.buf.PutUint32(lastUnixtimeIdx, unixtime) - s.pos += 4 - return - } - - if s.baseDelta == 0 { - s.baseDelta = unixtime - s.lastUnixtime - s.lastDeltaOfDelta = 0 - s.lastUnixtime = unixtime - s.buf.PutUint32(lastUnixtimeIdx, unixtime) - - n := s.buf.PutVarUint64(s.pos, uint64(s.baseDelta)) - s.pos += n - s.encodeNewDeltaOfDelta(0, 0, 1) - return - } - - deltaOfDelta := int64(unixtime-s.lastUnixtime) - int64(s.baseDelta) - s.lastUnixtime = unixtime - s.buf.PutUint32(lastUnixtimeIdx, unixtime) - - if deltaOfDelta == s.lastDeltaOfDelta { - if s.length == 0 { - s.length = 2 - s.shiftOnePosToRight() - s.buf.SetByte(s.numIdx-1, 0) - s8q := s.buf.GetByte(s.pos - 1) - s.buf.SetFlag(s.pos-2, 1<<(8-s8q)) - } else { - s.length++ - if s.length < 130 { - s.buf.SetByte(s.numIdx-1, byte(s.length-2)) - } else if s.length == 130 { - s.shiftOnePosToRight() - s.encode2bLength() - } else { - if s.length < 32769 { - s.encode2bLength() - } else { - s.appendNewDeltaOfDelta(deltaOfDelta) - } - } - } - } else { - s.appendNewDeltaOfDelta(deltaOfDelta) - } -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) appendNewDeltaOfDelta(deltaOfDelta int64) { - s.length = 0 - s8 := s.buf.GetByte(s.pos - 2) - s8q := s.buf.GetByte(s.pos - 1) - - if s8q == 8 { - s.pos -= 1 - s8 = 0 - s8q = 1 - } else { - s.pos -= 2 - s8q++ - } - - s.encodeNewDeltaOfDelta(deltaOfDelta, s8, s8q) -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) encodeNewDeltaOfDelta(deltaOfDelta int64, s8 byte, s8q byte) { - s.lastDeltaOfDelta = deltaOfDelta - s.numIdx = s.pos - n := s.buf.ReversePutVarInt64(s.pos, deltaOfDelta) - s.pos += n - s.buf.SetByte(s.pos, s8) - s.pos++ - s.buf.SetByte(s.pos, s8q) - s.pos++ -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) shiftOnePosToRight() { - s.buf.ShiftOnePosToRight(s.numIdx, s.pos) - s.pos++ - s.numIdx++ -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) encode2bLength() { - num := s.length - 2 - s.buf.SetByte(s.numIdx-1, byte(num&127)|128) - s.buf.SetByte(s.numIdx-2, byte(num>>7)) -} - -func (s *ReverseTimeDeltaOfDeltaCompressor) DeleteLast() { - var ( - s8q = s.buf.GetByte(s.pos - 1) - s8 = s.buf.GetByte(s.pos - 2) - flag byte = 1 << uint(8-s8q) - ) - - if s.length > 0 { - if s.length == 2 { - s.length = 0 - s.buf.UnsetFlag(s.pos-2, flag) - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - } else if s.length < 130 { - s.length-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else if s.length == 130 { - s.length-- - s.buf.ShiftOnePosToLeft(s.numIdx, s.pos) - s.numIdx-- - s.pos-- - s.buf.SetByte(s.numIdx-1, byte(s.length)-2) - } else { - s.length-- - s.encode2bLength() - } - } else { - if s8q > 1 { - s8q-- - flag = 1 << uint(8-s8q) - s.pos = s.numIdx + 2 - s.buf.SetByte(s.pos-2, s8) - s.buf.SetByte(s.pos-1, s8q) - } else { - s.pos = s.numIdx + 1 - s.buf.SetByte(s.pos-1, 8) - s8 = s.buf.GetByte(s.pos - 2) - flag = 1 - } - var ( - pos = s.pos - 3 - n int - err error - ) - s.lastDeltaOfDelta, n, err = s.buf.ReverseGetVarInt64(pos) - if err != nil { - panic(err) - } - s.numIdx = pos - n - if (s8 & flag) == flag { - s.length, _ = s.buf.DecodeRunLength(s.numIdx - 1) - } - } - - delta := int64(s.baseDelta) + s.lastDeltaOfDelta - s.lastUnixtime = uint32(int64(s.lastUnixtime) - delta) - s.buf.PutUint32(lastUnixtimeIdx, s.lastUnixtime) -} - -type ReverseTimeDeltaOfDeltaDecompressor struct { - step byte - buf *conbuf.ContinuousBuffer - pos int - bound int - lastUnixtime uint32 - baseDelta uint32 - lastDeltaOfDelta int64 - length uint16 - idxOf8 uint - s8 byte -} - -func NewReverseTimeDeltaOfDeltaDecompressor(buf *conbuf.ContinuousBuffer, size int) *ReverseTimeDeltaOfDeltaDecompressor { - return &ReverseTimeDeltaOfDeltaDecompressor{ - buf: buf, - pos: size, - } -} - -func (s *ReverseTimeDeltaOfDeltaDecompressor) NextValue() (value uint32, done bool) { - if s.step == 0 { - if s.pos == 0 { - return 0, true - } - s.lastUnixtime = s.buf.GetUint32(lastUnixtimeIdx) - s.step = 1 - return s.lastUnixtime, false - } - - if s.step == 1 { - if s.pos == baseDeltaIdx { - return 0, true - } - u64, n, err := s.buf.GetVarUint64(baseDeltaIdx) - if err != nil { - panic("EOF") - } - s.bound = baseDeltaIdx + n - s.baseDelta = uint32(u64) - - s.pos-- - s.idxOf8 = uint(8 - s.buf.GetByte(s.pos)) - s.pos-- - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - - s.readVar() - if s.length > 0 { - s.length-- - } - s.step = 2 - return s.lastUnixtime, false - } - - if s.length > 0 { - s.length-- - delta := int64(s.baseDelta) + s.lastDeltaOfDelta - s.lastUnixtime = uint32(int64(s.lastUnixtime) - delta) - return s.lastUnixtime, false - } - - if s.pos < s.bound { - return 0, true - } - - if s.idxOf8 == 0 { - s.s8 = s.buf.GetByte(s.pos) - s.pos-- - } - s.readVar() - if s.length > 0 { - s.length-- - } - return s.lastUnixtime, false -} - -func (s *ReverseTimeDeltaOfDeltaDecompressor) readVar() { - var ( - n int - err error - ) - - s.lastDeltaOfDelta, n, err = s.buf.ReverseGetVarInt64(s.pos) - if err != nil { - panic(err) - } - s.pos -= n - - delta := int64(s.baseDelta) + s.lastDeltaOfDelta - s.lastUnixtime = uint32(int64(s.lastUnixtime) - delta) - - var flag byte = 1 << s.idxOf8 - if (s.s8 & flag) == flag { - s.length, n = s.buf.DecodeRunLength(s.pos) - s.pos -= n - } - if s.idxOf8 == 7 { - s.idxOf8 = 0 - } else { - s.idxOf8++ - } -} diff --git a/go.sum b/go.sum index 7a7aa11..2b1421c 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gordenko.dev/dima/bin v0.0.0-20260528204801-12b890585248 h1:APYOkErjDz3hykfcddvmABsexoyKUgdRPU3XiM16F34= -gordenko.dev/dima/bin v0.0.0-20260528204801-12b890585248/go.mod h1:/I+9fvRUzXHgXSwGEwOK1mBBM4BJ3AtCmoCZ2upDiwk= gordenko.dev/dima/bin v0.0.0-20260604235618-bff16d774d98 h1:pQzJ4wnSrFXn9Hu+v6KvWZ4GQVBmuTljJGZ20Pb+BJA= gordenko.dev/dima/bin v0.0.0-20260604235618-bff16d774d98/go.mod h1:/I+9fvRUzXHgXSwGEwOK1mBBM4BJ3AtCmoCZ2upDiwk= gordenko.dev/dima/pretty v0.0.0-20221225212746-0c27d8c0ac69 h1:nyJ3mzTQ46yUeMZCdLyYcs7B5JCS54c67v84miyhq2E=