Skip to content

Commit 7a68c09

Browse files
committed
core/rawdb: assume first item in freezer always start from zero
1 parent 1458933 commit 7a68c09

File tree

2 files changed

+52
-13
lines changed

2 files changed

+52
-13
lines changed

core/rawdb/freezer_table.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -519,16 +519,27 @@ func (t *freezerTable) Append(item uint64, blob []byte) error {
519519
// getBounds returns the indexes for the item
520520
// returns start, end, filenumber and error
521521
func (t *freezerTable) getBounds(item uint64) (uint32, uint32, uint32, error) {
522-
var startIdx, endIdx indexEntry
523522
buffer := make([]byte, indexEntrySize)
524-
if _, err := t.index.ReadAt(buffer, int64(item*indexEntrySize)); err != nil {
525-
return 0, 0, 0, err
526-
}
527-
startIdx.unmarshalBinary(buffer)
523+
var startIdx, endIdx indexEntry
524+
// Read second index
528525
if _, err := t.index.ReadAt(buffer, int64((item+1)*indexEntrySize)); err != nil {
529526
return 0, 0, 0, err
530527
}
531528
endIdx.unmarshalBinary(buffer)
529+
// Read first index (unless it's the very first item)
530+
if item != 0 {
531+
if _, err := t.index.ReadAt(buffer, int64(item*indexEntrySize)); err != nil {
532+
return 0, 0, 0, err
533+
}
534+
startIdx.unmarshalBinary(buffer)
535+
} else {
536+
// Special case if we're reading the first item in the freezer. We assume that
537+
// the first item always start from zero(regarding the deletion, we
538+
// only support deletion by files, so that the assumption is held).
539+
// This means we can use the first item metadata to carry information about
540+
// the 'global' offset, for the deletion-case
541+
return 0, endIdx.offset, endIdx.filenum, nil
542+
}
532543
if startIdx.filenum != endIdx.filenum {
533544
// If a piece of data 'crosses' a data-file,
534545
// it's actually in one piece on the second data-file.

core/rawdb/freezer_table_test.go

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -567,39 +567,67 @@ func TestOffset(t *testing.T) {
567567

568568
}
569569
// Now open again
570-
{
570+
checkPresent := func(numDeleted uint64) {
571571
f, err := newCustomTable(os.TempDir(), fname, rm, wm, sg, 40, true)
572572
if err != nil {
573573
t.Fatal(err)
574574
}
575575
f.printIndex()
576576
// It should allow writing item 6
577-
f.Append(6, getChunk(20, 0x99))
577+
f.Append(numDeleted+2, getChunk(20, 0x99))
578578

579579
// It should be fine to fetch 4,5,6
580-
if got, err := f.Retrieve(4); err != nil {
580+
if got, err := f.Retrieve(numDeleted); err != nil {
581581
t.Fatal(err)
582-
} else if exp := getChunk(16, 0xbb); !bytes.Equal(got, exp) {
582+
} else if exp := getChunk(20, 0xbb); !bytes.Equal(got, exp) {
583583
t.Fatalf("expected %x got %x", exp, got)
584584
}
585-
if got, err := f.Retrieve(5); err != nil {
585+
if got, err := f.Retrieve(numDeleted + 1); err != nil {
586586
t.Fatal(err)
587587
} else if exp := getChunk(20, 0xaa); !bytes.Equal(got, exp) {
588588
t.Fatalf("expected %x got %x", exp, got)
589589
}
590-
if got, err := f.Retrieve(6); err != nil {
590+
if got, err := f.Retrieve(numDeleted + 2); err != nil {
591591
t.Fatal(err)
592592
} else if exp := getChunk(20, 0x99); !bytes.Equal(got, exp) {
593593
t.Fatalf("expected %x got %x", exp, got)
594594
}
595595

596596
// It should error at 0, 1,2,3
597-
for i := 0; i < 4; i++ {
598-
if _, err := f.Retrieve(uint64(i)); err == nil {
597+
for i := numDeleted - 1; i > numDeleted-10; i-- {
598+
if _, err := f.Retrieve(i); err == nil {
599599
t.Fatal("expected err")
600600
}
601601
}
602602
}
603+
checkPresent(4)
604+
// Now, let's pretend we have deleted 1M items
605+
{
606+
// Read the index file
607+
p := filepath.Join(os.TempDir(), fmt.Sprintf("%v.ridx", fname))
608+
indexFile, err := os.OpenFile(p, os.O_RDWR, 0644)
609+
if err != nil {
610+
t.Fatal(err)
611+
}
612+
indexBuf := make([]byte, 3*indexEntrySize)
613+
indexFile.Read(indexBuf)
614+
615+
// Update the index file, so that we store
616+
// [ file = 2, offset = 1M ] at index zero
617+
618+
tailId := uint32(2) // First file is 2
619+
itemOffset := uint32(1000000) // We have removed 1M items
620+
zeroIndex := indexEntry{
621+
offset: itemOffset,
622+
filenum: tailId,
623+
}
624+
buf := zeroIndex.marshallBinary()
625+
// Overwrite index zero
626+
copy(indexBuf, buf)
627+
indexFile.WriteAt(indexBuf, 0)
628+
indexFile.Close()
629+
}
630+
checkPresent(1000000)
603631
}
604632

605633
// TODO (?)

0 commit comments

Comments
 (0)