From e2a559e2435a0629164f69142274c9a131afc24b Mon Sep 17 00:00:00 2001 From: Zilog8 Date: Tue, 8 Jun 2021 01:45:35 -0400 Subject: [PATCH] Allow Storage Backends to do their own Hashing (#518) * Allow Storage Backends to do their own Hashing - Describes an optional interface 'SelfHashing' that a storage backend's type implementing 'PieceImpl' may also implement in order to calculate piece hashsums itself. - Alters the 'hashPiece' function in the torrent package to look for types implementing 'SelfHashing' . If not implemented, calculate the hash as usual. --- storage/interface.go | 10 ++++++++-- torrent.go | 12 +++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/storage/interface.go b/storage/interface.go index 869556f8..584338cb 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -22,8 +22,9 @@ type TorrentImpl interface { Close() error } -// Interacts with torrent piece data. Optional interfaces to implement include io.WriterTo, such as -// when a piece supports a more efficient way to write out incomplete chunks +// Interacts with torrent piece data. Optional interfaces to implement include: +// io.WriterTo, such as when a piece supports a more efficient way to write out incomplete chunks. +// SelfHashing, such as when a piece supports a more efficient way to hash its contents. type PieceImpl interface { // These interfaces are not as strict as normally required. They can // assume that the parameters are appropriate for the dimensions of the @@ -43,3 +44,8 @@ type Completion struct { Complete bool Ok bool } + +// Allows a storage backend to override hashing (i.e. if it can do it more efficiently than the torrent client can) +type SelfHashing interface { + SelfHash() (metainfo.Hash, error) +} diff --git a/torrent.go b/torrent.go index e3876474..82b70c13 100644 --- a/torrent.go +++ b/torrent.go @@ -810,10 +810,20 @@ func (t *Torrent) pieceLength(piece pieceIndex) pp.Integer { } func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash, err error) { - hash := pieceHash.New() p := t.piece(piece) p.waitNoPendingWrites() storagePiece := t.pieces[piece].Storage() + + //Does the backend want to do its own hashing? + if i, ok := storagePiece.PieceImpl.(storage.SelfHashing); ok { + var sum metainfo.Hash + //log.Printf("A piece decided to self-hash: %d", piece) + sum, err = i.SelfHash() + missinggo.CopyExact(&ret, sum) + return + } + + hash := pieceHash.New() const logPieceContents = false if logPieceContents { var examineBuf bytes.Buffer -- 2.44.0