]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add PrefixDeleter support to ResourcePieces storage
authorMatt Joiner <anacrolix@gmail.com>
Sat, 9 Mar 2024 23:29:05 +0000 (10:29 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 9 Mar 2024 23:29:05 +0000 (10:29 +1100)
go.mod
go.sum
storage/issue96_test.go
storage/piece-resource.go
storage/possum/possum_test.go

diff --git a/go.mod b/go.mod
index 1af03a6edd73e57be5e46847b734f93afd61927e..51402c253d78d77aa68fb87cd2659dcbfb12428a 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
        github.com/anacrolix/missinggo/perf v1.0.0
        github.com/anacrolix/missinggo/v2 v2.7.3
        github.com/anacrolix/multiless v0.3.0
-       github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315
+       github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8
        github.com/anacrolix/squirrel v0.6.0
        github.com/anacrolix/sync v0.5.1
        github.com/anacrolix/tagflag v1.3.0
diff --git a/go.sum b/go.sum
index fb5f86b14f10b09ab79cce4838e8b88ab583242b..0834ba1b947d37b6a467065e74700b41ed940162 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -107,8 +107,8 @@ github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg=
 github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl4thEPc=
 github.com/anacrolix/multiless v0.3.0 h1:5Bu0DZncjE4e06b9r1Ap2tUY4Au0NToBP5RpuEngSis=
 github.com/anacrolix/multiless v0.3.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4=
-github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315 h1:bwdpi8LWvEHrNgsu44SKmCzLeZ5iEH4rwmNafDdRHJ4=
-github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315/go.mod h1:pw5HEMBSiL+otYzHe4q5jGaVuy5unl+Mt4Bx6SDemW8=
+github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8 h1:XDKUI9RHyhyfGXVXb/4N+l5kGo5jQITrrbF7EZPLuak=
+github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8/go.mod h1:pw5HEMBSiL+otYzHe4q5jGaVuy5unl+Mt4Bx6SDemW8=
 github.com/anacrolix/squirrel v0.6.0 h1:ovfWW42wcGzrVYYI9s56pEYzfeTwtXxCCvSd+KwvUEA=
 github.com/anacrolix/squirrel v0.6.0/go.mod h1:60vdNPUbK1jYWePp39Wqn9whHm12Yb9JEuwOXzLMDuY=
 github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg=
index 1be98aa5e738cd8976e7587d96759638175be916..d9857881a7c0a8d6a8b0a963e0710920859e1251 100644 (file)
@@ -1,9 +1,9 @@
 package storage
 
 import (
-       g "github.com/anacrolix/generics"
        "testing"
 
+       g "github.com/anacrolix/generics"
        "github.com/stretchr/testify/require"
 
        "github.com/anacrolix/torrent/metainfo"
index 94325027b047a27f52f25e9d5871b3a3e04d4aa1..1b0ae236a5f3c633afd7f95020eac046ec02045c 100644 (file)
@@ -75,6 +75,10 @@ type ConsecutiveChunkReader interface {
        ReadConsecutiveChunks(prefix string) (io.ReadCloser, error)
 }
 
+type PrefixDeleter interface {
+       DeletePrefix(prefix string) error
+}
+
 type piecePerResourcePiece struct {
        mp metainfo.Piece
        // The piece hash if we have it. It could be 20 or 32 bytes depending on the info version.
@@ -140,7 +144,7 @@ type SizedPutter interface {
        PutSized(io.Reader, int64) error
 }
 
-func (s piecePerResourcePiece) MarkComplete() error {
+func (s piecePerResourcePiece) MarkComplete() (err error) {
        s.mu.Lock()
        defer s.mu.Unlock()
        incompleteChunks := s.getChunks()
@@ -162,11 +166,20 @@ func (s piecePerResourcePiece) MarkComplete() error {
                        return completedInstance.Put(r)
                }
        }()
-       if err == nil && !s.opts.LeaveIncompleteChunks {
-               // I think we do this synchronously here since we don't want callers to act on the completed
-               // piece if we're concurrently still deleting chunks. The caller may decide to start
-               // downloading chunks again and won't expect us to delete them. It seems to be much faster
-               // to let the resource provider do this if possible.
+       if err != nil || s.opts.LeaveIncompleteChunks {
+               return
+       }
+
+       // I think we do this synchronously here since we don't want callers to act on the completed
+       // piece if we're concurrently still deleting chunks. The caller may decide to start
+       // downloading chunks again and won't expect us to delete them. It seems to be much faster
+       // to let the resource provider do this if possible.
+       if pd, ok := s.rp.(PrefixDeleter); ok {
+               err = pd.DeletePrefix(s.incompleteDirPath() + "/")
+               if err != nil {
+                       err = fmt.Errorf("deleting incomplete prefix: %w", err)
+               }
+       } else {
                var wg sync.WaitGroup
                for _, c := range incompleteChunks {
                        wg.Add(1)
index 1c0e81105db25851e47c43649495e2e397569337..3abefd49332d557163a2f24fa509c517ccf7f666 100644 (file)
@@ -28,5 +28,11 @@ func BenchmarkProvider(b *testing.B) {
        clientStorageImpl := storage.NewResourcePiecesOpts(
                possumTorrentProvider,
                storage.ResourcePiecesOpts{LeaveIncompleteChunks: true})
-       test_storage.BenchmarkPieceMarkComplete(b, clientStorageImpl, test_storage.DefaultPieceSize, test_storage.DefaultNumPieces, 0)
+       test_storage.BenchmarkPieceMarkComplete(
+               b,
+               clientStorageImpl,
+               test_storage.DefaultPieceSize,
+               test_storage.DefaultNumPieces,
+               0,
+       )
 }