mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-25 07:56:16 +00:00
core/rawdb: fix tail truncation and add tests
This commit is contained in:
parent
43b1f7e9fe
commit
d9eea18517
2 changed files with 58 additions and 7 deletions
|
|
@ -841,7 +841,7 @@ func (t *freezerTable) truncateTail(items uint64) error {
|
|||
func (t *freezerTable) resetTo(tail uint64) error {
|
||||
// Sync the entire table before resetting, eliminating the potential
|
||||
// data corruption.
|
||||
err := t.Sync()
|
||||
err := t.doSync()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -870,8 +870,9 @@ func (t *freezerTable) resetTo(tail uint64) error {
|
|||
}
|
||||
t.headId = t.headId + 1
|
||||
t.tailId = t.headId
|
||||
t.headBytes = 0
|
||||
|
||||
t.head, err = t.openFile(t.headId, openFreezerFileForAppend)
|
||||
t.head, err = t.openFile(t.headId, openFreezerFileTruncated)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1139,6 +1139,7 @@ const (
|
|||
opTruncateHeadAll
|
||||
opTruncateTail
|
||||
opTruncateTailAll
|
||||
opTruncateTailOverHead
|
||||
opCheckAll
|
||||
opMax // boundary value, not an actual op
|
||||
)
|
||||
|
|
@ -1226,6 +1227,11 @@ func (randTest) Generate(r *rand.Rand, size int) reflect.Value {
|
|||
step.target = deleted + uint64(len(items))
|
||||
items = items[:0]
|
||||
deleted = step.target
|
||||
case opTruncateTailOverHead:
|
||||
newDeleted := deleted + uint64(len(items)) + 10
|
||||
step.target = newDeleted
|
||||
deleted = newDeleted
|
||||
items = items[:0]
|
||||
}
|
||||
steps = append(steps, step)
|
||||
}
|
||||
|
|
@ -1268,7 +1274,7 @@ func runRandTest(rt randTest) bool {
|
|||
for i := 0; i < len(step.items); i++ {
|
||||
batch.AppendRaw(step.items[i], step.blobs[i])
|
||||
}
|
||||
batch.commit()
|
||||
rt[i].err = batch.commit()
|
||||
values = append(values, step.blobs...)
|
||||
|
||||
case opRetrieve:
|
||||
|
|
@ -1290,24 +1296,28 @@ func runRandTest(rt randTest) bool {
|
|||
}
|
||||
|
||||
case opTruncateHead:
|
||||
f.truncateHead(step.target)
|
||||
rt[i].err = f.truncateHead(step.target)
|
||||
|
||||
length := f.items.Load() - f.itemHidden.Load()
|
||||
values = values[:length]
|
||||
|
||||
case opTruncateHeadAll:
|
||||
f.truncateHead(step.target)
|
||||
rt[i].err = f.truncateHead(step.target)
|
||||
values = nil
|
||||
|
||||
case opTruncateTail:
|
||||
prev := f.itemHidden.Load()
|
||||
f.truncateTail(step.target)
|
||||
rt[i].err = f.truncateTail(step.target)
|
||||
|
||||
truncated := f.itemHidden.Load() - prev
|
||||
values = values[truncated:]
|
||||
|
||||
case opTruncateTailAll:
|
||||
f.truncateTail(step.target)
|
||||
rt[i].err = f.truncateTail(step.target)
|
||||
values = nil
|
||||
|
||||
case opTruncateTailOverHead:
|
||||
rt[i].err = f.truncateTail(step.target)
|
||||
values = nil
|
||||
}
|
||||
// Abort the test on error.
|
||||
|
|
@ -1633,3 +1643,43 @@ func TestFreezerAncientBytes(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncateOverHead(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fn := fmt.Sprintf("t-%d", rand.Uint64())
|
||||
f, err := newTable(os.TempDir(), fn, metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 100, freezerTableConfig{noSnappy: true}, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Tail truncation on an empty table
|
||||
if err := f.truncateTail(10); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
batch := f.newBatch()
|
||||
data := getChunk(10, 1)
|
||||
require.NoError(t, batch.AppendRaw(uint64(10), data))
|
||||
require.NoError(t, batch.commit())
|
||||
|
||||
got, err := f.RetrieveItems(uint64(10), 1, 0)
|
||||
require.NoError(t, err)
|
||||
if !bytes.Equal(got[0], data) {
|
||||
t.Fatalf("Unexpected bytes, want: %v, got: %v", data, got[0])
|
||||
}
|
||||
|
||||
// Tail truncation on the non-empty table
|
||||
if err := f.truncateTail(20); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
batch = f.newBatch()
|
||||
data = getChunk(10, 1)
|
||||
require.NoError(t, batch.AppendRaw(uint64(20), data))
|
||||
require.NoError(t, batch.commit())
|
||||
|
||||
got, err = f.RetrieveItems(uint64(20), 1, 0)
|
||||
require.NoError(t, err)
|
||||
if !bytes.Equal(got[0], data) {
|
||||
t.Fatalf("Unexpected bytes, want: %v, got: %v", data, got[0])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue