]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Got file storage working with segment index
authorMatt Joiner <anacrolix@gmail.com>
Sun, 31 May 2020 14:14:51 +0000 (00:14 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 31 May 2020 14:14:51 +0000 (00:14 +1000)
client.go
common/upverted_files.go [new file with mode: 0644]
segments/segments.go
segments/segments_test.go
storage/file.go

index 9861f7ef3ee052c9aa3e664ed6fe933a8b25f840..a607b912477232d54b9c15c024b7f628af7f279d 100644 (file)
--- a/client.go
+++ b/client.go
@@ -1233,9 +1233,9 @@ func (cl *Client) AddTorrent(mi *metainfo.MetaInfo) (T *Torrent, err error) {
        var ss []string
        slices.MakeInto(&ss, mi.Nodes)
        cl.AddDHTNodes(ss)
-       for _, url := range mi.UrlList {
-               T.addWebSeed(url)
-       }
+       //for _, url := range mi.UrlList {
+       //T.addWebSeed(url)
+       //}
        return
 }
 
diff --git a/common/upverted_files.go b/common/upverted_files.go
new file mode 100644 (file)
index 0000000..1933e16
--- /dev/null
@@ -0,0 +1,18 @@
+package common
+
+import (
+       "github.com/anacrolix/torrent/metainfo"
+       "github.com/anacrolix/torrent/segments"
+)
+
+func LengthIterFromUpvertedFiles(fis []metainfo.FileInfo) segments.LengthIter {
+       i := 0
+       return func() (segments.Length, bool) {
+               if i == len(fis) {
+                       return -1, false
+               }
+               l := fis[i].Length
+               i++
+               return l, true
+       }
+}
index 97b611da02858f4e9692708ba61db2592691d829..4b3f5e8b67c4fb26bbb939df60fadb182488be89 100644 (file)
@@ -43,7 +43,7 @@ func Scan(haystack func() (Length, bool), needle Extent, callback Callback) {
                                if !callback(i, e1) {
                                        return
                                }
-                               needle.Start -= e1.Length
+                               needle.Start = 0
                                needle.Length -= e1.Length
                        }
                } else {
index 836fdbe0be916e7fec6f68206188d6a0c2a26ac0..8dcff6cc8a86faa162578f396d891d22a438fecb 100644 (file)
@@ -57,6 +57,26 @@ func testLocater(t *testing.T, newLocater newLocater) {
                Extent{6, 2},
                2,
                []Extent{})
+       assertLocate(t, newLocater,
+               []Length{1652, 1514, 1554, 1618, 1546, 129241752, 1537}, // 128737588
+               Extent{0, 16384},
+               0,
+               []Extent{
+                       {0, 1652},
+                       {0, 1514},
+                       {0, 1554},
+                       {0, 1618},
+                       {0, 1546},
+                       {0, 8500}})
+       assertLocate(t, newLocater,
+               []Length{1652, 1514, 1554, 1618, 1546, 129241752, 1537, 1536, 1551}, // 128737588
+               Extent{129236992, 16384},
+               5,
+               []Extent{
+                       {129229108, 12644},
+                       {0, 1537},
+                       {0, 1536},
+                       {0, 667}})
 }
 
 func TestScan(t *testing.T) {
index 013351d77f9be42066cdd1ad7728ad5cf50543bf..d0c0dfab38abde019247576cf7ae0122eceac54b 100644 (file)
@@ -2,10 +2,13 @@ package storage
 
 import (
        "io"
+       "log"
        "os"
        "path/filepath"
 
        "github.com/anacrolix/missinggo"
+       "github.com/anacrolix/torrent/common"
+       "github.com/anacrolix/torrent/segments"
 
        "github.com/anacrolix/torrent/metainfo"
 )
@@ -67,19 +70,24 @@ func (fs *fileClientImpl) OpenTorrent(info *metainfo.Info, infoHash metainfo.Has
        if err != nil {
                return nil, err
        }
+       upvertedFiles := info.UpvertedFiles()
        return &fileTorrentImpl{
                dir,
-               info,
+               info.Name,
+               upvertedFiles,
+               segments.NewIndex(common.LengthIterFromUpvertedFiles(upvertedFiles)),
                infoHash,
                fs.pc,
        }, nil
 }
 
 type fileTorrentImpl struct {
-       dir        string
-       info       *metainfo.Info
-       infoHash   metainfo.Hash
-       completion PieceCompletion
+       dir            string
+       infoName       string
+       upvertedFiles  []metainfo.FileInfo
+       segmentLocater segments.Index
+       infoHash       metainfo.Hash
+       completion     PieceCompletion
 }
 
 func (fts *fileTorrentImpl) Piece(p metainfo.Piece) PieceImpl {
@@ -154,62 +162,46 @@ func (fst *fileTorrentImplIO) readFileAt(fi metainfo.FileInfo, b []byte, off int
 
 // Only returns EOF at the end of the torrent. Premature EOF is ErrUnexpectedEOF.
 func (fst fileTorrentImplIO) ReadAt(b []byte, off int64) (n int, err error) {
-       for _, fi := range fst.fts.info.UpvertedFiles() {
-               for off < fi.Length {
-                       n1, err1 := fst.readFileAt(fi, b, off)
-                       n += n1
-                       off += int64(n1)
-                       b = b[n1:]
-                       if len(b) == 0 {
-                               // Got what we need.
-                               return
-                       }
-                       if n1 != 0 {
-                               // Made progress.
-                               continue
-                       }
-                       err = err1
-                       return
-               }
-               off -= fi.Length
+       fst.fts.segmentLocater.Locate(segments.Extent{off, int64(len(b))}, func(i int, e segments.Extent) bool {
+               n1, err1 := fst.readFileAt(fst.fts.upvertedFiles[i], b[:e.Length], e.Start)
+               n += n1
+               b = b[n1:]
+               err = err1
+               return err == nil // && int64(n1) == e.Length
+       })
+       if len(b) != 0 && err == nil {
+               err = io.EOF
        }
-       err = io.EOF
        return
 }
 
 func (fst fileTorrentImplIO) WriteAt(p []byte, off int64) (n int, err error) {
-       for _, fi := range fst.fts.info.UpvertedFiles() {
-               if off >= fi.Length {
-                       off -= fi.Length
-                       continue
-               }
-               n1 := len(p)
-               if int64(n1) > fi.Length-off {
-                       n1 = int(fi.Length - off)
-               }
-               name := fst.fts.fileInfoName(fi)
+       log.Printf("write at %v: %v bytes", off, len(p))
+       fst.fts.segmentLocater.Locate(segments.Extent{off, int64(len(p))}, func(i int, e segments.Extent) bool {
+               name := fst.fts.fileInfoName(fst.fts.upvertedFiles[i])
                os.MkdirAll(filepath.Dir(name), 0777)
                var f *os.File
                f, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE, 0666)
                if err != nil {
-                       return
-               }
-               n1, err = f.WriteAt(p[:n1], off)
-               // TODO: On some systems, write errors can be delayed until the Close.
-               f.Close()
-               if err != nil {
-                       return
+                       return false
                }
+               var n1 int
+               n1, err = f.WriteAt(p[:e.Length], e.Start)
+               log.Printf("%v %v wrote %v: %v", i, e, n1, err)
+               closeErr := f.Close()
                n += n1
-               off = 0
                p = p[n1:]
-               if len(p) == 0 {
-                       break
+               if err == nil {
+                       err = closeErr
                }
-       }
+               //if err == nil && int64(n1) != e.Length {
+               //      err = io.ErrShortWrite
+               //}
+               return err == nil
+       })
        return
 }
 
 func (fts *fileTorrentImpl) fileInfoName(fi metainfo.FileInfo) string {
-       return filepath.Join(append([]string{fts.dir, fts.info.Name}, fi.Path...)...)
+       return filepath.Join(append([]string{fts.dir, fts.infoName}, fi.Path...)...)
 }