mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 21:17:16 +00:00
965d1101f4
* another way to check if account has storage * cleanup * v0 of walk by db version * save progress, to switch to another task. Put tombstone is still not correct. * place tombstone only if exists something to hide * db-based implementation * db-based implementation * db-based implementation * fix prop check * improve prop check logic * Need custom logic to skip subtree for account and storage buckets because storage bucket has incarnation in key * rebase to master * remove all tombstones when account deleted * remove all tombstones when account deleted * added db integrity check * don't rely on account.Root because it valid only about last incarnation * remove all tombstones when account deleted * dial with incarnation in MultiWalk2 * dial with incarnation in MultiWalk2 * when fixedbytes=40 resolver did compare cacheKey with storageKey without removing incarnation * rebase to master * rebase to master Co-authored-by: alex.sharov <alex.sharov@lazada.com>
69 lines
1.5 KiB
Go
69 lines
1.5 KiB
Go
package dbutils
|
|
|
|
import "bytes"
|
|
|
|
// 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:]
|
|
}
|
|
|
|
func ChangeSetByIndexBucket(b []byte) []byte {
|
|
if bytes.Equal(b, AccountsHistoryBucket) {
|
|
return AccountChangeSetBucket
|
|
}
|
|
if bytes.Equal(b, StorageHistoryBucket) {
|
|
return StorageChangeSetBucket
|
|
}
|
|
panic("wrong bucket")
|
|
}
|
|
|
|
// Cmp - like bytes.Compare, but nil - means "bucket over" and has highest order.
|
|
func Cmp(k1, k2 []byte) int {
|
|
if k1 == nil && k2 == nil {
|
|
return 0
|
|
}
|
|
if k1 == nil {
|
|
return 1
|
|
}
|
|
if k2 == nil {
|
|
return -1
|
|
}
|
|
|
|
return bytes.Compare(k1, k2)
|
|
}
|
|
|
|
// IsBefore - kind of bytes.Compare, but nil is the last key. And return
|
|
func IsBefore(k1, k2 []byte) (bool, []byte) {
|
|
switch Cmp(k1, k2) {
|
|
case -1, 0:
|
|
return true, k1
|
|
default:
|
|
return false, k2
|
|
}
|
|
}
|