From a44accadbe7e3e50ead041343a945f90cc9a699e Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 7 Oct 2013 10:35:10 +1100 Subject: [PATCH] Create more efficient writer method for MMapSpan for use with hashing --- client.go | 6 +----- cmd/torrent-verify/main.go | 19 +++++++++---------- mmap_span.go | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/client.go b/client.go index 7247321b..1eb15b9d 100644 --- a/client.go +++ b/client.go @@ -229,13 +229,9 @@ func (t *Torrent) PieceSize(piece int) (size int64) { return } -func (t *Torrent) PieceReader(piece int) io.Reader { - return io.NewSectionReader(t.Data, int64(piece)*t.MetaInfo.PieceLength, t.MetaInfo.PieceLength) -} - func (t *Torrent) HashPiece(piece int) (ps pieceSum) { hash := PieceHash.New() - n, err := io.Copy(hash, t.PieceReader(piece)) + n, err := t.Data.WriteSectionTo(hash, int64(piece)*t.MetaInfo.PieceLength, int64(piece)*t.MetaInfo.PieceLength) if err != nil { panic(err) } diff --git a/cmd/torrent-verify/main.go b/cmd/torrent-verify/main.go index 7259f0e2..993dfedb 100644 --- a/cmd/torrent-verify/main.go +++ b/cmd/torrent-verify/main.go @@ -5,8 +5,9 @@ import ( "bytes" "crypto/sha1" "flag" + "fmt" + "github.com/davecheney/profile" metainfo "github.com/nsf/libtorgo/torrent" - "io" "launchpad.net/gommap" "log" "os" @@ -23,6 +24,7 @@ func init() { } func main() { + defer profile.Start(profile.CPUProfile).Stop() metaInfo, err := metainfo.LoadFromFile(*filePath) if err != nil { log.Fatal(err) @@ -32,7 +34,7 @@ func main() { log.Print(err) } defer devZero.Close() - var mmapSpan torrent.MmapSpan + var mMapSpan torrent.MMapSpan for _, file := range metaInfo.Files { filename := filepath.Join(append([]string{*dirPath, metaInfo.Name}, file.Path...)...) osFile, err := os.Open(filename) @@ -52,24 +54,21 @@ func main() { log.Printf("file mmap has wrong size: %#v", filename) } osFile.Close() - mmapSpan = append(mmapSpan, torrent.Mmap{goMMap}) + mMapSpan = append(mMapSpan, torrent.MMap{goMMap}) } log.Println(len(metaInfo.Files)) - log.Println(mmapSpan.Size()) + log.Println(mMapSpan.Size()) log.Println(len(metaInfo.Pieces)) - for piece := int64(0); ; piece++ { + for piece := 0; piece < (len(metaInfo.Pieces)+sha1.Size-1)/sha1.Size; piece++ { expectedHash := metaInfo.Pieces[sha1.Size*piece : sha1.Size*(piece+1)] if len(expectedHash) == 0 { break } hash := sha1.New() - n, err := io.Copy(hash, io.NewSectionReader(mmapSpan, piece*metaInfo.PieceLength, metaInfo.PieceLength)) - if n != metaInfo.PieceLength { - panic("oh no") - } + _, err := mMapSpan.WriteSectionTo(hash, int64(piece)*metaInfo.PieceLength, metaInfo.PieceLength) if err != nil { log.Fatal(err) } - log.Println(piece, bytes.Equal(hash.Sum(nil), expectedHash)) + fmt.Println(piece, bytes.Equal(hash.Sum(nil), expectedHash)) } } diff --git a/mmap_span.go b/mmap_span.go index 9d2f39bb..fcc5cd4e 100644 --- a/mmap_span.go +++ b/mmap_span.go @@ -48,6 +48,24 @@ func (me MMapSpan) ReadAt(p []byte, off int64) (n int, err error) { return } +func (me MMapSpan) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) { + me.span().ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) { + var _n int + p := interval.(MMap).MMap[intervalOffset:] + if n < int64(len(p)) { + p = p[:n] + } + _n, err = w.Write(p) + written += int64(_n) + n -= int64(_n) + if err != nil { + return true + } + return n != 0 + }) + return +} + func (me MMapSpan) WriteAt(p []byte, off int64) (n int, err error) { me.span().ApplyTo(off, func(iOff int64, i sizer) (stop bool) { _n := copy(i.(MMap).MMap[iOff:], p) -- 2.48.1