mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-29 07:07:16 +00:00
eliasfano: To fix checkptr fatal error (#697)
``` go test -race -run=TestEliasFano ./recsplit/eliasfano32 fatal error: checkptr: converted pointer straddles multiple allocations goroutine 35 [running]: runtime.throw({0x13bb5bf?, 0x13446ca?}) runtime/panic.go:1047 +0x5d fp=0xc000137790 sp=0xc000137760 pc=0x108a13d runtime.checkptrAlignment(0xa9?, 0x0?, 0x0?) runtime/checkptr.go:26 +0x6c fp=0xc0001377b0 sp=0xc000137790 pc=0x1059f8c github.com/ledgerwatch/erigon-lib/recsplit/eliasfano32.Min({0xc00012c280, 0x40, 0x40}) github.com/ledgerwatch/erigon-lib/recsplit/eliasfano32/elias_fano.go:324 +0x36f fp=0xc000137868 sp=0xc0001377b0 pc=0x133e66f github.com/ledgerwatch/erigon-lib/recsplit/eliasfano32.TestEliasFano(0x0?) github.com/ledgerwatch/erigon-lib/recsplit/eliasfano32/elias_fano_test.go:58 ```
This commit is contained in:
parent
222bb666e9
commit
9819f6af24
@ -1409,7 +1409,7 @@ func (s *state) Encode(buf []byte) ([]byte, error) {
|
|||||||
if err := binary.Write(ee, binary.BigEndian, uint16(len(s.Root))); err != nil {
|
if err := binary.Write(ee, binary.BigEndian, uint16(len(s.Root))); err != nil {
|
||||||
return nil, fmt.Errorf("encode root len: %w", err)
|
return nil, fmt.Errorf("encode root len: %w", err)
|
||||||
}
|
}
|
||||||
if n, err := ee.Write(s.Root[:]); err != nil || n != len(s.Root) {
|
if n, err := ee.Write(s.Root); err != nil || n != len(s.Root) {
|
||||||
return nil, fmt.Errorf("encode root: %w", err)
|
return nil, fmt.Errorf("encode root: %w", err)
|
||||||
}
|
}
|
||||||
d := make([]byte, len(s.Depths))
|
d := make([]byte, len(s.Depths))
|
||||||
|
@ -280,9 +280,8 @@ func (ef *EliasFano) Write(w io.Writer) error {
|
|||||||
if _, e := w.Write(numBuf[:]); e != nil {
|
if _, e := w.Write(numBuf[:]); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
p := (*[maxDataSize]byte)(unsafe.Pointer(&ef.data[0]))
|
b := unsafe.Slice((*byte)(unsafe.Pointer(&ef.data[0])), len(ef.data)*uint64Size)
|
||||||
b := (*p)[:]
|
if _, e := w.Write(b); e != nil {
|
||||||
if _, e := w.Write(b[:len(ef.data)*8]); e != nil {
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -295,17 +294,14 @@ func (ef *EliasFano) AppendBytes(buf []byte) []byte {
|
|||||||
buf = append(buf, numBuf[:]...)
|
buf = append(buf, numBuf[:]...)
|
||||||
binary.BigEndian.PutUint64(numBuf[:], ef.u)
|
binary.BigEndian.PutUint64(numBuf[:], ef.u)
|
||||||
buf = append(buf, numBuf[:]...)
|
buf = append(buf, numBuf[:]...)
|
||||||
p := (*[maxDataSize]byte)(unsafe.Pointer(&ef.data[0]))
|
b := unsafe.Slice((*byte)(unsafe.Pointer(&ef.data[0])), len(ef.data)*uint64Size)
|
||||||
b := (*p)[:]
|
buf = append(buf, b...)
|
||||||
buf = append(buf, b[:len(ef.data)*8]...)
|
|
||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxDataSize = 0xFFFFFFFFFFFF //2^48
|
|
||||||
|
|
||||||
// Read inputs the state of golomb rice encoding from a reader s
|
// Read inputs the state of golomb rice encoding from a reader s
|
||||||
func ReadEliasFano(r []byte) (*EliasFano, int) {
|
func ReadEliasFano(r []byte) (*EliasFano, int) {
|
||||||
p := (*[maxDataSize / 8]uint64)(unsafe.Pointer(&r[16]))
|
p := unsafe.Slice((*uint64)(unsafe.Pointer(&r[16])), (len(r)-16)/uint64Size)
|
||||||
ef := &EliasFano{
|
ef := &EliasFano{
|
||||||
count: binary.BigEndian.Uint64(r[:8]),
|
count: binary.BigEndian.Uint64(r[:8]),
|
||||||
u: binary.BigEndian.Uint64(r[8:16]),
|
u: binary.BigEndian.Uint64(r[8:16]),
|
||||||
@ -318,10 +314,12 @@ func ReadEliasFano(r []byte) (*EliasFano, int) {
|
|||||||
|
|
||||||
func Max(r []byte) uint64 { return binary.BigEndian.Uint64(r[8:16]) - 1 }
|
func Max(r []byte) uint64 { return binary.BigEndian.Uint64(r[8:16]) - 1 }
|
||||||
|
|
||||||
|
const uint64Size = 8
|
||||||
|
|
||||||
func Min(r []byte) uint64 {
|
func Min(r []byte) uint64 {
|
||||||
count := binary.BigEndian.Uint64(r[:8])
|
count := binary.BigEndian.Uint64(r[:8])
|
||||||
u := binary.BigEndian.Uint64(r[8:16])
|
u := binary.BigEndian.Uint64(r[8:16])
|
||||||
p := (*[maxDataSize / 8]uint64)(unsafe.Pointer(&r[16]))
|
p := unsafe.Slice((*uint64)(unsafe.Pointer(&r[16])), (len(r)-16)/uint64Size)
|
||||||
var l uint64
|
var l uint64
|
||||||
if u/(count+1) == 0 {
|
if u/(count+1) == 0 {
|
||||||
l = 0
|
l = 0
|
||||||
@ -650,9 +648,8 @@ func (ef *DoubleEliasFano) Write(w io.Writer) error {
|
|||||||
if _, e := w.Write(numBuf[:]); e != nil {
|
if _, e := w.Write(numBuf[:]); e != nil {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
p := (*[maxDataSize]byte)(unsafe.Pointer(&ef.data[0]))
|
b := unsafe.Slice((*byte)(unsafe.Pointer(&ef.data[0])), len(ef.data)*uint64Size)
|
||||||
b := (*p)[:]
|
if _, e := w.Write(b); e != nil {
|
||||||
if _, e := w.Write(b[:len(ef.data)*8]); e != nil {
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -665,8 +662,7 @@ func (ef *DoubleEliasFano) Read(r []byte) int {
|
|||||||
ef.uPosition = binary.BigEndian.Uint64(r[16:24])
|
ef.uPosition = binary.BigEndian.Uint64(r[16:24])
|
||||||
ef.cumKeysMinDelta = binary.BigEndian.Uint64(r[24:32])
|
ef.cumKeysMinDelta = binary.BigEndian.Uint64(r[24:32])
|
||||||
ef.posMinDelta = binary.BigEndian.Uint64(r[32:40])
|
ef.posMinDelta = binary.BigEndian.Uint64(r[32:40])
|
||||||
p := (*[maxDataSize / 8]uint64)(unsafe.Pointer(&r[40]))
|
ef.data = unsafe.Slice((*uint64)(unsafe.Pointer(&r[40])), (len(r)-40)/uint64Size)
|
||||||
ef.data = p[:]
|
|
||||||
ef.deriveFields()
|
ef.deriveFields()
|
||||||
return 40 + 8*len(ef.data)
|
return 40 + 8*len(ef.data)
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,16 @@ func TestEliasFano(t *testing.T) {
|
|||||||
v, ok = ef.Search(11)
|
v, ok = ef.Search(11)
|
||||||
assert.True(t, ok, "search4")
|
assert.True(t, ok, "search4")
|
||||||
assert.Equal(t, uint64(14), v, "search4")
|
assert.Equal(t, uint64(14), v, "search4")
|
||||||
|
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
ef.Write(buf)
|
ef.Write(buf)
|
||||||
assert.Equal(t, ef.Max(), Max(buf.Bytes()))
|
assert.Equal(t, ef.AppendBytes(nil), buf.Bytes())
|
||||||
assert.Equal(t, ef.Min(), Min(buf.Bytes()))
|
|
||||||
|
ef2, _ := ReadEliasFano(buf.Bytes())
|
||||||
|
assert.Equal(t, ef.Min(), ef2.Min())
|
||||||
|
assert.Equal(t, ef.Max(), ef2.Max())
|
||||||
|
assert.Equal(t, ef2.Max(), Max(buf.Bytes()))
|
||||||
|
assert.Equal(t, ef2.Min(), Min(buf.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIterator(t *testing.T) {
|
func TestIterator(t *testing.T) {
|
||||||
|
@ -1375,7 +1375,7 @@ func DecodeAccountBytes(enc []byte) (nonce uint64, balance *uint256.Int, hash []
|
|||||||
pos++
|
pos++
|
||||||
if codeHashBytes > 0 {
|
if codeHashBytes > 0 {
|
||||||
codeHash := make([]byte, length.Hash)
|
codeHash := make([]byte, length.Hash)
|
||||||
copy(codeHash[:], enc[pos:pos+codeHashBytes])
|
copy(codeHash, enc[pos:pos+codeHashBytes])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user