mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-24 12:37:16 +00:00
64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package dbutils
|
|
|
|
// EncodeTimestamp has the property: if a < b, then Encoding(a) < Encoding(b) lexicographically
|
|
func EncodeTimestamp(timestamp uint64) []byte {
|
|
var suffix []byte
|
|
var limit uint64 = 32
|
|
|
|
for bytecount := 1; bytecount <= 8; bytecount++ {
|
|
if timestamp < limit {
|
|
suffix = make([]byte, bytecount)
|
|
b := timestamp
|
|
for i := bytecount - 1; i > 0; i-- {
|
|
suffix[i] = byte(b & 0xff)
|
|
b >>= 8
|
|
}
|
|
suffix[0] = byte(b) | (byte(bytecount) << 5) // 3 most significant bits of the first byte are bytecount
|
|
break
|
|
}
|
|
limit <<= 8
|
|
}
|
|
return suffix
|
|
}
|
|
|
|
func DecodeTimestamp(suffix []byte) (uint64, []byte) {
|
|
bytecount := int(suffix[0] >> 5)
|
|
timestamp := uint64(suffix[0] & 0x1f)
|
|
for i := 1; i < bytecount; i++ {
|
|
timestamp = (timestamp << 8) | uint64(suffix[i])
|
|
}
|
|
return timestamp, suffix[bytecount:]
|
|
}
|
|
|
|
// NextSubtree does []byte++. Returns false if overflow.
|
|
func NextSubtree(in []byte) ([]byte, bool) {
|
|
r := make([]byte, len(in))
|
|
copy(r, in)
|
|
for i := len(r) - 1; i >= 0; i-- {
|
|
if r[i] != 255 {
|
|
r[i]++
|
|
return r, true
|
|
}
|
|
|
|
r = r[:i] // make it shorter, because in tries after 11ff goes 12, but not 1200
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
// NextNibblesSubtree does []byte++. Returns false if overflow.
|
|
func NextNibblesSubtree(in []byte, out *[]byte) bool {
|
|
r := (*out)[:len(in)]
|
|
copy(r, in)
|
|
for i := len(r) - 1; i >= 0; i-- {
|
|
if r[i] != 15 { // max value of nibbles
|
|
r[i]++
|
|
*out = r
|
|
return true
|
|
}
|
|
|
|
r = r[:i] // make it shorter, because in tries after 11ff goes 12, but not 1200
|
|
}
|
|
*out = r
|
|
return false
|
|
}
|