mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +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 {
|
func (t *freezerTable) resetTo(tail uint64) error {
|
||||||
// Sync the entire table before resetting, eliminating the potential
|
// Sync the entire table before resetting, eliminating the potential
|
||||||
// data corruption.
|
// data corruption.
|
||||||
err := t.Sync()
|
err := t.doSync()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -870,8 +870,9 @@ func (t *freezerTable) resetTo(tail uint64) error {
|
||||||
}
|
}
|
||||||
t.headId = t.headId + 1
|
t.headId = t.headId + 1
|
||||||
t.tailId = t.headId
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1139,6 +1139,7 @@ const (
|
||||||
opTruncateHeadAll
|
opTruncateHeadAll
|
||||||
opTruncateTail
|
opTruncateTail
|
||||||
opTruncateTailAll
|
opTruncateTailAll
|
||||||
|
opTruncateTailOverHead
|
||||||
opCheckAll
|
opCheckAll
|
||||||
opMax // boundary value, not an actual op
|
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))
|
step.target = deleted + uint64(len(items))
|
||||||
items = items[:0]
|
items = items[:0]
|
||||||
deleted = step.target
|
deleted = step.target
|
||||||
|
case opTruncateTailOverHead:
|
||||||
|
newDeleted := deleted + uint64(len(items)) + 10
|
||||||
|
step.target = newDeleted
|
||||||
|
deleted = newDeleted
|
||||||
|
items = items[:0]
|
||||||
}
|
}
|
||||||
steps = append(steps, step)
|
steps = append(steps, step)
|
||||||
}
|
}
|
||||||
|
|
@ -1268,7 +1274,7 @@ func runRandTest(rt randTest) bool {
|
||||||
for i := 0; i < len(step.items); i++ {
|
for i := 0; i < len(step.items); i++ {
|
||||||
batch.AppendRaw(step.items[i], step.blobs[i])
|
batch.AppendRaw(step.items[i], step.blobs[i])
|
||||||
}
|
}
|
||||||
batch.commit()
|
rt[i].err = batch.commit()
|
||||||
values = append(values, step.blobs...)
|
values = append(values, step.blobs...)
|
||||||
|
|
||||||
case opRetrieve:
|
case opRetrieve:
|
||||||
|
|
@ -1290,24 +1296,28 @@ func runRandTest(rt randTest) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
case opTruncateHead:
|
case opTruncateHead:
|
||||||
f.truncateHead(step.target)
|
rt[i].err = f.truncateHead(step.target)
|
||||||
|
|
||||||
length := f.items.Load() - f.itemHidden.Load()
|
length := f.items.Load() - f.itemHidden.Load()
|
||||||
values = values[:length]
|
values = values[:length]
|
||||||
|
|
||||||
case opTruncateHeadAll:
|
case opTruncateHeadAll:
|
||||||
f.truncateHead(step.target)
|
rt[i].err = f.truncateHead(step.target)
|
||||||
values = nil
|
values = nil
|
||||||
|
|
||||||
case opTruncateTail:
|
case opTruncateTail:
|
||||||
prev := f.itemHidden.Load()
|
prev := f.itemHidden.Load()
|
||||||
f.truncateTail(step.target)
|
rt[i].err = f.truncateTail(step.target)
|
||||||
|
|
||||||
truncated := f.itemHidden.Load() - prev
|
truncated := f.itemHidden.Load() - prev
|
||||||
values = values[truncated:]
|
values = values[truncated:]
|
||||||
|
|
||||||
case opTruncateTailAll:
|
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
|
values = nil
|
||||||
}
|
}
|
||||||
// Abort the test on error.
|
// 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