forked from cerc-io/ipld-eth-server
Update vendor directory and make necessary code changes
Fixes for new geth version
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
os:
|
||||
- linux
|
||||
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.11.x
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOTFLAGS="-race"
|
||||
matrix:
|
||||
- BUILD_DEPTYPE=gx
|
||||
- BUILD_DEPTYPE=gomod
|
||||
|
||||
|
||||
# disable travis install
|
||||
install:
|
||||
- true
|
||||
|
||||
script:
|
||||
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
|
||||
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $GOPATH/src/gx
|
||||
- $GOPATH/pkg/mod
|
||||
- $HOME/.cache/go-build
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 IPFS
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
all: deps
|
||||
gx:
|
||||
go get github.com/whyrusleeping/gx
|
||||
go get github.com/whyrusleeping/gx-go
|
||||
deps: gx
|
||||
gx --verbose install --global
|
||||
gx-go rewrite
|
||||
test: deps
|
||||
gx test -v -race -coverprofile=coverage.txt -covermode=atomic .
|
||||
rw:
|
||||
gx-go rewrite
|
||||
rwundo:
|
||||
gx-go rewrite --undo
|
||||
publish: rwundo
|
||||
gx publish
|
||||
.PHONY: all gx deps test rw rwundo publish
|
||||
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# go-ipfs-chunker
|
||||
|
||||
[](http://ipn.io)
|
||||
[](http://ipfs.io/)
|
||||
[](https://github.com/RichardLitt/standard-readme)
|
||||
[](https://godoc.org/github.com/ipfs/go-ipfs-chunker)
|
||||
[](https://travis-ci.org/ipfs/go-ipfs-chunker)
|
||||
|
||||
> go-ipfs-chunker implements data Splitters for go-ipfs.
|
||||
|
||||
`go-ipfs-chunker` provides the `Splitter` interface. IPFS splitters read data from a reader an create "chunks". These chunks are used to build the ipfs DAGs (Merkle Tree) and are the base unit to obtain the sums that ipfs uses to address content.
|
||||
|
||||
The package provides a `SizeSplitter` which creates chunks of equal size and it is used by default in most cases, and a `rabin` fingerprint chunker. This chunker will attempt to split data in a way that the resulting blocks are the same when the data has repetitive patterns, thus optimizing the resulting DAGs.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Install](#install)
|
||||
- [Usage](#usage)
|
||||
- [Contribute](#contribute)
|
||||
- [License](#license)
|
||||
|
||||
## Install
|
||||
|
||||
`go-ipfs-chunker` works like a regular Go module:
|
||||
|
||||
```
|
||||
> go get github.com/ipfs/go-ipfs-chunker
|
||||
```
|
||||
|
||||
It uses [Gx](https://github.com/whyrusleeping/gx) to manage dependencies. You can use `make all` to build it with the `gx` dependencies.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
import "github.com/ipfs/go-ipfs-chunker"
|
||||
```
|
||||
|
||||
Check the [GoDoc documentation](https://godoc.org/github.com/ipfs/go-ipfs-chunker)
|
||||
|
||||
## Contribute
|
||||
|
||||
PRs accepted.
|
||||
|
||||
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
|
||||
|
||||
## License
|
||||
|
||||
MIT © Protocol Labs, Inc.
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
module github.com/ipfs/go-ipfs-chunker
|
||||
|
||||
require (
|
||||
github.com/ipfs/go-block-format v0.0.2
|
||||
github.com/ipfs/go-ipfs-util v0.0.1
|
||||
github.com/ipfs/go-log v0.0.1
|
||||
github.com/libp2p/go-buffer-pool v0.0.1
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f
|
||||
)
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gxed/hashland/keccakpg v0.0.1 h1:wrk3uMNaMxbXiHibbPO4S0ymqJMm41WiudyFSs7UnsU=
|
||||
github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU=
|
||||
github.com/gxed/hashland/murmur3 v0.0.1 h1:SheiaIt0sda5K+8FLz952/1iWS9zrnKsEJaOJu4ZbSc=
|
||||
github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48=
|
||||
github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE=
|
||||
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
|
||||
github.com/ipfs/go-cid v0.0.1 h1:GBjWPktLnNyX0JiQCNFpUuUSoMw5KMyqrsejHYlILBE=
|
||||
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
|
||||
github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50=
|
||||
github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
|
||||
github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc=
|
||||
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/libp2p/go-buffer-pool v0.0.1 h1:9Rrn/H46cXjaA2HQ5Y8lyhOS1NhTkZ4yuEs2r3Eechg=
|
||||
github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16 h1:5W7KhL8HVF3XCFOweFD3BNESdnO8ewyYTFT2R+/b8FQ=
|
||||
github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U=
|
||||
github.com/mr-tron/base58 v1.1.0 h1:Y51FGVJ91WBqCEabAi5OPUz38eAx8DakuAm5svLcsfQ=
|
||||
github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
|
||||
github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI=
|
||||
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
|
||||
github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
|
||||
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
|
||||
github.com/multiformats/go-multihash v0.0.1 h1:HHwN1K12I+XllBCrqKnhX949Orn4oawPkegHMu2vDqQ=
|
||||
github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U=
|
||||
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
|
||||
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
|
||||
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo=
|
||||
github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo=
|
||||
golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"author": "hsanjuan",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ipfs/go-ipfs-chunker"
|
||||
},
|
||||
"gx": {
|
||||
"dvcsimport": "github.com/ipfs/go-ipfs-chunker"
|
||||
},
|
||||
"gxDependencies": [
|
||||
{
|
||||
"hash": "QmbkT7eMTyXfpeyB3ZMxxcxg7XH8t6uXp49jqzz4HB7BGF",
|
||||
"name": "go-log",
|
||||
"version": "1.5.9"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmZooytqEoUwQjv7KzH4d3xyJnyvD3AWJaCDMYt5pbCtua",
|
||||
"name": "chunker",
|
||||
"version": "0.0.1"
|
||||
},
|
||||
{
|
||||
"author": "whyrusleeping",
|
||||
"hash": "QmNohiVssaPw3KVLZik59DBVGTSm2dGvYT9eoXt5DQ36Yz",
|
||||
"name": "go-ipfs-util",
|
||||
"version": "1.2.9"
|
||||
},
|
||||
{
|
||||
"author": "stebalien",
|
||||
"hash": "QmYYLnAzR28nAQ4U5MFniLprnktu6eTFKibeNt96V21EZK",
|
||||
"name": "go-block-format",
|
||||
"version": "0.2.2"
|
||||
},
|
||||
{
|
||||
"author": "Stebalien",
|
||||
"hash": "QmQDvJoB6aJWN3sjr3xsgXqKCXf4jU5zdMXpDMsBkYVNqa",
|
||||
"name": "go-buffer-pool",
|
||||
"version": "0.1.3"
|
||||
}
|
||||
],
|
||||
"gxVersion": "0.12.1",
|
||||
"language": "go",
|
||||
"license": "MIT",
|
||||
"name": "go-ipfs-chunker",
|
||||
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
|
||||
"version": "0.1.6"
|
||||
}
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package chunk
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRabinMin = errors.New("rabin min must be greater than 16")
|
||||
ErrSize = errors.New("chunker size muster greater than 0")
|
||||
)
|
||||
|
||||
// FromString returns a Splitter depending on the given string:
|
||||
// it supports "default" (""), "size-{size}", "rabin", "rabin-{blocksize}" and
|
||||
// "rabin-{min}-{avg}-{max}".
|
||||
func FromString(r io.Reader, chunker string) (Splitter, error) {
|
||||
switch {
|
||||
case chunker == "" || chunker == "default":
|
||||
return DefaultSplitter(r), nil
|
||||
|
||||
case strings.HasPrefix(chunker, "size-"):
|
||||
sizeStr := strings.Split(chunker, "-")[1]
|
||||
size, err := strconv.Atoi(sizeStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if size <= 0 {
|
||||
return nil, ErrSize
|
||||
}
|
||||
return NewSizeSplitter(r, int64(size)), nil
|
||||
|
||||
case strings.HasPrefix(chunker, "rabin"):
|
||||
return parseRabinString(r, chunker)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unrecognized chunker option: %s", chunker)
|
||||
}
|
||||
}
|
||||
|
||||
func parseRabinString(r io.Reader, chunker string) (Splitter, error) {
|
||||
parts := strings.Split(chunker, "-")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
return NewRabin(r, uint64(DefaultBlockSize)), nil
|
||||
case 2:
|
||||
size, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRabin(r, uint64(size)), nil
|
||||
case 4:
|
||||
sub := strings.Split(parts[1], ":")
|
||||
if len(sub) > 1 && sub[0] != "min" {
|
||||
return nil, errors.New("first label must be min")
|
||||
}
|
||||
min, err := strconv.Atoi(sub[len(sub)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if min < 16 {
|
||||
return nil, ErrRabinMin
|
||||
}
|
||||
sub = strings.Split(parts[2], ":")
|
||||
if len(sub) > 1 && sub[0] != "avg" {
|
||||
log.Error("sub == ", sub)
|
||||
return nil, errors.New("second label must be avg")
|
||||
}
|
||||
avg, err := strconv.Atoi(sub[len(sub)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sub = strings.Split(parts[3], ":")
|
||||
if len(sub) > 1 && sub[0] != "max" {
|
||||
return nil, errors.New("final label must be max")
|
||||
}
|
||||
max, err := strconv.Atoi(sub[len(sub)-1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewRabinMinMax(r, uint64(min), uint64(avg), uint64(max)), nil
|
||||
default:
|
||||
return nil, errors.New("incorrect format (expected 'rabin' 'rabin-[avg]' or 'rabin-[min]-[avg]-[max]'")
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package chunk
|
||||
|
||||
import (
|
||||
"hash/fnv"
|
||||
"io"
|
||||
|
||||
"github.com/whyrusleeping/chunker"
|
||||
)
|
||||
|
||||
// IpfsRabinPoly is the irreducible polynomial of degree 53 used by for Rabin.
|
||||
var IpfsRabinPoly = chunker.Pol(17437180132763653)
|
||||
|
||||
// Rabin implements the Splitter interface and splits content with Rabin
|
||||
// fingerprints.
|
||||
type Rabin struct {
|
||||
r *chunker.Chunker
|
||||
reader io.Reader
|
||||
}
|
||||
|
||||
// NewRabin creates a new Rabin splitter with the given
|
||||
// average block size.
|
||||
func NewRabin(r io.Reader, avgBlkSize uint64) *Rabin {
|
||||
min := avgBlkSize / 3
|
||||
max := avgBlkSize + (avgBlkSize / 2)
|
||||
|
||||
return NewRabinMinMax(r, min, avgBlkSize, max)
|
||||
}
|
||||
|
||||
// NewRabinMinMax returns a new Rabin splitter which uses
|
||||
// the given min, average and max block sizes.
|
||||
func NewRabinMinMax(r io.Reader, min, avg, max uint64) *Rabin {
|
||||
h := fnv.New32a()
|
||||
ch := chunker.New(r, IpfsRabinPoly, h, avg, min, max)
|
||||
|
||||
return &Rabin{
|
||||
r: ch,
|
||||
reader: r,
|
||||
}
|
||||
}
|
||||
|
||||
// NextBytes reads the next bytes from the reader and returns a slice.
|
||||
func (r *Rabin) NextBytes() ([]byte, error) {
|
||||
ch, err := r.r.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ch.Data, nil
|
||||
}
|
||||
|
||||
// Reader returns the io.Reader associated to this Splitter.
|
||||
func (r *Rabin) Reader() io.Reader {
|
||||
return r.reader
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
// Package chunk implements streaming block splitters.
|
||||
// Splitters read data from a reader and provide byte slices (chunks)
|
||||
// The size and contents of these slices depend on the splitting method
|
||||
// used.
|
||||
package chunk
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
pool "github.com/libp2p/go-buffer-pool"
|
||||
)
|
||||
|
||||
var log = logging.Logger("chunk")
|
||||
|
||||
// DefaultBlockSize is the chunk size that splitters produce (or aim to).
|
||||
var DefaultBlockSize int64 = 1024 * 256
|
||||
|
||||
// A Splitter reads bytes from a Reader and creates "chunks" (byte slices)
|
||||
// that can be used to build DAG nodes.
|
||||
type Splitter interface {
|
||||
Reader() io.Reader
|
||||
NextBytes() ([]byte, error)
|
||||
}
|
||||
|
||||
// SplitterGen is a splitter generator, given a reader.
|
||||
type SplitterGen func(r io.Reader) Splitter
|
||||
|
||||
// DefaultSplitter returns a SizeSplitter with the DefaultBlockSize.
|
||||
func DefaultSplitter(r io.Reader) Splitter {
|
||||
return NewSizeSplitter(r, DefaultBlockSize)
|
||||
}
|
||||
|
||||
// SizeSplitterGen returns a SplitterGen function which will create
|
||||
// a splitter with the given size when called.
|
||||
func SizeSplitterGen(size int64) SplitterGen {
|
||||
return func(r io.Reader) Splitter {
|
||||
return NewSizeSplitter(r, size)
|
||||
}
|
||||
}
|
||||
|
||||
// Chan returns a channel that receives each of the chunks produced
|
||||
// by a splitter, along with another one for errors.
|
||||
func Chan(s Splitter) (<-chan []byte, <-chan error) {
|
||||
out := make(chan []byte)
|
||||
errs := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(out)
|
||||
defer close(errs)
|
||||
|
||||
// all-chunks loop (keep creating chunks)
|
||||
for {
|
||||
b, err := s.NextBytes()
|
||||
if err != nil {
|
||||
errs <- err
|
||||
return
|
||||
}
|
||||
|
||||
out <- b
|
||||
}
|
||||
}()
|
||||
return out, errs
|
||||
}
|
||||
|
||||
type sizeSplitterv2 struct {
|
||||
r io.Reader
|
||||
size uint32
|
||||
err error
|
||||
}
|
||||
|
||||
// NewSizeSplitter returns a new size-based Splitter with the given block size.
|
||||
func NewSizeSplitter(r io.Reader, size int64) Splitter {
|
||||
return &sizeSplitterv2{
|
||||
r: r,
|
||||
size: uint32(size),
|
||||
}
|
||||
}
|
||||
|
||||
// NextBytes produces a new chunk.
|
||||
func (ss *sizeSplitterv2) NextBytes() ([]byte, error) {
|
||||
if ss.err != nil {
|
||||
return nil, ss.err
|
||||
}
|
||||
|
||||
full := pool.Get(int(ss.size))
|
||||
n, err := io.ReadFull(ss.r, full)
|
||||
switch err {
|
||||
case io.ErrUnexpectedEOF:
|
||||
ss.err = io.EOF
|
||||
small := make([]byte, n)
|
||||
copy(small, full)
|
||||
pool.Put(full)
|
||||
return small, nil
|
||||
case nil:
|
||||
return full, nil
|
||||
default:
|
||||
pool.Put(full)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Reader returns the io.Reader associated to this Splitter.
|
||||
func (ss *sizeSplitterv2) Reader() io.Reader {
|
||||
return ss.r
|
||||
}
|
||||
Reference in New Issue
Block a user