From: Marco Vidonis <31407403+marcovidonis@users.noreply.github.com> Date: Thu, 23 Jun 2022 12:44:06 +0000 (+0100) Subject: optimise torrent piece length (#758) X-Git-Tag: v1.46.0~2 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=8f711b633fbaaff3d4e41cc831496853663ff55a;p=btrtrc.git optimise torrent piece length (#758) --- diff --git a/cmd/torrent/piece-length.go b/cmd/torrent/piece-length.go new file mode 100644 index 00000000..b6574fd3 --- /dev/null +++ b/cmd/torrent/piece-length.go @@ -0,0 +1,53 @@ +// From https://github.com/jackpal/Taipei-Torrent + +// Copyright (c) 2010 Jack Palevich. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package main + +// For more context on why these numbers, see http://wiki.vuze.com/w/Torrent_Piece_Size +const MinimumPieceLength = 16 * 1024 +const TargetPieceCountLog2 = 10 +const TargetPieceCountMin = 1 << TargetPieceCountLog2 + +// Target piece count should be < TargetPieceCountMax +const TargetPieceCountMax = TargetPieceCountMin << 1 + +// Choose a good piecelength. +func choosePieceLength(totalLength int64) (pieceLength int64) { + // Must be a power of 2. + // Must be a multiple of 16KB + // Prefer to provide around 1024..2048 pieces. + pieceLength = MinimumPieceLength + pieces := totalLength / pieceLength + for pieces >= TargetPieceCountMax { + pieceLength <<= 1 + pieces >>= 1 + } + return +} diff --git a/cmd/torrent/serve.go b/cmd/torrent/serve.go index a6a47aae..7915ddd9 100644 --- a/cmd/torrent/serve.go +++ b/cmd/torrent/serve.go @@ -27,8 +27,13 @@ func serve(ctx args.SubCmdCtx) error { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { cl.WriteStatus(w) }) + totalLength, err := totalLength(filePath) + if err != nil { + return fmt.Errorf("calculating total length of %q: %v", filePath, err) + } + pieceLength := choosePieceLength(totalLength) info := metainfo.Info{ - PieceLength: 1 << 18, + PieceLength: pieceLength, } err = info.BuildFromFilePath(filePath) if err != nil { diff --git a/cmd/torrent/total-length.go b/cmd/torrent/total-length.go new file mode 100644 index 00000000..52888eef --- /dev/null +++ b/cmd/torrent/total-length.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" +) + +func totalLength(path string) (totalLength int64, err error) { + err = filepath.Walk(path, func(path string, info os.FileInfo, err error) error { + if info.IsDir() { + return nil + } + totalLength += info.Size() + return nil + }) + if err != nil { + return 0, fmt.Errorf("walking path, %w", err) + } + return totalLength, nil +}