From: Matt Joiner <anacrolix@gmail.com>
Date: Sun, 6 Oct 2013 23:35:10 +0000 (+1100)
Subject: Create more efficient writer method for MMapSpan for use with hashing
X-Git-Tag: v1.0.0~1799
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=a44accadbe7e3e50ead041343a945f90cc9a699e;p=btrtrc.git

Create more efficient writer method for MMapSpan for use with hashing
---

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)