package enc import ( "gordenko.dev/dima/diploma/bin" ) // REVERSE const ( lastUnixtimeIdx = 0 baseDeltaIdx = 4 ) type ReverseTimeDeltaOfDeltaDecompressor struct { step byte buf []byte pos int bound int lastUnixtime uint32 baseDelta uint32 lastDeltaOfDelta int64 length uint16 idxOf8 uint s8 byte } func NewReverseTimeDeltaOfDeltaDecompressor(buf []byte) *ReverseTimeDeltaOfDeltaDecompressor { return &ReverseTimeDeltaOfDeltaDecompressor{ buf: buf, pos: len(buf), } } func (s *ReverseTimeDeltaOfDeltaDecompressor) NextValue() (value uint32, done bool) { if s.step == 0 { if s.pos == 0 { return 0, true } s.lastUnixtime = bin.GetUint32(s.buf[lastUnixtimeIdx:]) s.step = 1 return s.lastUnixtime, false } if s.step == 1 { if s.pos == baseDeltaIdx { return 0, true } u64, n, err := bin.GetVarUint64(s.buf[baseDeltaIdx:]) if err != nil { panic("EOF") } s.bound = baseDeltaIdx + n s.baseDelta = uint32(u64) s.pos-- s.idxOf8 = uint(8 - s.buf[s.pos]) s.pos-- s.s8 = s.buf[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[s.pos] s.pos-- } s.readVar() if s.length > 0 { s.length-- } return s.lastUnixtime, false } func GetTimeRange(timestampsBuf []byte) (since, until uint32) { decompressor := NewReverseTimeDeltaOfDeltaDecompressor(timestampsBuf) value, done := decompressor.NextValue() if done { return } since = value until = value for { value, done = decompressor.NextValue() if done { return } since = value } } func (s *ReverseTimeDeltaOfDeltaDecompressor) readVar() { var ( n int err error ) s.lastDeltaOfDelta, n, err = bin.ReverseGetVarInt64(s.buf[:s.pos+1]) 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.decodeLength() } if s.idxOf8 == 7 { s.idxOf8 = 0 } else { s.idxOf8++ } } func (s *ReverseTimeDeltaOfDeltaDecompressor) decodeLength() { b1 := s.buf[s.pos] s.pos-- if b1 < 128 { s.length = uint16(b1) } else { b2 := s.buf[s.pos] s.pos-- s.length = uint16(b1&127) | (uint16(b2) << 7) } s.length += 2 }