Example #1
0
func (me *store) pieceComplete(p metainfo.Piece) bool {
	if me.completionKnown(p) {
		return me.isComplete(p)
	}
	// Prevent a errors from stalling the caller.
	if !me.lastError.IsZero() && time.Since(me.lastError) < time.Second {
		return false
	}
	length, err := me.db.GetLength(me.completedPiecePath(p))
	if err == dataBackend.ErrNotFound {
		me.setCompletion(p, false)
		return false
	}
	if err != nil {
		me.lastError = time.Now()
		log.Printf("%+v", err)
		return false
	}
	complete := length == p.Length()
	if !complete {
		log.Printf("completed piece %x has wrong length: %d", p.Hash(), length)
	}
	me.setCompletion(p, complete)
	return complete
}
Example #2
0
func (me *store) path(p metainfo.Piece, completed bool) string {
	return filepath.Join(me.baseDir, func() string {
		if completed {
			return "complete"
		} else {
			return "incomplete"
		}
	}(), fmt.Sprintf("%x", p.Hash()))
}
Example #3
0
func (me *mapPieceCompletion) Set(p metainfo.Piece, b bool) error {
	if b {
		if me.m == nil {
			me.m = make(map[metainfo.PieceKey]struct{})
		}
		me.m[p.Key()] = struct{}{}
	} else {
		delete(me.m, p.Key())
	}
	return nil
}
Example #4
0
func (me *store) PieceCompleted(p metainfo.Piece) (err error) {
	hash, err := me.hashCopyFile(me.incompletePiecePath(p), me.completedPiecePath(p), p.Length())
	if err == nil && !bytes.Equal(hash, p.Hash()) {
		err = errors.New("piece incomplete")
	}
	if err != nil {
		me.deleteCompleted(p)
		return
	}
	me.removePath(me.incompletePiecePath(p))
	me.setCompletion(p, true)
	return
}
Example #5
0
func (me *store) PieceCompleted(p metainfo.Piece) (err error) {
	err = me.makeSpace(p.Length())
	if err != nil {
		return
	}
	var (
		incompletePiecePath = me.path(p, false)
		completedPiecePath  = me.path(p, true)
	)
	fSrc, err := os.Open(incompletePiecePath)
	if err != nil {
		return
	}
	defer fSrc.Close()
	os.MkdirAll(filepath.Dir(completedPiecePath), dirPerm)
	fDst, err := os.OpenFile(completedPiecePath, os.O_EXCL|os.O_CREATE|os.O_WRONLY, filePerm)
	if err != nil {
		return
	}
	defer fDst.Close()
	hasher := sha1.New()
	r := io.TeeReader(io.LimitReader(fSrc, p.Length()), hasher)
	_, err = io.Copy(fDst, r)
	if err != nil {
		return
	}
	if !bytes.Equal(hasher.Sum(nil), p.Hash()) {
		err = errors.New("piece incomplete")
		os.Remove(completedPiecePath)
		return
	}
	os.Remove(incompletePiecePath)
	me.completed[sliceToPieceHashArray(p.Hash())] = struct{}{}
	return
}
Example #6
0
func (s *piecePerResource) Piece(p metainfo.Piece) Piece {
	completed, err := s.p.NewInstance(path.Join("completed", p.Hash().HexString()))
	if err != nil {
		panic(err)
	}
	incomplete, err := s.p.NewInstance(path.Join("incomplete", p.Hash().HexString()))
	if err != nil {
		panic(err)
	}
	return piecePerResourcePiece{
		p: p,
		c: completed,
		i: incomplete,
	}
}
Example #7
0
func (me *mmapTorrentStorage) Piece(p metainfo.Piece) Piece {
	return mmapStoragePiece{
		storage:  me,
		p:        p,
		ReaderAt: io.NewSectionReader(me.span, p.Offset(), p.Length()),
		WriterAt: missinggo.NewSectionWriter(me.span, p.Offset(), p.Length()),
	}
}
Example #8
0
func (fts *fileTorrentStorage) Piece(p metainfo.Piece) Piece {
	// Create a view onto the file-based torrent storage.
	_io := fileStorageTorrent{fts}
	// Return the appropriate segments of this.
	return &fileStoragePiece{
		fts,
		p,
		missinggo.NewSectionWriter(_io, p.Offset(), p.Length()),
		io.NewSectionReader(_io, p.Offset(), p.Length()),
	}
}
Example #9
0
func (me *fileStorage) Piece(p metainfo.Piece) Piece {
	_io := &fileStorageTorrent{
		p.Info,
		me.baseDir,
	}
	return &fileStoragePiece{
		me,
		p,
		missinggo.NewSectionWriter(_io, p.Offset(), p.Length()),
		io.NewSectionReader(_io, p.Offset(), p.Length()),
	}
}
Example #10
0
// Returns the file for the given piece, if it exists. It could be completed,
// or incomplete.
func (me *store) pieceRead(p metainfo.Piece) (f *os.File) {
	f, err := os.Open(me.path(p, true))
	if err == nil {
		return
	}
	if !os.IsNotExist(err) {
		panic(err)
	}
	// Mark the file not completed, in case we thought it was. TODO: Trigger
	// an asynchronous initCompleted to reinitialize the entire completed map
	// as there are likely other files missing.
	me.mu.Lock()
	delete(me.completed, sliceToPieceHashArray(p.Hash()))
	me.mu.Unlock()
	f, err = os.Open(me.path(p, false))
	if err == nil {
		return
	}
	if !os.IsNotExist(err) {
		panic(err)
	}
	return
}
Example #11
0
File: db.go Project: ymonk/torrent
func (me *dbPieceCompletion) Get(p metainfo.Piece) (ret bool, err error) {
	row := me.db.QueryRow(`select exists(select * from completed where infohash=? and "index"=?)`, p.Info.Hash().HexString(), p.Index())
	err = row.Scan(&ret)
	return
}
Example #12
0
func (me *data) pieceReader(p metainfo.Piece, off int64) (ret io.ReadCloser, err error) {
	return me.store.getPieceRange(p, off, p.Length()-off)
}
Example #13
0
func pieceHashArray(p metainfo.Piece) [20]byte {
	return sliceToPieceHashArray(p.Hash())
}
Example #14
0
func (me *store) incompletePiecePath(p metainfo.Piece) string {
	return path.Join(
		"incomplete",
		strconv.FormatInt(int64(os.Getpid()), 10),
		hex.EncodeToString(p.Hash()))
}
Example #15
0
func (me *store) completedPiecePath(p metainfo.Piece) string {
	return path.Join("completed", hex.EncodeToString(p.Hash()))
}
Example #16
0
func (me *store) pieceComplete(p metainfo.Piece) bool {
	_, ok := me.completed[sliceToPieceHashArray(p.Hash())]
	return ok
}
Example #17
0
func (me *store) pieceComplete(p metainfo.Piece) bool {
	me.mu.Lock()
	defer me.mu.Unlock()
	_, ok := me.completed[sliceToPieceHashArray(p.Hash())]
	return ok
}
Example #18
0
File: db.go Project: ymonk/torrent
func (me *dbPieceCompletion) Set(p metainfo.Piece, b bool) (err error) {
	if b {
		_, err = me.db.Exec(`insert into completed (infohash, "index") values (?, ?)`, p.Info.Hash().HexString(), p.Index())
	} else {
		_, err = me.db.Exec(`delete from completed where infohash=? and "index"=?`, p.Info.Hash().HexString(), p.Index())
	}
	return
}
Example #19
0
func (me *mapPieceCompletion) Get(p metainfo.Piece) (bool, error) {
	_, ok := me.m[p.Key()]
	return ok, nil
}