@@ -186,6 +186,20 @@ func NewLDBStore(params *LDBStoreParams) (s *LDBStore, err error) {
186
186
return s , nil
187
187
}
188
188
189
+ // MarkAccessed increments the access counter as a best effort for a chunk, so
190
+ // the chunk won't get garbage collected.
191
+ func (s * LDBStore ) MarkAccessed (addr Address ) {
192
+ s .lock .Lock ()
193
+ defer s .lock .Unlock ()
194
+
195
+ if s .closed {
196
+ return
197
+ }
198
+
199
+ proximity := s .po (addr )
200
+ s .tryAccessIdx (addr , proximity )
201
+ }
202
+
189
203
// initialize and set values for processing of gc round
190
204
func (s * LDBStore ) startGC (c int ) {
191
205
@@ -349,6 +363,7 @@ func (s *LDBStore) collectGarbage() error {
349
363
s .delete (s .gc .batch .Batch , index , keyIdx , po )
350
364
singleIterationCount ++
351
365
s .gc .count ++
366
+ log .Trace ("garbage collect enqueued chunk for deletion" , "key" , hash )
352
367
353
368
// break if target is not on max garbage batch boundary
354
369
if s .gc .count >= s .gc .target {
@@ -685,12 +700,7 @@ func (s *LDBStore) Put(ctx context.Context, chunk Chunk) error {
685
700
idata , err := s .db .Get (ikey )
686
701
if err != nil {
687
702
s .doPut (chunk , & index , po )
688
- } else {
689
- log .Debug ("ldbstore.put: chunk already exists, only update access" , "key" , chunk .Address (), "po" , po )
690
- decodeIndex (idata , & index )
691
703
}
692
- index .Access = s .accessCnt
693
- s .accessCnt ++
694
704
idata = encodeIndex (& index )
695
705
s .batch .Put (ikey , idata )
696
706
@@ -723,7 +733,8 @@ func (s *LDBStore) doPut(chunk Chunk, index *dpaDBIndex, po uint8) {
723
733
s .entryCnt ++
724
734
dbEntryCount .Inc (1 )
725
735
s .dataIdx ++
726
-
736
+ index .Access = s .accessCnt
737
+ s .accessCnt ++
727
738
cntKey := make ([]byte , 2 )
728
739
cntKey [0 ] = keyDistanceCnt
729
740
cntKey [1 ] = po
@@ -796,18 +807,23 @@ func newMockEncodeDataFunc(mockStore *mock.NodeStore) func(chunk Chunk) []byte {
796
807
}
797
808
}
798
809
799
- // try to find index; if found, update access cnt and return true
800
- func (s * LDBStore ) tryAccessIdx (ikey []byte , po uint8 , index * dpaDBIndex ) bool {
810
+ // tryAccessIdx tries to find index entry. If found then increments the access
811
+ // count for garbage collection and returns the index entry and true for found,
812
+ // otherwise returns nil and false.
813
+ func (s * LDBStore ) tryAccessIdx (addr Address , po uint8 ) (* dpaDBIndex , bool ) {
814
+ ikey := getIndexKey (addr )
801
815
idata , err := s .db .Get (ikey )
802
816
if err != nil {
803
- return false
817
+ return nil , false
804
818
}
819
+
820
+ index := new (dpaDBIndex )
805
821
decodeIndex (idata , index )
806
822
oldGCIdxKey := getGCIdxKey (index )
807
823
s .batch .Put (keyAccessCnt , U64ToBytes (s .accessCnt ))
808
- s .accessCnt ++
809
824
index .Access = s .accessCnt
810
825
idata = encodeIndex (index )
826
+ s .accessCnt ++
811
827
s .batch .Put (ikey , idata )
812
828
newGCIdxKey := getGCIdxKey (index )
813
829
newGCIdxData := getGCIdxValue (index , po , ikey )
@@ -817,7 +833,7 @@ func (s *LDBStore) tryAccessIdx(ikey []byte, po uint8, index *dpaDBIndex) bool {
817
833
case s .batchesC <- struct {}{}:
818
834
default :
819
835
}
820
- return true
836
+ return index , true
821
837
}
822
838
823
839
// GetSchema is returning the current named schema of the datastore as read from LevelDB
@@ -858,12 +874,12 @@ func (s *LDBStore) Get(_ context.Context, addr Address) (chunk Chunk, err error)
858
874
859
875
// TODO: To conform with other private methods of this object indices should not be updated
860
876
func (s * LDBStore ) get (addr Address ) (chunk * chunk , err error ) {
861
- var indx dpaDBIndex
862
877
if s .closed {
863
878
return nil , ErrDBClosed
864
879
}
865
880
proximity := s .po (addr )
866
- if s .tryAccessIdx (getIndexKey (addr ), proximity , & indx ) {
881
+ index , found := s .tryAccessIdx (addr , proximity )
882
+ if found {
867
883
var data []byte
868
884
if s .getDataFunc != nil {
869
885
// if getDataFunc is defined, use it to retrieve the chunk data
@@ -874,12 +890,12 @@ func (s *LDBStore) get(addr Address) (chunk *chunk, err error) {
874
890
}
875
891
} else {
876
892
// default DbStore functionality to retrieve chunk data
877
- datakey := getDataKey (indx .Idx , proximity )
893
+ datakey := getDataKey (index .Idx , proximity )
878
894
data , err = s .db .Get (datakey )
879
- log .Trace ("ldbstore.get retrieve" , "key" , addr , "indexkey" , indx .Idx , "datakey" , fmt .Sprintf ("%x" , datakey ), "proximity" , proximity )
895
+ log .Trace ("ldbstore.get retrieve" , "key" , addr , "indexkey" , index .Idx , "datakey" , fmt .Sprintf ("%x" , datakey ), "proximity" , proximity )
880
896
if err != nil {
881
897
log .Trace ("ldbstore.get chunk found but could not be accessed" , "key" , addr , "err" , err )
882
- s .deleteNow (& indx , getIndexKey (addr ), s .po (addr ))
898
+ s .deleteNow (index , getIndexKey (addr ), s .po (addr ))
883
899
return
884
900
}
885
901
}
0 commit comments