github.com/uber/kraken@v0.1.4/lib/metainfogen/config.go (about)

     1  // Copyright (c) 2016-2019 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package metainfogen
    15  
    16  import (
    17  	"errors"
    18  	"sort"
    19  
    20  	"github.com/c2h5oh/datasize"
    21  )
    22  
    23  // Config defines Generator configuration.
    24  type Config struct {
    25  	PieceLengths map[datasize.ByteSize]datasize.ByteSize `yaml:"piece_lengths"`
    26  }
    27  
    28  type rangeConfig struct {
    29  	fileSize    int64
    30  	pieceLength int64
    31  }
    32  
    33  // pieceLengthConfig represents a sorted list joining file size to torrent piece
    34  // length for all files under said size, for example, these ranges:
    35  //
    36  //   [
    37  //     (0, 1mb),
    38  //     (2gb, 4mb),
    39  //     (4gb, 8mb),
    40  //   ]
    41  //
    42  // are interpreted as:
    43  //
    44  //   N < 2gb           : 1mb
    45  //   N >= 2gb, N < 4gb : 4mb
    46  //   N >= 4gb          : 8mb
    47  //
    48  type pieceLengthConfig struct {
    49  	ranges []rangeConfig
    50  }
    51  
    52  func newPieceLengthConfig(
    53  	pieceLengthByFileSize map[datasize.ByteSize]datasize.ByteSize) (*pieceLengthConfig, error) {
    54  
    55  	if len(pieceLengthByFileSize) == 0 {
    56  		return nil, errors.New("no piece lengths configured")
    57  	}
    58  	var ranges []rangeConfig
    59  	for fileSize, pieceLength := range pieceLengthByFileSize {
    60  		ranges = append(ranges, rangeConfig{
    61  			fileSize:    int64(fileSize),
    62  			pieceLength: int64(pieceLength),
    63  		})
    64  	}
    65  	sort.Slice(ranges, func(i, j int) bool {
    66  		return ranges[i].fileSize < ranges[j].fileSize
    67  	})
    68  	return &pieceLengthConfig{ranges}, nil
    69  }
    70  
    71  func (c *pieceLengthConfig) get(fileSize int64) int64 {
    72  	pieceLength := c.ranges[0].pieceLength
    73  	for _, r := range c.ranges {
    74  		if fileSize < r.fileSize {
    75  			break
    76  		}
    77  		pieceLength = r.pieceLength
    78  	}
    79  	return pieceLength
    80  }