diff --git a/weed/storage/volume_backup.go b/weed/storage/volume_backup.go index 7aad2b971..a8ec50cad 100644 --- a/weed/storage/volume_backup.go +++ b/weed/storage/volume_backup.go @@ -194,12 +194,31 @@ func (v *Volume) BinarySearchByAppendAtNs(sinceNs uint64) (offset Offset, isLast err = fmt.Errorf("read entry %d: %v", m, err) return } - for ; offset.IsZero() && m < h; m++ { - offset, err = v.readOffsetFromIndex(m) - if err != nil { - err = fmt.Errorf("read entry %d: %v", m, err) + if offset.IsZero() { + leftIndex, _, leftNs, leftErr := v.readLeftNs(m) + if leftErr != nil { + err = leftErr return } + rightIndex, rightOffset, rightNs, rightErr := v.readRightNs(m) + if rightErr != nil { + err = rightErr + return + } + if rightNs <= sinceNs { + l = rightIndex + if l == entryCount { + return Offset{}, true, nil + } else { + continue + } + } + if sinceNs < leftNs { + h = leftIndex + 1 + continue + } + return rightOffset, false, nil + } if offset.IsZero() { return Offset{}, true, nil @@ -230,6 +249,38 @@ func (v *Volume) BinarySearchByAppendAtNs(sinceNs uint64) (offset Offset, isLast } +func (v *Volume) readRightNs(m int64) (index int64, offset Offset, ts uint64, err error) { + index = m + for offset.IsZero() { + index++ + offset, err = v.readOffsetFromIndex(index) + if err != nil { + err = fmt.Errorf("read entry %d: %v", index, err) + return + } + } + if !offset.IsZero() { + ts, err = v.readAppendAtNs(offset) + } + return +} + +func (v *Volume) readLeftNs(m int64) (index int64, offset Offset, ts uint64, err error) { + index = m + for offset.IsZero() { + index-- + offset, err = v.readOffsetFromIndex(index) + if err != nil { + err = fmt.Errorf("read entry %d: %v", index, err) + return + } + } + if !offset.IsZero() { + ts, err = v.readAppendAtNs(offset) + } + return +} + // bytes is of size NeedleMapEntrySize func (v *Volume) readOffsetFromIndex(m int64) (Offset, error) { v.dataFileAccessLock.RLock() diff --git a/weed/storage/volume_write_test.go b/weed/storage/volume_write_test.go index e0ee3dac7..4245bdb52 100644 --- a/weed/storage/volume_write_test.go +++ b/weed/storage/volume_write_test.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/chrislusf/seaweedfs/weed/storage/needle" "github.com/chrislusf/seaweedfs/weed/storage/super_block" + "github.com/chrislusf/seaweedfs/weed/storage/types" "io/ioutil" "os" "testing" @@ -22,7 +23,7 @@ func TestSearchVolumesWithDeletedNeedles(t *testing.T) { t.Fatalf("volume creation: %v", err) } - count := 10 + count := 20 for i:=1;i