diff --git a/bzz/dbstore.go b/bzz/dbstore.go index 44c42bb620..510f2a59bd 100644 --- a/bzz/dbstore.go +++ b/bzz/dbstore.go @@ -6,6 +6,7 @@ package bzz import ( "bytes" "encoding/binary" + "fmt" "sync" "github.com/ethereum/go-ethereum/ethdb" @@ -192,7 +193,7 @@ func (s *dbStore) collectGarbage(ratio float32) { } gcnt := 0 - for gcnt < gcArraySize { + for (gcnt < gcArraySize) && (uint64(gcnt) < s.entryCnt) { if (s.gcPos == nil) || (s.gcPos[0] != kpIndex) { it.Seek(s.gcStartPos) @@ -227,11 +228,11 @@ func (s *dbStore) collectGarbage(ratio float32) { cutidx := gcListSelect(s.gcArray, 0, gcnt-1, int(float32(gcnt)*ratio)) cutval := s.gcArray[cutidx].value - //fmt.Print(s.entryCnt, " ") + fmt.Print(gcnt, " ", s.entryCnt, " ") // actual gc for i := 0; i < gcnt; i++ { - if s.gcArray[i].value < cutval { + if s.gcArray[i].value <= cutval { batch := new(leveldb.Batch) batch.Delete(s.gcArray[i].idxKey) batch.Delete(getDataKey(s.gcArray[i].idx)) @@ -241,7 +242,7 @@ func (s *dbStore) collectGarbage(ratio float32) { } } - //fmt.Println(s.entryCnt) + fmt.Println(s.entryCnt) s.db.Put(keyGCPos, s.gcPos) @@ -352,9 +353,12 @@ func (s *dbStore) setCapacity(c uint64) { if s.entryCnt > c { var ratio float32 - ratio = float32(0.99) - float32(c)/float32(s.entryCnt) - if ratio < 0 { - ratio = 0 + ratio = float32(1.01) - float32(c)/float32(s.entryCnt) + if ratio < gcArrayFreeRatio { + ratio = gcArrayFreeRatio + } + if ratio > 1 { + ratio = 1 } for s.entryCnt > c { s.collectGarbage(ratio) diff --git a/bzz/dpa_test.go b/bzz/dpa_test.go index 82dfb40a2c..443efd23db 100644 --- a/bzz/dpa_test.go +++ b/bzz/dpa_test.go @@ -8,6 +8,8 @@ import ( // "time" ) +const testDataSize = 0x1000000 + func TestDPA(t *testing.T) { test.LogInit() os.RemoveAll("/tmp/bzz") @@ -27,7 +29,7 @@ func TestDPA(t *testing.T) { ChunkStore: localStore, } dpa.Start() - reader, slice := testDataReader(0x1000000) + reader, slice := testDataReader(testDataSize) key, err := dpa.Store(reader) if err != nil { t.Errorf("Store error: %v", err) @@ -60,3 +62,58 @@ func TestDPA(t *testing.T) { t.Errorf("Comparison error after removing memStore.") } } + +func TestDPA_capacity(t *testing.T) { + test.LogInit() + os.RemoveAll("/tmp/bzz") + dbStore, err := newDbStore("/tmp/bzz") + if err != nil { + t.Errorf("DB error: %v", err) + } + memStore := newMemStore(dbStore) + localStore := &localStore{ + memStore, + dbStore, + } + localStore.memStore.setCapacity(0) + chunker := &TreeChunker{} + chunker.Init() + dpa := &DPA{ + Chunker: chunker, + ChunkStore: localStore, + } + dpa.Start() + reader, slice := testDataReader(testDataSize) + key, err := dpa.Store(reader) + if err != nil { + t.Errorf("Store error: %v", err) + } + resultReader := dpa.Retrieve(key) + resultSlice := make([]byte, len(slice)) + n, err := resultReader.ReadAt(resultSlice, 0) + if err != nil { + t.Errorf("Retrieve error: %v", err) + } + if n != len(slice) { + t.Errorf("Slice size error got %d, expected %d.", n, len(slice)) + } + if !bytes.Equal(slice, resultSlice) { + t.Errorf("Comparison error.") + } + localStore.memStore.setCapacity(0) + // localStore.dbStore.setCapacity(0) + resultReader = dpa.Retrieve(key) + for i, _ := range resultSlice { + resultSlice[i] = 0 + } + n, err = resultReader.ReadAt(resultSlice, 0) + if err != nil { + t.Errorf("Retrieve error after removing memStore: %v", err) + } + if n != len(slice) { + t.Errorf("Slice size error after removing memStore got %d, expected %d.", n, len(slice)) + } + if !bytes.Equal(slice, resultSlice) { + t.Errorf("Comparison error after removing memStore.") + } +}