@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "errors"
2222 "fmt"
23+ "github.com/ethersphere/swarm/shed"
2324 "time"
2425
2526 "github.com/ethereum/go-ethereum/metrics"
@@ -201,7 +202,7 @@ func (db *DB) setSync(batch *leveldb.Batch, addr chunk.Address, mode chunk.ModeS
201202 // provided by the access function, and it is not
202203 // a property of a chunk provided to Accessor.Put.
203204
204- i , err := db .retrievalDataIndex .Get (item )
205+ accessIndexItem , err := db .retrievalDataIndex .Get (item )
205206 if err != nil {
206207 if err == leveldb .ErrNotFound {
207208 // chunk is not found,
@@ -213,8 +214,8 @@ func (db *DB) setSync(batch *leveldb.Batch, addr chunk.Address, mode chunk.ModeS
213214 }
214215 return 0 , err
215216 }
216- item .StoreTimestamp = i .StoreTimestamp
217- item .BinID = i .BinID
217+ item .StoreTimestamp = accessIndexItem .StoreTimestamp
218+ item .BinID = accessIndexItem .BinID
218219
219220 switch mode {
220221 case chunk .ModeSetSyncPull :
@@ -286,10 +287,10 @@ func (db *DB) setSync(batch *leveldb.Batch, addr chunk.Address, mode chunk.ModeS
286287 db .pushIndex .DeleteInBatch (batch , item )
287288 }
288289
289- i , err = db .retrievalAccessIndex .Get (item )
290+ accessIndexItem , err = db .retrievalAccessIndex .Get (item )
290291 switch err {
291292 case nil :
292- item .AccessTimestamp = i .AccessTimestamp
293+ item .AccessTimestamp = accessIndexItem .AccessTimestamp
293294 db .gcIndex .DeleteInBatch (batch , item )
294295 gcSizeChange --
295296 case leveldb .ErrNotFound :
@@ -306,50 +307,57 @@ func (db *DB) setSync(batch *leveldb.Batch, addr chunk.Address, mode chunk.ModeS
306307 return 0 , err
307308 }
308309 if ! pinned {
309- // set access timestamp based on quantile calculated from
310- // chunk proximity and db.responsibilityRadius
311- f := chunkQuantileFraction (int (db .po (item .Address )), db .getResponsibilityRadius ())
312- gcSize , err := db .gcSize .Get ()
310+ err := db .addToGC (batch , item , accessIndexItem )
313311 if err != nil {
314312 return 0 , err
315313 }
316- position := quantilePosition (gcSize , f .Numerator , f .Denominator )
317- var gcQuantiles quantiles
318- err = db .gcQuantiles .Get (& gcQuantiles )
319- if err != nil && err != leveldb .ErrNotFound {
320- return 0 , err
314+ gcSizeChange ++
315+ }
316+
317+ return gcSizeChange , nil
318+ }
319+
320+ func (db * DB ) addToGC (batch * leveldb.Batch , item shed.Item , i shed.Item ) error {
321+ // set access timestamp based on quantile calculated from
322+ // chunk proximity and db.responsibilityRadius
323+ f := db .gcPolicy .GetEvictionMetric (item .Address )
324+ gcSize , err := db .gcSize .Get ()
325+ if err != nil {
326+ return err
327+ }
328+ position := quantilePosition (gcSize , f .Numerator , f .Denominator )
329+ var gcQuantiles quantiles
330+ err = db .gcQuantiles .Get (& gcQuantiles )
331+ if err != nil && err != leveldb .ErrNotFound {
332+ return err
333+ }
334+ var found bool
335+ for _ , q := range gcQuantiles {
336+ if q .Fraction == f {
337+ item .AccessTimestamp = q .Item .AccessTimestamp + 1
338+ found = true
339+ break
321340 }
322- var found bool
323- for _ , q := range gcQuantiles {
324- if q . Fraction == f {
325- item . AccessTimestamp = q . Item . AccessTimestamp + 1
326- found = true
327- break
328- }
341+ }
342+ if len ( gcQuantiles ) > 0 && ! found {
343+ var shift int64
344+ if closest := gcQuantiles . Closest ( f ); closest == nil {
345+ shift = int64 ( position )
346+ } else {
347+ shift = int64 ( closest . Position ) - int64 ( position )
329348 }
330- if len (gcQuantiles ) > 0 && ! found {
331- var shift int64
332- if closest := gcQuantiles .Closest (f ); closest == nil {
333- shift = int64 (position )
334- } else {
335- shift = int64 (closest .Position ) - int64 (position )
336- }
337- i , err = db .gcIndex .Offset (nil , shift )
338- if err != nil {
339- return 0 , err
340- }
349+ i , err = db .gcIndex .Offset (nil , shift )
350+ if err == nil {
341351 item .AccessTimestamp = i .AccessTimestamp + 1
342352 }
343- gcQuantiles = gcQuantiles .Set (f , item , position )
344- db .gcQuantiles .PutInBatch (batch , gcQuantiles )
345-
346- db .retrievalAccessIndex .PutInBatch (batch , item )
347- db .pushIndex .DeleteInBatch (batch , item )
348- db .gcIndex .PutInBatch (batch , item )
349- gcSizeChange ++
350353 }
354+ gcQuantiles = gcQuantiles .Set (f , item , position )
355+ db .gcQuantiles .PutInBatch (batch , gcQuantiles )
351356
352- return gcSizeChange , nil
357+ db .retrievalAccessIndex .PutInBatch (batch , item )
358+ db .pushIndex .DeleteInBatch (batch , item )
359+ db .gcIndex .PutInBatch (batch , item )
360+ return nil
353361}
354362
355363// setRemove removes the chunk by updating indexes:
0 commit comments