mirror of https://github.com/etcd-io/dbtester.git
*: sync with etcd master
This commit is contained in:
parent
2e89ad5f23
commit
9b92ce04d6
|
|
@ -18,10 +18,6 @@
|
||||||
"Comment": "go.weekly.2012-01-27-130-g672fe54",
|
"Comment": "go.weekly.2012-01-27-130-g672fe54",
|
||||||
"Rev": "672fe547df4e49efc6db67a74391368bcb149b37"
|
"Rev": "672fe547df4e49efc6db67a74391368bcb149b37"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/bkaradzic/go-lz4",
|
|
||||||
"Rev": "74ddf82598bc4745b965729e9c6a463bedd33049"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/cheggaaa/pb",
|
"ImportPath": "github.com/cheggaaa/pb",
|
||||||
"Comment": "v1.0.2-4-g8808370",
|
"Comment": "v1.0.2-4-g8808370",
|
||||||
|
|
@ -29,53 +25,48 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/auth/authpb",
|
"ImportPath": "github.com/coreos/etcd/auth/authpb",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/client",
|
"ImportPath": "github.com/coreos/etcd/client",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/clientv3",
|
"ImportPath": "github.com/coreos/etcd/clientv3",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
|
"ImportPath": "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb",
|
"ImportPath": "github.com/coreos/etcd/etcdserver/etcdserverpb",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/mvcc/mvccpb",
|
"ImportPath": "github.com/coreos/etcd/mvcc/mvccpb",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/coreos/etcd/pkg/compress",
|
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/pkg/pathutil",
|
"ImportPath": "github.com/coreos/etcd/pkg/pathutil",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/pkg/tlsutil",
|
"ImportPath": "github.com/coreos/etcd/pkg/tlsutil",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/etcd/pkg/types",
|
"ImportPath": "github.com/coreos/etcd/pkg/types",
|
||||||
"Comment": "v2.3.0-646-gf383235",
|
"Comment": "v2.3.0-664-gb776153",
|
||||||
"Rev": "f383235c3384f50360061b7ee86fa40c323a8e08"
|
"Rev": "b7761530e1d5b9f404811d63786df60023a88db9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/cpuguy83/go-md2man/md2man",
|
"ImportPath": "github.com/cpuguy83/go-md2man/md2man",
|
||||||
|
|
@ -129,10 +120,6 @@
|
||||||
"ImportPath": "github.com/golang/protobuf/proto",
|
"ImportPath": "github.com/golang/protobuf/proto",
|
||||||
"Rev": "6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3"
|
"Rev": "6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/golang/snappy",
|
|
||||||
"Rev": "43fea289edce21979658cbbdb3925390890aa86e"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gonum/floats",
|
"ImportPath": "github.com/gonum/floats",
|
||||||
"Rev": "856ee8119ad91596c5394fa0a5c0470b6f16e676"
|
"Rev": "856ee8119ad91596c5394fa0a5c0470b6f16e676"
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dbtester/remotestorage"
|
"github.com/coreos/dbtester/remotestorage"
|
||||||
"github.com/coreos/etcd/pkg/compress"
|
// "github.com/coreos/etcd/pkg/compress"
|
||||||
"github.com/gyuho/psn/ps"
|
"github.com/gyuho/psn/ps"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
@ -244,13 +244,13 @@ func (t *transporterServer) Transfer(ctx context.Context, r *Request) (*Response
|
||||||
"--initial-cluster", clusterStr,
|
"--initial-cluster", clusterStr,
|
||||||
"--initial-cluster-state", "new",
|
"--initial-cluster-state", "new",
|
||||||
}
|
}
|
||||||
if t.req.EtcdCompression != "" {
|
// if t.req.EtcdCompression != "" {
|
||||||
if compress.ParseType(t.req.EtcdCompression) != compress.NoCompress {
|
// if compress.ParseType(t.req.EtcdCompression) != compress.NoCompress {
|
||||||
flags = append(flags,
|
// flags = append(flags,
|
||||||
"--experimental-compression", t.req.EtcdCompression,
|
// "--experimental-compression", t.req.EtcdCompression,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
flagString := strings.Join(flags, " ")
|
flagString := strings.Join(flags, " ")
|
||||||
|
|
||||||
cmd := exec.Command(etcdBinaryPath, flags...)
|
cmd := exec.Command(etcdBinaryPath, flags...)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ type Config struct {
|
||||||
AgentEndpoints []string
|
AgentEndpoints []string
|
||||||
DatabaseEndpoints []string
|
DatabaseEndpoints []string
|
||||||
|
|
||||||
// cgzip, cgzip-lv2, gzip, snappy, snappy-cpp
|
// snappy
|
||||||
EtcdCompression string `yaml:"etcd_compression"`
|
EtcdCompression string `yaml:"etcd_compression"`
|
||||||
|
|
||||||
Step1 struct {
|
Step1 struct {
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ func step1(cfg Config) error {
|
||||||
|
|
||||||
req.ZookeeperMaxClientCnxns = cfg.Step1.ZookeeperMaxClientCnxns
|
req.ZookeeperMaxClientCnxns = cfg.Step1.ZookeeperMaxClientCnxns
|
||||||
req.ZookeeperSnapCount = cfg.Step1.ZookeeperSnapCount
|
req.ZookeeperSnapCount = cfg.Step1.ZookeeperSnapCount
|
||||||
req.EtcdCompression = cfg.EtcdCompression
|
// req.EtcdCompression = cfg.EtcdCompression
|
||||||
|
|
||||||
donec, errc := make(chan struct{}), make(chan error)
|
donec, errc := make(chan struct{}), make(chan error)
|
||||||
for i := range cfg.PeerIPs {
|
for i := range cfg.PeerIPs {
|
||||||
|
|
@ -248,8 +248,8 @@ func step2(cfg Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "etcdv3":
|
case "etcdv3":
|
||||||
etcdClients = mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections, cfg.EtcdCompression)
|
// etcdClients = mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections, cfg.EtcdCompression)
|
||||||
// etcdClients = mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections)
|
etcdClients = mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections)
|
||||||
for i := range etcdClients {
|
for i := range etcdClients {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go doPutEtcdv3(context.Background(), etcdClients[i], requests)
|
go doPutEtcdv3(context.Background(), etcdClients[i], requests)
|
||||||
|
|
@ -382,8 +382,8 @@ func step2(cfg Config) error {
|
||||||
log.Printf("PUT '%s' to etcd", key)
|
log.Printf("PUT '%s' to etcd", key)
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, 1, 1, cfg.EtcdCompression)
|
// clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, 1, 1, cfg.EtcdCompression)
|
||||||
// clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, 1, 1)
|
clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, 1, 1)
|
||||||
_, err = clients[0].Do(context.Background(), clientv3.OpPut(key, value))
|
_, err = clients[0].Do(context.Background(), clientv3.OpPut(key, value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
|
@ -447,8 +447,8 @@ func step2(cfg Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "etcdv3":
|
case "etcdv3":
|
||||||
clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections, cfg.EtcdCompression)
|
// clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections, cfg.EtcdCompression)
|
||||||
// clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections)
|
clients := mustCreateClientsEtcdv3(cfg.DatabaseEndpoints, cfg.Step2.Clients, cfg.Step2.Connections)
|
||||||
for i := range clients {
|
for i := range clients {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go doRangeEtcdv3(clients[i].KV, requests)
|
go doRangeEtcdv3(clients[i].KV, requests)
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import (
|
||||||
|
|
||||||
clientv2 "github.com/coreos/etcd/client"
|
clientv2 "github.com/coreos/etcd/client"
|
||||||
"github.com/coreos/etcd/clientv3"
|
"github.com/coreos/etcd/clientv3"
|
||||||
"github.com/coreos/etcd/pkg/compress"
|
// "github.com/coreos/etcd/pkg/compress"
|
||||||
"github.com/dustin/go-humanize"
|
"github.com/dustin/go-humanize"
|
||||||
consulapi "github.com/hashicorp/consul/api"
|
consulapi "github.com/hashicorp/consul/api"
|
||||||
"github.com/samuel/go-zookeeper/zk"
|
"github.com/samuel/go-zookeeper/zk"
|
||||||
|
|
@ -75,13 +75,13 @@ var (
|
||||||
dialTotal int
|
dialTotal int
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustCreateConnEtcdv3(endpoints []string, compressType compress.Type) *clientv3.Client {
|
// func mustCreateConnEtcdv3(endpoints []string, compressType compress.Type) *clientv3.Client {
|
||||||
// func mustCreateConnEtcdv3(endpoints []string) *clientv3.Client {
|
func mustCreateConnEtcdv3(endpoints []string) *clientv3.Client {
|
||||||
endpoint := endpoints[dialTotal%len(endpoints)]
|
endpoint := endpoints[dialTotal%len(endpoints)]
|
||||||
dialTotal++
|
dialTotal++
|
||||||
cfg := clientv3.Config{
|
cfg := clientv3.Config{
|
||||||
Endpoints: []string{endpoint},
|
Endpoints: []string{endpoint},
|
||||||
CompressType: compressType,
|
// CompressType: compressType,
|
||||||
}
|
}
|
||||||
client, err := clientv3.New(cfg)
|
client, err := clientv3.New(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -91,12 +91,12 @@ func mustCreateConnEtcdv3(endpoints []string, compressType compress.Type) *clien
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustCreateClientsEtcdv3(endpoints []string, totalClients, totalConns int, compressionTypeTxt string) []*clientv3.Client {
|
// func mustCreateClientsEtcdv3(endpoints []string, totalClients, totalConns int, compressionTypeTxt string) []*clientv3.Client {
|
||||||
// func mustCreateClientsEtcdv3(endpoints []string, totalClients, totalConns int) []*clientv3.Client {
|
func mustCreateClientsEtcdv3(endpoints []string, totalClients, totalConns int) []*clientv3.Client {
|
||||||
conns := make([]*clientv3.Client, totalConns)
|
conns := make([]*clientv3.Client, totalConns)
|
||||||
for i := range conns {
|
for i := range conns {
|
||||||
conns[i] = mustCreateConnEtcdv3(endpoints, compress.ParseType(compressionTypeTxt))
|
// conns[i] = mustCreateConnEtcdv3(endpoints, compress.ParseType(compressionTypeTxt))
|
||||||
// conns[i] = mustCreateConnEtcdv3(endpoints)
|
conns[i] = mustCreateConnEtcdv3(endpoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
clients := make([]*clientv3.Client, totalClients)
|
clients := make([]*clientv3.Client, totalClients)
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/lz4-example/lz4-example
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.1
|
|
||||||
- 1.2
|
|
||||||
- 1.3
|
|
||||||
- 1.4
|
|
||||||
- 1.5
|
|
||||||
- tip
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
|
||||||
Copyright 2013 Damian Gryski. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. 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.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
|
|
||||||
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
go-lz4
|
|
||||||
======
|
|
||||||
|
|
||||||
go-lz4 is port of LZ4 lossless compression algorithm to Go. The original C code
|
|
||||||
is located at:
|
|
||||||
|
|
||||||
https://github.com/Cyan4973/lz4
|
|
||||||
|
|
||||||
Status
|
|
||||||
------
|
|
||||||
[](http://travis-ci.org/bkaradzic/go-lz4)
|
|
||||||
[](https://godoc.org/github.com/bkaradzic/go-lz4)
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
|
|
||||||
go get github.com/bkaradzic/go-lz4
|
|
||||||
|
|
||||||
import "github.com/bkaradzic/go-lz4"
|
|
||||||
|
|
||||||
The package name is `lz4`
|
|
||||||
|
|
||||||
Notes
|
|
||||||
-----
|
|
||||||
|
|
||||||
* go-lz4 saves a uint32 with the original uncompressed length at the beginning
|
|
||||||
of the encoded buffer. They may get in the way of interoperability with
|
|
||||||
other implementations.
|
|
||||||
|
|
||||||
Contributors
|
|
||||||
------------
|
|
||||||
|
|
||||||
Damian Gryski ([@dgryski](https://github.com/dgryski))
|
|
||||||
Dustin Sallings ([@dustin](https://github.com/dustin))
|
|
||||||
|
|
||||||
Contact
|
|
||||||
-------
|
|
||||||
|
|
||||||
[@bkaradzic](https://twitter.com/bkaradzic)
|
|
||||||
http://www.stuckingeometry.com
|
|
||||||
|
|
||||||
Project page
|
|
||||||
https://github.com/bkaradzic/go-lz4
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
|
||||||
Copyright 2013 Damian Gryski. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
2. 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.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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.
|
|
||||||
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
// +build gofuzz
|
|
||||||
|
|
||||||
package lz4
|
|
||||||
|
|
||||||
import "encoding/binary"
|
|
||||||
|
|
||||||
func Fuzz(data []byte) int {
|
|
||||||
|
|
||||||
if len(data) < 4 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ln := binary.LittleEndian.Uint32(data)
|
|
||||||
if ln > (1 << 21) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := Decode(nil, data); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. 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.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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 lz4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrCorrupt indicates the input was corrupt
|
|
||||||
ErrCorrupt = errors.New("corrupt input")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
mlBits = 4
|
|
||||||
mlMask = (1 << mlBits) - 1
|
|
||||||
runBits = 8 - mlBits
|
|
||||||
runMask = (1 << runBits) - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
type decoder struct {
|
|
||||||
src []byte
|
|
||||||
dst []byte
|
|
||||||
spos uint32
|
|
||||||
dpos uint32
|
|
||||||
ref uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) readByte() (uint8, error) {
|
|
||||||
if int(d.spos) == len(d.src) {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
b := d.src[d.spos]
|
|
||||||
d.spos++
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) getLen() (uint32, error) {
|
|
||||||
|
|
||||||
length := uint32(0)
|
|
||||||
ln, err := d.readByte()
|
|
||||||
if err != nil {
|
|
||||||
return 0, ErrCorrupt
|
|
||||||
}
|
|
||||||
for ln == 255 {
|
|
||||||
length += 255
|
|
||||||
ln, err = d.readByte()
|
|
||||||
if err != nil {
|
|
||||||
return 0, ErrCorrupt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
length += uint32(ln)
|
|
||||||
|
|
||||||
return length, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) cp(length, decr uint32) {
|
|
||||||
|
|
||||||
if int(d.ref+length) < int(d.dpos) {
|
|
||||||
copy(d.dst[d.dpos:], d.dst[d.ref:d.ref+length])
|
|
||||||
} else {
|
|
||||||
for ii := uint32(0); ii < length; ii++ {
|
|
||||||
d.dst[d.dpos+ii] = d.dst[d.ref+ii]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.dpos += length
|
|
||||||
d.ref += length - decr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *decoder) finish(err error) error {
|
|
||||||
if err == io.EOF {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode returns the decoded form of src. The returned slice may be a
|
|
||||||
// subslice of dst if it was large enough to hold the entire decoded block.
|
|
||||||
func Decode(dst, src []byte) ([]byte, error) {
|
|
||||||
|
|
||||||
if len(src) < 4 {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
uncompressedLen := binary.LittleEndian.Uint32(src)
|
|
||||||
|
|
||||||
if uncompressedLen == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if uncompressedLen > MaxInputSize {
|
|
||||||
return nil, ErrTooLarge
|
|
||||||
}
|
|
||||||
|
|
||||||
if dst == nil || len(dst) < int(uncompressedLen) {
|
|
||||||
dst = make([]byte, uncompressedLen)
|
|
||||||
}
|
|
||||||
|
|
||||||
d := decoder{src: src, dst: dst[:uncompressedLen], spos: 4}
|
|
||||||
|
|
||||||
decr := []uint32{0, 3, 2, 3}
|
|
||||||
|
|
||||||
for {
|
|
||||||
code, err := d.readByte()
|
|
||||||
if err != nil {
|
|
||||||
return d.dst, d.finish(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
length := uint32(code >> mlBits)
|
|
||||||
if length == runMask {
|
|
||||||
ln, err := d.getLen()
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
length += ln
|
|
||||||
}
|
|
||||||
|
|
||||||
if int(d.spos+length) > len(d.src) || int(d.dpos+length) > len(d.dst) {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
for ii := uint32(0); ii < length; ii++ {
|
|
||||||
d.dst[d.dpos+ii] = d.src[d.spos+ii]
|
|
||||||
}
|
|
||||||
|
|
||||||
d.spos += length
|
|
||||||
d.dpos += length
|
|
||||||
|
|
||||||
if int(d.spos) == len(d.src) {
|
|
||||||
return d.dst, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if int(d.spos+2) >= len(d.src) {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
back := uint32(d.src[d.spos]) | uint32(d.src[d.spos+1])<<8
|
|
||||||
|
|
||||||
if back > d.dpos {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
d.spos += 2
|
|
||||||
d.ref = d.dpos - back
|
|
||||||
|
|
||||||
length = uint32(code & mlMask)
|
|
||||||
if length == mlMask {
|
|
||||||
ln, err := d.getLen()
|
|
||||||
if err != nil {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
length += ln
|
|
||||||
}
|
|
||||||
|
|
||||||
literal := d.dpos - d.ref
|
|
||||||
|
|
||||||
if literal < 4 {
|
|
||||||
if int(d.dpos+4) > len(d.dst) {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
d.cp(4, decr[literal])
|
|
||||||
} else {
|
|
||||||
length += 4
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.dpos+length > uncompressedLen {
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
d.cp(length, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2011-2012 Branimir Karadzic. All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. 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.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER ``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 COPYRIGHT HOLDER 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 lz4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
minMatch = 4
|
|
||||||
hashLog = 17
|
|
||||||
hashTableSize = 1 << hashLog
|
|
||||||
hashShift = (minMatch * 8) - hashLog
|
|
||||||
incompressible uint32 = 128
|
|
||||||
uninitHash = 0x88888888
|
|
||||||
|
|
||||||
// MaxInputSize is the largest buffer than can be compressed in a single block
|
|
||||||
MaxInputSize = 0x7E000000
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrTooLarge indicates the input buffer was too large
|
|
||||||
ErrTooLarge = errors.New("input too large")
|
|
||||||
)
|
|
||||||
|
|
||||||
type encoder struct {
|
|
||||||
src []byte
|
|
||||||
dst []byte
|
|
||||||
hashTable []uint32
|
|
||||||
pos uint32
|
|
||||||
anchor uint32
|
|
||||||
dpos uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompressBound returns the maximum length of a lz4 block, given it's uncompressed length
|
|
||||||
func CompressBound(isize int) int {
|
|
||||||
if isize > MaxInputSize {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return isize + ((isize) / 255) + 16 + 4
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *encoder) writeLiterals(length, mlLen, pos uint32) {
|
|
||||||
|
|
||||||
ln := length
|
|
||||||
|
|
||||||
var code byte
|
|
||||||
if ln > runMask-1 {
|
|
||||||
code = runMask
|
|
||||||
} else {
|
|
||||||
code = byte(ln)
|
|
||||||
}
|
|
||||||
|
|
||||||
if mlLen > mlMask-1 {
|
|
||||||
e.dst[e.dpos] = (code << mlBits) + byte(mlMask)
|
|
||||||
} else {
|
|
||||||
e.dst[e.dpos] = (code << mlBits) + byte(mlLen)
|
|
||||||
}
|
|
||||||
e.dpos++
|
|
||||||
|
|
||||||
if code == runMask {
|
|
||||||
ln -= runMask
|
|
||||||
for ; ln > 254; ln -= 255 {
|
|
||||||
e.dst[e.dpos] = 255
|
|
||||||
e.dpos++
|
|
||||||
}
|
|
||||||
|
|
||||||
e.dst[e.dpos] = byte(ln)
|
|
||||||
e.dpos++
|
|
||||||
}
|
|
||||||
|
|
||||||
for ii := uint32(0); ii < length; ii++ {
|
|
||||||
e.dst[e.dpos+ii] = e.src[pos+ii]
|
|
||||||
}
|
|
||||||
|
|
||||||
e.dpos += length
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode returns the encoded form of src. The returned array may be a
|
|
||||||
// sub-slice of dst if it was large enough to hold the entire output.
|
|
||||||
func Encode(dst, src []byte) ([]byte, error) {
|
|
||||||
|
|
||||||
if len(src) >= MaxInputSize {
|
|
||||||
return nil, ErrTooLarge
|
|
||||||
}
|
|
||||||
|
|
||||||
if n := CompressBound(len(src)); len(dst) < n {
|
|
||||||
dst = make([]byte, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
e := encoder{src: src, dst: dst, hashTable: make([]uint32, hashTableSize)}
|
|
||||||
|
|
||||||
binary.LittleEndian.PutUint32(dst, uint32(len(src)))
|
|
||||||
e.dpos = 4
|
|
||||||
|
|
||||||
var (
|
|
||||||
step uint32 = 1
|
|
||||||
limit = incompressible
|
|
||||||
)
|
|
||||||
|
|
||||||
for {
|
|
||||||
if int(e.pos)+12 >= len(e.src) {
|
|
||||||
e.writeLiterals(uint32(len(e.src))-e.anchor, 0, e.anchor)
|
|
||||||
return e.dst[:e.dpos], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sequence := uint32(e.src[e.pos+3])<<24 | uint32(e.src[e.pos+2])<<16 | uint32(e.src[e.pos+1])<<8 | uint32(e.src[e.pos+0])
|
|
||||||
|
|
||||||
hash := (sequence * 2654435761) >> hashShift
|
|
||||||
ref := e.hashTable[hash] + uninitHash
|
|
||||||
e.hashTable[hash] = e.pos - uninitHash
|
|
||||||
|
|
||||||
if ((e.pos-ref)>>16) != 0 || uint32(e.src[ref+3])<<24|uint32(e.src[ref+2])<<16|uint32(e.src[ref+1])<<8|uint32(e.src[ref+0]) != sequence {
|
|
||||||
if e.pos-e.anchor > limit {
|
|
||||||
limit <<= 1
|
|
||||||
step += 1 + (step >> 2)
|
|
||||||
}
|
|
||||||
e.pos += step
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if step > 1 {
|
|
||||||
e.hashTable[hash] = ref - uninitHash
|
|
||||||
e.pos -= step - 1
|
|
||||||
step = 1
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
limit = incompressible
|
|
||||||
|
|
||||||
ln := e.pos - e.anchor
|
|
||||||
back := e.pos - ref
|
|
||||||
|
|
||||||
anchor := e.anchor
|
|
||||||
|
|
||||||
e.pos += minMatch
|
|
||||||
ref += minMatch
|
|
||||||
e.anchor = e.pos
|
|
||||||
|
|
||||||
for int(e.pos) < len(e.src)-5 && e.src[e.pos] == e.src[ref] {
|
|
||||||
e.pos++
|
|
||||||
ref++
|
|
||||||
}
|
|
||||||
|
|
||||||
mlLen := e.pos - e.anchor
|
|
||||||
|
|
||||||
e.writeLiterals(ln, mlLen, anchor)
|
|
||||||
e.dst[e.dpos] = uint8(back)
|
|
||||||
e.dst[e.dpos+1] = uint8(back >> 8)
|
|
||||||
e.dpos += 2
|
|
||||||
|
|
||||||
if mlLen > mlMask-1 {
|
|
||||||
mlLen -= mlMask
|
|
||||||
for mlLen > 254 {
|
|
||||||
mlLen -= 255
|
|
||||||
|
|
||||||
e.dst[e.dpos] = 255
|
|
||||||
e.dpos++
|
|
||||||
}
|
|
||||||
|
|
||||||
e.dst[e.dpos] = byte(mlLen)
|
|
||||||
e.dpos++
|
|
||||||
}
|
|
||||||
|
|
||||||
e.anchor = e.pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -756,20 +756,21 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileDescriptorAuth = []byte{
|
var fileDescriptorAuth = []byte{
|
||||||
// 236 bytes of a gzipped FileDescriptorProto
|
// 254 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x2c, 0x2d, 0xc9,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x2c, 0x2d, 0xc9,
|
||||||
0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0xb1, 0x0b, 0x92, 0xa4, 0x44, 0xd2, 0xf3,
|
0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x03, 0xb1, 0x0b, 0x92, 0xa4, 0x44, 0xd2, 0xf3,
|
||||||
0xd3, 0xf3, 0xc1, 0x42, 0xfa, 0x20, 0x16, 0x44, 0x56, 0xc9, 0x94, 0x8b, 0x25, 0xb4, 0x38, 0xb5,
|
0xd3, 0xf3, 0xc1, 0x42, 0xfa, 0x20, 0x16, 0x44, 0x56, 0xc9, 0x87, 0x8b, 0x25, 0xb4, 0x38, 0xb5,
|
||||||
0x48, 0x88, 0x87, 0x8b, 0x25, 0x2f, 0x31, 0x37, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x47, 0x48,
|
0x48, 0x48, 0x88, 0x8b, 0x25, 0x2f, 0x31, 0x37, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0x27, 0x08,
|
||||||
0x80, 0x8b, 0xa3, 0x20, 0xb1, 0xb8, 0xb8, 0x3c, 0xbf, 0x28, 0x45, 0x82, 0x09, 0x2c, 0xc2, 0xcb,
|
0xcc, 0x16, 0x92, 0xe2, 0xe2, 0x28, 0x48, 0x2c, 0x2e, 0x2e, 0xcf, 0x2f, 0x4a, 0x91, 0x60, 0x02,
|
||||||
0xc5, 0x5a, 0x94, 0x9f, 0x93, 0x5a, 0x2c, 0xc1, 0xac, 0xc0, 0xac, 0xc1, 0xa9, 0x54, 0xc0, 0xc5,
|
0x8b, 0xc3, 0xf9, 0x42, 0x22, 0x5c, 0xac, 0x45, 0xf9, 0x39, 0xa9, 0xc5, 0x12, 0xcc, 0x0a, 0xcc,
|
||||||
0x15, 0x90, 0x5a, 0x94, 0x9b, 0x59, 0x5c, 0x9c, 0x99, 0x9f, 0x27, 0xc4, 0xcd, 0xc5, 0x9c, 0x9d,
|
0x1a, 0x9c, 0x41, 0x10, 0x8e, 0x52, 0x3d, 0x17, 0x57, 0x40, 0x6a, 0x51, 0x6e, 0x66, 0x71, 0x71,
|
||||||
0x5a, 0x09, 0xd5, 0xab, 0x09, 0xd4, 0x0b, 0x94, 0x0a, 0xa9, 0x2c, 0x48, 0x05, 0xeb, 0xe5, 0x33,
|
0x66, 0x7e, 0x9e, 0x90, 0x00, 0x17, 0x73, 0x76, 0x6a, 0x25, 0xd4, 0x48, 0x10, 0x53, 0xc8, 0x18,
|
||||||
0x12, 0xd7, 0x83, 0x38, 0x41, 0x0f, 0xa1, 0x45, 0x0f, 0x24, 0xad, 0xa4, 0xc5, 0xc5, 0x02, 0xa2,
|
0x68, 0x22, 0x50, 0x3e, 0xa4, 0xb2, 0x20, 0x15, 0x6c, 0x22, 0x9f, 0x91, 0xb8, 0x1e, 0xc4, 0x79,
|
||||||
0x85, 0x38, 0xb8, 0x58, 0x82, 0x5c, 0x1d, 0x5d, 0x04, 0x18, 0x84, 0x38, 0xb9, 0x58, 0xc3, 0x83,
|
0x7a, 0x08, 0x7d, 0x7a, 0x20, 0xe9, 0x20, 0xb8, 0x42, 0x25, 0x2d, 0x2e, 0x16, 0x10, 0x2d, 0xc4,
|
||||||
0x3c, 0x43, 0x5c, 0x05, 0x18, 0x81, 0x36, 0x72, 0x82, 0x04, 0x21, 0x5c, 0x26, 0x25, 0x7b, 0xa0,
|
0xc1, 0xc5, 0x12, 0xe4, 0xea, 0xe8, 0x22, 0xc0, 0x20, 0xc4, 0xc9, 0xc5, 0x1a, 0x1e, 0xe4, 0x19,
|
||||||
0x1a, 0xa0, 0x03, 0xd0, 0x1c, 0xaa, 0xc9, 0xc5, 0x0b, 0xb4, 0x19, 0x61, 0x2e, 0xd0, 0x46, 0x66,
|
0xe2, 0x2a, 0xc0, 0x28, 0xc4, 0xcb, 0xc5, 0x09, 0x12, 0x84, 0x70, 0x99, 0x94, 0x42, 0x80, 0x6a,
|
||||||
0x0d, 0x6e, 0x23, 0x21, 0x4c, 0x1b, 0x9d, 0x44, 0x4e, 0x3c, 0x94, 0x63, 0xb8, 0x00, 0xc4, 0x27,
|
0x80, 0x2e, 0xc1, 0xea, 0x1d, 0x0b, 0x2e, 0x5e, 0xa0, 0x1b, 0x10, 0xf6, 0x00, 0x5d, 0xc0, 0xac,
|
||||||
0x1e, 0xc9, 0x31, 0x5e, 0x00, 0xe2, 0x07, 0x40, 0x9c, 0xc4, 0x06, 0x0e, 0x06, 0x63, 0x40, 0x00,
|
0xc1, 0x6d, 0x24, 0x84, 0xe9, 0x82, 0x20, 0x54, 0x85, 0x4e, 0x22, 0x27, 0x1e, 0xca, 0x31, 0x5c,
|
||||||
0x00, 0x00, 0xff, 0xff, 0x8d, 0x09, 0x06, 0x6e, 0x32, 0x01, 0x00, 0x00,
|
0x00, 0xe2, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x00, 0xf1, 0x03, 0x20, 0x4e, 0x62, 0x03, 0x87, 0xa0,
|
||||||
|
0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x92, 0x06, 0xa1, 0xed, 0x6d, 0x01, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/pkg/compress"
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
|
@ -123,17 +122,6 @@ func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
|
||||||
opts = append(opts, grpc.WithInsecure())
|
opts = append(opts, grpc.WithInsecure())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch c.cfg.CompressType {
|
|
||||||
case compress.Snappy:
|
|
||||||
opts = append(opts,
|
|
||||||
grpc.WithCompressor(compress.NewSnappyCompressor()),
|
|
||||||
grpc.WithDecompressor(compress.NewSnappyDecompressor()))
|
|
||||||
case compress.Lz4:
|
|
||||||
opts = append(opts,
|
|
||||||
grpc.WithCompressor(compress.NewLz4Compressor()),
|
|
||||||
grpc.WithDecompressor(compress.NewLz4Decompressor()))
|
|
||||||
}
|
|
||||||
|
|
||||||
proto := "tcp"
|
proto := "tcp"
|
||||||
if url, uerr := url.Parse(endpoint); uerr == nil && url.Scheme == "unix" {
|
if url, uerr := url.Parse(endpoint); uerr == nil && url.Scheme == "unix" {
|
||||||
proto = "unix"
|
proto = "unix"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/pkg/compress"
|
|
||||||
"github.com/coreos/etcd/pkg/tlsutil"
|
"github.com/coreos/etcd/pkg/tlsutil"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
@ -44,8 +43,6 @@ type Config struct {
|
||||||
|
|
||||||
// Logger is the logger used by client library.
|
// Logger is the logger used by client library.
|
||||||
Logger Logger
|
Logger Logger
|
||||||
|
|
||||||
CompressType compress.Type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type yamlConfig struct {
|
type yamlConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -440,7 +440,7 @@ func (w *watcher) serveStream(ws *watcherStream) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// resume up to last seen event if disconnected
|
// resume up to last seen event if disconnected
|
||||||
if resuming {
|
if resuming && wr.Err() == nil {
|
||||||
resuming = false
|
resuming = false
|
||||||
// trim events already seen
|
// trim events already seen
|
||||||
for i := 0; i < len(wr.Events); i++ {
|
for i := 0; i < len(wr.Events); i++ {
|
||||||
|
|
@ -454,6 +454,7 @@ func (w *watcher) serveStream(ws *watcherStream) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
resuming = false
|
||||||
// TODO don't keep buffering if subscriber stops reading
|
// TODO don't keep buffering if subscriber stops reading
|
||||||
wrs = append(wrs, wr)
|
wrs = append(wrs, wr)
|
||||||
case resumeRev := <-ws.resumec:
|
case resumeRev := <-ws.resumec:
|
||||||
|
|
|
||||||
|
|
@ -110,23 +110,23 @@ var _ = math.Inf
|
||||||
const _ = proto.GoGoProtoPackageIsVersion1
|
const _ = proto.GoGoProtoPackageIsVersion1
|
||||||
|
|
||||||
type Request struct {
|
type Request struct {
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"`
|
ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD" json:"ID"`
|
||||||
Method string `protobuf:"bytes,2,opt,name=Method" json:"Method"`
|
Method string `protobuf:"bytes,2,opt,name=Method,json=method" json:"Method"`
|
||||||
Path string `protobuf:"bytes,3,opt,name=Path" json:"Path"`
|
Path string `protobuf:"bytes,3,opt,name=Path,json=path" json:"Path"`
|
||||||
Val string `protobuf:"bytes,4,opt,name=Val" json:"Val"`
|
Val string `protobuf:"bytes,4,opt,name=Val,json=val" json:"Val"`
|
||||||
Dir bool `protobuf:"varint,5,opt,name=Dir" json:"Dir"`
|
Dir bool `protobuf:"varint,5,opt,name=Dir,json=dir" json:"Dir"`
|
||||||
PrevValue string `protobuf:"bytes,6,opt,name=PrevValue" json:"PrevValue"`
|
PrevValue string `protobuf:"bytes,6,opt,name=PrevValue,json=prevValue" json:"PrevValue"`
|
||||||
PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex" json:"PrevIndex"`
|
PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex,json=prevIndex" json:"PrevIndex"`
|
||||||
PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist" json:"PrevExist,omitempty"`
|
PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist,json=prevExist" json:"PrevExist,omitempty"`
|
||||||
Expiration int64 `protobuf:"varint,9,opt,name=Expiration" json:"Expiration"`
|
Expiration int64 `protobuf:"varint,9,opt,name=Expiration,json=expiration" json:"Expiration"`
|
||||||
Wait bool `protobuf:"varint,10,opt,name=Wait" json:"Wait"`
|
Wait bool `protobuf:"varint,10,opt,name=Wait,json=wait" json:"Wait"`
|
||||||
Since uint64 `protobuf:"varint,11,opt,name=Since" json:"Since"`
|
Since uint64 `protobuf:"varint,11,opt,name=Since,json=since" json:"Since"`
|
||||||
Recursive bool `protobuf:"varint,12,opt,name=Recursive" json:"Recursive"`
|
Recursive bool `protobuf:"varint,12,opt,name=Recursive,json=recursive" json:"Recursive"`
|
||||||
Sorted bool `protobuf:"varint,13,opt,name=Sorted" json:"Sorted"`
|
Sorted bool `protobuf:"varint,13,opt,name=Sorted,json=sorted" json:"Sorted"`
|
||||||
Quorum bool `protobuf:"varint,14,opt,name=Quorum" json:"Quorum"`
|
Quorum bool `protobuf:"varint,14,opt,name=Quorum,json=quorum" json:"Quorum"`
|
||||||
Time int64 `protobuf:"varint,15,opt,name=Time" json:"Time"`
|
Time int64 `protobuf:"varint,15,opt,name=Time,json=time" json:"Time"`
|
||||||
Stream bool `protobuf:"varint,16,opt,name=Stream" json:"Stream"`
|
Stream bool `protobuf:"varint,16,opt,name=Stream,json=stream" json:"Stream"`
|
||||||
Refresh *bool `protobuf:"varint,17,opt,name=Refresh" json:"Refresh,omitempty"`
|
Refresh *bool `protobuf:"varint,17,opt,name=Refresh,json=refresh" json:"Refresh,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,8 +136,8 @@ func (*Request) ProtoMessage() {}
|
||||||
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{0} }
|
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorEtcdserver, []int{0} }
|
||||||
|
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
NodeID uint64 `protobuf:"varint,1,opt,name=NodeID" json:"NodeID"`
|
NodeID uint64 `protobuf:"varint,1,opt,name=NodeID,json=nodeID" json:"NodeID"`
|
||||||
ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"`
|
ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID,json=clusterID" json:"ClusterID"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1005,25 +1005,30 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileDescriptorEtcdserver = []byte{
|
var fileDescriptorEtcdserver = []byte{
|
||||||
// 320 bytes of a gzipped FileDescriptorProto
|
// 388 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x91, 0x4f, 0x4f, 0xf2, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x5c, 0x92, 0xd1, 0xee, 0xd2, 0x30,
|
||||||
0x10, 0xc6, 0x69, 0x29, 0xff, 0xf6, 0xe5, 0xd5, 0x52, 0x31, 0x4e, 0x3c, 0xa0, 0xe1, 0xe4, 0x49,
|
0x14, 0xc6, 0xff, 0xdb, 0xca, 0x60, 0x15, 0x15, 0x1b, 0x62, 0x4e, 0x88, 0x41, 0x43, 0xbc, 0xf0,
|
||||||
0xcf, 0x5e, 0x11, 0x0e, 0x1c, 0x34, 0x08, 0x46, 0xcf, 0x2b, 0x1d, 0x61, 0x13, 0x60, 0x71, 0x3a,
|
0x4a, 0xdf, 0x01, 0xe1, 0x82, 0x44, 0x0d, 0x82, 0xd1, 0xeb, 0xba, 0x1d, 0xa1, 0x09, 0x5b, 0x47,
|
||||||
0x4b, 0xf8, 0x88, 0x1c, 0xfd, 0x04, 0x46, 0xfd, 0x22, 0xba, 0xd5, 0xc6, 0x6e, 0x3d, 0x6c, 0xd2,
|
0xdb, 0x4d, 0xde, 0xc0, 0x57, 0xe3, 0xd2, 0x27, 0x30, 0xea, 0x93, 0xd8, 0x16, 0x86, 0xd5, 0x8b,
|
||||||
0xfc, 0x9e, 0x67, 0x66, 0x9e, 0x99, 0x8a, 0x10, 0x79, 0x1a, 0x27, 0x48, 0x1b, 0xa4, 0xf3, 0x35,
|
0x26, 0xcb, 0xef, 0xfb, 0xce, 0xe9, 0xd7, 0x73, 0x46, 0x47, 0x68, 0xf2, 0x42, 0xa3, 0x6a, 0x51,
|
||||||
0x69, 0xd6, 0x51, 0x33, 0x27, 0xeb, 0xc7, 0xe3, 0xf6, 0x4c, 0xcf, 0xf4, 0xb7, 0x70, 0x91, 0x7e,
|
0xbd, 0xac, 0x95, 0x34, 0x92, 0x0d, 0xff, 0x92, 0xfa, 0xf3, 0x64, 0xbc, 0x93, 0x3b, 0xe9, 0x85,
|
||||||
0xfd, 0x78, 0xba, 0x9f, 0xbe, 0xa8, 0x8d, 0xf1, 0xd9, 0x60, 0xc2, 0x51, 0x28, 0xfc, 0x61, 0x1f,
|
0x57, 0xee, 0xeb, 0xe2, 0x99, 0x7d, 0x23, 0xb4, 0xbf, 0xc1, 0x63, 0x83, 0xda, 0xb0, 0x31, 0x8d,
|
||||||
0xbc, 0x53, 0xef, 0x2c, 0xe8, 0x05, 0xbb, 0xd7, 0x93, 0x52, 0xd4, 0x16, 0xd5, 0x6b, 0xe4, 0xb9,
|
0x57, 0x0b, 0x88, 0x9e, 0x45, 0x2f, 0xc8, 0x9c, 0x9c, 0x7f, 0x3c, 0xbd, 0xdb, 0xc4, 0x62, 0xc1,
|
||||||
0x8e, 0xc1, 0xb7, 0xb4, 0x91, 0xd1, 0x48, 0x04, 0x23, 0xc9, 0x73, 0x28, 0x3b, 0xac, 0x25, 0xca,
|
0x9e, 0xd0, 0xf4, 0x2d, 0x9a, 0xbd, 0x2c, 0x20, 0xb6, 0x4a, 0x76, 0x55, 0xd2, 0xd2, 0x33, 0x06,
|
||||||
0xf7, 0x72, 0x01, 0x41, 0x11, 0xf5, 0x15, 0x41, 0xc5, 0xa2, 0x7a, 0x86, 0x8e, 0x44, 0x63, 0x44,
|
0x94, 0xac, 0xb9, 0xd9, 0x43, 0x12, 0x68, 0xa4, 0xb6, 0x84, 0x3d, 0xa6, 0xc9, 0x47, 0x7e, 0x00,
|
||||||
0xb8, 0xb1, 0x4e, 0x83, 0x50, 0x75, 0xbc, 0x99, 0x30, 0x5c, 0xc5, 0xb8, 0x85, 0x9a, 0x93, 0x20,
|
0x12, 0x08, 0x49, 0xcb, 0x0f, 0x8e, 0x2f, 0x84, 0x82, 0x9e, 0xe5, 0x83, 0x8e, 0x17, 0x42, 0xb1,
|
||||||
0x13, 0x06, 0x5b, 0x95, 0x30, 0xd4, 0x7f, 0x5b, 0x79, 0x11, 0x08, 0x31, 0xd8, 0xae, 0x15, 0x49,
|
0x19, 0xcd, 0xd6, 0x0a, 0x5b, 0x5b, 0xd3, 0x20, 0xa4, 0x41, 0x55, 0x56, 0x77, 0xb8, 0xf3, 0xac,
|
||||||
0x56, 0x7a, 0x05, 0x0d, 0xab, 0x94, 0xf3, 0x78, 0x0f, 0x52, 0x31, 0x08, 0x67, 0xf0, 0x81, 0xa8,
|
0xaa, 0x02, 0x4f, 0xd0, 0x0f, 0x82, 0x7a, 0x8f, 0xc7, 0x9d, 0x67, 0x79, 0x12, 0xda, 0xc0, 0xe0,
|
||||||
0x4c, 0xd4, 0x6a, 0x8a, 0xf0, 0xaf, 0xd8, 0x7b, 0x8c, 0x53, 0x43, 0x89, 0xda, 0x20, 0x34, 0x1d,
|
0x76, 0x4b, 0x74, 0xf1, 0x78, 0xcc, 0x9e, 0x53, 0xba, 0x3c, 0xd5, 0x42, 0x71, 0x23, 0x64, 0x05,
|
||||||
0xb7, 0x5d, 0x7b, 0xa2, 0x89, 0x31, 0x86, 0xff, 0x45, 0x7a, 0x6b, 0x34, 0x99, 0x25, 0xec, 0x39,
|
0x99, 0x35, 0x25, 0xd7, 0x46, 0x14, 0x6f, 0xdc, 0xbd, 0xed, 0x13, 0x17, 0x06, 0x68, 0x10, 0x95,
|
||||||
0xd4, 0x4e, 0xbb, 0x53, 0x4b, 0x84, 0x7d, 0x27, 0x41, 0x5a, 0xcf, 0x84, 0x72, 0x09, 0xa1, 0xe3,
|
0x7c, 0xb5, 0x84, 0x4d, 0x68, 0x6f, 0x2b, 0xaa, 0x1c, 0xe1, 0x5e, 0x90, 0xa1, 0xa7, 0x1d, 0x72,
|
||||||
0x3c, 0x4c, 0x2f, 0xfd, 0x44, 0x98, 0xcc, 0xa1, 0x95, 0x2f, 0xd2, 0xbd, 0x14, 0x75, 0x7b, 0x63,
|
0xf7, 0x6f, 0x30, 0x6f, 0x94, 0x16, 0x2d, 0xc2, 0x30, 0x28, 0xcd, 0x54, 0x87, 0xdd, 0x4c, 0xb7,
|
||||||
0x19, 0x4b, 0x96, 0x69, 0xe1, 0x8d, 0x8e, 0xf1, 0xcf, 0x5f, 0xb0, 0x39, 0xaf, 0x16, 0x26, 0x61,
|
0x52, 0x19, 0x2c, 0xe0, 0x7e, 0x60, 0x48, 0xb5, 0x67, 0x4e, 0x7d, 0xdf, 0x48, 0xd5, 0x94, 0xf0,
|
||||||
0x24, 0x2b, 0xf8, 0xb9, 0xd0, 0x0b, 0x77, 0xef, 0x9d, 0xd2, 0xee, 0xa3, 0xe3, 0xbd, 0xd8, 0xf7,
|
0x20, 0x54, 0x8f, 0x9e, 0xb9, 0x54, 0x1f, 0x44, 0x89, 0xf0, 0x30, 0x48, 0x4d, 0x8c, 0x25, 0xbe,
|
||||||
0x66, 0xdf, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x32, 0x78, 0xf7, 0x38, 0x05, 0x02, 0x00, 0x00,
|
0xab, 0x51, 0xc8, 0x4b, 0x18, 0xfd, 0xd3, 0xd5, 0x33, 0x36, 0x75, 0x8b, 0xfe, 0xa2, 0x50, 0xef,
|
||||||
|
0xe1, 0x51, 0x30, 0x95, 0xbe, 0xba, 0xc0, 0xd9, 0x1b, 0x3a, 0xb0, 0x7b, 0xe6, 0x05, 0x37, 0xdc,
|
||||||
|
0x75, 0x7a, 0x27, 0x0b, 0xfc, 0xef, 0x6f, 0x48, 0x2b, 0xcf, 0xdc, 0x0b, 0x5f, 0x1f, 0x1a, 0x6d,
|
||||||
|
0x50, 0x59, 0x43, 0x1c, 0x6e, 0x21, 0xef, 0xf0, 0x7c, 0x74, 0xfe, 0x35, 0xbd, 0x3b, 0xff, 0x9e,
|
||||||
|
0x46, 0xdf, 0xed, 0xf9, 0x69, 0xcf, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x8e, 0x1a, 0x0d,
|
||||||
|
0xa0, 0x02, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,22 +22,22 @@ var _ = math.Inf
|
||||||
// An InternalRaftRequest is the union of all requests which can be
|
// An InternalRaftRequest is the union of all requests which can be
|
||||||
// sent via raft.
|
// sent via raft.
|
||||||
type InternalRaftRequest struct {
|
type InternalRaftRequest struct {
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"`
|
V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"`
|
||||||
Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"`
|
Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"`
|
||||||
Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"`
|
Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"`
|
||||||
DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"`
|
DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range,json=deleteRange" json:"delete_range,omitempty"`
|
||||||
Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"`
|
Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"`
|
||||||
Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"`
|
Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"`
|
||||||
LeaseGrant *LeaseGrantRequest `protobuf:"bytes,8,opt,name=lease_grant" json:"lease_grant,omitempty"`
|
LeaseGrant *LeaseGrantRequest `protobuf:"bytes,8,opt,name=lease_grant,json=leaseGrant" json:"lease_grant,omitempty"`
|
||||||
LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"`
|
LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke,json=leaseRevoke" json:"lease_revoke,omitempty"`
|
||||||
AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"`
|
AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable,json=authEnable" json:"auth_enable,omitempty"`
|
||||||
AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add" json:"auth_user_add,omitempty"`
|
AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add,json=authUserAdd" json:"auth_user_add,omitempty"`
|
||||||
AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,12,opt,name=auth_user_delete" json:"auth_user_delete,omitempty"`
|
AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,12,opt,name=auth_user_delete,json=authUserDelete" json:"auth_user_delete,omitempty"`
|
||||||
AuthUserChangePassword *AuthUserChangePasswordRequest `protobuf:"bytes,13,opt,name=auth_user_change_password" json:"auth_user_change_password,omitempty"`
|
AuthUserChangePassword *AuthUserChangePasswordRequest `protobuf:"bytes,13,opt,name=auth_user_change_password,json=authUserChangePassword" json:"auth_user_change_password,omitempty"`
|
||||||
AuthUserGrant *AuthUserGrantRequest `protobuf:"bytes,14,opt,name=auth_user_grant" json:"auth_user_grant,omitempty"`
|
AuthUserGrant *AuthUserGrantRequest `protobuf:"bytes,14,opt,name=auth_user_grant,json=authUserGrant" json:"auth_user_grant,omitempty"`
|
||||||
AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,15,opt,name=auth_role_add" json:"auth_role_add,omitempty"`
|
AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,15,opt,name=auth_role_add,json=authRoleAdd" json:"auth_role_add,omitempty"`
|
||||||
AuthRoleGrant *AuthRoleGrantRequest `protobuf:"bytes,16,opt,name=auth_role_grant" json:"auth_role_grant,omitempty"`
|
AuthRoleGrant *AuthRoleGrantRequest `protobuf:"bytes,16,opt,name=auth_role_grant,json=authRoleGrant" json:"auth_role_grant,omitempty"`
|
||||||
Authenticate *AuthenticateRequest `protobuf:"bytes,17,opt,name=authenticate" json:"authenticate,omitempty"`
|
Authenticate *AuthenticateRequest `protobuf:"bytes,17,opt,name=authenticate" json:"authenticate,omitempty"`
|
||||||
Alarm *AlarmRequest `protobuf:"bytes,18,opt,name=alarm" json:"alarm,omitempty"`
|
Alarm *AlarmRequest `protobuf:"bytes,18,opt,name=alarm" json:"alarm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -1185,35 +1185,39 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileDescriptorRaftInternal = []byte{
|
var fileDescriptorRaftInternal = []byte{
|
||||||
// 473 bytes of a gzipped FileDescriptorProto
|
// 534 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x93, 0xdf, 0x6e, 0xd3, 0x30,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x94, 0xdf, 0x6e, 0xd3, 0x30,
|
||||||
0x14, 0xc6, 0x69, 0xf7, 0x8f, 0x9d, 0xb6, 0xb4, 0x74, 0x20, 0x99, 0x5e, 0x8c, 0xad, 0x08, 0x09,
|
0x14, 0xc6, 0x69, 0xf7, 0x87, 0xcd, 0xfd, 0x8b, 0x07, 0xc8, 0xf4, 0x62, 0x8c, 0x22, 0x24, 0x04,
|
||||||
0x84, 0x54, 0xa4, 0x0d, 0xc1, 0x05, 0xe2, 0xa2, 0x6c, 0x13, 0x9a, 0x84, 0xd0, 0x14, 0xc1, 0x75,
|
0x52, 0x41, 0xe3, 0x01, 0xa0, 0xb4, 0x15, 0x1a, 0x02, 0x69, 0x8a, 0xe0, 0x3a, 0x72, 0x93, 0xb3,
|
||||||
0xe4, 0x26, 0x87, 0xae, 0x22, 0xb5, 0x83, 0xe3, 0x94, 0xf1, 0x50, 0xbc, 0xc7, 0x2e, 0x79, 0x04,
|
0xae, 0x22, 0x8d, 0x83, 0xe3, 0x94, 0xf1, 0x86, 0xbb, 0xe4, 0x11, 0x80, 0xb7, 0xe0, 0x0e, 0xfb,
|
||||||
0xe0, 0x49, 0xb0, 0x4f, 0xe2, 0x35, 0xe9, 0xdc, 0x8b, 0x48, 0xde, 0xce, 0xef, 0xf7, 0x9d, 0xe4,
|
0x24, 0x71, 0x9a, 0xcd, 0xbd, 0xa8, 0x94, 0x7c, 0xe7, 0x3b, 0xbf, 0xf3, 0xc5, 0x47, 0x2e, 0x39,
|
||||||
0xab, 0x0c, 0x7b, 0x8a, 0x7f, 0xd5, 0xe1, 0x4c, 0x68, 0x54, 0x82, 0x27, 0xa3, 0x54, 0x49, 0x2d,
|
0x92, 0xfc, 0x42, 0xf9, 0xcb, 0x58, 0x81, 0x8c, 0x79, 0x34, 0x4a, 0xa4, 0x50, 0x82, 0xb6, 0x41,
|
||||||
0xfb, 0x6d, 0xd4, 0x51, 0x9c, 0xa1, 0x5a, 0xa0, 0x4a, 0x27, 0x83, 0x07, 0x53, 0x39, 0x95, 0x34,
|
0x05, 0x61, 0x0a, 0x72, 0x0d, 0x32, 0x99, 0x0f, 0xee, 0x2f, 0xc4, 0x42, 0x60, 0xe1, 0x95, 0x79,
|
||||||
0x78, 0x69, 0x4f, 0x05, 0x33, 0xe8, 0x2d, 0x99, 0xf2, 0x3f, 0xbb, 0x2a, 0x8d, 0x8a, 0xe3, 0xf0,
|
0xca, 0x3d, 0x83, 0x7e, 0xe5, 0x29, 0x94, 0x43, 0x99, 0x04, 0xf9, 0xe3, 0xf0, 0xdf, 0x01, 0x39,
|
||||||
0xd7, 0x0e, 0xec, 0x9d, 0x97, 0x99, 0x81, 0x59, 0x10, 0xe0, 0xf7, 0x1c, 0x33, 0xdd, 0x07, 0x68,
|
0x3a, 0x2b, 0x98, 0x9e, 0x1e, 0xe0, 0xc1, 0xf7, 0x0c, 0x52, 0x45, 0xbb, 0xa4, 0x79, 0x36, 0x65,
|
||||||
0x9e, 0x9f, 0xb2, 0xc6, 0x41, 0xe3, 0xd9, 0x66, 0xff, 0x10, 0x9a, 0x8b, 0x23, 0xd6, 0x34, 0xe7,
|
0x8d, 0x93, 0xc6, 0xf3, 0x5d, 0xaf, 0xb9, 0x9c, 0xd2, 0x67, 0xa4, 0xb9, 0x3e, 0x65, 0x4d, 0xfd,
|
||||||
0xd6, 0xd1, 0xc3, 0x51, 0x75, 0xe3, 0xc8, 0xe1, 0xcf, 0x61, 0x4b, 0x71, 0x31, 0x45, 0xb6, 0x41,
|
0xde, 0x3a, 0x7d, 0x30, 0xda, 0x9c, 0x3a, 0x2a, 0x5a, 0x3c, 0x6d, 0xa0, 0xaf, 0xc9, 0x9e, 0xe4,
|
||||||
0xd4, 0x60, 0x85, 0xb2, 0x23, 0x87, 0x3e, 0x85, 0x8d, 0x34, 0xd7, 0x6c, 0x93, 0x40, 0x56, 0x07,
|
0xf1, 0x02, 0xd8, 0x0e, 0x3a, 0x07, 0x37, 0x9c, 0xa6, 0x54, 0xda, 0x73, 0x23, 0x7d, 0x41, 0x76,
|
||||||
0x2f, 0xf2, 0x9b, 0x17, 0x78, 0x0d, 0xed, 0x18, 0x13, 0xd4, 0x18, 0x16, 0xc1, 0x5b, 0xc4, 0x1f,
|
0x92, 0x4c, 0xb1, 0x5d, 0xf4, 0xb3, 0xba, 0xff, 0x3c, 0x2b, 0xf3, 0x78, 0xc6, 0x44, 0x27, 0xa4,
|
||||||
0xd4, 0xf9, 0x53, 0x22, 0x56, 0xe3, 0xf5, 0x95, 0x60, 0xdb, 0xbe, 0xf8, 0xcf, 0x57, 0xc2, 0x61,
|
0x1d, 0x42, 0x04, 0x0a, 0xfc, 0x7c, 0xc8, 0x1e, 0x36, 0x9d, 0xd4, 0x9b, 0xa6, 0xe8, 0xa8, 0x8d,
|
||||||
0xc7, 0x00, 0x91, 0x9c, 0xa7, 0x3c, 0xd2, 0x33, 0x29, 0xd8, 0x0e, 0xd1, 0x8f, 0xeb, 0xf4, 0xc9,
|
0x6a, 0x85, 0x95, 0x66, 0x06, 0xaa, 0xab, 0x98, 0xed, 0xbb, 0x06, 0x7e, 0xb9, 0x8a, 0xed, 0x40,
|
||||||
0xcd, 0xdc, 0x49, 0xaf, 0xa0, 0x95, 0x20, 0xcf, 0x30, 0x9c, 0x9a, 0x77, 0xd2, 0xec, 0xae, 0xcf,
|
0x6d, 0xa2, 0x6f, 0x09, 0x09, 0xc4, 0x2a, 0xe1, 0x81, 0x5a, 0x8a, 0x98, 0xdd, 0xc5, 0x96, 0xc7,
|
||||||
0xfa, 0x68, 0x81, 0x0f, 0x76, 0x5e, 0xf9, 0x92, 0xc2, 0x52, 0xb8, 0x90, 0xdf, 0x90, 0xed, 0xfa,
|
0xf5, 0x96, 0x89, 0xad, 0x97, 0x9d, 0x1b, 0x2d, 0xf4, 0x1d, 0x69, 0x45, 0xc0, 0x53, 0xf0, 0x17,
|
||||||
0xbe, 0x84, 0xb4, 0x80, 0x80, 0xca, 0x36, 0x9e, 0xeb, 0xcb, 0x10, 0x05, 0x9f, 0x24, 0xc8, 0xc0,
|
0x3a, 0xb1, 0x62, 0x07, 0x2e, 0xc2, 0x27, 0x63, 0xf8, 0x60, 0xea, 0x96, 0x10, 0x59, 0xc9, 0x7c,
|
||||||
0xb7, 0x6d, 0x6c, 0x80, 0x33, 0x9a, 0x3b, 0xeb, 0x0d, 0x74, 0xc8, 0xca, 0x0d, 0x13, 0xf2, 0x38,
|
0x73, 0x4e, 0x90, 0xb0, 0x16, 0xdf, 0x80, 0x1d, 0xba, 0xbe, 0x19, 0x11, 0x1e, 0x1a, 0xec, 0x37,
|
||||||
0x66, 0x2d, 0xdf, 0x3a, 0xeb, 0x7d, 0x31, 0x7f, 0x8d, 0xe3, 0xd8, 0x89, 0xef, 0xa0, 0xb7, 0x14,
|
0x47, 0x95, 0x66, 0x62, 0xf0, 0x4c, 0x5d, 0xfa, 0x10, 0xf3, 0x79, 0x04, 0x8c, 0xb8, 0x62, 0x8c,
|
||||||
0x8b, 0xea, 0x59, 0x9b, 0xdc, 0x27, 0x7e, 0xb7, 0x2c, 0xbf, 0xd4, 0x3f, 0xc1, 0xa3, 0xa5, 0x1e,
|
0xb5, 0x61, 0x86, 0x75, 0x1b, 0x83, 0x5b, 0x89, 0x4e, 0x49, 0x07, 0x09, 0x99, 0xf6, 0xfb, 0x3c,
|
||||||
0x5d, 0xda, 0x9f, 0x24, 0x4c, 0x79, 0x96, 0xfd, 0x90, 0x2a, 0x66, 0x1d, 0xca, 0x79, 0xe1, 0xcf,
|
0x0c, 0x59, 0xcb, 0x95, 0xc3, 0x30, 0xbe, 0xea, 0xb7, 0x71, 0x18, 0xda, 0x1c, 0xbc, 0xd2, 0xe8,
|
||||||
0x39, 0x21, 0xf8, 0xa2, 0x64, 0x5d, 0xde, 0x5b, 0xe8, 0x2e, 0xf3, 0x8a, 0xbe, 0xef, 0x51, 0xca,
|
0x67, 0xd2, 0xaf, 0x28, 0xf9, 0x52, 0x58, 0x1b, 0x41, 0x4f, 0xdd, 0xa0, 0x62, 0x99, 0x05, 0xab,
|
||||||
0xd0, 0x9f, 0x52, 0xab, 0xdc, 0x95, 0xa0, 0x64, 0x82, 0x54, 0x42, 0x77, 0x5d, 0x09, 0x81, 0x21,
|
0xcb, 0x6b, 0x32, 0xbd, 0x20, 0x8f, 0x2a, 0x5c, 0x70, 0x69, 0xd6, 0xeb, 0x27, 0x3c, 0x4d, 0x7f,
|
||||||
0x2a, 0x25, 0xb8, 0xad, 0x24, 0x16, 0x5b, 0x7b, 0xeb, 0xb6, 0x5a, 0x75, 0x65, 0x6b, 0xdb, 0xca,
|
0x08, 0x19, 0xb2, 0x0e, 0x72, 0x5f, 0xba, 0xb9, 0x13, 0x34, 0x9f, 0x17, 0xde, 0x92, 0xff, 0x90,
|
||||||
0x28, 0xf4, 0x2c, 0xe2, 0xa6, 0xbd, 0xfb, 0x64, 0x1e, 0xde, 0x36, 0x1d, 0x51, 0xb9, 0x3d, 0x3c,
|
0x3b, 0xcb, 0xf4, 0x23, 0xe9, 0x55, 0x73, 0xf2, 0x4d, 0x76, 0x91, 0x3e, 0x74, 0xd3, 0x6b, 0xcb,
|
||||||
0xe1, 0x6a, 0xce, 0xfa, 0xbe, 0xdb, 0x33, 0xb6, 0xa3, 0x12, 0x1d, 0x76, 0xa1, 0x73, 0x36, 0x4f,
|
0xec, 0xf0, 0x4d, 0xd5, 0x1e, 0xa4, 0x14, 0x11, 0xe0, 0x41, 0xf6, 0xb6, 0x1d, 0xa4, 0xa7, 0x1d,
|
||||||
0xf5, 0xcf, 0x00, 0xb3, 0x54, 0x8a, 0x0c, 0xdf, 0xf7, 0xae, 0xff, 0xee, 0xdf, 0xb9, 0xfe, 0xb7,
|
0x37, 0x0f, 0xb2, 0xd0, 0x6c, 0x22, 0xa4, 0xe4, 0x89, 0xfa, 0xdb, 0x12, 0x99, 0x9e, 0xdb, 0x89,
|
||||||
0xdf, 0xf8, 0x6d, 0x9e, 0x3f, 0xe6, 0x99, 0x6c, 0xd3, 0xcd, 0x3e, 0xfe, 0x1f, 0x00, 0x00, 0xff,
|
0xac, 0x4a, 0x67, 0xa4, 0x6d, 0x04, 0x88, 0xd5, 0x32, 0xe0, 0x7a, 0x21, 0xf7, 0x10, 0xf4, 0xe4,
|
||||||
0xff, 0x8e, 0xdf, 0x9b, 0x7d, 0x31, 0x04, 0x00, 0x00,
|
0x36, 0xa8, 0x74, 0x94, 0x9c, 0x5a, 0x9b, 0xb9, 0xfa, 0x3c, 0xe2, 0x72, 0xc5, 0xa8, 0xeb, 0xea,
|
||||||
|
0x8f, 0x4d, 0xc9, 0x5e, 0x7d, 0x34, 0x0e, 0x7b, 0xa4, 0x33, 0x5b, 0x25, 0xea, 0xa7, 0x07, 0x69,
|
||||||
|
0x22, 0xe2, 0x14, 0xde, 0xf7, 0xaf, 0xff, 0x1c, 0xdf, 0xb9, 0xfe, 0x7b, 0xdc, 0xf8, 0xa5, 0x7f,
|
||||||
|
0xbf, 0xf5, 0x6f, 0xbe, 0x8f, 0xff, 0x52, 0x6f, 0xfe, 0x07, 0x00, 0x00, 0xff, 0xff, 0xee, 0xd7,
|
||||||
|
0xc5, 0x26, 0xfd, 0x04, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,13 +182,13 @@ func (AlarmRequest_AlarmAction) EnumDescriptor() ([]byte, []int) {
|
||||||
|
|
||||||
type ResponseHeader struct {
|
type ResponseHeader struct {
|
||||||
// cluster_id is the ID of the cluster which sent the response.
|
// cluster_id is the ID of the cluster which sent the response.
|
||||||
ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,proto3" json:"cluster_id,omitempty"`
|
ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,json=clusterId,proto3" json:"cluster_id,omitempty"`
|
||||||
// member_id is the ID of the member which sent the response.
|
// member_id is the ID of the member which sent the response.
|
||||||
MemberId uint64 `protobuf:"varint,2,opt,name=member_id,proto3" json:"member_id,omitempty"`
|
MemberId uint64 `protobuf:"varint,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"`
|
||||||
// revision is the key-value store revision when the request was applied.
|
// revision is the key-value store revision when the request was applied.
|
||||||
Revision int64 `protobuf:"varint,3,opt,name=revision,proto3" json:"revision,omitempty"`
|
Revision int64 `protobuf:"varint,3,opt,name=revision,proto3" json:"revision,omitempty"`
|
||||||
// raft_term is the raft term when the request was applied.
|
// raft_term is the raft term when the request was applied.
|
||||||
RaftTerm uint64 `protobuf:"varint,4,opt,name=raft_term,proto3" json:"raft_term,omitempty"`
|
RaftTerm uint64 `protobuf:"varint,4,opt,name=raft_term,json=raftTerm,proto3" json:"raft_term,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ResponseHeader) Reset() { *m = ResponseHeader{} }
|
func (m *ResponseHeader) Reset() { *m = ResponseHeader{} }
|
||||||
|
|
@ -201,7 +201,7 @@ type RangeRequest struct {
|
||||||
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
// range_end is the upper bound on the requested range [key, range_end).
|
// range_end is the upper bound on the requested range [key, range_end).
|
||||||
// If range_end is '\0', the range is all keys >= key.
|
// If range_end is '\0', the range is all keys >= key.
|
||||||
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,omitempty"`
|
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
|
||||||
// limit is a limit on the number of keys returned for the request.
|
// limit is a limit on the number of keys returned for the request.
|
||||||
Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
|
Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
|
||||||
// revision is the point-in-time of the key-value store to use for the range.
|
// revision is the point-in-time of the key-value store to use for the range.
|
||||||
|
|
@ -209,9 +209,9 @@ type RangeRequest struct {
|
||||||
// If the revision has been compacted, ErrCompaction is returned as a response.
|
// If the revision has been compacted, ErrCompaction is returned as a response.
|
||||||
Revision int64 `protobuf:"varint,4,opt,name=revision,proto3" json:"revision,omitempty"`
|
Revision int64 `protobuf:"varint,4,opt,name=revision,proto3" json:"revision,omitempty"`
|
||||||
// sort_order is the order for returned sorted results.
|
// sort_order is the order for returned sorted results.
|
||||||
SortOrder RangeRequest_SortOrder `protobuf:"varint,5,opt,name=sort_order,proto3,enum=etcdserverpb.RangeRequest_SortOrder" json:"sort_order,omitempty"`
|
SortOrder RangeRequest_SortOrder `protobuf:"varint,5,opt,name=sort_order,json=sortOrder,proto3,enum=etcdserverpb.RangeRequest_SortOrder" json:"sort_order,omitempty"`
|
||||||
// sort_target is the key-value field to use for sorting.
|
// sort_target is the key-value field to use for sorting.
|
||||||
SortTarget RangeRequest_SortTarget `protobuf:"varint,6,opt,name=sort_target,proto3,enum=etcdserverpb.RangeRequest_SortTarget" json:"sort_target,omitempty"`
|
SortTarget RangeRequest_SortTarget `protobuf:"varint,6,opt,name=sort_target,json=sortTarget,proto3,enum=etcdserverpb.RangeRequest_SortTarget" json:"sort_target,omitempty"`
|
||||||
// serializable sets the range request to use serializable member-local reads.
|
// serializable sets the range request to use serializable member-local reads.
|
||||||
// Range requests are linearizable by default; linearizable requests have higher
|
// Range requests are linearizable by default; linearizable requests have higher
|
||||||
// latency and lower throughput than serializable requests but reflect the current
|
// latency and lower throughput than serializable requests but reflect the current
|
||||||
|
|
@ -290,7 +290,7 @@ type DeleteRangeRequest struct {
|
||||||
// range_end is the key following the last key to delete for the range [key, range_end).
|
// range_end is the key following the last key to delete for the range [key, range_end).
|
||||||
// If range_end is not given, the range is defined to contain only the key argument.
|
// If range_end is not given, the range is defined to contain only the key argument.
|
||||||
// If range_end is '\0', the range is all keys greater than or equal to the key argument.
|
// If range_end is '\0', the range is all keys greater than or equal to the key argument.
|
||||||
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,omitempty"`
|
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} }
|
func (m *DeleteRangeRequest) Reset() { *m = DeleteRangeRequest{} }
|
||||||
|
|
@ -338,13 +338,13 @@ type isRequestUnion_Request interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestUnion_RequestRange struct {
|
type RequestUnion_RequestRange struct {
|
||||||
RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,oneof"`
|
RequestRange *RangeRequest `protobuf:"bytes,1,opt,name=request_range,json=requestRange,oneof"`
|
||||||
}
|
}
|
||||||
type RequestUnion_RequestPut struct {
|
type RequestUnion_RequestPut struct {
|
||||||
RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,oneof"`
|
RequestPut *PutRequest `protobuf:"bytes,2,opt,name=request_put,json=requestPut,oneof"`
|
||||||
}
|
}
|
||||||
type RequestUnion_RequestDeleteRange struct {
|
type RequestUnion_RequestDeleteRange struct {
|
||||||
RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,oneof"`
|
RequestDeleteRange *DeleteRangeRequest `protobuf:"bytes,3,opt,name=request_delete_range,json=requestDeleteRange,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*RequestUnion_RequestRange) isRequestUnion_Request() {}
|
func (*RequestUnion_RequestRange) isRequestUnion_Request() {}
|
||||||
|
|
@ -494,13 +494,13 @@ type isResponseUnion_Response interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseUnion_ResponseRange struct {
|
type ResponseUnion_ResponseRange struct {
|
||||||
ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,oneof"`
|
ResponseRange *RangeResponse `protobuf:"bytes,1,opt,name=response_range,json=responseRange,oneof"`
|
||||||
}
|
}
|
||||||
type ResponseUnion_ResponsePut struct {
|
type ResponseUnion_ResponsePut struct {
|
||||||
ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,oneof"`
|
ResponsePut *PutResponse `protobuf:"bytes,2,opt,name=response_put,json=responsePut,oneof"`
|
||||||
}
|
}
|
||||||
type ResponseUnion_ResponseDeleteRange struct {
|
type ResponseUnion_ResponseDeleteRange struct {
|
||||||
ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,oneof"`
|
ResponseDeleteRange *DeleteRangeResponse `protobuf:"bytes,3,opt,name=response_delete_range,json=responseDeleteRange,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ResponseUnion_ResponseRange) isResponseUnion_Response() {}
|
func (*ResponseUnion_ResponseRange) isResponseUnion_Response() {}
|
||||||
|
|
@ -658,10 +658,10 @@ type Compare_Version struct {
|
||||||
Version int64 `protobuf:"varint,4,opt,name=version,proto3,oneof"`
|
Version int64 `protobuf:"varint,4,opt,name=version,proto3,oneof"`
|
||||||
}
|
}
|
||||||
type Compare_CreateRevision struct {
|
type Compare_CreateRevision struct {
|
||||||
CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,proto3,oneof"`
|
CreateRevision int64 `protobuf:"varint,5,opt,name=create_revision,json=createRevision,proto3,oneof"`
|
||||||
}
|
}
|
||||||
type Compare_ModRevision struct {
|
type Compare_ModRevision struct {
|
||||||
ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,proto3,oneof"`
|
ModRevision int64 `protobuf:"varint,6,opt,name=mod_revision,json=modRevision,proto3,oneof"`
|
||||||
}
|
}
|
||||||
type Compare_Value struct {
|
type Compare_Value struct {
|
||||||
Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"`
|
Value []byte `protobuf:"bytes,7,opt,name=value,proto3,oneof"`
|
||||||
|
|
@ -882,10 +882,10 @@ func (m *TxnResponse) GetResponses() []*ResponseUnion {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompactionRequest compacts the key-value store upto a given revision. All superseded keys
|
// CompactionRequest compacts the key-value store up to a given revision. All superseded keys
|
||||||
// with a revision less than the compaction revision will be removed.
|
// with a revision less than the compaction revision will be removed.
|
||||||
type CompactionRequest struct {
|
type CompactionRequest struct {
|
||||||
// revision is the key-value store revision for the compation operation.
|
// revision is the key-value store revision for the compaction operation.
|
||||||
Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"`
|
Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"`
|
||||||
// physical is set so the RPC will wait until the compaction is physically
|
// physical is set so the RPC will wait until the compaction is physically
|
||||||
// applied to the local database such that compacted entries are totally
|
// applied to the local database such that compacted entries are totally
|
||||||
|
|
@ -953,7 +953,7 @@ type SnapshotResponse struct {
|
||||||
// stream indicates the point in time of the snapshot.
|
// stream indicates the point in time of the snapshot.
|
||||||
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
||||||
// remaining_bytes is the number of blob bytes to be sent after this message
|
// remaining_bytes is the number of blob bytes to be sent after this message
|
||||||
RemainingBytes uint64 `protobuf:"varint,2,opt,name=remaining_bytes,proto3" json:"remaining_bytes,omitempty"`
|
RemainingBytes uint64 `protobuf:"varint,2,opt,name=remaining_bytes,json=remainingBytes,proto3" json:"remaining_bytes,omitempty"`
|
||||||
// blob contains the next chunk of the snapshot in the snapshot stream.
|
// blob contains the next chunk of the snapshot in the snapshot stream.
|
||||||
Blob []byte `protobuf:"bytes,3,opt,name=blob,proto3" json:"blob,omitempty"`
|
Blob []byte `protobuf:"bytes,3,opt,name=blob,proto3" json:"blob,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -991,10 +991,10 @@ type isWatchRequest_RequestUnion interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type WatchRequest_CreateRequest struct {
|
type WatchRequest_CreateRequest struct {
|
||||||
CreateRequest *WatchCreateRequest `protobuf:"bytes,1,opt,name=create_request,oneof"`
|
CreateRequest *WatchCreateRequest `protobuf:"bytes,1,opt,name=create_request,json=createRequest,oneof"`
|
||||||
}
|
}
|
||||||
type WatchRequest_CancelRequest struct {
|
type WatchRequest_CancelRequest struct {
|
||||||
CancelRequest *WatchCancelRequest `protobuf:"bytes,2,opt,name=cancel_request,oneof"`
|
CancelRequest *WatchCancelRequest `protobuf:"bytes,2,opt,name=cancel_request,json=cancelRequest,oneof"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*WatchRequest_CreateRequest) isWatchRequest_RequestUnion() {}
|
func (*WatchRequest_CreateRequest) isWatchRequest_RequestUnion() {}
|
||||||
|
|
@ -1101,14 +1101,14 @@ type WatchCreateRequest struct {
|
||||||
// range_end is the end of the range [key, range_end) to watch. If range_end is not given,
|
// range_end is the end of the range [key, range_end) to watch. If range_end is not given,
|
||||||
// only the key argument is watched. If range_end is equal to '\0', all keys greater than
|
// only the key argument is watched. If range_end is equal to '\0', all keys greater than
|
||||||
// or equal to the key argument are watched.
|
// or equal to the key argument are watched.
|
||||||
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,proto3" json:"range_end,omitempty"`
|
RangeEnd []byte `protobuf:"bytes,2,opt,name=range_end,json=rangeEnd,proto3" json:"range_end,omitempty"`
|
||||||
// start_revision is an optional revision to watch from (inclusive). No start_revision is "now".
|
// start_revision is an optional revision to watch from (inclusive). No start_revision is "now".
|
||||||
StartRevision int64 `protobuf:"varint,3,opt,name=start_revision,proto3" json:"start_revision,omitempty"`
|
StartRevision int64 `protobuf:"varint,3,opt,name=start_revision,json=startRevision,proto3" json:"start_revision,omitempty"`
|
||||||
// progress_notify is set so that the etcd server will periodically send a WatchResponse with
|
// progress_notify is set so that the etcd server will periodically send a WatchResponse with
|
||||||
// no events to the new watcher if there are no recent events. It is useful when clients
|
// no events to the new watcher if there are no recent events. It is useful when clients
|
||||||
// wish to recover a disconnected watcher starting from a recent known revision.
|
// wish to recover a disconnected watcher starting from a recent known revision.
|
||||||
// The etcd server may decide how often it will send notifications based on current load.
|
// The etcd server may decide how often it will send notifications based on current load.
|
||||||
ProgressNotify bool `protobuf:"varint,4,opt,name=progress_notify,proto3" json:"progress_notify,omitempty"`
|
ProgressNotify bool `protobuf:"varint,4,opt,name=progress_notify,json=progressNotify,proto3" json:"progress_notify,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} }
|
func (m *WatchCreateRequest) Reset() { *m = WatchCreateRequest{} }
|
||||||
|
|
@ -1118,7 +1118,7 @@ func (*WatchCreateRequest) Descriptor() ([]byte, []int) { return fileDescriptorR
|
||||||
|
|
||||||
type WatchCancelRequest struct {
|
type WatchCancelRequest struct {
|
||||||
// watch_id is the watcher id to cancel so that no more events are transmitted.
|
// watch_id is the watcher id to cancel so that no more events are transmitted.
|
||||||
WatchId int64 `protobuf:"varint,1,opt,name=watch_id,proto3" json:"watch_id,omitempty"`
|
WatchId int64 `protobuf:"varint,1,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *WatchCancelRequest) Reset() { *m = WatchCancelRequest{} }
|
func (m *WatchCancelRequest) Reset() { *m = WatchCancelRequest{} }
|
||||||
|
|
@ -1129,7 +1129,7 @@ func (*WatchCancelRequest) Descriptor() ([]byte, []int) { return fileDescriptorR
|
||||||
type WatchResponse struct {
|
type WatchResponse struct {
|
||||||
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
||||||
// watch_id is the ID of the watcher that corresponds to the response.
|
// watch_id is the ID of the watcher that corresponds to the response.
|
||||||
WatchId int64 `protobuf:"varint,2,opt,name=watch_id,proto3" json:"watch_id,omitempty"`
|
WatchId int64 `protobuf:"varint,2,opt,name=watch_id,json=watchId,proto3" json:"watch_id,omitempty"`
|
||||||
// created is set to true if the response is for a create watch request.
|
// created is set to true if the response is for a create watch request.
|
||||||
// The client should record the watch_id and expect to receive events for
|
// The client should record the watch_id and expect to receive events for
|
||||||
// the created watcher from the same stream.
|
// the created watcher from the same stream.
|
||||||
|
|
@ -1146,7 +1146,7 @@ type WatchResponse struct {
|
||||||
//
|
//
|
||||||
// The client should treat the watcher as canceled and should not try to create any
|
// The client should treat the watcher as canceled and should not try to create any
|
||||||
// watcher with the same start_revision again.
|
// watcher with the same start_revision again.
|
||||||
CompactRevision int64 `protobuf:"varint,5,opt,name=compact_revision,proto3" json:"compact_revision,omitempty"`
|
CompactRevision int64 `protobuf:"varint,5,opt,name=compact_revision,json=compactRevision,proto3" json:"compact_revision,omitempty"`
|
||||||
Events []*mvccpb.Event `protobuf:"bytes,11,rep,name=events" json:"events,omitempty"`
|
Events []*mvccpb.Event `protobuf:"bytes,11,rep,name=events" json:"events,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1171,9 +1171,9 @@ func (m *WatchResponse) GetEvents() []*mvccpb.Event {
|
||||||
|
|
||||||
type LeaseGrantRequest struct {
|
type LeaseGrantRequest struct {
|
||||||
// TTL is the advisory time-to-live in seconds.
|
// TTL is the advisory time-to-live in seconds.
|
||||||
TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"`
|
TTL int64 `protobuf:"varint,1,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"`
|
||||||
// ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID.
|
// ID is the requested ID for the lease. If ID is set to 0, the lessor chooses an ID.
|
||||||
ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} }
|
func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} }
|
||||||
|
|
@ -1184,9 +1184,9 @@ func (*LeaseGrantRequest) Descriptor() ([]byte, []int) { return fileDescriptorRp
|
||||||
type LeaseGrantResponse struct {
|
type LeaseGrantResponse struct {
|
||||||
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
||||||
// ID is the lease ID for the granted lease.
|
// ID is the lease ID for the granted lease.
|
||||||
ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
// TTL is the server chosen lease time-to-live in seconds.
|
// TTL is the server chosen lease time-to-live in seconds.
|
||||||
TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"`
|
TTL int64 `protobuf:"varint,3,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"`
|
||||||
Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"`
|
Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1204,7 +1204,7 @@ func (m *LeaseGrantResponse) GetHeader() *ResponseHeader {
|
||||||
|
|
||||||
type LeaseRevokeRequest struct {
|
type LeaseRevokeRequest struct {
|
||||||
// ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted.
|
// ID is the lease ID to revoke. When the ID is revoked, all associated keys will be deleted.
|
||||||
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID int64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} }
|
func (m *LeaseRevokeRequest) Reset() { *m = LeaseRevokeRequest{} }
|
||||||
|
|
@ -1230,7 +1230,7 @@ func (m *LeaseRevokeResponse) GetHeader() *ResponseHeader {
|
||||||
|
|
||||||
type LeaseKeepAliveRequest struct {
|
type LeaseKeepAliveRequest struct {
|
||||||
// ID is the lease ID for the lease to keep alive.
|
// ID is the lease ID for the lease to keep alive.
|
||||||
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID int64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} }
|
func (m *LeaseKeepAliveRequest) Reset() { *m = LeaseKeepAliveRequest{} }
|
||||||
|
|
@ -1241,9 +1241,9 @@ func (*LeaseKeepAliveRequest) Descriptor() ([]byte, []int) { return fileDescript
|
||||||
type LeaseKeepAliveResponse struct {
|
type LeaseKeepAliveResponse struct {
|
||||||
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
|
||||||
// ID is the lease ID from the keep alive request.
|
// ID is the lease ID from the keep alive request.
|
||||||
ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID int64 `protobuf:"varint,2,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
// TTL is the new time-to-live for the lease.
|
// TTL is the new time-to-live for the lease.
|
||||||
TTL int64 `protobuf:"varint,3,opt,name=TTL,proto3" json:"TTL,omitempty"`
|
TTL int64 `protobuf:"varint,3,opt,name=TTL,json=tTL,proto3" json:"TTL,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} }
|
func (m *LeaseKeepAliveResponse) Reset() { *m = LeaseKeepAliveResponse{} }
|
||||||
|
|
@ -1260,7 +1260,7 @@ func (m *LeaseKeepAliveResponse) GetHeader() *ResponseHeader {
|
||||||
|
|
||||||
type Member struct {
|
type Member struct {
|
||||||
// ID is the member ID for this member.
|
// ID is the member ID for this member.
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
// name is the human-readable name of the member. If the member is not started, the name will be an empty string.
|
// name is the human-readable name of the member. If the member is not started, the name will be an empty string.
|
||||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
// peerURLs is the list of URLs the member exposes to the cluster for communication.
|
// peerURLs is the list of URLs the member exposes to the cluster for communication.
|
||||||
|
|
@ -1311,7 +1311,7 @@ func (m *MemberAddResponse) GetMember() *Member {
|
||||||
|
|
||||||
type MemberRemoveRequest struct {
|
type MemberRemoveRequest struct {
|
||||||
// ID is the member ID of the member to remove.
|
// ID is the member ID of the member to remove.
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemberRemoveRequest) Reset() { *m = MemberRemoveRequest{} }
|
func (m *MemberRemoveRequest) Reset() { *m = MemberRemoveRequest{} }
|
||||||
|
|
@ -1337,7 +1337,7 @@ func (m *MemberRemoveResponse) GetHeader() *ResponseHeader {
|
||||||
|
|
||||||
type MemberUpdateRequest struct {
|
type MemberUpdateRequest struct {
|
||||||
// ID is the member ID of the member to update.
|
// ID is the member ID of the member to update.
|
||||||
ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
ID uint64 `protobuf:"varint,1,opt,name=ID,json=iD,proto3" json:"ID,omitempty"`
|
||||||
// peerURLs is the new list of URLs the member will use to communicate with the cluster.
|
// peerURLs is the new list of URLs the member will use to communicate with the cluster.
|
||||||
PeerURLs []string `protobuf:"bytes,2,rep,name=peerURLs" json:"peerURLs,omitempty"`
|
PeerURLs []string `protobuf:"bytes,2,rep,name=peerURLs" json:"peerURLs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
@ -13966,152 +13966,166 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileDescriptorRpc = []byte{
|
var fileDescriptorRpc = []byte{
|
||||||
// 2339 bytes of a gzipped FileDescriptorProto
|
// 2576 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x3a, 0x4b, 0x53, 0x1b, 0xd9,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5a, 0xcd, 0x72, 0x1b, 0xc7,
|
||||||
0xd5, 0xe8, 0x81, 0x84, 0x8e, 0x84, 0x90, 0x2f, 0xd8, 0xc6, 0xf2, 0xd8, 0x83, 0x1b, 0xec, 0x9a,
|
0x11, 0x26, 0x7e, 0x08, 0x10, 0x0d, 0x10, 0xa2, 0x86, 0x94, 0x4c, 0x41, 0xb6, 0x2c, 0xaf, 0x24,
|
||||||
0xef, 0x1b, 0x17, 0xce, 0xc8, 0x99, 0x4c, 0x2a, 0x99, 0xaa, 0x89, 0x00, 0x19, 0x1c, 0x63, 0x60,
|
0x5b, 0x89, 0x1d, 0x2a, 0x66, 0x9c, 0x43, 0x2a, 0x2e, 0xa5, 0x40, 0x02, 0x96, 0x68, 0x52, 0xa4,
|
||||||
0x24, 0xc1, 0xd4, 0x54, 0xa5, 0x4a, 0xd5, 0x48, 0xd7, 0xd0, 0x63, 0xbd, 0xa6, 0xbb, 0xc5, 0x98,
|
0xbc, 0x04, 0xa9, 0xf8, 0xc4, 0x5a, 0x02, 0x23, 0x12, 0x25, 0xfc, 0x79, 0x77, 0x41, 0x89, 0xaa,
|
||||||
0x59, 0xe4, 0x27, 0x64, 0x93, 0x54, 0xe5, 0x47, 0x64, 0x9f, 0x7d, 0x76, 0xc9, 0x2a, 0x59, 0x66,
|
0xca, 0x25, 0x55, 0x79, 0x02, 0xe7, 0x94, 0xca, 0x0b, 0xe4, 0x01, 0xf2, 0x0e, 0xa9, 0x5c, 0x92,
|
||||||
0x95, 0xa4, 0xb2, 0xcc, 0x5f, 0xc8, 0x26, 0xe7, 0xbe, 0xba, 0x6f, 0xb7, 0xae, 0xc0, 0x69, 0xb2,
|
0x27, 0x48, 0x52, 0x39, 0xa5, 0x72, 0xc9, 0x3d, 0xb9, 0xa4, 0xe7, 0x77, 0x67, 0x07, 0xbb, 0x94,
|
||||||
0x30, 0xd0, 0xe7, 0x9e, 0xf7, 0xeb, 0x9e, 0x73, 0x67, 0xa0, 0xe0, 0x8e, 0xbb, 0x9b, 0x63, 0x77,
|
0x9c, 0x65, 0x0e, 0x22, 0x77, 0x7a, 0xba, 0xbf, 0xe9, 0xee, 0xe9, 0xe9, 0xe9, 0x1e, 0x0a, 0x2a,
|
||||||
0xe4, 0x8f, 0x48, 0x89, 0xfa, 0xdd, 0x9e, 0x47, 0xdd, 0x0b, 0xea, 0x8e, 0x4f, 0xab, 0x2b, 0x67,
|
0xfe, 0xa4, 0xbb, 0x36, 0xf1, 0xc7, 0xe1, 0x98, 0xd4, 0x68, 0xd8, 0xed, 0x05, 0xd4, 0x3f, 0xa3,
|
||||||
0xa3, 0xb3, 0x11, 0x3f, 0x78, 0xc6, 0xfe, 0x12, 0x38, 0xd5, 0x7b, 0x0c, 0xe7, 0xd9, 0xe0, 0xa2,
|
0xfe, 0xe4, 0xb8, 0xb1, 0x72, 0x32, 0x3e, 0x19, 0xf3, 0x89, 0x07, 0xec, 0x4b, 0xf0, 0x34, 0x6e,
|
||||||
0xdb, 0xe5, 0x3f, 0xc6, 0xa7, 0xcf, 0xde, 0x5e, 0xc8, 0xa3, 0xfb, 0xfc, 0xc8, 0x9e, 0xf8, 0xe7,
|
0x30, 0x9e, 0x07, 0xc3, 0xb3, 0x6e, 0x97, 0xff, 0x98, 0x1c, 0x3f, 0x78, 0x71, 0x26, 0xa7, 0x6e,
|
||||||
0xfc, 0x07, 0x1e, 0xb1, 0x5f, 0xe2, 0xd0, 0xfa, 0x05, 0x94, 0x9b, 0xd4, 0x1b, 0x8f, 0x86, 0x1e,
|
0xf2, 0x29, 0x6f, 0x1a, 0x9e, 0xf2, 0x1f, 0x38, 0xc5, 0x7e, 0x89, 0x49, 0xe7, 0x57, 0x39, 0xa8,
|
||||||
0xdd, 0xa3, 0x76, 0x8f, 0xba, 0x84, 0x00, 0x74, 0xfb, 0x13, 0xcf, 0xa7, 0x6e, 0xc7, 0xe9, 0xad,
|
0xbb, 0x34, 0x98, 0x8c, 0x47, 0x01, 0x7d, 0x4c, 0xbd, 0x1e, 0xf5, 0xc9, 0x7b, 0x00, 0xdd, 0xc1,
|
||||||
0xa6, 0xd6, 0x52, 0x1f, 0x65, 0xc9, 0x2d, 0x28, 0x0c, 0xe8, 0xe0, 0x54, 0x80, 0xd2, 0x1c, 0x54,
|
0x34, 0x08, 0xa9, 0x7f, 0xd4, 0xef, 0xad, 0xe6, 0x6e, 0xe7, 0xee, 0x17, 0xdd, 0x8a, 0xa4, 0x6c,
|
||||||
0x81, 0x05, 0x97, 0x5e, 0x38, 0x9e, 0x33, 0x1a, 0xae, 0x66, 0x10, 0x92, 0x61, 0x48, 0xae, 0xfd,
|
0xf5, 0xc8, 0x4d, 0xa8, 0x0c, 0xe9, 0xf0, 0x58, 0xcc, 0xe6, 0xf9, 0xec, 0x82, 0x20, 0xe0, 0x64,
|
||||||
0xc6, 0xef, 0x20, 0xe5, 0x60, 0x35, 0xcb, 0x90, 0xac, 0x3f, 0xa7, 0xa1, 0xd4, 0xb4, 0x87, 0x67,
|
0x03, 0x16, 0x7c, 0x7a, 0xd6, 0x0f, 0xfa, 0xe3, 0xd1, 0x6a, 0x01, 0xe7, 0x0a, 0xae, 0x1e, 0x33,
|
||||||
0xb4, 0x49, 0xbf, 0x9d, 0x50, 0xcf, 0x27, 0x45, 0xc8, 0xbc, 0xa5, 0x97, 0x9c, 0x6b, 0x49, 0x10,
|
0x41, 0xdf, 0x7b, 0x1e, 0x1e, 0x21, 0xcc, 0x70, 0xb5, 0x28, 0x04, 0x19, 0xa1, 0x83, 0x63, 0xe7,
|
||||||
0xe0, 0x61, 0x87, 0x0e, 0x05, 0xd7, 0x12, 0x59, 0x84, 0xf9, 0xbe, 0x33, 0x70, 0x7c, 0xc9, 0x52,
|
0xd7, 0x05, 0xa8, 0xb9, 0xde, 0xe8, 0x84, 0xba, 0xf4, 0x9b, 0x29, 0x0d, 0x42, 0xb2, 0x04, 0x85,
|
||||||
0x17, 0x92, 0xe5, 0x90, 0x1f, 0x03, 0x78, 0x23, 0xd7, 0xef, 0x8c, 0x5c, 0xd4, 0x75, 0x75, 0x1e,
|
0x17, 0xf4, 0x9c, 0x2f, 0x5f, 0x73, 0xd9, 0xa7, 0x90, 0x47, 0x8e, 0x23, 0x3a, 0x12, 0x0b, 0xd7,
|
||||||
0x61, 0xe5, 0xda, 0xc6, 0xa6, 0xee, 0xa0, 0x4d, 0x5d, 0xe0, 0x66, 0x0b, 0x91, 0x0f, 0x19, 0x2e,
|
0x98, 0x3c, 0x12, 0xda, 0xa3, 0x1e, 0x59, 0x81, 0xf9, 0x41, 0x7f, 0xd8, 0x0f, 0xe5, 0xaa, 0x62,
|
||||||
0xf9, 0x09, 0x14, 0x39, 0xa5, 0x6f, 0xbb, 0x67, 0xd4, 0x5f, 0xcd, 0x71, 0xd2, 0xc7, 0xd7, 0x90,
|
0x10, 0x53, 0xa7, 0x68, 0xa9, 0xb3, 0x09, 0x10, 0x8c, 0xfd, 0xf0, 0x68, 0xec, 0xa3, 0xd1, 0xab,
|
||||||
0xb6, 0x39, 0x32, 0x59, 0x81, 0x12, 0xe2, 0x38, 0x76, 0xdf, 0xf9, 0xde, 0x3e, 0xed, 0xd3, 0xd5,
|
0xf3, 0x38, 0x5b, 0x5f, 0xbf, 0xbb, 0x66, 0xba, 0x7a, 0xcd, 0x54, 0x68, 0x6d, 0x1f, 0x99, 0xf7,
|
||||||
0x3c, 0x12, 0x2f, 0x58, 0x9b, 0x50, 0x08, 0xd9, 0x2f, 0x40, 0xf6, 0xe0, 0xf0, 0xa0, 0x51, 0x99,
|
0x18, 0xaf, 0x5b, 0x09, 0xd4, 0x27, 0xf9, 0x02, 0xaa, 0x1c, 0x24, 0xf4, 0xfc, 0x13, 0x1a, 0xae,
|
||||||
0x43, 0xff, 0xe5, 0xea, 0xad, 0xed, 0xc6, 0xc1, 0x4e, 0x25, 0x85, 0xf6, 0xe6, 0x77, 0x1a, 0xe2,
|
0x96, 0x38, 0xca, 0xbd, 0x37, 0xa0, 0x74, 0x38, 0xb3, 0xcb, 0x97, 0x17, 0xdf, 0xc4, 0x81, 0x1a,
|
||||||
0x23, 0x6d, 0x6d, 0x01, 0x68, 0x3c, 0xf3, 0x90, 0x79, 0xd5, 0xf8, 0x1a, 0xf1, 0x11, 0xe7, 0xa4,
|
0xf2, 0xf7, 0xbd, 0x41, 0xff, 0xb5, 0x77, 0x3c, 0xa0, 0xab, 0x65, 0x04, 0x5a, 0x70, 0x63, 0x34,
|
||||||
0xd1, 0x6c, 0xbd, 0x3c, 0x3c, 0x40, 0x02, 0x24, 0xde, 0x6e, 0x36, 0xea, 0xed, 0x46, 0x25, 0xcd,
|
0x67, 0x0d, 0x2a, 0x5a, 0x07, 0xb2, 0x00, 0xc5, 0xdd, 0xbd, 0xdd, 0xf6, 0xd2, 0x1c, 0x01, 0x28,
|
||||||
0x30, 0x5e, 0x1f, 0xee, 0x54, 0x32, 0xa4, 0x00, 0xf3, 0x27, 0xf5, 0xfd, 0xe3, 0x46, 0x25, 0x6b,
|
0x35, 0xf7, 0x37, 0xdb, 0xbb, 0xad, 0xa5, 0x1c, 0xa9, 0x42, 0xb9, 0xd5, 0x16, 0x83, 0xbc, 0xb3,
|
||||||
0x7d, 0x03, 0x8b, 0x52, 0x49, 0x11, 0x34, 0xf2, 0x14, 0x72, 0xe7, 0x3c, 0x70, 0xdc, 0xa9, 0xc5,
|
0x01, 0x10, 0xad, 0x46, 0xca, 0x50, 0xd8, 0x6e, 0x7f, 0x8d, 0xfc, 0xc8, 0x73, 0xd8, 0x76, 0xf7,
|
||||||
0xda, 0x07, 0x31, 0x8b, 0xa2, 0xc1, 0x7d, 0x80, 0xfe, 0xbf, 0xf0, 0xd0, 0xd9, 0x19, 0x44, 0xad,
|
0xb7, 0xf6, 0x76, 0x51, 0x00, 0x85, 0x37, 0xdd, 0x76, 0xb3, 0xd3, 0x5e, 0xca, 0x33, 0x8e, 0x27,
|
||||||
0x6c, 0x8a, 0x54, 0xd9, 0x7c, 0x45, 0x2f, 0x4f, 0xec, 0xfe, 0x84, 0x92, 0x12, 0x64, 0x07, 0x23,
|
0x7b, 0xad, 0xa5, 0x02, 0xa9, 0xc0, 0xfc, 0x61, 0x73, 0xe7, 0xa0, 0xbd, 0x54, 0x74, 0x7e, 0x01,
|
||||||
0x97, 0x72, 0xef, 0x2f, 0x58, 0x9f, 0x01, 0x1c, 0x4d, 0x7c, 0x63, 0xe8, 0x30, 0x4e, 0x17, 0x8c,
|
0x8b, 0x52, 0x7d, 0x11, 0x22, 0xe4, 0x33, 0x28, 0x9d, 0xf2, 0x30, 0xe1, 0x3b, 0x53, 0x5d, 0x7f,
|
||||||
0x42, 0x0b, 0x1b, 0xb5, 0x3d, 0x41, 0x98, 0xb1, 0x7e, 0x0a, 0x45, 0x4e, 0x98, 0x44, 0x45, 0xeb,
|
0xd7, 0xb2, 0x35, 0x16, 0x4a, 0xae, 0xe4, 0x45, 0xf3, 0x0a, 0x2f, 0xce, 0x02, 0xdc, 0xb4, 0x02,
|
||||||
0x87, 0x40, 0x76, 0x68, 0x9f, 0xfa, 0xf4, 0xbf, 0x49, 0x1c, 0xab, 0x0d, 0xcb, 0x11, 0xaa, 0x44,
|
0x8a, 0x2c, 0xad, 0x89, 0x08, 0x5d, 0xdb, 0xa6, 0xe7, 0x87, 0xde, 0x60, 0x4a, 0x5d, 0x36, 0x49,
|
||||||
0xde, 0x59, 0x82, 0x7c, 0x8f, 0x33, 0x11, 0x5c, 0x33, 0xd6, 0x1f, 0x52, 0x98, 0xbf, 0x42, 0x83,
|
0x08, 0x14, 0x87, 0x63, 0x9f, 0xf2, 0x0d, 0x5c, 0x70, 0xf9, 0xb7, 0xf3, 0x25, 0xc0, 0xd3, 0x69,
|
||||||
0xe3, 0x21, 0x26, 0x21, 0x79, 0x0e, 0x8b, 0xae, 0xf8, 0xee, 0x70, 0x0d, 0x24, 0xdb, 0xea, 0xec,
|
0x98, 0x1e, 0x12, 0xb8, 0xeb, 0x67, 0x0c, 0x41, 0x86, 0x83, 0x18, 0xf0, 0x58, 0xa0, 0x5e, 0x40,
|
||||||
0x34, 0xda, 0x9b, 0x23, 0xcf, 0xa0, 0xa8, 0x88, 0xc6, 0x13, 0x9f, 0xb3, 0x2e, 0xd6, 0x56, 0xa3,
|
0x75, 0x2c, 0xb0, 0x81, 0xb3, 0x09, 0x55, 0x8e, 0x95, 0xc5, 0x10, 0x04, 0x21, 0x2d, 0x3a, 0xa0,
|
||||||
0x24, 0xa1, 0xa3, 0x91, 0xe0, 0x67, 0xb0, 0xa2, 0x08, 0x84, 0x3e, 0x52, 0x58, 0x86, 0x53, 0xae,
|
0x21, 0xcd, 0x10, 0xab, 0x0e, 0x85, 0xe5, 0x18, 0x48, 0x26, 0xd7, 0xae, 0x42, 0xb9, 0xc7, 0xc1,
|
||||||
0x45, 0x29, 0xa7, 0x9d, 0xb5, 0x37, 0xb7, 0x55, 0x80, 0xbc, 0xe4, 0x60, 0xfd, 0x29, 0x85, 0x29,
|
0xc4, 0x3a, 0x05, 0x57, 0x0d, 0x9d, 0x7f, 0xe5, 0xf0, 0x48, 0x09, 0x0d, 0x0f, 0x46, 0x2c, 0xe2,
|
||||||
0x23, 0xed, 0x14, 0x46, 0x7c, 0x0a, 0x65, 0x57, 0x02, 0x22, 0x56, 0xdc, 0x37, 0x5a, 0x21, 0x3d,
|
0x9b, 0xb0, 0xe8, 0x8b, 0xf1, 0x11, 0xd7, 0x45, 0xae, 0xd3, 0x48, 0x0f, 0xd7, 0xc7, 0x73, 0x6e,
|
||||||
0x34, 0x47, 0x3e, 0x81, 0x52, 0x40, 0x16, 0xda, 0x71, 0xcf, 0x60, 0x47, 0x40, 0xb2, 0x05, 0xb7,
|
0x4d, 0x8a, 0x70, 0x32, 0xf9, 0x29, 0x54, 0x15, 0xc4, 0x64, 0x1a, 0xf2, 0x15, 0xab, 0xeb, 0xab,
|
||||||
0x03, 0x12, 0x83, 0x25, 0x8f, 0xae, 0xb0, 0x44, 0xf1, 0xc0, 0xa2, 0x59, 0x50, 0x3c, 0xac, 0xbf,
|
0x71, 0x80, 0x68, 0xc7, 0x50, 0x1c, 0x24, 0x3b, 0x12, 0x49, 0x07, 0x56, 0x94, 0xb0, 0xd0, 0x51,
|
||||||
0xa6, 0x21, 0xbf, 0x3d, 0x1a, 0x8c, 0x6d, 0x97, 0x62, 0x28, 0x72, 0x08, 0x9f, 0xf4, 0x7d, 0xae,
|
0xaa, 0x51, 0xe0, 0x28, 0xb7, 0xe3, 0x28, 0xb3, 0x6e, 0x46, 0x34, 0x22, 0xe5, 0x8d, 0xc9, 0x8d,
|
||||||
0x7d, 0xb9, 0xb6, 0x1e, 0x65, 0x26, 0xd1, 0xd4, 0xef, 0x26, 0x47, 0x65, 0x44, 0xb2, 0xfe, 0xd3,
|
0x0a, 0x94, 0x25, 0xd5, 0xf9, 0x77, 0x0e, 0xc3, 0x55, 0xba, 0x49, 0x98, 0xdc, 0x82, 0xba, 0x2f,
|
||||||
0xef, 0x41, 0x24, 0x2b, 0x55, 0xe6, 0x5e, 0x46, 0xe6, 0x5e, 0x1e, 0x71, 0xc3, 0x8e, 0x84, 0x56,
|
0x09, 0x31, 0x9b, 0x6f, 0x26, 0xda, 0x2c, 0x1d, 0x3c, 0xe7, 0x2e, 0x2a, 0x21, 0x61, 0xf5, 0x43,
|
||||||
0xde, 0x83, 0xa5, 0xae, 0x4b, 0x6d, 0x66, 0x9c, 0x6a, 0x56, 0xf3, 0xf2, 0xe8, 0x0e, 0x94, 0x06,
|
0xa8, 0x69, 0x94, 0xc8, 0xec, 0x1b, 0x09, 0x66, 0x6b, 0x84, 0xaa, 0x12, 0x60, 0x86, 0x3f, 0x83,
|
||||||
0xa3, 0x5e, 0x08, 0xcf, 0x49, 0xf8, 0x92, 0xaa, 0x1f, 0xd6, 0x49, 0x4a, 0x7b, 0x73, 0xd6, 0x27,
|
0x6b, 0x5a, 0x3e, 0xc1, 0xf2, 0x0f, 0x2e, 0xb0, 0x5c, 0x03, 0x2e, 0x2b, 0x04, 0xd3, 0x76, 0x60,
|
||||||
0xb0, 0x18, 0xd5, 0x14, 0x6b, 0xbe, 0xf1, 0xe5, 0x71, 0x7d, 0x5f, 0x34, 0x88, 0x5d, 0xde, 0x13,
|
0xf9, 0x4d, 0x90, 0x9d, 0xdf, 0x14, 0xa0, 0xbc, 0x39, 0x1e, 0x4e, 0x3c, 0x9f, 0x6d, 0x53, 0x09,
|
||||||
0x9a, 0xd8, 0x20, 0xb0, 0xcf, 0xec, 0x37, 0x5a, 0x2d, 0x6c, 0x27, 0x9f, 0x07, 0x24, 0x81, 0x9e,
|
0xe9, 0xd3, 0x41, 0xc8, 0xcd, 0xad, 0xaf, 0xdf, 0x89, 0xaf, 0x20, 0xd9, 0xd4, 0x6f, 0x97, 0xb3,
|
||||||
0x41, 0x23, 0x99, 0xd3, 0x1a, 0x49, 0x4a, 0x35, 0x92, 0x74, 0xd8, 0x48, 0x32, 0x5b, 0x65, 0x28,
|
0xba, 0x52, 0x84, 0x09, 0xcb, 0x74, 0x96, 0x7f, 0x0b, 0x61, 0x99, 0xcc, 0xa4, 0x88, 0x3a, 0x0a,
|
||||||
0x09, 0x4f, 0x74, 0x26, 0x2c, 0x29, 0xac, 0x5f, 0xa5, 0x00, 0xda, 0xef, 0x86, 0xaa, 0xde, 0x9e,
|
0x85, 0xe8, 0x28, 0x34, 0xa0, 0x8c, 0x82, 0x51, 0x0a, 0x46, 0x5b, 0x14, 0x81, 0x7c, 0x0f, 0xae,
|
||||||
0x40, 0xbe, 0x2b, 0x98, 0xa3, 0x7b, 0x59, 0xb3, 0xb8, 0x6d, 0xf4, 0x14, 0xf9, 0x18, 0xf2, 0xde,
|
0x74, 0x7d, 0xea, 0x31, 0x7f, 0xa8, 0x34, 0x3d, 0x2f, 0x79, 0xea, 0x62, 0xc2, 0x55, 0xe9, 0xfa,
|
||||||
0xa4, 0xdb, 0xa5, 0x9e, 0x6a, 0x2a, 0xf1, 0x52, 0xd0, 0xab, 0x07, 0x91, 0xdf, 0xd8, 0x4e, 0x7f,
|
0x0e, 0xd4, 0x86, 0xe3, 0x5e, 0xc4, 0x57, 0x92, 0x7c, 0x55, 0xa4, 0x6a, 0xa6, 0xeb, 0x2a, 0x1f,
|
||||||
0xc2, 0x3b, 0xcc, 0x35, 0xc8, 0xd6, 0x2f, 0xa1, 0xc8, 0xf5, 0x49, 0x54, 0xc9, 0xd8, 0x21, 0xb8,
|
0xb0, 0xfc, 0x59, 0xc3, 0x59, 0x31, 0x74, 0x3e, 0x85, 0xc5, 0x98, 0xad, 0x2c, 0xc5, 0xb5, 0xbf,
|
||||||
0x5a, 0xb4, 0x27, 0x6b, 0x79, 0x81, 0x60, 0xb7, 0x56, 0x79, 0xe4, 0x49, 0xf1, 0xf7, 0xcd, 0x3c,
|
0x3a, 0x68, 0xee, 0x88, 0x7c, 0xf8, 0x88, 0xa7, 0x40, 0x17, 0xf3, 0x21, 0xa6, 0xd5, 0x9d, 0xf6,
|
||||||
0x84, 0xfc, 0xcf, 0xe0, 0x16, 0x37, 0xb2, 0xeb, 0xe3, 0x97, 0x72, 0x8b, 0x7e, 0x21, 0xa5, 0xd4,
|
0xfe, 0x3e, 0x66, 0xcf, 0xcf, 0xb5, 0x88, 0x4c, 0xa0, 0x46, 0xde, 0x9c, 0x33, 0xf2, 0x66, 0x4e,
|
||||||
0x15, 0x35, 0x3e, 0xbf, 0xf4, 0x9c, 0xae, 0xdd, 0x17, 0x82, 0xb0, 0xcd, 0x13, 0x9d, 0x30, 0x51,
|
0xe5, 0xcd, 0x7c, 0x94, 0x37, 0x0b, 0x1b, 0x75, 0xa8, 0x09, 0x87, 0x1c, 0x4d, 0x59, 0x1c, 0x3a,
|
||||||
0x13, 0x5c, 0x84, 0xe2, 0x9e, 0xed, 0x9d, 0x4b, 0xb1, 0xd6, 0xcf, 0xa1, 0x24, 0x3e, 0x13, 0x39,
|
0xbf, 0xcb, 0x01, 0x74, 0x5e, 0x8d, 0x54, 0xc2, 0x78, 0x00, 0xe5, 0xae, 0x00, 0xc7, 0x0d, 0x62,
|
||||||
0x03, 0xbb, 0xfa, 0x39, 0x52, 0x73, 0xf5, 0x16, 0xad, 0x5b, 0xb0, 0xd4, 0x1a, 0xda, 0x63, 0xef,
|
0x39, 0xf1, 0x5a, 0xa2, 0x8f, 0x5d, 0xc5, 0x85, 0xb9, 0xa1, 0x1c, 0x4c, 0xbb, 0x5d, 0x1a, 0xa8,
|
||||||
0x7c, 0xa4, 0x3a, 0x8e, 0x75, 0x06, 0x95, 0x10, 0x94, 0x48, 0xc4, 0x5d, 0x58, 0x72, 0xe9, 0xc0,
|
0x24, 0x6a, 0x1f, 0x5a, 0xe3, 0x9c, 0xbb, 0x8a, 0x95, 0x49, 0x3d, 0xf7, 0xfa, 0x83, 0x29, 0xcf,
|
||||||
0x76, 0x86, 0xce, 0xf0, 0xac, 0x73, 0x7a, 0xe9, 0x53, 0x4f, 0x8e, 0x09, 0x28, 0xfb, 0xb4, 0x3f,
|
0xaa, 0x6f, 0x94, 0x92, 0xac, 0xce, 0x6f, 0x73, 0x50, 0xe5, 0xba, 0x66, 0xca, 0x4b, 0xef, 0x42,
|
||||||
0x3a, 0x15, 0xc5, 0x63, 0xfd, 0x16, 0xfb, 0xe9, 0x57, 0xb6, 0xdf, 0x55, 0x86, 0xe1, 0xa5, 0x5c,
|
0x85, 0xab, 0x41, 0x7b, 0x32, 0x33, 0x2d, 0xb8, 0x11, 0x81, 0xfc, 0x04, 0xf3, 0xa3, 0x94, 0x0b,
|
||||||
0x0e, 0x4a, 0x87, 0x43, 0xa4, 0xb4, 0x58, 0x8f, 0xe3, 0x34, 0xdb, 0x1c, 0x31, 0xec, 0x92, 0x8c,
|
0xa4, 0x6e, 0x37, 0x93, 0x61, 0x85, 0x72, 0x11, 0xb7, 0xb3, 0x0d, 0x57, 0xb9, 0x7b, 0xba, 0x21,
|
||||||
0xd6, 0x1e, 0x76, 0x69, 0x3f, 0xa0, 0x4d, 0xcf, 0xa6, 0xe5, 0x88, 0x61, 0x7f, 0x5c, 0x0a, 0xfb,
|
0x9b, 0x90, 0x0e, 0x35, 0x2f, 0xfa, 0x9c, 0x75, 0xd1, 0xe3, 0xdc, 0xe4, 0xf4, 0x3c, 0xe8, 0x77,
|
||||||
0xb8, 0x48, 0x7f, 0x0a, 0x64, 0x5a, 0xc8, 0xb5, 0xe3, 0xca, 0x1d, 0x28, 0x7b, 0x58, 0x45, 0x7e,
|
0xbd, 0x81, 0x54, 0x44, 0x8f, 0xf1, 0x82, 0x21, 0x26, 0x58, 0xa6, 0xbb, 0x61, 0x11, 0xaa, 0x8f,
|
||||||
0x27, 0x36, 0x0a, 0xa1, 0x3b, 0x70, 0xbc, 0x3a, 0xc3, 0x7c, 0xf3, 0x3a, 0xc3, 0x91, 0xef, 0xbc,
|
0xbd, 0xe0, 0x54, 0xaa, 0xe4, 0xfc, 0x1c, 0x6a, 0x62, 0x98, 0xc9, 0x8d, 0x78, 0x2b, 0x9e, 0x22,
|
||||||
0xb9, 0xe4, 0xcd, 0x62, 0xc1, 0x7a, 0xa2, 0xc4, 0xe8, 0xfa, 0xb0, 0x1c, 0xfa, 0x8e, 0x41, 0xd5,
|
0x0a, 0x57, 0x7c, 0xd1, 0xe5, 0xdf, 0xce, 0x55, 0xb8, 0xb2, 0x3f, 0xf2, 0x26, 0xc1, 0xe9, 0x58,
|
||||||
0xc0, 0x95, 0xb1, 0x7e, 0x87, 0x4d, 0x5b, 0x3a, 0x2a, 0x51, 0x3c, 0x74, 0x8e, 0xfc, 0x2a, 0x63,
|
0x25, 0x5a, 0x56, 0xc6, 0x2d, 0x45, 0xb4, 0x4c, 0x2b, 0x7e, 0x04, 0x57, 0x7c, 0x3a, 0xf4, 0xfa,
|
||||||
0x77, 0x9b, 0xf0, 0x74, 0x4f, 0xdc, 0xee, 0x0c, 0x45, 0xb8, 0x0f, 0x21, 0x5c, 0x39, 0xb2, 0x0a,
|
0xa3, 0xfe, 0xe8, 0xe4, 0xe8, 0xf8, 0x3c, 0xa4, 0x81, 0xac, 0xf2, 0xea, 0x9a, 0xbc, 0xc1, 0xa8,
|
||||||
0x95, 0xae, 0x48, 0xdc, 0x58, 0x23, 0xc3, 0xb1, 0x21, 0x47, 0x2f, 0xe8, 0xd0, 0xf7, 0x56, 0x8b,
|
0x4c, 0xb5, 0xe3, 0xc1, 0xf8, 0x58, 0x9e, 0x75, 0xfe, 0xed, 0xfc, 0x1e, 0xef, 0x9c, 0x67, 0x5e,
|
||||||
0xbc, 0x70, 0x16, 0xd5, 0xe4, 0xd0, 0x60, 0x50, 0xeb, 0x29, 0xdc, 0xda, 0x67, 0xd7, 0xff, 0x2e,
|
0xd8, 0x55, 0x5e, 0x20, 0x5b, 0x50, 0xd7, 0x27, 0x9c, 0x53, 0xa4, 0x2e, 0x56, 0xb6, 0xe7, 0x32,
|
||||||
0xfa, 0x47, 0x9f, 0x17, 0xda, 0xed, 0x7d, 0x59, 0x25, 0x00, 0xe9, 0x97, 0x3b, 0xf2, 0x52, 0xfd,
|
0x9b, 0xf2, 0xc4, 0xab, 0x6c, 0xbf, 0xd8, 0x35, 0x09, 0x1c, 0xca, 0x1b, 0x75, 0xe9, 0x40, 0x43,
|
||||||
0x06, 0x88, 0x8e, 0x9d, 0xc8, 0x3e, 0x8d, 0x9f, 0x12, 0x24, 0x3c, 0x8f, 0x93, 0x08, 0x75, 0xdd,
|
0xe5, 0xd3, 0xa1, 0x38, 0xa3, 0x09, 0x65, 0x12, 0x36, 0xae, 0x44, 0x37, 0xa1, 0x38, 0x9f, 0xdf,
|
||||||
0x91, 0xcb, 0x4d, 0x2a, 0x58, 0x6b, 0x52, 0x56, 0x93, 0x5e, 0x8c, 0xde, 0x06, 0x61, 0x15, 0xd4,
|
0xe6, 0x80, 0xcc, 0xea, 0xf0, 0x5d, 0x8b, 0xd0, 0x7b, 0x50, 0x0f, 0xf0, 0xd8, 0x87, 0x47, 0x56,
|
||||||
0xc2, 0xd3, 0xdb, 0xb0, 0x1c, 0xc1, 0x48, 0x54, 0xae, 0xeb, 0x70, 0x9b, 0x33, 0x79, 0x45, 0xe9,
|
0x0d, 0xbc, 0xc8, 0xa9, 0x3a, 0x4b, 0xa1, 0x87, 0xb1, 0xf8, 0x3e, 0xc1, 0x90, 0x0e, 0x8e, 0x46,
|
||||||
0xb8, 0xde, 0x77, 0x2e, 0x8c, 0x92, 0x3a, 0x70, 0x27, 0x8e, 0xf4, 0x3f, 0xb5, 0xdd, 0xda, 0x83,
|
0xe3, 0xb0, 0xff, 0xfc, 0x9c, 0x67, 0xc6, 0x05, 0xb7, 0xae, 0xc8, 0xbb, 0x9c, 0xea, 0x3c, 0x50,
|
||||||
0xdc, 0x6b, 0x3e, 0xa5, 0x6b, 0x62, 0x79, 0x05, 0x0e, 0xed, 0x81, 0x98, 0xd4, 0x0a, 0xbc, 0x5d,
|
0x4a, 0x99, 0xca, 0x93, 0x1b, 0xb0, 0xf0, 0x92, 0x51, 0x55, 0x75, 0x8e, 0x57, 0x3e, 0x1f, 0x6f,
|
||||||
0x51, 0xea, 0x1e, 0x37, 0xf7, 0x45, 0x13, 0x2c, 0x88, 0x79, 0xdf, 0xc1, 0x30, 0x72, 0x58, 0x96,
|
0xf5, 0x9c, 0x7f, 0xe0, 0x05, 0x28, 0xdd, 0x9f, 0x29, 0x06, 0xcc, 0x25, 0xf2, 0xb1, 0x25, 0x58,
|
||||||
0xc1, 0xac, 0x0d, 0xa8, 0x08, 0x4e, 0xf5, 0x5e, 0x4f, 0x4b, 0xd2, 0x80, 0x32, 0xc5, 0xb1, 0xce,
|
0xbd, 0x21, 0xb6, 0xa5, 0x27, 0x2b, 0x35, 0x35, 0x64, 0xe7, 0x4c, 0x78, 0x19, 0xa7, 0x84, 0x3d,
|
||||||
0xe0, 0x96, 0x86, 0x95, 0xc8, 0x96, 0x0d, 0xc8, 0x89, 0xc5, 0x42, 0xd6, 0xee, 0x4a, 0x14, 0x5b,
|
0x7a, 0x8c, 0x89, 0x7e, 0xa9, 0x2b, 0xce, 0x99, 0x95, 0xe9, 0xdd, 0x2b, 0x92, 0xae, 0xbd, 0x73,
|
||||||
0xb0, 0xb7, 0x1e, 0xc1, 0xb2, 0xf8, 0xab, 0x49, 0x07, 0x23, 0x93, 0x73, 0xb3, 0xd6, 0x0e, 0xac,
|
0x0f, 0x4a, 0xf4, 0x8c, 0x8e, 0xc2, 0x60, 0xb5, 0xca, 0xf3, 0xc2, 0xa2, 0x2a, 0x17, 0xdb, 0x8c,
|
||||||
0x44, 0x51, 0x12, 0xc5, 0xf1, 0xb9, 0x12, 0x74, 0x3c, 0xee, 0x69, 0x6d, 0x40, 0x77, 0xa7, 0xee,
|
0xea, 0xca, 0x49, 0xe7, 0xc7, 0x70, 0x75, 0x87, 0xd5, 0x75, 0x8f, 0xd0, 0xfb, 0x66, 0x85, 0xd8,
|
||||||
0x86, 0x34, 0x77, 0x43, 0x20, 0x5a, 0x11, 0x25, 0x12, 0xbd, 0xac, 0x9c, 0xb9, 0xef, 0x78, 0x41,
|
0xe9, 0xec, 0x48, 0xaf, 0x14, 0xc2, 0xce, 0x0e, 0xa9, 0x43, 0x7e, 0xab, 0x25, 0x6d, 0xc8, 0xf7,
|
||||||
0x63, 0x76, 0x80, 0xe8, 0xc0, 0x44, 0x2e, 0x7e, 0x0c, 0x79, 0xe1, 0x62, 0x75, 0x43, 0x9b, 0x7d,
|
0x5b, 0xce, 0x2f, 0x71, 0xa3, 0x4d, 0xb9, 0x4c, 0x6e, 0xb2, 0xc0, 0xd5, 0xf2, 0x85, 0x68, 0x79,
|
||||||
0x8c, 0xf2, 0x77, 0xe8, 0x1b, 0xd7, 0x3e, 0x1b, 0xd0, 0xa0, 0x86, 0xd9, 0x55, 0xa6, 0x03, 0x13,
|
0x2c, 0x45, 0xa9, 0xef, 0x8f, 0x7d, 0xee, 0x90, 0x8a, 0x2b, 0x06, 0xce, 0x5d, 0xa9, 0x03, 0xda,
|
||||||
0x19, 0xf6, 0x7b, 0xec, 0xf9, 0xf5, 0xbe, 0xed, 0x0e, 0x94, 0x37, 0x7f, 0x04, 0x39, 0x71, 0x37,
|
0x3c, 0x7e, 0xa1, 0x83, 0x4d, 0xa0, 0xe5, 0xb4, 0xaa, 0xdb, 0xb0, 0x1c, 0xe3, 0xca, 0x94, 0x9c,
|
||||||
0xca, 0xc1, 0xed, 0x49, 0x94, 0x5c, 0xc7, 0x15, 0x1f, 0x75, 0x8e, 0xcd, 0x3c, 0x2f, 0x0c, 0x91,
|
0x3e, 0x82, 0x6b, 0x1c, 0x6c, 0x9b, 0xd2, 0x49, 0x73, 0xd0, 0x3f, 0x4b, 0x5d, 0x75, 0x02, 0xd7,
|
||||||
0xd9, 0x9f, 0xc5, 0x21, 0x65, 0xde, 0x66, 0x08, 0x3c, 0xff, 0xcb, 0xb5, 0xbb, 0x06, 0x46, 0xed,
|
0x6d, 0xc6, 0xff, 0xaf, 0x8f, 0x9c, 0x53, 0x28, 0x3d, 0xe1, 0xfd, 0xa3, 0xa1, 0x4b, 0x91, 0xf3,
|
||||||
0xcb, 0x31, 0xc5, 0x95, 0xa2, 0xa8, 0x33, 0xc2, 0x71, 0x68, 0xb7, 0xd1, 0xc6, 0x19, 0xa9, 0x04,
|
0x62, 0x86, 0x19, 0x79, 0x43, 0x51, 0xdd, 0x57, 0x5c, 0xfe, 0xcd, 0xb3, 0x39, 0xa5, 0xfe, 0x81,
|
||||||
0x0b, 0xf5, 0xed, 0xf6, 0xcb, 0x13, 0x31, 0x25, 0x95, 0x01, 0x76, 0x1a, 0xc1, 0x77, 0xda, 0xda,
|
0xbb, 0x23, 0x2e, 0x8e, 0x8a, 0xab, 0xc7, 0xe4, 0x16, 0xeb, 0x5c, 0xfb, 0x18, 0x1e, 0x7c, 0xb6,
|
||||||
0x95, 0x54, 0xb2, 0xa6, 0x74, 0xf1, 0xa9, 0xa8, 0xf8, 0xf4, 0xd5, 0xe2, 0xcf, 0x61, 0x51, 0x1a,
|
0xc8, 0x67, 0x0d, 0x0a, 0x76, 0x50, 0x4b, 0x62, 0xa5, 0x66, 0xaf, 0x67, 0xdc, 0x1c, 0x1a, 0x2f,
|
||||||
0x95, 0x28, 0x80, 0xff, 0x87, 0xfe, 0x62, 0xe4, 0x2a, 0x7e, 0xf7, 0x0c, 0x72, 0x64, 0x10, 0xf1,
|
0x17, 0xc7, 0x73, 0x5e, 0xc2, 0x55, 0x83, 0x3f, 0x93, 0x1b, 0x3e, 0x81, 0x92, 0x68, 0x92, 0x65,
|
||||||
0x5a, 0x6b, 0xf9, 0xb6, 0x3f, 0xf1, 0x54, 0x00, 0x7f, 0x93, 0x82, 0xb2, 0x82, 0x24, 0x5d, 0x89,
|
0xd2, 0x5a, 0x89, 0x4b, 0x89, 0x65, 0x5c, 0xc9, 0xe3, 0xdc, 0x83, 0x65, 0x49, 0xa1, 0xc3, 0x71,
|
||||||
0xd4, 0xb8, 0x2b, 0x1a, 0x48, 0x19, 0x72, 0xbd, 0xd3, 0x96, 0xf3, 0xbd, 0xdc, 0xf5, 0xd8, 0x77,
|
0xd2, 0x5e, 0x71, 0xff, 0x38, 0x3b, 0xb0, 0x12, 0x67, 0xcb, 0x14, 0x22, 0x4d, 0xb5, 0xe8, 0xc1,
|
||||||
0x5f, 0xb0, 0xcb, 0xaa, 0xa7, 0x02, 0xf6, 0x0a, 0xf0, 0x72, 0xd8, 0xa3, 0xef, 0xf8, 0xed, 0x21,
|
0xa4, 0x67, 0xe4, 0x40, 0x7b, 0x53, 0x4c, 0x87, 0xe5, 0x2d, 0x87, 0x69, 0x85, 0x14, 0x44, 0x26,
|
||||||
0x9e, 0x0a, 0x10, 0xd4, 0x66, 0xef, 0x02, 0x39, 0x5e, 0xad, 0x98, 0x6c, 0xf5, 0x89, 0x7f, 0xde,
|
0x85, 0x96, 0x95, 0xfb, 0x77, 0xfa, 0x81, 0xbe, 0xe9, 0x5e, 0x03, 0x31, 0x89, 0x99, 0x36, 0x65,
|
||||||
0x18, 0xb2, 0x6d, 0x5a, 0xe9, 0xba, 0x02, 0x84, 0x01, 0x77, 0x1c, 0x4f, 0x87, 0x7e, 0x0a, 0xcb,
|
0x0d, 0xca, 0xc2, 0xe1, 0xaa, 0xaa, 0x4a, 0xde, 0x15, 0xc5, 0xc4, 0x14, 0x6a, 0xd1, 0xe7, 0xbe,
|
||||||
0x0c, 0x8a, 0xf9, 0x87, 0x23, 0x56, 0x58, 0x92, 0xaa, 0xab, 0xa5, 0x82, 0xae, 0x66, 0x7b, 0xde,
|
0x77, 0x32, 0xa4, 0x3a, 0xe7, 0xb0, 0x12, 0xc2, 0x24, 0x66, 0xb2, 0xf8, 0x4f, 0x78, 0x7d, 0x36,
|
||||||
0x77, 0x23, 0x57, 0x5c, 0x77, 0x05, 0xb6, 0x45, 0x32, 0xb2, 0x63, 0x2f, 0xd2, 0xc3, 0xae, 0xa3,
|
0x07, 0x9e, 0x3f, 0x54, 0xce, 0x7f, 0x08, 0x25, 0x51, 0x9b, 0xc8, 0x42, 0xfe, 0xc3, 0x38, 0x8c,
|
||||||
0x5a, 0x09, 0xa9, 0x76, 0x69, 0x50, 0x05, 0x8f, 0xe1, 0xb6, 0x82, 0xca, 0x15, 0xc5, 0xc4, 0xce,
|
0xc9, 0x2b, 0x06, 0x4d, 0x51, 0xc9, 0x48, 0x29, 0xb6, 0x59, 0xf2, 0x6d, 0xa6, 0x65, 0xbd, 0xd5,
|
||||||
0xfa, 0x02, 0x1e, 0x28, 0xb4, 0xed, 0x73, 0x36, 0x28, 0x1c, 0x49, 0xe6, 0xef, 0x2b, 0xbd, 0x06,
|
0xb4, 0xc8, 0x0f, 0x60, 0xde, 0x63, 0x22, 0xfc, 0x2c, 0xd6, 0xd7, 0xdf, 0x49, 0x80, 0xee, 0x9c,
|
||||||
0x2b, 0x81, 0x74, 0xfd, 0x26, 0x45, 0xba, 0x89, 0x27, 0xe3, 0x55, 0x60, 0x5f, 0xee, 0xa8, 0x2f,
|
0x4f, 0xa8, 0x2b, 0xb8, 0x9c, 0xcf, 0xa0, 0x6a, 0xac, 0xc0, 0xaa, 0xde, 0x47, 0xed, 0x0e, 0x96,
|
||||||
0xfb, 0xb9, 0x75, 0x37, 0xd4, 0x2d, 0x72, 0xc7, 0x59, 0x96, 0x30, 0xa5, 0x89, 0xa8, 0xb3, 0x1c,
|
0xc2, 0x35, 0x58, 0x68, 0x6e, 0x76, 0xb6, 0x0e, 0x45, 0x31, 0x5c, 0x07, 0x68, 0xb5, 0xf5, 0x38,
|
||||||
0xa0, 0xcc, 0x65, 0x38, 0x9a, 0xb9, 0x92, 0x25, 0x83, 0x46, 0xcc, 0xb5, 0x5e, 0x08, 0xfd, 0x38,
|
0x8f, 0x55, 0x90, 0x90, 0x92, 0x27, 0xdc, 0xd4, 0x27, 0x97, 0xa6, 0x4f, 0xfe, 0xad, 0xf4, 0x79,
|
||||||
0x7a, 0x4c, 0x3f, 0xcd, 0xae, 0x35, 0xc8, 0x8e, 0xa9, 0x2c, 0x8a, 0x62, 0x8d, 0x6c, 0x8a, 0x37,
|
0x05, 0x8b, 0xd2, 0xfc, 0x4c, 0x31, 0xf0, 0x29, 0x7a, 0x98, 0xc1, 0xa8, 0x10, 0xb8, 0x91, 0xb0,
|
||||||
0xa7, 0xcd, 0x23, 0x84, 0x39, 0x1e, 0x4b, 0x24, 0x5d, 0x40, 0x54, 0xe7, 0x2d, 0xa1, 0x8f, 0x4a,
|
0xac, 0x3a, 0x9d, 0x82, 0xd1, 0xc1, 0xea, 0x61, 0x3f, 0xf4, 0xc2, 0x69, 0xa0, 0x42, 0xe0, 0x8f,
|
||||||
0x8b, 0x44, 0xed, 0x66, 0x5b, 0xe4, 0x4b, 0x90, 0x45, 0x89, 0x98, 0xb4, 0x84, 0xa5, 0x61, 0xd2,
|
0x39, 0xa8, 0x2b, 0x4a, 0xd6, 0x66, 0x5e, 0xf5, 0x4a, 0x22, 0xe7, 0xe9, 0x4e, 0xe9, 0x3a, 0x94,
|
||||||
0x25, 0xaa, 0x1d, 0x9c, 0x45, 0x7c, 0xb4, 0x4e, 0x56, 0x8e, 0xd2, 0x2c, 0x48, 0xc9, 0x9b, 0x98,
|
0x7a, 0xc7, 0xfb, 0xfd, 0xd7, 0xea, 0x51, 0x43, 0x8e, 0x18, 0x7d, 0x20, 0xd6, 0x11, 0x2f, 0x6a,
|
||||||
0x17, 0x64, 0x68, 0x22, 0x26, 0x2f, 0xe0, 0x4e, 0x3c, 0xa1, 0x13, 0xf1, 0x39, 0x80, 0x87, 0xb3,
|
0x72, 0xc4, 0xca, 0x6f, 0xf6, 0xb6, 0xb6, 0x35, 0xea, 0xd1, 0x57, 0xfc, 0xa6, 0x2d, 0xba, 0x11,
|
||||||
0x32, 0x3e, 0x11, 0xbf, 0x46, 0x98, 0xcc, 0x37, 0x18, 0x0e, 0x75, 0xf3, 0x6e, 0x34, 0xd5, 0x49,
|
0x81, 0x97, 0xcb, 0xf2, 0xe5, 0x8d, 0x37, 0x52, 0xe6, 0x4b, 0x1c, 0x06, 0x79, 0x73, 0x1a, 0x9e,
|
||||||
0x5f, 0x07, 0x25, 0x74, 0x53, 0x26, 0x37, 0x0e, 0x98, 0x5e, 0x92, 0x37, 0x71, 0xb0, 0x56, 0xc1,
|
0xb6, 0x47, 0xec, 0xd1, 0x49, 0x59, 0xb8, 0x02, 0x84, 0x11, 0x5b, 0xfd, 0xc0, 0xa4, 0xb6, 0x61,
|
||||||
0x37, 0x55, 0xe7, 0x26, 0x0e, 0xfe, 0x7f, 0x0b, 0x0a, 0xc1, 0x2d, 0xa9, 0x3d, 0xa0, 0x16, 0x21,
|
0x99, 0x51, 0x31, 0xee, 0xb1, 0x98, 0x8e, 0x32, 0x86, 0x4a, 0xdb, 0x39, 0x2b, 0x6d, 0x7b, 0x41,
|
||||||
0x7f, 0x70, 0xd8, 0x3a, 0xaa, 0x6f, 0xe3, 0xad, 0x5c, 0xfb, 0x57, 0x1a, 0xd2, 0xaf, 0x4e, 0xc8,
|
0xf0, 0x72, 0xec, 0xf7, 0xa4, 0x69, 0x7a, 0xec, 0xb4, 0x04, 0xf8, 0x41, 0x10, 0x4b, 0xcc, 0xdf,
|
||||||
0x16, 0xcc, 0xf3, 0x87, 0x21, 0x72, 0xc5, 0x53, 0x5b, 0xf5, 0xaa, 0x07, 0x2c, 0x6b, 0x8e, 0x7c,
|
0x15, 0x65, 0x25, 0x42, 0x79, 0x44, 0xf5, 0xe9, 0xfc, 0x18, 0xae, 0x29, 0xaa, 0x6c, 0x9c, 0xd3,
|
||||||
0x0e, 0x99, 0xa3, 0x89, 0x4f, 0x66, 0xbe, 0xbc, 0x55, 0x67, 0xbf, 0x65, 0x21, 0x75, 0x1b, 0x8a,
|
0xe1, 0x9d, 0x3d, 0x78, 0x4f, 0x31, 0x6f, 0x9e, 0xb2, 0xa2, 0xee, 0xa9, 0x04, 0xff, 0x5f, 0x75,
|
||||||
0xda, 0x03, 0x15, 0xb9, 0xf6, 0x15, 0xae, 0x7a, 0xfd, 0xeb, 0x96, 0xd0, 0xa9, 0xfd, 0x6e, 0x18,
|
0x7a, 0x08, 0x2b, 0x5a, 0x27, 0xb3, 0x4e, 0x41, 0x9c, 0x69, 0x20, 0x63, 0x03, 0x71, 0xd8, 0x37,
|
||||||
0xd7, 0x29, 0x7c, 0x88, 0x89, 0xeb, 0xa4, 0x3d, 0x89, 0x20, 0xf5, 0x81, 0x7c, 0x0e, 0xeb, 0xfa,
|
0xa3, 0xf9, 0xe3, 0x81, 0xbe, 0xec, 0xd8, 0xb7, 0xf3, 0x4e, 0xa4, 0x7d, 0xac, 0x56, 0x70, 0xee,
|
||||||
0xe4, 0x43, 0xc3, 0xfb, 0x8c, 0xfe, 0x74, 0x51, 0x5d, 0x9b, 0x8d, 0xa0, 0xf8, 0xd5, 0x0e, 0x61,
|
0x0b, 0x63, 0x5d, 0x64, 0xba, 0xd8, 0x65, 0xca, 0x2d, 0x8c, 0xd3, 0x70, 0x8b, 0x04, 0x66, 0xd4,
|
||||||
0x9e, 0x6f, 0x9d, 0xe4, 0x85, 0xfa, 0xa3, 0x6a, 0x58, 0xa6, 0x67, 0xb8, 0x3b, 0xb2, 0xaf, 0x5a,
|
0x98, 0x5b, 0x1c, 0x57, 0x68, 0xcc, 0xd9, 0x2d, 0x8d, 0x67, 0x2c, 0xff, 0x10, 0x8a, 0x13, 0x2a,
|
||||||
0x73, 0x1f, 0xa5, 0x7e, 0x90, 0xaa, 0xfd, 0x3a, 0x0d, 0xf3, 0x7c, 0xe9, 0x21, 0x5f, 0x02, 0x84,
|
0xcf, 0x6b, 0x75, 0x9d, 0xac, 0x89, 0xd7, 0xe5, 0xb5, 0xa7, 0x48, 0xeb, 0x07, 0x2c, 0x6a, 0x5d,
|
||||||
0x5b, 0x5f, 0x5c, 0xdb, 0xa9, 0xed, 0x31, 0xae, 0xed, 0xf4, 0xc2, 0x28, 0x22, 0xa2, 0xad, 0x6e,
|
0x3e, 0x6f, 0x2e, 0x16, 0xb7, 0xe2, 0x4b, 0xa1, 0x9b, 0x0a, 0xb5, 0x4c, 0xa9, 0x73, 0x5b, 0xc4,
|
||||||
0xc4, 0x44, 0x12, 0xb9, 0x5f, 0xe2, 0x11, 0x31, 0xec, 0x7d, 0xc8, 0xd5, 0x86, 0x72, 0x74, 0x4d,
|
0xa2, 0x8e, 0xd0, 0x4c, 0x60, 0xc7, 0xc2, 0x0b, 0x51, 0x60, 0x67, 0x3a, 0xd5, 0x58, 0x04, 0x86,
|
||||||
0x23, 0xeb, 0x06, 0xb2, 0xf8, 0xa6, 0x57, 0xdd, 0xb8, 0x1a, 0x29, 0xe2, 0x95, 0xbf, 0xb1, 0x67,
|
0x68, 0xb5, 0x3a, 0xd3, 0x62, 0xa0, 0x14, 0xd6, 0x51, 0x7f, 0x19, 0xd6, 0xeb, 0xe0, 0xcf, 0x04,
|
||||||
0x4c, 0xf1, 0xdf, 0x58, 0x30, 0x84, 0x85, 0x60, 0x89, 0x22, 0x0f, 0x4d, 0xa3, 0x79, 0x78, 0x7d,
|
0xb6, 0x0b, 0xd7, 0xed, 0x33, 0x93, 0x09, 0xef, 0x10, 0x6e, 0xa5, 0x1d, 0xab, 0x4c, 0xb8, 0x4f,
|
||||||
0x57, 0x3f, 0x9c, 0x79, 0x1e, 0xa8, 0xff, 0x15, 0x94, 0xf4, 0x45, 0x88, 0x3c, 0x32, 0x91, 0x44,
|
0xa2, 0xd3, 0x71, 0x09, 0xd5, 0xbc, 0x69, 0xf6, 0xa5, 0x94, 0xdc, 0x72, 0x4f, 0xf4, 0x19, 0xbd,
|
||||||
0xf6, 0xa8, 0xaa, 0x75, 0x15, 0xca, 0x34, 0x63, 0xb1, 0xe6, 0x98, 0x19, 0x47, 0xf6, 0x26, 0x33,
|
0x2c, 0xb0, 0x4b, 0xdb, 0x60, 0xf3, 0xf4, 0x5f, 0xc6, 0x46, 0x18, 0x49, 0xe3, 0xb2, 0xd4, 0xbb,
|
||||||
0xe3, 0xe8, 0x96, 0x84, 0x8c, 0x31, 0x33, 0xc2, 0x25, 0x87, 0x18, 0x4d, 0xd4, 0x76, 0xa2, 0x78,
|
0x8c, 0x8d, 0xf8, 0xbe, 0x03, 0x15, 0x5d, 0x3d, 0x18, 0x7f, 0x38, 0xa9, 0x42, 0x79, 0x77, 0x6f,
|
||||||
0x66, 0x4c, 0xef, 0x47, 0x98, 0xc7, 0xff, 0x4e, 0x43, 0xf1, 0xb5, 0xed, 0x0c, 0x7d, 0x3a, 0x64,
|
0xff, 0x69, 0x73, 0x13, 0xeb, 0x96, 0xf5, 0x7f, 0xe6, 0x21, 0xbf, 0x7d, 0x48, 0x36, 0x60, 0x5e,
|
||||||
0x4f, 0x1c, 0xac, 0x7b, 0xf0, 0x46, 0x13, 0x4f, 0x67, 0x7d, 0xd7, 0x88, 0xa7, 0x73, 0x64, 0x64,
|
0x3c, 0xf9, 0x5e, 0xf0, 0x28, 0xde, 0xb8, 0xe8, 0xf1, 0xd8, 0x99, 0x23, 0x9f, 0x43, 0x81, 0x3d,
|
||||||
0x47, 0x35, 0x1b, 0x90, 0x13, 0x93, 0x34, 0x89, 0x21, 0x46, 0x26, 0xee, 0xea, 0x07, 0xe6, 0x43,
|
0xfa, 0xa6, 0xbe, 0x8a, 0x37, 0xd2, 0x1f, 0x8e, 0x51, 0xba, 0x03, 0x55, 0xe3, 0x85, 0x97, 0xbc,
|
||||||
0xdd, 0xda, 0x70, 0xa5, 0x8a, 0x5b, 0x3b, 0xb5, 0x81, 0x55, 0xd7, 0x66, 0x23, 0x04, 0x2c, 0xbf,
|
0xf1, 0x55, 0xbc, 0xf1, 0xe6, 0xd7, 0x63, 0xa1, 0x53, 0xe7, 0xd5, 0xc8, 0xd6, 0x29, 0x7a, 0x91,
|
||||||
0x80, 0x2c, 0x7b, 0x1d, 0x24, 0xb1, 0x56, 0xa1, 0x3d, 0x20, 0x56, 0xab, 0xa6, 0xa3, 0x80, 0xc1,
|
0xb4, 0x75, 0x32, 0xde, 0xff, 0x50, 0x7a, 0x57, 0xbe, 0x2c, 0x77, 0x43, 0xf2, 0x7e, 0xc2, 0x43,
|
||||||
0x6b, 0x58, 0x50, 0xef, 0x7f, 0xe4, 0x41, 0x4c, 0xff, 0xe8, 0x53, 0x61, 0xf5, 0xe1, 0xac, 0x63,
|
0xa5, 0xf9, 0x12, 0xd7, 0xb8, 0x9d, 0xce, 0xa0, 0xf0, 0xd6, 0xf7, 0x60, 0x9e, 0xbf, 0x52, 0x90,
|
||||||
0xc5, 0x0c, 0xd3, 0xfb, 0xef, 0x05, 0xc8, 0xb2, 0xfb, 0x81, 0xd9, 0x1a, 0xce, 0x73, 0x71, 0x5b,
|
0x2f, 0xd4, 0x47, 0x23, 0xe1, 0x0d, 0x27, 0xc5, 0xdd, 0xb1, 0xf7, 0x0d, 0x67, 0xee, 0x7e, 0xee,
|
||||||
0xa7, 0x16, 0x80, 0xb8, 0xad, 0xd3, 0xa3, 0xa0, 0xa8, 0x79, 0x6d, 0xbc, 0x23, 0x06, 0x92, 0xe8,
|
0x87, 0xb9, 0xf5, 0x6f, 0xf3, 0x30, 0xcf, 0xbb, 0x56, 0xf2, 0x15, 0x40, 0xd4, 0xde, 0xdb, 0xda,
|
||||||
0xfe, 0x10, 0xaf, 0x79, 0xc3, 0x6c, 0x28, 0x72, 0x5b, 0x9f, 0xf7, 0x88, 0x81, 0x28, 0xb6, 0x80,
|
0xce, 0x3c, 0x18, 0xd8, 0xda, 0xce, 0xbe, 0x0c, 0x88, 0x1d, 0x31, 0xfa, 0x70, 0x92, 0x24, 0x12,
|
||||||
0xc4, 0x73, 0xdb, 0x34, 0x2e, 0x22, 0xe3, 0x23, 0xc8, 0xcb, 0x79, 0xcf, 0xa4, 0x6a, 0x74, 0x3b,
|
0xbb, 0xd6, 0xec, 0x1d, 0x49, 0x68, 0xe2, 0x11, 0xd5, 0x83, 0x7a, 0xbc, 0xcf, 0x26, 0x77, 0x12,
|
||||||
0x31, 0xa9, 0x1a, 0x1b, 0x16, 0x43, 0x8e, 0x38, 0x4b, 0xcc, 0xe2, 0x18, 0x8e, 0xf2, 0xb3, 0x38,
|
0xc4, 0xec, 0x76, 0xbd, 0x71, 0xf7, 0x62, 0xa6, 0x98, 0x57, 0xfe, 0x92, 0xc7, 0x7d, 0x13, 0x7f,
|
||||||
0x6a, 0x83, 0x08, 0x72, 0xfc, 0x1a, 0x20, 0x9c, 0x04, 0xe3, 0xcd, 0xce, 0xb8, 0xf8, 0xc4, 0x9b,
|
0xb7, 0xc5, 0x2d, 0xac, 0xe8, 0x56, 0x96, 0xdc, 0x4a, 0x6a, 0x73, 0xa2, 0x3a, 0xa2, 0xf1, 0x7e,
|
||||||
0x9d, 0x79, 0x98, 0x44, 0xd6, 0xdf, 0x02, 0x99, 0x1e, 0x0e, 0xc9, 0xc7, 0x66, 0x6a, 0xe3, 0xd2,
|
0xea, 0xbc, 0x56, 0xff, 0x19, 0xd4, 0xcc, 0xd6, 0x93, 0x7c, 0x90, 0xd8, 0x39, 0x99, 0xdd, 0x6b,
|
||||||
0x54, 0x7d, 0xfa, 0x7e, 0xc8, 0x81, 0xc8, 0x13, 0x28, 0x04, 0xf3, 0x23, 0xb1, 0x66, 0xd8, 0xaf,
|
0xc3, 0xb9, 0x88, 0x65, 0x16, 0x58, 0xb4, 0x90, 0xc9, 0xc0, 0xb1, 0x0e, 0x35, 0x19, 0x38, 0xde,
|
||||||
0xdf, 0x34, 0xeb, 0x57, 0xe2, 0xc4, 0xbd, 0x24, 0xef, 0x9a, 0x19, 0x44, 0xd1, 0xeb, 0x66, 0xe3,
|
0x81, 0x22, 0x30, 0x46, 0x46, 0xd4, 0x38, 0x92, 0x44, 0x13, 0x8d, 0x3e, 0xd3, 0x8e, 0x8c, 0xd9,
|
||||||
0x6a, 0x24, 0x3d, 0xa4, 0x72, 0xc6, 0x34, 0x85, 0x34, 0xba, 0xc1, 0x99, 0x42, 0x1a, 0x1b, 0x50,
|
0x9e, 0x13, 0xe3, 0xf8, 0x3f, 0x79, 0xa8, 0x3e, 0xf1, 0xfa, 0xa3, 0x90, 0x8e, 0xd8, 0x43, 0x17,
|
||||||
0x43, 0x8e, 0x33, 0x92, 0x24, 0xba, 0xef, 0xcd, 0xe2, 0x38, 0x95, 0x24, 0xe1, 0xf4, 0x69, 0x32,
|
0xcb, 0x1e, 0x3c, 0xd1, 0xd8, 0xe1, 0x6c, 0xb6, 0x69, 0x76, 0x38, 0xc7, 0x7a, 0x18, 0x54, 0xb3,
|
||||||
0x7f, 0x6a, 0x5d, 0x34, 0x99, 0x3f, 0x3d, 0xc0, 0x8a, 0x88, 0x05, 0x03, 0xa9, 0x29, 0x62, 0xf1,
|
0x0d, 0x25, 0xd1, 0x4a, 0x10, 0x8b, 0x31, 0xd6, 0x72, 0x34, 0xde, 0x4d, 0x9e, 0x34, 0xad, 0x8d,
|
||||||
0x7d, 0xb3, 0xba, 0x7e, 0x25, 0x4e, 0x5c, 0xe5, 0xd9, 0x11, 0x9b, 0x5a, 0x40, 0x67, 0xa9, 0x1c,
|
0xba, 0x52, 0xdb, 0xda, 0x99, 0x26, 0xb6, 0x71, 0x3b, 0x9d, 0x41, 0x43, 0xfe, 0x0c, 0x8a, 0xec,
|
||||||
0x8f, 0xd8, 0x56, 0xe9, 0x8f, 0xff, 0x7c, 0x98, 0xfa, 0x0b, 0xfe, 0xfb, 0x07, 0xfe, 0x3b, 0xcd,
|
0x41, 0x9b, 0x58, 0xa9, 0xc2, 0x78, 0xf3, 0x6e, 0x34, 0x92, 0xa6, 0x34, 0xc0, 0x13, 0x58, 0x50,
|
||||||
0xf1, 0xff, 0x95, 0xe2, 0xf9, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x6e, 0x06, 0x62, 0xb3,
|
0x6f, 0xd4, 0xe4, 0x3d, 0x4b, 0xff, 0xf8, 0x7b, 0x76, 0xe3, 0x56, 0xda, 0xb4, 0x02, 0xc3, 0xf0,
|
||||||
0x21, 0x00, 0x00,
|
0xfe, 0x6b, 0x05, 0x8a, 0xec, 0x9e, 0x60, 0xb6, 0x46, 0x65, 0xa4, 0x6d, 0xeb, 0x4c, 0x2f, 0x63,
|
||||||
|
0xdb, 0x3a, 0x5b, 0x81, 0x8a, 0x33, 0x6f, 0x54, 0x93, 0x24, 0x41, 0x24, 0xde, 0x0a, 0xd9, 0x67,
|
||||||
|
0x3e, 0xa1, 0x14, 0x15, 0xb1, 0x6d, 0x96, 0x95, 0x24, 0x41, 0xc8, 0xea, 0xa5, 0xec, 0xd8, 0x4e,
|
||||||
|
0xaa, 0x4a, 0x11, 0xf8, 0x29, 0x94, 0x65, 0x1d, 0x99, 0xa4, 0x6a, 0xbc, 0xb1, 0x4a, 0x52, 0xd5,
|
||||||
|
0x2a, 0x42, 0x23, 0x44, 0xac, 0x35, 0xd2, 0x10, 0xa3, 0x6e, 0x22, 0x0d, 0xd1, 0x28, 0x54, 0x10,
|
||||||
|
0xf1, 0x6b, 0x80, 0xa8, 0xa2, 0xb4, 0x93, 0x5d, 0x62, 0x8f, 0x66, 0x27, 0xbb, 0xe4, 0xa2, 0x14,
|
||||||
|
0xa1, 0xbf, 0x01, 0x32, 0x5b, 0x5c, 0x92, 0x8f, 0x93, 0xa5, 0x13, 0x3b, 0xbb, 0xc6, 0x27, 0x6f,
|
||||||
|
0xc7, 0xac, 0x97, 0x3c, 0x84, 0x8a, 0xae, 0x3b, 0x89, 0x93, 0x62, 0xbf, 0x79, 0xd3, 0xdc, 0xb9,
|
||||||
|
0x90, 0xc7, 0xf6, 0x92, 0xbc, 0x6b, 0x52, 0x84, 0xe2, 0xd7, 0xcd, 0xdd, 0x8b, 0x99, 0xcc, 0x2d,
|
||||||
|
0x95, 0xb5, 0x68, 0xd2, 0x96, 0xc6, 0x5b, 0xc9, 0xa4, 0x2d, 0xb5, 0x0a, 0xd9, 0x08, 0x31, 0x25,
|
||||||
|
0x48, 0xe2, 0x2d, 0x67, 0x1a, 0xe2, 0x4c, 0x90, 0x44, 0x55, 0x69, 0x92, 0xf9, 0x33, 0x1d, 0x6b,
|
||||||
|
0x92, 0xf9, 0xb3, 0x85, 0xad, 0xd8, 0x31, 0x5d, 0xa0, 0x26, 0xed, 0x98, 0xdd, 0xf2, 0x36, 0xee,
|
||||||
|
0x5c, 0xc8, 0x63, 0xab, 0x9c, 0xbe, 0x63, 0x33, 0x7d, 0x6f, 0x9a, 0xca, 0xf6, 0x8e, 0x6d, 0xd4,
|
||||||
|
0xfe, 0xf0, 0xf7, 0x5b, 0xb9, 0x3f, 0xe3, 0xbf, 0xbf, 0xe1, 0xbf, 0xe3, 0x12, 0xff, 0x1f, 0x5b,
|
||||||
|
0x3f, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf4, 0xad, 0xd4, 0x1a, 0x26, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -311,10 +311,10 @@ message TxnResponse {
|
||||||
repeated ResponseUnion responses = 3;
|
repeated ResponseUnion responses = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CompactionRequest compacts the key-value store upto a given revision. All superseded keys
|
// CompactionRequest compacts the key-value store up to a given revision. All superseded keys
|
||||||
// with a revision less than the compaction revision will be removed.
|
// with a revision less than the compaction revision will be removed.
|
||||||
message CompactionRequest {
|
message CompactionRequest {
|
||||||
// revision is the key-value store revision for the compation operation.
|
// revision is the key-value store revision for the compaction operation.
|
||||||
int64 revision = 1;
|
int64 revision = 1;
|
||||||
// physical is set so the RPC will wait until the compaction is physically
|
// physical is set so the RPC will wait until the compaction is physically
|
||||||
// applied to the local database such that compacted entries are totally
|
// applied to the local database such that compacted entries are totally
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ type KeyValue struct {
|
||||||
// key is the key in bytes. An empty key is not allowed.
|
// key is the key in bytes. An empty key is not allowed.
|
||||||
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||||
// create_revision is the revision of last creation on this key.
|
// create_revision is the revision of last creation on this key.
|
||||||
CreateRevision int64 `protobuf:"varint,2,opt,name=create_revision,proto3" json:"create_revision,omitempty"`
|
CreateRevision int64 `protobuf:"varint,2,opt,name=create_revision,json=createRevision,proto3" json:"create_revision,omitempty"`
|
||||||
// mod_revision is the revision of last modification on this key.
|
// mod_revision is the revision of last modification on this key.
|
||||||
ModRevision int64 `protobuf:"varint,3,opt,name=mod_revision,proto3" json:"mod_revision,omitempty"`
|
ModRevision int64 `protobuf:"varint,3,opt,name=mod_revision,json=modRevision,proto3" json:"mod_revision,omitempty"`
|
||||||
// version is the version of the key. A deletion resets
|
// version is the version of the key. A deletion resets
|
||||||
// the version to zero and any modification of the key
|
// the version to zero and any modification of the key
|
||||||
// increases its version.
|
// increases its version.
|
||||||
|
|
@ -662,21 +662,23 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var fileDescriptorKv = []byte{
|
var fileDescriptorKv = []byte{
|
||||||
// 255 bytes of a gzipped FileDescriptorProto
|
// 285 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc8, 0x2e, 0xd3, 0x2b,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0xc8, 0x2e, 0xd3, 0x2b,
|
||||||
0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcb, 0x2d, 0x4b, 0x4e, 0x2e, 0x48, 0x92, 0x12, 0x49, 0xcf,
|
0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcb, 0x2d, 0x4b, 0x4e, 0x2e, 0x48, 0x92, 0x12, 0x49, 0xcf,
|
||||||
0x4f, 0xcf, 0x07, 0x0b, 0xe9, 0x83, 0x58, 0x10, 0x59, 0xa5, 0x52, 0x2e, 0x0e, 0xef, 0xd4, 0xca,
|
0x4f, 0xcf, 0x07, 0x0b, 0xe9, 0x83, 0x58, 0x10, 0x59, 0xa5, 0x75, 0x8c, 0x5c, 0x1c, 0xde, 0xa9,
|
||||||
0xb0, 0xc4, 0x9c, 0xd2, 0x54, 0x21, 0x6e, 0x2e, 0xe6, 0xec, 0xd4, 0x4a, 0x09, 0x46, 0x05, 0x46,
|
0x95, 0x61, 0x89, 0x39, 0xa5, 0xa9, 0x42, 0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x12, 0x8c, 0x0a,
|
||||||
0x0d, 0x1e, 0x21, 0x71, 0x2e, 0xfe, 0xe4, 0xa2, 0xd4, 0xc4, 0x92, 0xd4, 0xf8, 0xa2, 0xd4, 0xb2,
|
0x8c, 0x1a, 0x3c, 0x41, 0x20, 0xa6, 0x90, 0x3a, 0x17, 0x7f, 0x72, 0x51, 0x6a, 0x62, 0x49, 0x6a,
|
||||||
0xcc, 0xe2, 0xcc, 0xfc, 0x3c, 0x09, 0x26, 0xa0, 0x04, 0xb3, 0x90, 0x08, 0x17, 0x4f, 0x6e, 0x7e,
|
0x7c, 0x51, 0x6a, 0x59, 0x66, 0x71, 0x66, 0x7e, 0x9e, 0x04, 0x13, 0x50, 0x96, 0x39, 0x88, 0x0f,
|
||||||
0x0a, 0x42, 0x94, 0x19, 0x2c, 0xca, 0xcf, 0xc5, 0x5e, 0x96, 0x5a, 0x04, 0x16, 0x60, 0x01, 0x0b,
|
0x22, 0x1c, 0x04, 0x15, 0x15, 0x52, 0xe4, 0xe2, 0xc9, 0xcd, 0x4f, 0x41, 0xa8, 0x62, 0x06, 0xab,
|
||||||
0xf0, 0x72, 0xb1, 0x96, 0x81, 0x4c, 0x95, 0x60, 0x05, 0x1b, 0x07, 0xe4, 0xe6, 0xa4, 0x26, 0x16,
|
0xe2, 0x06, 0x8a, 0xc1, 0x95, 0x48, 0x70, 0xb1, 0x97, 0xa5, 0x16, 0x81, 0x65, 0x59, 0xc0, 0xb2,
|
||||||
0xa7, 0x4a, 0xb0, 0x81, 0x64, 0x95, 0xaa, 0xb8, 0x58, 0x5d, 0xcb, 0x52, 0xf3, 0x4a, 0x84, 0x54,
|
0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x19, 0xc8, 0x01, 0x12, 0xac, 0x60, 0x9b, 0x21, 0x1c, 0x90,
|
||||||
0xb9, 0x58, 0x4a, 0x2a, 0x0b, 0x52, 0xc1, 0x96, 0xf2, 0x19, 0x89, 0xeb, 0x41, 0x1c, 0xab, 0x07,
|
0x68, 0x4e, 0x6a, 0x62, 0x71, 0xaa, 0x04, 0x1b, 0x58, 0x35, 0x84, 0xa3, 0xd4, 0xc2, 0xc8, 0xc5,
|
||||||
0x96, 0x84, 0x90, 0x21, 0x40, 0x69, 0x21, 0x19, 0x2e, 0xa6, 0xec, 0x32, 0xb0, 0x03, 0xb8, 0x8d,
|
0xea, 0x5a, 0x96, 0x9a, 0x57, 0x22, 0xa4, 0xcd, 0xc5, 0x52, 0x52, 0x59, 0x90, 0x0a, 0x76, 0x2e,
|
||||||
0x04, 0x60, 0x8a, 0x60, 0x0e, 0x57, 0xd2, 0xe1, 0xe2, 0x44, 0x28, 0x65, 0xe7, 0x62, 0x0e, 0x08,
|
0x9f, 0x91, 0xb8, 0x1e, 0xc4, 0x9f, 0x7a, 0x60, 0x49, 0x08, 0x19, 0x02, 0x94, 0x0e, 0x02, 0x2b,
|
||||||
0x0d, 0x11, 0x60, 0x10, 0xe2, 0xe2, 0x62, 0x73, 0x71, 0xf5, 0x71, 0x0d, 0x71, 0x15, 0x60, 0x04,
|
0x12, 0x52, 0xe0, 0x62, 0xca, 0x2e, 0x03, 0xbb, 0x9d, 0xdb, 0x48, 0x00, 0xa6, 0x14, 0xe6, 0xf1,
|
||||||
0xb1, 0x5d, 0x23, 0x02, 0x3c, 0x83, 0x5c, 0x05, 0x98, 0x9c, 0x44, 0x4e, 0x3c, 0x94, 0x63, 0xb8,
|
0x20, 0xa0, 0x9c, 0x92, 0x0e, 0x17, 0x27, 0x5c, 0x93, 0x10, 0x3b, 0x17, 0x73, 0x40, 0x68, 0x88,
|
||||||
0x00, 0xc4, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x00, 0xe2, 0x07, 0x40, 0x9c, 0xc4, 0x06, 0x0e, 0x0f,
|
0x00, 0x83, 0x10, 0x17, 0x17, 0x9b, 0x8b, 0xab, 0x8f, 0x6b, 0x88, 0xab, 0x00, 0x23, 0x88, 0xed,
|
||||||
0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x2d, 0xc3, 0x10, 0x39, 0x01, 0x00, 0x00,
|
0x1a, 0x11, 0xe0, 0x19, 0xe4, 0x2a, 0xc0, 0xe4, 0x24, 0x72, 0xe2, 0xa1, 0x1c, 0xc3, 0x05, 0x20,
|
||||||
|
0x3e, 0xf1, 0x48, 0x8e, 0xf1, 0x02, 0x10, 0x3f, 0x00, 0xe2, 0x24, 0x36, 0x70, 0xa0, 0x1a, 0x03,
|
||||||
|
0x02, 0x00, 0x00, 0xff, 0xff, 0x80, 0xae, 0xe6, 0x9d, 0x7e, 0x01, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
// Copyright 2016 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package compress
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
type Type int
|
|
||||||
|
|
||||||
const (
|
|
||||||
NoCompress Type = iota
|
|
||||||
Snappy
|
|
||||||
Lz4
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
headers = [...]string{
|
|
||||||
"",
|
|
||||||
"snappy",
|
|
||||||
"lz4",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ct Type) String() string {
|
|
||||||
return headers[ct]
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseType(opt string) Type {
|
|
||||||
switch opt {
|
|
||||||
case "snappy":
|
|
||||||
return Snappy
|
|
||||||
|
|
||||||
case "lz4":
|
|
||||||
return Lz4
|
|
||||||
|
|
||||||
default:
|
|
||||||
return NoCompress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Compressor interface {
|
|
||||||
// Do compresses p into w.
|
|
||||||
Do(w io.Writer, p []byte) error
|
|
||||||
|
|
||||||
// Type returns the compression algorithm the Compressor uses.
|
|
||||||
Type() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCompressor(ct Type) Compressor {
|
|
||||||
switch ct {
|
|
||||||
case Snappy:
|
|
||||||
return NewSnappyCompressor()
|
|
||||||
|
|
||||||
case Lz4:
|
|
||||||
return NewLz4Compressor()
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Decompressor interface {
|
|
||||||
// Do reads the data from r and uncompress them.
|
|
||||||
Do(r io.Reader) ([]byte, error)
|
|
||||||
|
|
||||||
// Type returns the compression algorithm the Decompressor uses.
|
|
||||||
Type() string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDecompressor(ct Type) Decompressor {
|
|
||||||
switch ct {
|
|
||||||
case Snappy:
|
|
||||||
return NewSnappyDecompressor()
|
|
||||||
|
|
||||||
case Lz4:
|
|
||||||
return NewLz4Decompressor()
|
|
||||||
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
// Copyright 2016 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
// Package compress wraps compression algorithms.
|
|
||||||
package compress
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
// Copyright 2016 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package compress
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/bkaradzic/go-lz4"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewLz4Compressor() Compressor {
|
|
||||||
return lz4Compressor{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type lz4Compressor struct{}
|
|
||||||
|
|
||||||
func (_ lz4Compressor) Do(w io.Writer, p []byte) error {
|
|
||||||
bts, err := lz4.Encode(nil, p)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = w.Write(bts)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ lz4Compressor) Type() string {
|
|
||||||
return headers[Lz4]
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLz4Decompressor() Decompressor {
|
|
||||||
return lz4Decompressor{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type lz4Decompressor struct{}
|
|
||||||
|
|
||||||
func (_ lz4Decompressor) Do(r io.Reader) ([]byte, error) {
|
|
||||||
src, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return lz4.Decode(nil, src)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ lz4Decompressor) Type() string {
|
|
||||||
return headers[Lz4]
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
// Copyright 2016 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package compress
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/golang/snappy"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
snappyWriterPool sync.Pool
|
|
||||||
snappyReaderPool sync.Pool
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewSnappyCompressor() Compressor {
|
|
||||||
return snappyCompressor{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type snappyCompressor struct{}
|
|
||||||
|
|
||||||
func (_ snappyCompressor) Do(w io.Writer, p []byte) error {
|
|
||||||
var writer *snappy.Writer
|
|
||||||
if wp := snappyWriterPool.Get(); wp != nil {
|
|
||||||
writer = wp.(*snappy.Writer)
|
|
||||||
writer.Reset(w)
|
|
||||||
} else {
|
|
||||||
writer = snappy.NewBufferedWriter(w)
|
|
||||||
}
|
|
||||||
if _, err := writer.Write(p); err != nil {
|
|
||||||
writer.Close()
|
|
||||||
snappyWriterPool.Put(writer)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
werr := writer.Close()
|
|
||||||
snappyWriterPool.Put(writer)
|
|
||||||
return werr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ snappyCompressor) Type() string {
|
|
||||||
return headers[Snappy]
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSnappyDecompressor() Decompressor {
|
|
||||||
return snappyDecompressor{}
|
|
||||||
}
|
|
||||||
|
|
||||||
type snappyDecompressor struct{}
|
|
||||||
|
|
||||||
func (_ snappyDecompressor) Do(r io.Reader) ([]byte, error) {
|
|
||||||
var reader *snappy.Reader
|
|
||||||
if wp := snappyReaderPool.Get(); wp != nil {
|
|
||||||
reader = wp.(*snappy.Reader)
|
|
||||||
reader.Reset(r)
|
|
||||||
} else {
|
|
||||||
reader = snappy.NewReader(r)
|
|
||||||
}
|
|
||||||
bts, err := ioutil.ReadAll(reader)
|
|
||||||
snappyReaderPool.Put(reader)
|
|
||||||
return bts, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ snappyDecompressor) Type() string {
|
|
||||||
return headers[Snappy]
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
cmd/snappytool/snappytool
|
|
||||||
testdata/bench
|
|
||||||
|
|
||||||
# These explicitly listed benchmark data files are for an obsolete version of
|
|
||||||
# snappy_test.go.
|
|
||||||
testdata/alice29.txt
|
|
||||||
testdata/asyoulik.txt
|
|
||||||
testdata/fireworks.jpeg
|
|
||||||
testdata/geo.protodata
|
|
||||||
testdata/html
|
|
||||||
testdata/html_x_4
|
|
||||||
testdata/kppkn.gtb
|
|
||||||
testdata/lcet10.txt
|
|
||||||
testdata/paper-100k.pdf
|
|
||||||
testdata/plrabn12.txt
|
|
||||||
testdata/urls.10K
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
# This is the official list of Snappy-Go authors for copyright purposes.
|
|
||||||
# This file is distinct from the CONTRIBUTORS files.
|
|
||||||
# See the latter for an explanation.
|
|
||||||
|
|
||||||
# Names should be added to this file as
|
|
||||||
# Name or Organization <email address>
|
|
||||||
# The email address is not required for organizations.
|
|
||||||
|
|
||||||
# Please keep the list sorted.
|
|
||||||
|
|
||||||
Damian Gryski <dgryski@gmail.com>
|
|
||||||
Google Inc.
|
|
||||||
Jan Mercl <0xjnml@gmail.com>
|
|
||||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
|
||||||
Sebastien Binet <seb.binet@gmail.com>
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
# This is the official list of people who can contribute
|
|
||||||
# (and typically have contributed) code to the Snappy-Go repository.
|
|
||||||
# The AUTHORS file lists the copyright holders; this file
|
|
||||||
# lists people. For example, Google employees are listed here
|
|
||||||
# but not in AUTHORS, because Google holds the copyright.
|
|
||||||
#
|
|
||||||
# The submission process automatically checks to make sure
|
|
||||||
# that people submitting code are listed in this file (by email address).
|
|
||||||
#
|
|
||||||
# Names should be added to this file only after verifying that
|
|
||||||
# the individual or the individual's organization has agreed to
|
|
||||||
# the appropriate Contributor License Agreement, found here:
|
|
||||||
#
|
|
||||||
# http://code.google.com/legal/individual-cla-v1.0.html
|
|
||||||
# http://code.google.com/legal/corporate-cla-v1.0.html
|
|
||||||
#
|
|
||||||
# The agreement for individuals can be filled out on the web.
|
|
||||||
#
|
|
||||||
# When adding J Random Contributor's name to this file,
|
|
||||||
# either J's name or J's organization's name should be
|
|
||||||
# added to the AUTHORS file, depending on whether the
|
|
||||||
# individual or corporate CLA was used.
|
|
||||||
|
|
||||||
# Names should be added to this file like so:
|
|
||||||
# Name <email address>
|
|
||||||
|
|
||||||
# Please keep the list sorted.
|
|
||||||
|
|
||||||
Damian Gryski <dgryski@gmail.com>
|
|
||||||
Jan Mercl <0xjnml@gmail.com>
|
|
||||||
Kai Backman <kaib@golang.org>
|
|
||||||
Marc-Antoine Ruel <maruel@chromium.org>
|
|
||||||
Nigel Tao <nigeltao@golang.org>
|
|
||||||
Rob Pike <r@golang.org>
|
|
||||||
Rodolfo Carvalho <rhcarvalho@gmail.com>
|
|
||||||
Russ Cox <rsc@golang.org>
|
|
||||||
Sebastien Binet <seb.binet@gmail.com>
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
Copyright (c) 2011 The Snappy-Go Authors. 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.
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
The Snappy compression format in the Go programming language.
|
|
||||||
|
|
||||||
To download and install from source:
|
|
||||||
$ go get github.com/golang/snappy
|
|
||||||
|
|
||||||
Unless otherwise noted, the Snappy-Go source files are distributed
|
|
||||||
under the BSD-style license found in the LICENSE file.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Benchmarks.
|
|
||||||
|
|
||||||
The golang/snappy benchmarks include compressing (Z) and decompressing (U) ten
|
|
||||||
or so files, the same set used by the C++ Snappy code (github.com/google/snappy
|
|
||||||
and note the "google", not "golang"). On an "Intel(R) Core(TM) i7-3770 CPU @
|
|
||||||
3.40GHz", Go's GOARCH=amd64 numbers as of 2016-04-29:
|
|
||||||
|
|
||||||
"go test -test.bench=."
|
|
||||||
|
|
||||||
_UFlat0-8 2.23GB/s ± 1% html
|
|
||||||
_UFlat1-8 1.43GB/s ± 0% urls
|
|
||||||
_UFlat2-8 23.7GB/s ± 1% jpg
|
|
||||||
_UFlat3-8 1.93GB/s ± 0% jpg_200
|
|
||||||
_UFlat4-8 13.9GB/s ± 2% pdf
|
|
||||||
_UFlat5-8 2.00GB/s ± 0% html4
|
|
||||||
_UFlat6-8 829MB/s ± 0% txt1
|
|
||||||
_UFlat7-8 799MB/s ± 0% txt2
|
|
||||||
_UFlat8-8 871MB/s ± 0% txt3
|
|
||||||
_UFlat9-8 730MB/s ± 0% txt4
|
|
||||||
_UFlat10-8 2.87GB/s ± 0% pb
|
|
||||||
_UFlat11-8 1.07GB/s ± 0% gaviota
|
|
||||||
|
|
||||||
_ZFlat0-8 1.04GB/s ± 0% html
|
|
||||||
_ZFlat1-8 536MB/s ± 0% urls
|
|
||||||
_ZFlat2-8 16.3GB/s ± 2% jpg
|
|
||||||
_ZFlat3-8 762MB/s ± 0% jpg_200
|
|
||||||
_ZFlat4-8 9.48GB/s ± 1% pdf
|
|
||||||
_ZFlat5-8 990MB/s ± 0% html4
|
|
||||||
_ZFlat6-8 381MB/s ± 0% txt1
|
|
||||||
_ZFlat7-8 353MB/s ± 0% txt2
|
|
||||||
_ZFlat8-8 398MB/s ± 0% txt3
|
|
||||||
_ZFlat9-8 329MB/s ± 0% txt4
|
|
||||||
_ZFlat10-8 1.35GB/s ± 1% pb
|
|
||||||
_ZFlat11-8 608MB/s ± 0% gaviota
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"go test -test.bench=. -tags=noasm"
|
|
||||||
|
|
||||||
_UFlat0-8 637MB/s ± 0% html
|
|
||||||
_UFlat1-8 506MB/s ± 0% urls
|
|
||||||
_UFlat2-8 23.0GB/s ± 5% jpg
|
|
||||||
_UFlat3-8 1.17GB/s ± 0% jpg_200
|
|
||||||
_UFlat4-8 4.44GB/s ± 1% pdf
|
|
||||||
_UFlat5-8 623MB/s ± 0% html4
|
|
||||||
_UFlat6-8 300MB/s ± 1% txt1
|
|
||||||
_UFlat7-8 293MB/s ± 0% txt2
|
|
||||||
_UFlat8-8 316MB/s ± 0% txt3
|
|
||||||
_UFlat9-8 285MB/s ± 0% txt4
|
|
||||||
_UFlat10-8 768MB/s ± 0% pb
|
|
||||||
_UFlat11-8 406MB/s ± 1% gaviota
|
|
||||||
|
|
||||||
_ZFlat0-8 411MB/s ± 1% html
|
|
||||||
_ZFlat1-8 250MB/s ± 1% urls
|
|
||||||
_ZFlat2-8 12.7GB/s ± 1% jpg
|
|
||||||
_ZFlat3-8 157MB/s ± 0% jpg_200
|
|
||||||
_ZFlat4-8 2.95GB/s ± 0% pdf
|
|
||||||
_ZFlat5-8 406MB/s ± 0% html4
|
|
||||||
_ZFlat6-8 182MB/s ± 0% txt1
|
|
||||||
_ZFlat7-8 173MB/s ± 1% txt2
|
|
||||||
_ZFlat8-8 191MB/s ± 0% txt3
|
|
||||||
_ZFlat9-8 166MB/s ± 0% txt4
|
|
||||||
_ZFlat10-8 480MB/s ± 0% pb
|
|
||||||
_ZFlat11-8 272MB/s ± 0% gaviota
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
For comparison (Go's encoded output is byte-for-byte identical to C++'s), here
|
|
||||||
are the numbers from C++ Snappy's
|
|
||||||
|
|
||||||
make CXXFLAGS="-O2 -DNDEBUG -g" clean snappy_unittest.log && cat snappy_unittest.log
|
|
||||||
|
|
||||||
BM_UFlat/0 2.4GB/s html
|
|
||||||
BM_UFlat/1 1.4GB/s urls
|
|
||||||
BM_UFlat/2 21.8GB/s jpg
|
|
||||||
BM_UFlat/3 1.5GB/s jpg_200
|
|
||||||
BM_UFlat/4 13.3GB/s pdf
|
|
||||||
BM_UFlat/5 2.1GB/s html4
|
|
||||||
BM_UFlat/6 1.0GB/s txt1
|
|
||||||
BM_UFlat/7 959.4MB/s txt2
|
|
||||||
BM_UFlat/8 1.0GB/s txt3
|
|
||||||
BM_UFlat/9 864.5MB/s txt4
|
|
||||||
BM_UFlat/10 2.9GB/s pb
|
|
||||||
BM_UFlat/11 1.2GB/s gaviota
|
|
||||||
|
|
||||||
BM_ZFlat/0 944.3MB/s html (22.31 %)
|
|
||||||
BM_ZFlat/1 501.6MB/s urls (47.78 %)
|
|
||||||
BM_ZFlat/2 14.3GB/s jpg (99.95 %)
|
|
||||||
BM_ZFlat/3 538.3MB/s jpg_200 (73.00 %)
|
|
||||||
BM_ZFlat/4 8.3GB/s pdf (83.30 %)
|
|
||||||
BM_ZFlat/5 903.5MB/s html4 (22.52 %)
|
|
||||||
BM_ZFlat/6 336.0MB/s txt1 (57.88 %)
|
|
||||||
BM_ZFlat/7 312.3MB/s txt2 (61.91 %)
|
|
||||||
BM_ZFlat/8 353.1MB/s txt3 (54.99 %)
|
|
||||||
BM_ZFlat/9 289.9MB/s txt4 (66.26 %)
|
|
||||||
BM_ZFlat/10 1.2GB/s pb (19.68 %)
|
|
||||||
BM_ZFlat/11 527.4MB/s gaviota (37.72 %)
|
|
||||||
|
|
@ -1,241 +0,0 @@
|
||||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrCorrupt reports that the input is invalid.
|
|
||||||
ErrCorrupt = errors.New("snappy: corrupt input")
|
|
||||||
// ErrTooLarge reports that the uncompressed length is too large.
|
|
||||||
ErrTooLarge = errors.New("snappy: decoded block is too large")
|
|
||||||
// ErrUnsupported reports that the input isn't supported.
|
|
||||||
ErrUnsupported = errors.New("snappy: unsupported input")
|
|
||||||
|
|
||||||
errUnsupportedCopy4Tag = errors.New("snappy: unsupported COPY_4 tag")
|
|
||||||
errUnsupportedLiteralLength = errors.New("snappy: unsupported literal length")
|
|
||||||
)
|
|
||||||
|
|
||||||
// DecodedLen returns the length of the decoded block.
|
|
||||||
func DecodedLen(src []byte) (int, error) {
|
|
||||||
v, _, err := decodedLen(src)
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// decodedLen returns the length of the decoded block and the number of bytes
|
|
||||||
// that the length header occupied.
|
|
||||||
func decodedLen(src []byte) (blockLen, headerLen int, err error) {
|
|
||||||
v, n := binary.Uvarint(src)
|
|
||||||
if n <= 0 || v > 0xffffffff {
|
|
||||||
return 0, 0, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
const wordSize = 32 << (^uint(0) >> 32 & 1)
|
|
||||||
if wordSize == 32 && v > 0x7fffffff {
|
|
||||||
return 0, 0, ErrTooLarge
|
|
||||||
}
|
|
||||||
return int(v), n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
decodeErrCodeCorrupt = 1
|
|
||||||
decodeErrCodeUnsupportedLiteralLength = 2
|
|
||||||
decodeErrCodeUnsupportedCopy4Tag = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
// Decode returns the decoded form of src. The returned slice may be a sub-
|
|
||||||
// slice of dst if dst was large enough to hold the entire decoded block.
|
|
||||||
// Otherwise, a newly allocated slice will be returned.
|
|
||||||
//
|
|
||||||
// The dst and src must not overlap. It is valid to pass a nil dst.
|
|
||||||
func Decode(dst, src []byte) ([]byte, error) {
|
|
||||||
dLen, s, err := decodedLen(src)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if dLen <= len(dst) {
|
|
||||||
dst = dst[:dLen]
|
|
||||||
} else {
|
|
||||||
dst = make([]byte, dLen)
|
|
||||||
}
|
|
||||||
switch decode(dst, src[s:]) {
|
|
||||||
case 0:
|
|
||||||
return dst, nil
|
|
||||||
case decodeErrCodeUnsupportedLiteralLength:
|
|
||||||
return nil, errUnsupportedLiteralLength
|
|
||||||
case decodeErrCodeUnsupportedCopy4Tag:
|
|
||||||
return nil, errUnsupportedCopy4Tag
|
|
||||||
}
|
|
||||||
return nil, ErrCorrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewReader returns a new Reader that decompresses from r, using the framing
|
|
||||||
// format described at
|
|
||||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
|
||||||
func NewReader(r io.Reader) *Reader {
|
|
||||||
return &Reader{
|
|
||||||
r: r,
|
|
||||||
decoded: make([]byte, maxBlockSize),
|
|
||||||
buf: make([]byte, maxEncodedLenOfMaxBlockSize+checksumSize),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reader is an io.Reader that can read Snappy-compressed bytes.
|
|
||||||
type Reader struct {
|
|
||||||
r io.Reader
|
|
||||||
err error
|
|
||||||
decoded []byte
|
|
||||||
buf []byte
|
|
||||||
// decoded[i:j] contains decoded bytes that have not yet been passed on.
|
|
||||||
i, j int
|
|
||||||
readHeader bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset discards any buffered data, resets all state, and switches the Snappy
|
|
||||||
// reader to read from r. This permits reusing a Reader rather than allocating
|
|
||||||
// a new one.
|
|
||||||
func (r *Reader) Reset(reader io.Reader) {
|
|
||||||
r.r = reader
|
|
||||||
r.err = nil
|
|
||||||
r.i = 0
|
|
||||||
r.j = 0
|
|
||||||
r.readHeader = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Reader) readFull(p []byte, allowEOF bool) (ok bool) {
|
|
||||||
if _, r.err = io.ReadFull(r.r, p); r.err != nil {
|
|
||||||
if r.err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read satisfies the io.Reader interface.
|
|
||||||
func (r *Reader) Read(p []byte) (int, error) {
|
|
||||||
if r.err != nil {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
if r.i < r.j {
|
|
||||||
n := copy(p, r.decoded[r.i:r.j])
|
|
||||||
r.i += n
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if !r.readFull(r.buf[:4], true) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
chunkType := r.buf[0]
|
|
||||||
if !r.readHeader {
|
|
||||||
if chunkType != chunkTypeStreamIdentifier {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
r.readHeader = true
|
|
||||||
}
|
|
||||||
chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16
|
|
||||||
if chunkLen > len(r.buf) {
|
|
||||||
r.err = ErrUnsupported
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// The chunk types are specified at
|
|
||||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
|
||||||
switch chunkType {
|
|
||||||
case chunkTypeCompressedData:
|
|
||||||
// Section 4.2. Compressed data (chunk type 0x00).
|
|
||||||
if chunkLen < checksumSize {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
buf := r.buf[:chunkLen]
|
|
||||||
if !r.readFull(buf, false) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
|
||||||
buf = buf[checksumSize:]
|
|
||||||
|
|
||||||
n, err := DecodedLen(buf)
|
|
||||||
if err != nil {
|
|
||||||
r.err = err
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if n > len(r.decoded) {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if _, err := Decode(r.decoded, buf); err != nil {
|
|
||||||
r.err = err
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if crc(r.decoded[:n]) != checksum {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
r.i, r.j = 0, n
|
|
||||||
continue
|
|
||||||
|
|
||||||
case chunkTypeUncompressedData:
|
|
||||||
// Section 4.3. Uncompressed data (chunk type 0x01).
|
|
||||||
if chunkLen < checksumSize {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
buf := r.buf[:checksumSize]
|
|
||||||
if !r.readFull(buf, false) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24
|
|
||||||
// Read directly into r.decoded instead of via r.buf.
|
|
||||||
n := chunkLen - checksumSize
|
|
||||||
if n > len(r.decoded) {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if !r.readFull(r.decoded[:n], false) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if crc(r.decoded[:n]) != checksum {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
r.i, r.j = 0, n
|
|
||||||
continue
|
|
||||||
|
|
||||||
case chunkTypeStreamIdentifier:
|
|
||||||
// Section 4.1. Stream identifier (chunk type 0xff).
|
|
||||||
if chunkLen != len(magicBody) {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
if !r.readFull(r.buf[:len(magicBody)], false) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
for i := 0; i < len(magicBody); i++ {
|
|
||||||
if r.buf[i] != magicBody[i] {
|
|
||||||
r.err = ErrCorrupt
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if chunkType <= 0x7f {
|
|
||||||
// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).
|
|
||||||
r.err = ErrUnsupported
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
// Section 4.4 Padding (chunk type 0xfe).
|
|
||||||
// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).
|
|
||||||
if !r.readFull(r.buf[:chunkLen], false) {
|
|
||||||
return 0, r.err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
// decode has the same semantics as in decode_other.go.
|
|
||||||
//
|
|
||||||
//go:noescape
|
|
||||||
func decode(dst, src []byte) int
|
|
||||||
|
|
@ -1,476 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// The asm code generally follows the pure Go code in decode_other.go, except
|
|
||||||
// where marked with a "!!!".
|
|
||||||
|
|
||||||
// func decode(dst, src []byte) int
|
|
||||||
//
|
|
||||||
// All local variables fit into registers. The non-zero stack size is only to
|
|
||||||
// spill registers and push args when issuing a CALL. The register allocation:
|
|
||||||
// - AX scratch
|
|
||||||
// - BX scratch
|
|
||||||
// - CX length or x
|
|
||||||
// - DX offset
|
|
||||||
// - SI &src[s]
|
|
||||||
// - DI &dst[d]
|
|
||||||
// + R8 dst_base
|
|
||||||
// + R9 dst_len
|
|
||||||
// + R10 dst_base + dst_len
|
|
||||||
// + R11 src_base
|
|
||||||
// + R12 src_len
|
|
||||||
// + R13 src_base + src_len
|
|
||||||
// - R14 used by doCopy
|
|
||||||
// - R15 used by doCopy
|
|
||||||
//
|
|
||||||
// The registers R8-R13 (marked with a "+") are set at the start of the
|
|
||||||
// function, and after a CALL returns, and are not otherwise modified.
|
|
||||||
//
|
|
||||||
// The d variable is implicitly DI - R8, and len(dst)-d is R10 - DI.
|
|
||||||
// The s variable is implicitly SI - R11, and len(src)-s is R13 - SI.
|
|
||||||
TEXT ·decode(SB), NOSPLIT, $48-56
|
|
||||||
// Initialize SI, DI and R8-R13.
|
|
||||||
MOVQ dst_base+0(FP), R8
|
|
||||||
MOVQ dst_len+8(FP), R9
|
|
||||||
MOVQ R8, DI
|
|
||||||
MOVQ R8, R10
|
|
||||||
ADDQ R9, R10
|
|
||||||
MOVQ src_base+24(FP), R11
|
|
||||||
MOVQ src_len+32(FP), R12
|
|
||||||
MOVQ R11, SI
|
|
||||||
MOVQ R11, R13
|
|
||||||
ADDQ R12, R13
|
|
||||||
|
|
||||||
loop:
|
|
||||||
// for s < len(src)
|
|
||||||
CMPQ SI, R13
|
|
||||||
JEQ end
|
|
||||||
|
|
||||||
// CX = uint32(src[s])
|
|
||||||
//
|
|
||||||
// switch src[s] & 0x03
|
|
||||||
MOVBLZX (SI), CX
|
|
||||||
MOVL CX, BX
|
|
||||||
ANDL $3, BX
|
|
||||||
CMPL BX, $1
|
|
||||||
JAE tagCopy
|
|
||||||
|
|
||||||
// ----------------------------------------
|
|
||||||
// The code below handles literal tags.
|
|
||||||
|
|
||||||
// case tagLiteral:
|
|
||||||
// x := uint32(src[s] >> 2)
|
|
||||||
// switch
|
|
||||||
SHRL $2, CX
|
|
||||||
CMPL CX, $60
|
|
||||||
JAE tagLit60Plus
|
|
||||||
|
|
||||||
// case x < 60:
|
|
||||||
// s++
|
|
||||||
INCQ SI
|
|
||||||
|
|
||||||
doLit:
|
|
||||||
// This is the end of the inner "switch", when we have a literal tag.
|
|
||||||
//
|
|
||||||
// We assume that CX == x and x fits in a uint32, where x is the variable
|
|
||||||
// used in the pure Go decode_other.go code.
|
|
||||||
|
|
||||||
// length = int(x) + 1
|
|
||||||
//
|
|
||||||
// Unlike the pure Go code, we don't need to check if length <= 0 because
|
|
||||||
// CX can hold 64 bits, so the increment cannot overflow.
|
|
||||||
INCQ CX
|
|
||||||
|
|
||||||
// Prepare to check if copying length bytes will run past the end of dst or
|
|
||||||
// src.
|
|
||||||
//
|
|
||||||
// AX = len(dst) - d
|
|
||||||
// BX = len(src) - s
|
|
||||||
MOVQ R10, AX
|
|
||||||
SUBQ DI, AX
|
|
||||||
MOVQ R13, BX
|
|
||||||
SUBQ SI, BX
|
|
||||||
|
|
||||||
// !!! Try a faster technique for short (16 or fewer bytes) copies.
|
|
||||||
//
|
|
||||||
// if length > 16 || len(dst)-d < 16 || len(src)-s < 16 {
|
|
||||||
// goto callMemmove // Fall back on calling runtime·memmove.
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The C++ snappy code calls this TryFastAppend. It also checks len(src)-s
|
|
||||||
// against 21 instead of 16, because it cannot assume that all of its input
|
|
||||||
// is contiguous in memory and so it needs to leave enough source bytes to
|
|
||||||
// read the next tag without refilling buffers, but Go's Decode assumes
|
|
||||||
// contiguousness (the src argument is a []byte).
|
|
||||||
CMPQ CX, $16
|
|
||||||
JGT callMemmove
|
|
||||||
CMPQ AX, $16
|
|
||||||
JLT callMemmove
|
|
||||||
CMPQ BX, $16
|
|
||||||
JLT callMemmove
|
|
||||||
|
|
||||||
// !!! Implement the copy from src to dst as a 16-byte load and store.
|
|
||||||
// (Decode's documentation says that dst and src must not overlap.)
|
|
||||||
//
|
|
||||||
// This always copies 16 bytes, instead of only length bytes, but that's
|
|
||||||
// OK. If the input is a valid Snappy encoding then subsequent iterations
|
|
||||||
// will fix up the overrun. Otherwise, Decode returns a nil []byte (and a
|
|
||||||
// non-nil error), so the overrun will be ignored.
|
|
||||||
//
|
|
||||||
// Note that on amd64, it is legal and cheap to issue unaligned 8-byte or
|
|
||||||
// 16-byte loads and stores. This technique probably wouldn't be as
|
|
||||||
// effective on architectures that are fussier about alignment.
|
|
||||||
MOVOU 0(SI), X0
|
|
||||||
MOVOU X0, 0(DI)
|
|
||||||
|
|
||||||
// d += length
|
|
||||||
// s += length
|
|
||||||
ADDQ CX, DI
|
|
||||||
ADDQ CX, SI
|
|
||||||
JMP loop
|
|
||||||
|
|
||||||
callMemmove:
|
|
||||||
// if length > len(dst)-d || length > len(src)-s { etc }
|
|
||||||
CMPQ CX, AX
|
|
||||||
JGT errCorrupt
|
|
||||||
CMPQ CX, BX
|
|
||||||
JGT errCorrupt
|
|
||||||
|
|
||||||
// copy(dst[d:], src[s:s+length])
|
|
||||||
//
|
|
||||||
// This means calling runtime·memmove(&dst[d], &src[s], length), so we push
|
|
||||||
// DI, SI and CX as arguments. Coincidentally, we also need to spill those
|
|
||||||
// three registers to the stack, to save local variables across the CALL.
|
|
||||||
MOVQ DI, 0(SP)
|
|
||||||
MOVQ SI, 8(SP)
|
|
||||||
MOVQ CX, 16(SP)
|
|
||||||
MOVQ DI, 24(SP)
|
|
||||||
MOVQ SI, 32(SP)
|
|
||||||
MOVQ CX, 40(SP)
|
|
||||||
CALL runtime·memmove(SB)
|
|
||||||
|
|
||||||
// Restore local variables: unspill registers from the stack and
|
|
||||||
// re-calculate R8-R13.
|
|
||||||
MOVQ 24(SP), DI
|
|
||||||
MOVQ 32(SP), SI
|
|
||||||
MOVQ 40(SP), CX
|
|
||||||
MOVQ dst_base+0(FP), R8
|
|
||||||
MOVQ dst_len+8(FP), R9
|
|
||||||
MOVQ R8, R10
|
|
||||||
ADDQ R9, R10
|
|
||||||
MOVQ src_base+24(FP), R11
|
|
||||||
MOVQ src_len+32(FP), R12
|
|
||||||
MOVQ R11, R13
|
|
||||||
ADDQ R12, R13
|
|
||||||
|
|
||||||
// d += length
|
|
||||||
// s += length
|
|
||||||
ADDQ CX, DI
|
|
||||||
ADDQ CX, SI
|
|
||||||
JMP loop
|
|
||||||
|
|
||||||
tagLit60Plus:
|
|
||||||
// !!! This fragment does the
|
|
||||||
//
|
|
||||||
// s += x - 58; if uint(s) > uint(len(src)) { etc }
|
|
||||||
//
|
|
||||||
// checks. In the asm version, we code it once instead of once per switch case.
|
|
||||||
ADDQ CX, SI
|
|
||||||
SUBQ $58, SI
|
|
||||||
MOVQ SI, BX
|
|
||||||
SUBQ R11, BX
|
|
||||||
CMPQ BX, R12
|
|
||||||
JA errCorrupt
|
|
||||||
|
|
||||||
// case x == 60:
|
|
||||||
CMPL CX, $61
|
|
||||||
JEQ tagLit61
|
|
||||||
JA tagLit62Plus
|
|
||||||
|
|
||||||
// x = uint32(src[s-1])
|
|
||||||
MOVBLZX -1(SI), CX
|
|
||||||
JMP doLit
|
|
||||||
|
|
||||||
tagLit61:
|
|
||||||
// case x == 61:
|
|
||||||
// x = uint32(src[s-2]) | uint32(src[s-1])<<8
|
|
||||||
MOVWLZX -2(SI), CX
|
|
||||||
JMP doLit
|
|
||||||
|
|
||||||
tagLit62Plus:
|
|
||||||
CMPL CX, $62
|
|
||||||
JA tagLit63
|
|
||||||
|
|
||||||
// case x == 62:
|
|
||||||
// x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
|
|
||||||
MOVWLZX -3(SI), CX
|
|
||||||
MOVBLZX -1(SI), BX
|
|
||||||
SHLL $16, BX
|
|
||||||
ORL BX, CX
|
|
||||||
JMP doLit
|
|
||||||
|
|
||||||
tagLit63:
|
|
||||||
// case x == 63:
|
|
||||||
// x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
|
|
||||||
MOVL -4(SI), CX
|
|
||||||
JMP doLit
|
|
||||||
|
|
||||||
// The code above handles literal tags.
|
|
||||||
// ----------------------------------------
|
|
||||||
// The code below handles copy tags.
|
|
||||||
|
|
||||||
tagCopy2:
|
|
||||||
// case tagCopy2:
|
|
||||||
// s += 3
|
|
||||||
ADDQ $3, SI
|
|
||||||
|
|
||||||
// if uint(s) > uint(len(src)) { etc }
|
|
||||||
MOVQ SI, BX
|
|
||||||
SUBQ R11, BX
|
|
||||||
CMPQ BX, R12
|
|
||||||
JA errCorrupt
|
|
||||||
|
|
||||||
// length = 1 + int(src[s-3])>>2
|
|
||||||
SHRQ $2, CX
|
|
||||||
INCQ CX
|
|
||||||
|
|
||||||
// offset = int(src[s-2]) | int(src[s-1])<<8
|
|
||||||
MOVWQZX -2(SI), DX
|
|
||||||
JMP doCopy
|
|
||||||
|
|
||||||
tagCopy:
|
|
||||||
// We have a copy tag. We assume that:
|
|
||||||
// - BX == src[s] & 0x03
|
|
||||||
// - CX == src[s]
|
|
||||||
CMPQ BX, $2
|
|
||||||
JEQ tagCopy2
|
|
||||||
JA errUC4T
|
|
||||||
|
|
||||||
// case tagCopy1:
|
|
||||||
// s += 2
|
|
||||||
ADDQ $2, SI
|
|
||||||
|
|
||||||
// if uint(s) > uint(len(src)) { etc }
|
|
||||||
MOVQ SI, BX
|
|
||||||
SUBQ R11, BX
|
|
||||||
CMPQ BX, R12
|
|
||||||
JA errCorrupt
|
|
||||||
|
|
||||||
// offset = int(src[s-2])&0xe0<<3 | int(src[s-1])
|
|
||||||
MOVQ CX, DX
|
|
||||||
ANDQ $0xe0, DX
|
|
||||||
SHLQ $3, DX
|
|
||||||
MOVBQZX -1(SI), BX
|
|
||||||
ORQ BX, DX
|
|
||||||
|
|
||||||
// length = 4 + int(src[s-2])>>2&0x7
|
|
||||||
SHRQ $2, CX
|
|
||||||
ANDQ $7, CX
|
|
||||||
ADDQ $4, CX
|
|
||||||
|
|
||||||
doCopy:
|
|
||||||
// This is the end of the outer "switch", when we have a copy tag.
|
|
||||||
//
|
|
||||||
// We assume that:
|
|
||||||
// - CX == length && CX > 0
|
|
||||||
// - DX == offset
|
|
||||||
|
|
||||||
// if offset <= 0 { etc }
|
|
||||||
CMPQ DX, $0
|
|
||||||
JLE errCorrupt
|
|
||||||
|
|
||||||
// if d < offset { etc }
|
|
||||||
MOVQ DI, BX
|
|
||||||
SUBQ R8, BX
|
|
||||||
CMPQ BX, DX
|
|
||||||
JLT errCorrupt
|
|
||||||
|
|
||||||
// if length > len(dst)-d { etc }
|
|
||||||
MOVQ R10, BX
|
|
||||||
SUBQ DI, BX
|
|
||||||
CMPQ CX, BX
|
|
||||||
JGT errCorrupt
|
|
||||||
|
|
||||||
// forwardCopy(dst[d:d+length], dst[d-offset:]); d += length
|
|
||||||
//
|
|
||||||
// Set:
|
|
||||||
// - R14 = len(dst)-d
|
|
||||||
// - R15 = &dst[d-offset]
|
|
||||||
MOVQ R10, R14
|
|
||||||
SUBQ DI, R14
|
|
||||||
MOVQ DI, R15
|
|
||||||
SUBQ DX, R15
|
|
||||||
|
|
||||||
// !!! Try a faster technique for short (16 or fewer bytes) forward copies.
|
|
||||||
//
|
|
||||||
// First, try using two 8-byte load/stores, similar to the doLit technique
|
|
||||||
// above. Even if dst[d:d+length] and dst[d-offset:] can overlap, this is
|
|
||||||
// still OK if offset >= 8. Note that this has to be two 8-byte load/stores
|
|
||||||
// and not one 16-byte load/store, and the first store has to be before the
|
|
||||||
// second load, due to the overlap if offset is in the range [8, 16).
|
|
||||||
//
|
|
||||||
// if length > 16 || offset < 8 || len(dst)-d < 16 {
|
|
||||||
// goto slowForwardCopy
|
|
||||||
// }
|
|
||||||
// copy 16 bytes
|
|
||||||
// d += length
|
|
||||||
CMPQ CX, $16
|
|
||||||
JGT slowForwardCopy
|
|
||||||
CMPQ DX, $8
|
|
||||||
JLT slowForwardCopy
|
|
||||||
CMPQ R14, $16
|
|
||||||
JLT slowForwardCopy
|
|
||||||
MOVQ 0(R15), AX
|
|
||||||
MOVQ AX, 0(DI)
|
|
||||||
MOVQ 8(R15), BX
|
|
||||||
MOVQ BX, 8(DI)
|
|
||||||
ADDQ CX, DI
|
|
||||||
JMP loop
|
|
||||||
|
|
||||||
slowForwardCopy:
|
|
||||||
// !!! If the forward copy is longer than 16 bytes, or if offset < 8, we
|
|
||||||
// can still try 8-byte load stores, provided we can overrun up to 10 extra
|
|
||||||
// bytes. As above, the overrun will be fixed up by subsequent iterations
|
|
||||||
// of the outermost loop.
|
|
||||||
//
|
|
||||||
// The C++ snappy code calls this technique IncrementalCopyFastPath. Its
|
|
||||||
// commentary says:
|
|
||||||
//
|
|
||||||
// ----
|
|
||||||
//
|
|
||||||
// The main part of this loop is a simple copy of eight bytes at a time
|
|
||||||
// until we've copied (at least) the requested amount of bytes. However,
|
|
||||||
// if d and d-offset are less than eight bytes apart (indicating a
|
|
||||||
// repeating pattern of length < 8), we first need to expand the pattern in
|
|
||||||
// order to get the correct results. For instance, if the buffer looks like
|
|
||||||
// this, with the eight-byte <d-offset> and <d> patterns marked as
|
|
||||||
// intervals:
|
|
||||||
//
|
|
||||||
// abxxxxxxxxxxxx
|
|
||||||
// [------] d-offset
|
|
||||||
// [------] d
|
|
||||||
//
|
|
||||||
// a single eight-byte copy from <d-offset> to <d> will repeat the pattern
|
|
||||||
// once, after which we can move <d> two bytes without moving <d-offset>:
|
|
||||||
//
|
|
||||||
// ababxxxxxxxxxx
|
|
||||||
// [------] d-offset
|
|
||||||
// [------] d
|
|
||||||
//
|
|
||||||
// and repeat the exercise until the two no longer overlap.
|
|
||||||
//
|
|
||||||
// This allows us to do very well in the special case of one single byte
|
|
||||||
// repeated many times, without taking a big hit for more general cases.
|
|
||||||
//
|
|
||||||
// The worst case of extra writing past the end of the match occurs when
|
|
||||||
// offset == 1 and length == 1; the last copy will read from byte positions
|
|
||||||
// [0..7] and write to [4..11], whereas it was only supposed to write to
|
|
||||||
// position 1. Thus, ten excess bytes.
|
|
||||||
//
|
|
||||||
// ----
|
|
||||||
//
|
|
||||||
// That "10 byte overrun" worst case is confirmed by Go's
|
|
||||||
// TestSlowForwardCopyOverrun, which also tests the fixUpSlowForwardCopy
|
|
||||||
// and finishSlowForwardCopy algorithm.
|
|
||||||
//
|
|
||||||
// if length > len(dst)-d-10 {
|
|
||||||
// goto verySlowForwardCopy
|
|
||||||
// }
|
|
||||||
SUBQ $10, R14
|
|
||||||
CMPQ CX, R14
|
|
||||||
JGT verySlowForwardCopy
|
|
||||||
|
|
||||||
makeOffsetAtLeast8:
|
|
||||||
// !!! As above, expand the pattern so that offset >= 8 and we can use
|
|
||||||
// 8-byte load/stores.
|
|
||||||
//
|
|
||||||
// for offset < 8 {
|
|
||||||
// copy 8 bytes from dst[d-offset:] to dst[d:]
|
|
||||||
// length -= offset
|
|
||||||
// d += offset
|
|
||||||
// offset += offset
|
|
||||||
// // The two previous lines together means that d-offset, and therefore
|
|
||||||
// // R15, is unchanged.
|
|
||||||
// }
|
|
||||||
CMPQ DX, $8
|
|
||||||
JGE fixUpSlowForwardCopy
|
|
||||||
MOVQ (R15), BX
|
|
||||||
MOVQ BX, (DI)
|
|
||||||
SUBQ DX, CX
|
|
||||||
ADDQ DX, DI
|
|
||||||
ADDQ DX, DX
|
|
||||||
JMP makeOffsetAtLeast8
|
|
||||||
|
|
||||||
fixUpSlowForwardCopy:
|
|
||||||
// !!! Add length (which might be negative now) to d (implied by DI being
|
|
||||||
// &dst[d]) so that d ends up at the right place when we jump back to the
|
|
||||||
// top of the loop. Before we do that, though, we save DI to AX so that, if
|
|
||||||
// length is positive, copying the remaining length bytes will write to the
|
|
||||||
// right place.
|
|
||||||
MOVQ DI, AX
|
|
||||||
ADDQ CX, DI
|
|
||||||
|
|
||||||
finishSlowForwardCopy:
|
|
||||||
// !!! Repeat 8-byte load/stores until length <= 0. Ending with a negative
|
|
||||||
// length means that we overrun, but as above, that will be fixed up by
|
|
||||||
// subsequent iterations of the outermost loop.
|
|
||||||
CMPQ CX, $0
|
|
||||||
JLE loop
|
|
||||||
MOVQ (R15), BX
|
|
||||||
MOVQ BX, (AX)
|
|
||||||
ADDQ $8, R15
|
|
||||||
ADDQ $8, AX
|
|
||||||
SUBQ $8, CX
|
|
||||||
JMP finishSlowForwardCopy
|
|
||||||
|
|
||||||
verySlowForwardCopy:
|
|
||||||
// verySlowForwardCopy is a simple implementation of forward copy. In C
|
|
||||||
// parlance, this is a do/while loop instead of a while loop, since we know
|
|
||||||
// that length > 0. In Go syntax:
|
|
||||||
//
|
|
||||||
// for {
|
|
||||||
// dst[d] = dst[d - offset]
|
|
||||||
// d++
|
|
||||||
// length--
|
|
||||||
// if length == 0 {
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
MOVB (R15), BX
|
|
||||||
MOVB BX, (DI)
|
|
||||||
INCQ R15
|
|
||||||
INCQ DI
|
|
||||||
DECQ CX
|
|
||||||
JNZ verySlowForwardCopy
|
|
||||||
JMP loop
|
|
||||||
|
|
||||||
// The code above handles copy tags.
|
|
||||||
// ----------------------------------------
|
|
||||||
|
|
||||||
end:
|
|
||||||
// This is the end of the "for s < len(src)".
|
|
||||||
//
|
|
||||||
// if d != len(dst) { etc }
|
|
||||||
CMPQ DI, R10
|
|
||||||
JNE errCorrupt
|
|
||||||
|
|
||||||
// return 0
|
|
||||||
MOVQ $0, ret+48(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
errCorrupt:
|
|
||||||
// return decodeErrCodeCorrupt
|
|
||||||
MOVQ $1, ret+48(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
errUC4T:
|
|
||||||
// return decodeErrCodeUnsupportedCopy4Tag
|
|
||||||
MOVQ $3, ret+48(FP)
|
|
||||||
RET
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
// decode writes the decoding of src to dst. It assumes that the varint-encoded
|
|
||||||
// length of the decompressed bytes has already been read, and that len(dst)
|
|
||||||
// equals that length.
|
|
||||||
//
|
|
||||||
// It returns 0 on success or a decodeErrCodeXxx error code on failure.
|
|
||||||
func decode(dst, src []byte) int {
|
|
||||||
var d, s, offset, length int
|
|
||||||
for s < len(src) {
|
|
||||||
switch src[s] & 0x03 {
|
|
||||||
case tagLiteral:
|
|
||||||
x := uint32(src[s] >> 2)
|
|
||||||
switch {
|
|
||||||
case x < 60:
|
|
||||||
s++
|
|
||||||
case x == 60:
|
|
||||||
s += 2
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
x = uint32(src[s-1])
|
|
||||||
case x == 61:
|
|
||||||
s += 3
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
x = uint32(src[s-2]) | uint32(src[s-1])<<8
|
|
||||||
case x == 62:
|
|
||||||
s += 4
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
|
|
||||||
case x == 63:
|
|
||||||
s += 5
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
|
|
||||||
}
|
|
||||||
length = int(x) + 1
|
|
||||||
if length <= 0 {
|
|
||||||
return decodeErrCodeUnsupportedLiteralLength
|
|
||||||
}
|
|
||||||
if length > len(dst)-d || length > len(src)-s {
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
copy(dst[d:], src[s:s+length])
|
|
||||||
d += length
|
|
||||||
s += length
|
|
||||||
continue
|
|
||||||
|
|
||||||
case tagCopy1:
|
|
||||||
s += 2
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
length = 4 + int(src[s-2])>>2&0x7
|
|
||||||
offset = int(src[s-2])&0xe0<<3 | int(src[s-1])
|
|
||||||
|
|
||||||
case tagCopy2:
|
|
||||||
s += 3
|
|
||||||
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
length = 1 + int(src[s-3])>>2
|
|
||||||
offset = int(src[s-2]) | int(src[s-1])<<8
|
|
||||||
|
|
||||||
case tagCopy4:
|
|
||||||
return decodeErrCodeUnsupportedCopy4Tag
|
|
||||||
}
|
|
||||||
|
|
||||||
if offset <= 0 || d < offset || length > len(dst)-d {
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
// Copy from an earlier sub-slice of dst to a later sub-slice. Unlike
|
|
||||||
// the built-in copy function, this byte-by-byte copy always runs
|
|
||||||
// forwards, even if the slices overlap. Conceptually, this is:
|
|
||||||
//
|
|
||||||
// d += forwardCopy(dst[d:d+length], dst[d-offset:])
|
|
||||||
for end := d + length; d != end; d++ {
|
|
||||||
dst[d] = dst[d-offset]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if d != len(dst) {
|
|
||||||
return decodeErrCodeCorrupt
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
@ -1,285 +0,0 @@
|
||||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
|
||||||
// slice of dst if dst was large enough to hold the entire encoded block.
|
|
||||||
// Otherwise, a newly allocated slice will be returned.
|
|
||||||
//
|
|
||||||
// The dst and src must not overlap. It is valid to pass a nil dst.
|
|
||||||
func Encode(dst, src []byte) []byte {
|
|
||||||
if n := MaxEncodedLen(len(src)); n < 0 {
|
|
||||||
panic(ErrTooLarge)
|
|
||||||
} else if len(dst) < n {
|
|
||||||
dst = make([]byte, n)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The block starts with the varint-encoded length of the decompressed bytes.
|
|
||||||
d := binary.PutUvarint(dst, uint64(len(src)))
|
|
||||||
|
|
||||||
for len(src) > 0 {
|
|
||||||
p := src
|
|
||||||
src = nil
|
|
||||||
if len(p) > maxBlockSize {
|
|
||||||
p, src = p[:maxBlockSize], p[maxBlockSize:]
|
|
||||||
}
|
|
||||||
if len(p) < minNonLiteralBlockSize {
|
|
||||||
d += emitLiteral(dst[d:], p)
|
|
||||||
} else {
|
|
||||||
d += encodeBlock(dst[d:], p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst[:d]
|
|
||||||
}
|
|
||||||
|
|
||||||
// inputMargin is the minimum number of extra input bytes to keep, inside
|
|
||||||
// encodeBlock's inner loop. On some architectures, this margin lets us
|
|
||||||
// implement a fast path for emitLiteral, where the copy of short (<= 16 byte)
|
|
||||||
// literals can be implemented as a single load to and store from a 16-byte
|
|
||||||
// register. That literal's actual length can be as short as 1 byte, so this
|
|
||||||
// can copy up to 15 bytes too much, but that's OK as subsequent iterations of
|
|
||||||
// the encoding loop will fix up the copy overrun, and this inputMargin ensures
|
|
||||||
// that we don't overrun the dst and src buffers.
|
|
||||||
const inputMargin = 16 - 1
|
|
||||||
|
|
||||||
// minNonLiteralBlockSize is the minimum size of the input to encodeBlock that
|
|
||||||
// could be encoded with a copy tag. This is the minimum with respect to the
|
|
||||||
// algorithm used by encodeBlock, not a minimum enforced by the file format.
|
|
||||||
//
|
|
||||||
// The encoded output must start with at least a 1 byte literal, as there are
|
|
||||||
// no previous bytes to copy. A minimal (1 byte) copy after that, generated
|
|
||||||
// from an emitCopy call in encodeBlock's main loop, would require at least
|
|
||||||
// another inputMargin bytes, for the reason above: we want any emitLiteral
|
|
||||||
// calls inside encodeBlock's main loop to use the fast path if possible, which
|
|
||||||
// requires being able to overrun by inputMargin bytes. Thus,
|
|
||||||
// minNonLiteralBlockSize equals 1 + 1 + inputMargin.
|
|
||||||
//
|
|
||||||
// The C++ code doesn't use this exact threshold, but it could, as discussed at
|
|
||||||
// https://groups.google.com/d/topic/snappy-compression/oGbhsdIJSJ8/discussion
|
|
||||||
// The difference between Go (2+inputMargin) and C++ (inputMargin) is purely an
|
|
||||||
// optimization. It should not affect the encoded form. This is tested by
|
|
||||||
// TestSameEncodingAsCppShortCopies.
|
|
||||||
const minNonLiteralBlockSize = 1 + 1 + inputMargin
|
|
||||||
|
|
||||||
// MaxEncodedLen returns the maximum length of a snappy block, given its
|
|
||||||
// uncompressed length.
|
|
||||||
//
|
|
||||||
// It will return a negative value if srcLen is too large to encode.
|
|
||||||
func MaxEncodedLen(srcLen int) int {
|
|
||||||
n := uint64(srcLen)
|
|
||||||
if n > 0xffffffff {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
// Compressed data can be defined as:
|
|
||||||
// compressed := item* literal*
|
|
||||||
// item := literal* copy
|
|
||||||
//
|
|
||||||
// The trailing literal sequence has a space blowup of at most 62/60
|
|
||||||
// since a literal of length 60 needs one tag byte + one extra byte
|
|
||||||
// for length information.
|
|
||||||
//
|
|
||||||
// Item blowup is trickier to measure. Suppose the "copy" op copies
|
|
||||||
// 4 bytes of data. Because of a special check in the encoding code,
|
|
||||||
// we produce a 4-byte copy only if the offset is < 65536. Therefore
|
|
||||||
// the copy op takes 3 bytes to encode, and this type of item leads
|
|
||||||
// to at most the 62/60 blowup for representing literals.
|
|
||||||
//
|
|
||||||
// Suppose the "copy" op copies 5 bytes of data. If the offset is big
|
|
||||||
// enough, it will take 5 bytes to encode the copy op. Therefore the
|
|
||||||
// worst case here is a one-byte literal followed by a five-byte copy.
|
|
||||||
// That is, 6 bytes of input turn into 7 bytes of "compressed" data.
|
|
||||||
//
|
|
||||||
// This last factor dominates the blowup, so the final estimate is:
|
|
||||||
n = 32 + n + n/6
|
|
||||||
if n > 0xffffffff {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
return int(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
var errClosed = errors.New("snappy: Writer is closed")
|
|
||||||
|
|
||||||
// NewWriter returns a new Writer that compresses to w.
|
|
||||||
//
|
|
||||||
// The Writer returned does not buffer writes. There is no need to Flush or
|
|
||||||
// Close such a Writer.
|
|
||||||
//
|
|
||||||
// Deprecated: the Writer returned is not suitable for many small writes, only
|
|
||||||
// for few large writes. Use NewBufferedWriter instead, which is efficient
|
|
||||||
// regardless of the frequency and shape of the writes, and remember to Close
|
|
||||||
// that Writer when done.
|
|
||||||
func NewWriter(w io.Writer) *Writer {
|
|
||||||
return &Writer{
|
|
||||||
w: w,
|
|
||||||
obuf: make([]byte, obufLen),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBufferedWriter returns a new Writer that compresses to w, using the
|
|
||||||
// framing format described at
|
|
||||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
|
||||||
//
|
|
||||||
// The Writer returned buffers writes. Users must call Close to guarantee all
|
|
||||||
// data has been forwarded to the underlying io.Writer. They may also call
|
|
||||||
// Flush zero or more times before calling Close.
|
|
||||||
func NewBufferedWriter(w io.Writer) *Writer {
|
|
||||||
return &Writer{
|
|
||||||
w: w,
|
|
||||||
ibuf: make([]byte, 0, maxBlockSize),
|
|
||||||
obuf: make([]byte, obufLen),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writer is an io.Writer than can write Snappy-compressed bytes.
|
|
||||||
type Writer struct {
|
|
||||||
w io.Writer
|
|
||||||
err error
|
|
||||||
|
|
||||||
// ibuf is a buffer for the incoming (uncompressed) bytes.
|
|
||||||
//
|
|
||||||
// Its use is optional. For backwards compatibility, Writers created by the
|
|
||||||
// NewWriter function have ibuf == nil, do not buffer incoming bytes, and
|
|
||||||
// therefore do not need to be Flush'ed or Close'd.
|
|
||||||
ibuf []byte
|
|
||||||
|
|
||||||
// obuf is a buffer for the outgoing (compressed) bytes.
|
|
||||||
obuf []byte
|
|
||||||
|
|
||||||
// wroteStreamHeader is whether we have written the stream header.
|
|
||||||
wroteStreamHeader bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset discards the writer's state and switches the Snappy writer to write to
|
|
||||||
// w. This permits reusing a Writer rather than allocating a new one.
|
|
||||||
func (w *Writer) Reset(writer io.Writer) {
|
|
||||||
w.w = writer
|
|
||||||
w.err = nil
|
|
||||||
if w.ibuf != nil {
|
|
||||||
w.ibuf = w.ibuf[:0]
|
|
||||||
}
|
|
||||||
w.wroteStreamHeader = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write satisfies the io.Writer interface.
|
|
||||||
func (w *Writer) Write(p []byte) (nRet int, errRet error) {
|
|
||||||
if w.ibuf == nil {
|
|
||||||
// Do not buffer incoming bytes. This does not perform or compress well
|
|
||||||
// if the caller of Writer.Write writes many small slices. This
|
|
||||||
// behavior is therefore deprecated, but still supported for backwards
|
|
||||||
// compatibility with code that doesn't explicitly Flush or Close.
|
|
||||||
return w.write(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The remainder of this method is based on bufio.Writer.Write from the
|
|
||||||
// standard library.
|
|
||||||
|
|
||||||
for len(p) > (cap(w.ibuf)-len(w.ibuf)) && w.err == nil {
|
|
||||||
var n int
|
|
||||||
if len(w.ibuf) == 0 {
|
|
||||||
// Large write, empty buffer.
|
|
||||||
// Write directly from p to avoid copy.
|
|
||||||
n, _ = w.write(p)
|
|
||||||
} else {
|
|
||||||
n = copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)
|
|
||||||
w.ibuf = w.ibuf[:len(w.ibuf)+n]
|
|
||||||
w.Flush()
|
|
||||||
}
|
|
||||||
nRet += n
|
|
||||||
p = p[n:]
|
|
||||||
}
|
|
||||||
if w.err != nil {
|
|
||||||
return nRet, w.err
|
|
||||||
}
|
|
||||||
n := copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)
|
|
||||||
w.ibuf = w.ibuf[:len(w.ibuf)+n]
|
|
||||||
nRet += n
|
|
||||||
return nRet, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Writer) write(p []byte) (nRet int, errRet error) {
|
|
||||||
if w.err != nil {
|
|
||||||
return 0, w.err
|
|
||||||
}
|
|
||||||
for len(p) > 0 {
|
|
||||||
obufStart := len(magicChunk)
|
|
||||||
if !w.wroteStreamHeader {
|
|
||||||
w.wroteStreamHeader = true
|
|
||||||
copy(w.obuf, magicChunk)
|
|
||||||
obufStart = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var uncompressed []byte
|
|
||||||
if len(p) > maxBlockSize {
|
|
||||||
uncompressed, p = p[:maxBlockSize], p[maxBlockSize:]
|
|
||||||
} else {
|
|
||||||
uncompressed, p = p, nil
|
|
||||||
}
|
|
||||||
checksum := crc(uncompressed)
|
|
||||||
|
|
||||||
// Compress the buffer, discarding the result if the improvement
|
|
||||||
// isn't at least 12.5%.
|
|
||||||
compressed := Encode(w.obuf[obufHeaderLen:], uncompressed)
|
|
||||||
chunkType := uint8(chunkTypeCompressedData)
|
|
||||||
chunkLen := 4 + len(compressed)
|
|
||||||
obufEnd := obufHeaderLen + len(compressed)
|
|
||||||
if len(compressed) >= len(uncompressed)-len(uncompressed)/8 {
|
|
||||||
chunkType = chunkTypeUncompressedData
|
|
||||||
chunkLen = 4 + len(uncompressed)
|
|
||||||
obufEnd = obufHeaderLen
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill in the per-chunk header that comes before the body.
|
|
||||||
w.obuf[len(magicChunk)+0] = chunkType
|
|
||||||
w.obuf[len(magicChunk)+1] = uint8(chunkLen >> 0)
|
|
||||||
w.obuf[len(magicChunk)+2] = uint8(chunkLen >> 8)
|
|
||||||
w.obuf[len(magicChunk)+3] = uint8(chunkLen >> 16)
|
|
||||||
w.obuf[len(magicChunk)+4] = uint8(checksum >> 0)
|
|
||||||
w.obuf[len(magicChunk)+5] = uint8(checksum >> 8)
|
|
||||||
w.obuf[len(magicChunk)+6] = uint8(checksum >> 16)
|
|
||||||
w.obuf[len(magicChunk)+7] = uint8(checksum >> 24)
|
|
||||||
|
|
||||||
if _, err := w.w.Write(w.obuf[obufStart:obufEnd]); err != nil {
|
|
||||||
w.err = err
|
|
||||||
return nRet, err
|
|
||||||
}
|
|
||||||
if chunkType == chunkTypeUncompressedData {
|
|
||||||
if _, err := w.w.Write(uncompressed); err != nil {
|
|
||||||
w.err = err
|
|
||||||
return nRet, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nRet += len(uncompressed)
|
|
||||||
}
|
|
||||||
return nRet, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flush flushes the Writer to its underlying io.Writer.
|
|
||||||
func (w *Writer) Flush() error {
|
|
||||||
if w.err != nil {
|
|
||||||
return w.err
|
|
||||||
}
|
|
||||||
if len(w.ibuf) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
w.write(w.ibuf)
|
|
||||||
w.ibuf = w.ibuf[:0]
|
|
||||||
return w.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close calls Flush and then closes the Writer.
|
|
||||||
func (w *Writer) Close() error {
|
|
||||||
w.Flush()
|
|
||||||
ret := w.err
|
|
||||||
if w.err == nil {
|
|
||||||
w.err = errClosed
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
// emitLiteral has the same semantics as in encode_other.go.
|
|
||||||
//
|
|
||||||
//go:noescape
|
|
||||||
func emitLiteral(dst, lit []byte) int
|
|
||||||
|
|
||||||
// emitCopy has the same semantics as in encode_other.go.
|
|
||||||
//
|
|
||||||
//go:noescape
|
|
||||||
func emitCopy(dst []byte, offset, length int) int
|
|
||||||
|
|
||||||
// extendMatch has the same semantics as in encode_other.go.
|
|
||||||
//
|
|
||||||
//go:noescape
|
|
||||||
func extendMatch(src []byte, i, j int) int
|
|
||||||
|
|
||||||
// encodeBlock has the same semantics as in encode_other.go.
|
|
||||||
//
|
|
||||||
//go:noescape
|
|
||||||
func encodeBlock(dst, src []byte) (d int)
|
|
||||||
|
|
@ -1,730 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !appengine
|
|
||||||
// +build gc
|
|
||||||
// +build !noasm
|
|
||||||
|
|
||||||
#include "textflag.h"
|
|
||||||
|
|
||||||
// The XXX lines assemble on Go 1.4, 1.5 and 1.7, but not 1.6, due to a
|
|
||||||
// Go toolchain regression. See https://github.com/golang/go/issues/15426 and
|
|
||||||
// https://github.com/golang/snappy/issues/29
|
|
||||||
//
|
|
||||||
// As a workaround, the package was built with a known good assembler, and
|
|
||||||
// those instructions were disassembled by "objdump -d" to yield the
|
|
||||||
// 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
|
||||||
// style comments, in AT&T asm syntax. Note that rsp here is a physical
|
|
||||||
// register, not Go/asm's SP pseudo-register (see https://golang.org/doc/asm).
|
|
||||||
// The instructions were then encoded as "BYTE $0x.." sequences, which assemble
|
|
||||||
// fine on Go 1.6.
|
|
||||||
|
|
||||||
// The asm code generally follows the pure Go code in encode_other.go, except
|
|
||||||
// where marked with a "!!!".
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// func emitLiteral(dst, lit []byte) int
|
|
||||||
//
|
|
||||||
// All local variables fit into registers. The register allocation:
|
|
||||||
// - AX len(lit)
|
|
||||||
// - BX n
|
|
||||||
// - DX return value
|
|
||||||
// - DI &dst[i]
|
|
||||||
// - R10 &lit[0]
|
|
||||||
//
|
|
||||||
// The 24 bytes of stack space is to call runtime·memmove.
|
|
||||||
//
|
|
||||||
// The unusual register allocation of local variables, such as R10 for the
|
|
||||||
// source pointer, matches the allocation used at the call site in encodeBlock,
|
|
||||||
// which makes it easier to manually inline this function.
|
|
||||||
TEXT ·emitLiteral(SB), NOSPLIT, $24-56
|
|
||||||
MOVQ dst_base+0(FP), DI
|
|
||||||
MOVQ lit_base+24(FP), R10
|
|
||||||
MOVQ lit_len+32(FP), AX
|
|
||||||
MOVQ AX, DX
|
|
||||||
MOVL AX, BX
|
|
||||||
SUBL $1, BX
|
|
||||||
|
|
||||||
CMPL BX, $60
|
|
||||||
JLT oneByte
|
|
||||||
CMPL BX, $256
|
|
||||||
JLT twoBytes
|
|
||||||
|
|
||||||
threeBytes:
|
|
||||||
MOVB $0xf4, 0(DI)
|
|
||||||
MOVW BX, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
ADDQ $3, DX
|
|
||||||
JMP memmove
|
|
||||||
|
|
||||||
twoBytes:
|
|
||||||
MOVB $0xf0, 0(DI)
|
|
||||||
MOVB BX, 1(DI)
|
|
||||||
ADDQ $2, DI
|
|
||||||
ADDQ $2, DX
|
|
||||||
JMP memmove
|
|
||||||
|
|
||||||
oneByte:
|
|
||||||
SHLB $2, BX
|
|
||||||
MOVB BX, 0(DI)
|
|
||||||
ADDQ $1, DI
|
|
||||||
ADDQ $1, DX
|
|
||||||
|
|
||||||
memmove:
|
|
||||||
MOVQ DX, ret+48(FP)
|
|
||||||
|
|
||||||
// copy(dst[i:], lit)
|
|
||||||
//
|
|
||||||
// This means calling runtime·memmove(&dst[i], &lit[0], len(lit)), so we push
|
|
||||||
// DI, R10 and AX as arguments.
|
|
||||||
MOVQ DI, 0(SP)
|
|
||||||
MOVQ R10, 8(SP)
|
|
||||||
MOVQ AX, 16(SP)
|
|
||||||
CALL runtime·memmove(SB)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// func emitCopy(dst []byte, offset, length int) int
|
|
||||||
//
|
|
||||||
// All local variables fit into registers. The register allocation:
|
|
||||||
// - AX length
|
|
||||||
// - SI &dst[0]
|
|
||||||
// - DI &dst[i]
|
|
||||||
// - R11 offset
|
|
||||||
//
|
|
||||||
// The unusual register allocation of local variables, such as R11 for the
|
|
||||||
// offset, matches the allocation used at the call site in encodeBlock, which
|
|
||||||
// makes it easier to manually inline this function.
|
|
||||||
TEXT ·emitCopy(SB), NOSPLIT, $0-48
|
|
||||||
MOVQ dst_base+0(FP), DI
|
|
||||||
MOVQ DI, SI
|
|
||||||
MOVQ offset+24(FP), R11
|
|
||||||
MOVQ length+32(FP), AX
|
|
||||||
|
|
||||||
loop0:
|
|
||||||
// for length >= 68 { etc }
|
|
||||||
CMPL AX, $68
|
|
||||||
JLT step1
|
|
||||||
|
|
||||||
// Emit a length 64 copy, encoded as 3 bytes.
|
|
||||||
MOVB $0xfe, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
SUBL $64, AX
|
|
||||||
JMP loop0
|
|
||||||
|
|
||||||
step1:
|
|
||||||
// if length > 64 { etc }
|
|
||||||
CMPL AX, $64
|
|
||||||
JLE step2
|
|
||||||
|
|
||||||
// Emit a length 60 copy, encoded as 3 bytes.
|
|
||||||
MOVB $0xee, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
SUBL $60, AX
|
|
||||||
|
|
||||||
step2:
|
|
||||||
// if length >= 12 || offset >= 2048 { goto step3 }
|
|
||||||
CMPL AX, $12
|
|
||||||
JGE step3
|
|
||||||
CMPL R11, $2048
|
|
||||||
JGE step3
|
|
||||||
|
|
||||||
// Emit the remaining copy, encoded as 2 bytes.
|
|
||||||
MOVB R11, 1(DI)
|
|
||||||
SHRL $8, R11
|
|
||||||
SHLB $5, R11
|
|
||||||
SUBB $4, AX
|
|
||||||
SHLB $2, AX
|
|
||||||
ORB AX, R11
|
|
||||||
ORB $1, R11
|
|
||||||
MOVB R11, 0(DI)
|
|
||||||
ADDQ $2, DI
|
|
||||||
|
|
||||||
// Return the number of bytes written.
|
|
||||||
SUBQ SI, DI
|
|
||||||
MOVQ DI, ret+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
step3:
|
|
||||||
// Emit the remaining copy, encoded as 3 bytes.
|
|
||||||
SUBL $1, AX
|
|
||||||
SHLB $2, AX
|
|
||||||
ORB $2, AX
|
|
||||||
MOVB AX, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
|
|
||||||
// Return the number of bytes written.
|
|
||||||
SUBQ SI, DI
|
|
||||||
MOVQ DI, ret+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// func extendMatch(src []byte, i, j int) int
|
|
||||||
//
|
|
||||||
// All local variables fit into registers. The register allocation:
|
|
||||||
// - DX &src[0]
|
|
||||||
// - SI &src[j]
|
|
||||||
// - R13 &src[len(src) - 8]
|
|
||||||
// - R14 &src[len(src)]
|
|
||||||
// - R15 &src[i]
|
|
||||||
//
|
|
||||||
// The unusual register allocation of local variables, such as R15 for a source
|
|
||||||
// pointer, matches the allocation used at the call site in encodeBlock, which
|
|
||||||
// makes it easier to manually inline this function.
|
|
||||||
TEXT ·extendMatch(SB), NOSPLIT, $0-48
|
|
||||||
MOVQ src_base+0(FP), DX
|
|
||||||
MOVQ src_len+8(FP), R14
|
|
||||||
MOVQ i+24(FP), R15
|
|
||||||
MOVQ j+32(FP), SI
|
|
||||||
ADDQ DX, R14
|
|
||||||
ADDQ DX, R15
|
|
||||||
ADDQ DX, SI
|
|
||||||
MOVQ R14, R13
|
|
||||||
SUBQ $8, R13
|
|
||||||
|
|
||||||
cmp8:
|
|
||||||
// As long as we are 8 or more bytes before the end of src, we can load and
|
|
||||||
// compare 8 bytes at a time. If those 8 bytes are equal, repeat.
|
|
||||||
CMPQ SI, R13
|
|
||||||
JA cmp1
|
|
||||||
MOVQ (R15), AX
|
|
||||||
MOVQ (SI), BX
|
|
||||||
CMPQ AX, BX
|
|
||||||
JNE bsf
|
|
||||||
ADDQ $8, R15
|
|
||||||
ADDQ $8, SI
|
|
||||||
JMP cmp8
|
|
||||||
|
|
||||||
bsf:
|
|
||||||
// If those 8 bytes were not equal, XOR the two 8 byte values, and return
|
|
||||||
// the index of the first byte that differs. The BSF instruction finds the
|
|
||||||
// least significant 1 bit, the amd64 architecture is little-endian, and
|
|
||||||
// the shift by 3 converts a bit index to a byte index.
|
|
||||||
XORQ AX, BX
|
|
||||||
BSFQ BX, BX
|
|
||||||
SHRQ $3, BX
|
|
||||||
ADDQ BX, SI
|
|
||||||
|
|
||||||
// Convert from &src[ret] to ret.
|
|
||||||
SUBQ DX, SI
|
|
||||||
MOVQ SI, ret+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
cmp1:
|
|
||||||
// In src's tail, compare 1 byte at a time.
|
|
||||||
CMPQ SI, R14
|
|
||||||
JAE extendMatchEnd
|
|
||||||
MOVB (R15), AX
|
|
||||||
MOVB (SI), BX
|
|
||||||
CMPB AX, BX
|
|
||||||
JNE extendMatchEnd
|
|
||||||
ADDQ $1, R15
|
|
||||||
ADDQ $1, SI
|
|
||||||
JMP cmp1
|
|
||||||
|
|
||||||
extendMatchEnd:
|
|
||||||
// Convert from &src[ret] to ret.
|
|
||||||
SUBQ DX, SI
|
|
||||||
MOVQ SI, ret+40(FP)
|
|
||||||
RET
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// func encodeBlock(dst, src []byte) (d int)
|
|
||||||
//
|
|
||||||
// All local variables fit into registers, other than "var table". The register
|
|
||||||
// allocation:
|
|
||||||
// - AX . .
|
|
||||||
// - BX . .
|
|
||||||
// - CX 56 shift (note that amd64 shifts by non-immediates must use CX).
|
|
||||||
// - DX 64 &src[0], tableSize
|
|
||||||
// - SI 72 &src[s]
|
|
||||||
// - DI 80 &dst[d]
|
|
||||||
// - R9 88 sLimit
|
|
||||||
// - R10 . &src[nextEmit]
|
|
||||||
// - R11 96 prevHash, currHash, nextHash, offset
|
|
||||||
// - R12 104 &src[base], skip
|
|
||||||
// - R13 . &src[nextS], &src[len(src) - 8]
|
|
||||||
// - R14 . len(src), bytesBetweenHashLookups, &src[len(src)], x
|
|
||||||
// - R15 112 candidate
|
|
||||||
//
|
|
||||||
// The second column (56, 64, etc) is the stack offset to spill the registers
|
|
||||||
// when calling other functions. We could pack this slightly tighter, but it's
|
|
||||||
// simpler to have a dedicated spill map independent of the function called.
|
|
||||||
//
|
|
||||||
// "var table [maxTableSize]uint16" takes up 32768 bytes of stack space. An
|
|
||||||
// extra 56 bytes, to call other functions, and an extra 64 bytes, to spill
|
|
||||||
// local variables (registers) during calls gives 32768 + 56 + 64 = 32888.
|
|
||||||
TEXT ·encodeBlock(SB), 0, $32888-56
|
|
||||||
MOVQ dst_base+0(FP), DI
|
|
||||||
MOVQ src_base+24(FP), SI
|
|
||||||
MOVQ src_len+32(FP), R14
|
|
||||||
|
|
||||||
// shift, tableSize := uint32(32-8), 1<<8
|
|
||||||
MOVQ $24, CX
|
|
||||||
MOVQ $256, DX
|
|
||||||
|
|
||||||
calcShift:
|
|
||||||
// for ; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 {
|
|
||||||
// shift--
|
|
||||||
// }
|
|
||||||
CMPQ DX, $16384
|
|
||||||
JGE varTable
|
|
||||||
CMPQ DX, R14
|
|
||||||
JGE varTable
|
|
||||||
SUBQ $1, CX
|
|
||||||
SHLQ $1, DX
|
|
||||||
JMP calcShift
|
|
||||||
|
|
||||||
varTable:
|
|
||||||
// var table [maxTableSize]uint16
|
|
||||||
//
|
|
||||||
// In the asm code, unlike the Go code, we can zero-initialize only the
|
|
||||||
// first tableSize elements. Each uint16 element is 2 bytes and each MOVOU
|
|
||||||
// writes 16 bytes, so we can do only tableSize/8 writes instead of the
|
|
||||||
// 2048 writes that would zero-initialize all of table's 32768 bytes.
|
|
||||||
SHRQ $3, DX
|
|
||||||
LEAQ table-32768(SP), BX
|
|
||||||
PXOR X0, X0
|
|
||||||
|
|
||||||
memclr:
|
|
||||||
MOVOU X0, 0(BX)
|
|
||||||
ADDQ $16, BX
|
|
||||||
SUBQ $1, DX
|
|
||||||
JNZ memclr
|
|
||||||
|
|
||||||
// !!! DX = &src[0]
|
|
||||||
MOVQ SI, DX
|
|
||||||
|
|
||||||
// sLimit := len(src) - inputMargin
|
|
||||||
MOVQ R14, R9
|
|
||||||
SUBQ $15, R9
|
|
||||||
|
|
||||||
// !!! Pre-emptively spill CX, DX and R9 to the stack. Their values don't
|
|
||||||
// change for the rest of the function.
|
|
||||||
MOVQ CX, 56(SP)
|
|
||||||
MOVQ DX, 64(SP)
|
|
||||||
MOVQ R9, 88(SP)
|
|
||||||
|
|
||||||
// nextEmit := 0
|
|
||||||
MOVQ DX, R10
|
|
||||||
|
|
||||||
// s := 1
|
|
||||||
ADDQ $1, SI
|
|
||||||
|
|
||||||
// nextHash := hash(load32(src, s), shift)
|
|
||||||
MOVL 0(SI), R11
|
|
||||||
IMULL $0x1e35a7bd, R11
|
|
||||||
SHRL CX, R11
|
|
||||||
|
|
||||||
outer:
|
|
||||||
// for { etc }
|
|
||||||
|
|
||||||
// skip := 32
|
|
||||||
MOVQ $32, R12
|
|
||||||
|
|
||||||
// nextS := s
|
|
||||||
MOVQ SI, R13
|
|
||||||
|
|
||||||
// candidate := 0
|
|
||||||
MOVQ $0, R15
|
|
||||||
|
|
||||||
inner0:
|
|
||||||
// for { etc }
|
|
||||||
|
|
||||||
// s := nextS
|
|
||||||
MOVQ R13, SI
|
|
||||||
|
|
||||||
// bytesBetweenHashLookups := skip >> 5
|
|
||||||
MOVQ R12, R14
|
|
||||||
SHRQ $5, R14
|
|
||||||
|
|
||||||
// nextS = s + bytesBetweenHashLookups
|
|
||||||
ADDQ R14, R13
|
|
||||||
|
|
||||||
// skip += bytesBetweenHashLookups
|
|
||||||
ADDQ R14, R12
|
|
||||||
|
|
||||||
// if nextS > sLimit { goto emitRemainder }
|
|
||||||
MOVQ R13, AX
|
|
||||||
SUBQ DX, AX
|
|
||||||
CMPQ AX, R9
|
|
||||||
JA emitRemainder
|
|
||||||
|
|
||||||
// candidate = int(table[nextHash])
|
|
||||||
// XXX: MOVWQZX table-32768(SP)(R11*2), R15
|
|
||||||
// XXX: 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
|
||||||
BYTE $0x4e
|
|
||||||
BYTE $0x0f
|
|
||||||
BYTE $0xb7
|
|
||||||
BYTE $0x7c
|
|
||||||
BYTE $0x5c
|
|
||||||
BYTE $0x78
|
|
||||||
|
|
||||||
// table[nextHash] = uint16(s)
|
|
||||||
MOVQ SI, AX
|
|
||||||
SUBQ DX, AX
|
|
||||||
|
|
||||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
|
||||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
|
||||||
BYTE $0x66
|
|
||||||
BYTE $0x42
|
|
||||||
BYTE $0x89
|
|
||||||
BYTE $0x44
|
|
||||||
BYTE $0x5c
|
|
||||||
BYTE $0x78
|
|
||||||
|
|
||||||
// nextHash = hash(load32(src, nextS), shift)
|
|
||||||
MOVL 0(R13), R11
|
|
||||||
IMULL $0x1e35a7bd, R11
|
|
||||||
SHRL CX, R11
|
|
||||||
|
|
||||||
// if load32(src, s) != load32(src, candidate) { continue } break
|
|
||||||
MOVL 0(SI), AX
|
|
||||||
MOVL (DX)(R15*1), BX
|
|
||||||
CMPL AX, BX
|
|
||||||
JNE inner0
|
|
||||||
|
|
||||||
fourByteMatch:
|
|
||||||
// As per the encode_other.go code:
|
|
||||||
//
|
|
||||||
// A 4-byte match has been found. We'll later see etc.
|
|
||||||
|
|
||||||
// !!! Jump to a fast path for short (<= 16 byte) literals. See the comment
|
|
||||||
// on inputMargin in encode.go.
|
|
||||||
MOVQ SI, AX
|
|
||||||
SUBQ R10, AX
|
|
||||||
CMPQ AX, $16
|
|
||||||
JLE emitLiteralFastPath
|
|
||||||
|
|
||||||
// ----------------------------------------
|
|
||||||
// Begin inline of the emitLiteral call.
|
|
||||||
//
|
|
||||||
// d += emitLiteral(dst[d:], src[nextEmit:s])
|
|
||||||
|
|
||||||
MOVL AX, BX
|
|
||||||
SUBL $1, BX
|
|
||||||
|
|
||||||
CMPL BX, $60
|
|
||||||
JLT inlineEmitLiteralOneByte
|
|
||||||
CMPL BX, $256
|
|
||||||
JLT inlineEmitLiteralTwoBytes
|
|
||||||
|
|
||||||
inlineEmitLiteralThreeBytes:
|
|
||||||
MOVB $0xf4, 0(DI)
|
|
||||||
MOVW BX, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
JMP inlineEmitLiteralMemmove
|
|
||||||
|
|
||||||
inlineEmitLiteralTwoBytes:
|
|
||||||
MOVB $0xf0, 0(DI)
|
|
||||||
MOVB BX, 1(DI)
|
|
||||||
ADDQ $2, DI
|
|
||||||
JMP inlineEmitLiteralMemmove
|
|
||||||
|
|
||||||
inlineEmitLiteralOneByte:
|
|
||||||
SHLB $2, BX
|
|
||||||
MOVB BX, 0(DI)
|
|
||||||
ADDQ $1, DI
|
|
||||||
|
|
||||||
inlineEmitLiteralMemmove:
|
|
||||||
// Spill local variables (registers) onto the stack; call; unspill.
|
|
||||||
//
|
|
||||||
// copy(dst[i:], lit)
|
|
||||||
//
|
|
||||||
// This means calling runtime·memmove(&dst[i], &lit[0], len(lit)), so we push
|
|
||||||
// DI, R10 and AX as arguments.
|
|
||||||
MOVQ DI, 0(SP)
|
|
||||||
MOVQ R10, 8(SP)
|
|
||||||
MOVQ AX, 16(SP)
|
|
||||||
ADDQ AX, DI // Finish the "d +=" part of "d += emitLiteral(etc)".
|
|
||||||
MOVQ SI, 72(SP)
|
|
||||||
MOVQ DI, 80(SP)
|
|
||||||
MOVQ R15, 112(SP)
|
|
||||||
CALL runtime·memmove(SB)
|
|
||||||
MOVQ 56(SP), CX
|
|
||||||
MOVQ 64(SP), DX
|
|
||||||
MOVQ 72(SP), SI
|
|
||||||
MOVQ 80(SP), DI
|
|
||||||
MOVQ 88(SP), R9
|
|
||||||
MOVQ 112(SP), R15
|
|
||||||
JMP inner1
|
|
||||||
|
|
||||||
inlineEmitLiteralEnd:
|
|
||||||
// End inline of the emitLiteral call.
|
|
||||||
// ----------------------------------------
|
|
||||||
|
|
||||||
emitLiteralFastPath:
|
|
||||||
// !!! Emit the 1-byte encoding "uint8(len(lit)-1)<<2".
|
|
||||||
MOVB AX, BX
|
|
||||||
SUBB $1, BX
|
|
||||||
SHLB $2, BX
|
|
||||||
MOVB BX, (DI)
|
|
||||||
ADDQ $1, DI
|
|
||||||
|
|
||||||
// !!! Implement the copy from lit to dst as a 16-byte load and store.
|
|
||||||
// (Encode's documentation says that dst and src must not overlap.)
|
|
||||||
//
|
|
||||||
// This always copies 16 bytes, instead of only len(lit) bytes, but that's
|
|
||||||
// OK. Subsequent iterations will fix up the overrun.
|
|
||||||
//
|
|
||||||
// Note that on amd64, it is legal and cheap to issue unaligned 8-byte or
|
|
||||||
// 16-byte loads and stores. This technique probably wouldn't be as
|
|
||||||
// effective on architectures that are fussier about alignment.
|
|
||||||
MOVOU 0(R10), X0
|
|
||||||
MOVOU X0, 0(DI)
|
|
||||||
ADDQ AX, DI
|
|
||||||
|
|
||||||
inner1:
|
|
||||||
// for { etc }
|
|
||||||
|
|
||||||
// base := s
|
|
||||||
MOVQ SI, R12
|
|
||||||
|
|
||||||
// !!! offset := base - candidate
|
|
||||||
MOVQ R12, R11
|
|
||||||
SUBQ R15, R11
|
|
||||||
SUBQ DX, R11
|
|
||||||
|
|
||||||
// ----------------------------------------
|
|
||||||
// Begin inline of the extendMatch call.
|
|
||||||
//
|
|
||||||
// s = extendMatch(src, candidate+4, s+4)
|
|
||||||
|
|
||||||
// !!! R14 = &src[len(src)]
|
|
||||||
MOVQ src_len+32(FP), R14
|
|
||||||
ADDQ DX, R14
|
|
||||||
|
|
||||||
// !!! R13 = &src[len(src) - 8]
|
|
||||||
MOVQ R14, R13
|
|
||||||
SUBQ $8, R13
|
|
||||||
|
|
||||||
// !!! R15 = &src[candidate + 4]
|
|
||||||
ADDQ $4, R15
|
|
||||||
ADDQ DX, R15
|
|
||||||
|
|
||||||
// !!! s += 4
|
|
||||||
ADDQ $4, SI
|
|
||||||
|
|
||||||
inlineExtendMatchCmp8:
|
|
||||||
// As long as we are 8 or more bytes before the end of src, we can load and
|
|
||||||
// compare 8 bytes at a time. If those 8 bytes are equal, repeat.
|
|
||||||
CMPQ SI, R13
|
|
||||||
JA inlineExtendMatchCmp1
|
|
||||||
MOVQ (R15), AX
|
|
||||||
MOVQ (SI), BX
|
|
||||||
CMPQ AX, BX
|
|
||||||
JNE inlineExtendMatchBSF
|
|
||||||
ADDQ $8, R15
|
|
||||||
ADDQ $8, SI
|
|
||||||
JMP inlineExtendMatchCmp8
|
|
||||||
|
|
||||||
inlineExtendMatchBSF:
|
|
||||||
// If those 8 bytes were not equal, XOR the two 8 byte values, and return
|
|
||||||
// the index of the first byte that differs. The BSF instruction finds the
|
|
||||||
// least significant 1 bit, the amd64 architecture is little-endian, and
|
|
||||||
// the shift by 3 converts a bit index to a byte index.
|
|
||||||
XORQ AX, BX
|
|
||||||
BSFQ BX, BX
|
|
||||||
SHRQ $3, BX
|
|
||||||
ADDQ BX, SI
|
|
||||||
JMP inlineExtendMatchEnd
|
|
||||||
|
|
||||||
inlineExtendMatchCmp1:
|
|
||||||
// In src's tail, compare 1 byte at a time.
|
|
||||||
CMPQ SI, R14
|
|
||||||
JAE inlineExtendMatchEnd
|
|
||||||
MOVB (R15), AX
|
|
||||||
MOVB (SI), BX
|
|
||||||
CMPB AX, BX
|
|
||||||
JNE inlineExtendMatchEnd
|
|
||||||
ADDQ $1, R15
|
|
||||||
ADDQ $1, SI
|
|
||||||
JMP inlineExtendMatchCmp1
|
|
||||||
|
|
||||||
inlineExtendMatchEnd:
|
|
||||||
// End inline of the extendMatch call.
|
|
||||||
// ----------------------------------------
|
|
||||||
|
|
||||||
// ----------------------------------------
|
|
||||||
// Begin inline of the emitCopy call.
|
|
||||||
//
|
|
||||||
// d += emitCopy(dst[d:], base-candidate, s-base)
|
|
||||||
|
|
||||||
// !!! length := s - base
|
|
||||||
MOVQ SI, AX
|
|
||||||
SUBQ R12, AX
|
|
||||||
|
|
||||||
inlineEmitCopyLoop0:
|
|
||||||
// for length >= 68 { etc }
|
|
||||||
CMPL AX, $68
|
|
||||||
JLT inlineEmitCopyStep1
|
|
||||||
|
|
||||||
// Emit a length 64 copy, encoded as 3 bytes.
|
|
||||||
MOVB $0xfe, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
SUBL $64, AX
|
|
||||||
JMP inlineEmitCopyLoop0
|
|
||||||
|
|
||||||
inlineEmitCopyStep1:
|
|
||||||
// if length > 64 { etc }
|
|
||||||
CMPL AX, $64
|
|
||||||
JLE inlineEmitCopyStep2
|
|
||||||
|
|
||||||
// Emit a length 60 copy, encoded as 3 bytes.
|
|
||||||
MOVB $0xee, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
SUBL $60, AX
|
|
||||||
|
|
||||||
inlineEmitCopyStep2:
|
|
||||||
// if length >= 12 || offset >= 2048 { goto inlineEmitCopyStep3 }
|
|
||||||
CMPL AX, $12
|
|
||||||
JGE inlineEmitCopyStep3
|
|
||||||
CMPL R11, $2048
|
|
||||||
JGE inlineEmitCopyStep3
|
|
||||||
|
|
||||||
// Emit the remaining copy, encoded as 2 bytes.
|
|
||||||
MOVB R11, 1(DI)
|
|
||||||
SHRL $8, R11
|
|
||||||
SHLB $5, R11
|
|
||||||
SUBB $4, AX
|
|
||||||
SHLB $2, AX
|
|
||||||
ORB AX, R11
|
|
||||||
ORB $1, R11
|
|
||||||
MOVB R11, 0(DI)
|
|
||||||
ADDQ $2, DI
|
|
||||||
JMP inlineEmitCopyEnd
|
|
||||||
|
|
||||||
inlineEmitCopyStep3:
|
|
||||||
// Emit the remaining copy, encoded as 3 bytes.
|
|
||||||
SUBL $1, AX
|
|
||||||
SHLB $2, AX
|
|
||||||
ORB $2, AX
|
|
||||||
MOVB AX, 0(DI)
|
|
||||||
MOVW R11, 1(DI)
|
|
||||||
ADDQ $3, DI
|
|
||||||
|
|
||||||
inlineEmitCopyEnd:
|
|
||||||
// End inline of the emitCopy call.
|
|
||||||
// ----------------------------------------
|
|
||||||
|
|
||||||
// nextEmit = s
|
|
||||||
MOVQ SI, R10
|
|
||||||
|
|
||||||
// if s >= sLimit { goto emitRemainder }
|
|
||||||
MOVQ SI, AX
|
|
||||||
SUBQ DX, AX
|
|
||||||
CMPQ AX, R9
|
|
||||||
JAE emitRemainder
|
|
||||||
|
|
||||||
// As per the encode_other.go code:
|
|
||||||
//
|
|
||||||
// We could immediately etc.
|
|
||||||
|
|
||||||
// x := load64(src, s-1)
|
|
||||||
MOVQ -1(SI), R14
|
|
||||||
|
|
||||||
// prevHash := hash(uint32(x>>0), shift)
|
|
||||||
MOVL R14, R11
|
|
||||||
IMULL $0x1e35a7bd, R11
|
|
||||||
SHRL CX, R11
|
|
||||||
|
|
||||||
// table[prevHash] = uint16(s-1)
|
|
||||||
MOVQ SI, AX
|
|
||||||
SUBQ DX, AX
|
|
||||||
SUBQ $1, AX
|
|
||||||
|
|
||||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
|
||||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
|
||||||
BYTE $0x66
|
|
||||||
BYTE $0x42
|
|
||||||
BYTE $0x89
|
|
||||||
BYTE $0x44
|
|
||||||
BYTE $0x5c
|
|
||||||
BYTE $0x78
|
|
||||||
|
|
||||||
// currHash := hash(uint32(x>>8), shift)
|
|
||||||
SHRQ $8, R14
|
|
||||||
MOVL R14, R11
|
|
||||||
IMULL $0x1e35a7bd, R11
|
|
||||||
SHRL CX, R11
|
|
||||||
|
|
||||||
// candidate = int(table[currHash])
|
|
||||||
// XXX: MOVWQZX table-32768(SP)(R11*2), R15
|
|
||||||
// XXX: 4e 0f b7 7c 5c 78 movzwq 0x78(%rsp,%r11,2),%r15
|
|
||||||
BYTE $0x4e
|
|
||||||
BYTE $0x0f
|
|
||||||
BYTE $0xb7
|
|
||||||
BYTE $0x7c
|
|
||||||
BYTE $0x5c
|
|
||||||
BYTE $0x78
|
|
||||||
|
|
||||||
// table[currHash] = uint16(s)
|
|
||||||
ADDQ $1, AX
|
|
||||||
|
|
||||||
// XXX: MOVW AX, table-32768(SP)(R11*2)
|
|
||||||
// XXX: 66 42 89 44 5c 78 mov %ax,0x78(%rsp,%r11,2)
|
|
||||||
BYTE $0x66
|
|
||||||
BYTE $0x42
|
|
||||||
BYTE $0x89
|
|
||||||
BYTE $0x44
|
|
||||||
BYTE $0x5c
|
|
||||||
BYTE $0x78
|
|
||||||
|
|
||||||
// if uint32(x>>8) == load32(src, candidate) { continue }
|
|
||||||
MOVL (DX)(R15*1), BX
|
|
||||||
CMPL R14, BX
|
|
||||||
JEQ inner1
|
|
||||||
|
|
||||||
// nextHash = hash(uint32(x>>16), shift)
|
|
||||||
SHRQ $8, R14
|
|
||||||
MOVL R14, R11
|
|
||||||
IMULL $0x1e35a7bd, R11
|
|
||||||
SHRL CX, R11
|
|
||||||
|
|
||||||
// s++
|
|
||||||
ADDQ $1, SI
|
|
||||||
|
|
||||||
// break out of the inner1 for loop, i.e. continue the outer loop.
|
|
||||||
JMP outer
|
|
||||||
|
|
||||||
emitRemainder:
|
|
||||||
// if nextEmit < len(src) { etc }
|
|
||||||
MOVQ src_len+32(FP), AX
|
|
||||||
ADDQ DX, AX
|
|
||||||
CMPQ R10, AX
|
|
||||||
JEQ encodeBlockEnd
|
|
||||||
|
|
||||||
// d += emitLiteral(dst[d:], src[nextEmit:])
|
|
||||||
//
|
|
||||||
// Push args.
|
|
||||||
MOVQ DI, 0(SP)
|
|
||||||
MOVQ $0, 8(SP) // Unnecessary, as the callee ignores it, but conservative.
|
|
||||||
MOVQ $0, 16(SP) // Unnecessary, as the callee ignores it, but conservative.
|
|
||||||
MOVQ R10, 24(SP)
|
|
||||||
SUBQ R10, AX
|
|
||||||
MOVQ AX, 32(SP)
|
|
||||||
MOVQ AX, 40(SP) // Unnecessary, as the callee ignores it, but conservative.
|
|
||||||
|
|
||||||
// Spill local variables (registers) onto the stack; call; unspill.
|
|
||||||
MOVQ DI, 80(SP)
|
|
||||||
CALL ·emitLiteral(SB)
|
|
||||||
MOVQ 80(SP), DI
|
|
||||||
|
|
||||||
// Finish the "d +=" part of "d += emitLiteral(etc)".
|
|
||||||
ADDQ 48(SP), DI
|
|
||||||
|
|
||||||
encodeBlockEnd:
|
|
||||||
MOVQ dst_base+0(FP), AX
|
|
||||||
SUBQ AX, DI
|
|
||||||
MOVQ DI, d+48(FP)
|
|
||||||
RET
|
|
||||||
|
|
@ -1,238 +0,0 @@
|
||||||
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build !amd64 appengine !gc noasm
|
|
||||||
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
func load32(b []byte, i int) uint32 {
|
|
||||||
b = b[i : i+4 : len(b)] // Help the compiler eliminate bounds checks on the next line.
|
|
||||||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
|
||||||
}
|
|
||||||
|
|
||||||
func load64(b []byte, i int) uint64 {
|
|
||||||
b = b[i : i+8 : len(b)] // Help the compiler eliminate bounds checks on the next line.
|
|
||||||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
|
||||||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
|
||||||
}
|
|
||||||
|
|
||||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
|
||||||
//
|
|
||||||
// It assumes that:
|
|
||||||
// dst is long enough to hold the encoded bytes
|
|
||||||
// 1 <= len(lit) && len(lit) <= 65536
|
|
||||||
func emitLiteral(dst, lit []byte) int {
|
|
||||||
i, n := 0, uint(len(lit)-1)
|
|
||||||
switch {
|
|
||||||
case n < 60:
|
|
||||||
dst[0] = uint8(n)<<2 | tagLiteral
|
|
||||||
i = 1
|
|
||||||
case n < 1<<8:
|
|
||||||
dst[0] = 60<<2 | tagLiteral
|
|
||||||
dst[1] = uint8(n)
|
|
||||||
i = 2
|
|
||||||
default:
|
|
||||||
dst[0] = 61<<2 | tagLiteral
|
|
||||||
dst[1] = uint8(n)
|
|
||||||
dst[2] = uint8(n >> 8)
|
|
||||||
i = 3
|
|
||||||
}
|
|
||||||
return i + copy(dst[i:], lit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// emitCopy writes a copy chunk and returns the number of bytes written.
|
|
||||||
//
|
|
||||||
// It assumes that:
|
|
||||||
// dst is long enough to hold the encoded bytes
|
|
||||||
// 1 <= offset && offset <= 65535
|
|
||||||
// 4 <= length && length <= 65535
|
|
||||||
func emitCopy(dst []byte, offset, length int) int {
|
|
||||||
i := 0
|
|
||||||
// The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The
|
|
||||||
// threshold for this loop is a little higher (at 68 = 64 + 4), and the
|
|
||||||
// length emitted down below is is a little lower (at 60 = 64 - 4), because
|
|
||||||
// it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed
|
|
||||||
// by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as
|
|
||||||
// a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as
|
|
||||||
// 3+3 bytes). The magic 4 in the 64±4 is because the minimum length for a
|
|
||||||
// tagCopy1 op is 4 bytes, which is why a length 3 copy has to be an
|
|
||||||
// encodes-as-3-bytes tagCopy2 instead of an encodes-as-2-bytes tagCopy1.
|
|
||||||
for length >= 68 {
|
|
||||||
// Emit a length 64 copy, encoded as 3 bytes.
|
|
||||||
dst[i+0] = 63<<2 | tagCopy2
|
|
||||||
dst[i+1] = uint8(offset)
|
|
||||||
dst[i+2] = uint8(offset >> 8)
|
|
||||||
i += 3
|
|
||||||
length -= 64
|
|
||||||
}
|
|
||||||
if length > 64 {
|
|
||||||
// Emit a length 60 copy, encoded as 3 bytes.
|
|
||||||
dst[i+0] = 59<<2 | tagCopy2
|
|
||||||
dst[i+1] = uint8(offset)
|
|
||||||
dst[i+2] = uint8(offset >> 8)
|
|
||||||
i += 3
|
|
||||||
length -= 60
|
|
||||||
}
|
|
||||||
if length >= 12 || offset >= 2048 {
|
|
||||||
// Emit the remaining copy, encoded as 3 bytes.
|
|
||||||
dst[i+0] = uint8(length-1)<<2 | tagCopy2
|
|
||||||
dst[i+1] = uint8(offset)
|
|
||||||
dst[i+2] = uint8(offset >> 8)
|
|
||||||
return i + 3
|
|
||||||
}
|
|
||||||
// Emit the remaining copy, encoded as 2 bytes.
|
|
||||||
dst[i+0] = uint8(offset>>8)<<5 | uint8(length-4)<<2 | tagCopy1
|
|
||||||
dst[i+1] = uint8(offset)
|
|
||||||
return i + 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// extendMatch returns the largest k such that k <= len(src) and that
|
|
||||||
// src[i:i+k-j] and src[j:k] have the same contents.
|
|
||||||
//
|
|
||||||
// It assumes that:
|
|
||||||
// 0 <= i && i < j && j <= len(src)
|
|
||||||
func extendMatch(src []byte, i, j int) int {
|
|
||||||
for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 {
|
|
||||||
}
|
|
||||||
return j
|
|
||||||
}
|
|
||||||
|
|
||||||
func hash(u, shift uint32) uint32 {
|
|
||||||
return (u * 0x1e35a7bd) >> shift
|
|
||||||
}
|
|
||||||
|
|
||||||
// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It
|
|
||||||
// assumes that the varint-encoded length of the decompressed bytes has already
|
|
||||||
// been written.
|
|
||||||
//
|
|
||||||
// It also assumes that:
|
|
||||||
// len(dst) >= MaxEncodedLen(len(src)) &&
|
|
||||||
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
|
|
||||||
func encodeBlock(dst, src []byte) (d int) {
|
|
||||||
// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.
|
|
||||||
// The table element type is uint16, as s < sLimit and sLimit < len(src)
|
|
||||||
// and len(src) <= maxBlockSize and maxBlockSize == 65536.
|
|
||||||
const (
|
|
||||||
maxTableSize = 1 << 14
|
|
||||||
// tableMask is redundant, but helps the compiler eliminate bounds
|
|
||||||
// checks.
|
|
||||||
tableMask = maxTableSize - 1
|
|
||||||
)
|
|
||||||
shift := uint32(32 - 8)
|
|
||||||
for tableSize := 1 << 8; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 {
|
|
||||||
shift--
|
|
||||||
}
|
|
||||||
// In Go, all array elements are zero-initialized, so there is no advantage
|
|
||||||
// to a smaller tableSize per se. However, it matches the C++ algorithm,
|
|
||||||
// and in the asm versions of this code, we can get away with zeroing only
|
|
||||||
// the first tableSize elements.
|
|
||||||
var table [maxTableSize]uint16
|
|
||||||
|
|
||||||
// sLimit is when to stop looking for offset/length copies. The inputMargin
|
|
||||||
// lets us use a fast path for emitLiteral in the main loop, while we are
|
|
||||||
// looking for copies.
|
|
||||||
sLimit := len(src) - inputMargin
|
|
||||||
|
|
||||||
// nextEmit is where in src the next emitLiteral should start from.
|
|
||||||
nextEmit := 0
|
|
||||||
|
|
||||||
// The encoded form must start with a literal, as there are no previous
|
|
||||||
// bytes to copy, so we start looking for hash matches at s == 1.
|
|
||||||
s := 1
|
|
||||||
nextHash := hash(load32(src, s), shift)
|
|
||||||
|
|
||||||
for {
|
|
||||||
// Copied from the C++ snappy implementation:
|
|
||||||
//
|
|
||||||
// Heuristic match skipping: If 32 bytes are scanned with no matches
|
|
||||||
// found, start looking only at every other byte. If 32 more bytes are
|
|
||||||
// scanned (or skipped), look at every third byte, etc.. When a match
|
|
||||||
// is found, immediately go back to looking at every byte. This is a
|
|
||||||
// small loss (~5% performance, ~0.1% density) for compressible data
|
|
||||||
// due to more bookkeeping, but for non-compressible data (such as
|
|
||||||
// JPEG) it's a huge win since the compressor quickly "realizes" the
|
|
||||||
// data is incompressible and doesn't bother looking for matches
|
|
||||||
// everywhere.
|
|
||||||
//
|
|
||||||
// The "skip" variable keeps track of how many bytes there are since
|
|
||||||
// the last match; dividing it by 32 (ie. right-shifting by five) gives
|
|
||||||
// the number of bytes to move ahead for each iteration.
|
|
||||||
skip := 32
|
|
||||||
|
|
||||||
nextS := s
|
|
||||||
candidate := 0
|
|
||||||
for {
|
|
||||||
s = nextS
|
|
||||||
bytesBetweenHashLookups := skip >> 5
|
|
||||||
nextS = s + bytesBetweenHashLookups
|
|
||||||
skip += bytesBetweenHashLookups
|
|
||||||
if nextS > sLimit {
|
|
||||||
goto emitRemainder
|
|
||||||
}
|
|
||||||
candidate = int(table[nextHash&tableMask])
|
|
||||||
table[nextHash&tableMask] = uint16(s)
|
|
||||||
nextHash = hash(load32(src, nextS), shift)
|
|
||||||
if load32(src, s) == load32(src, candidate) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A 4-byte match has been found. We'll later see if more than 4 bytes
|
|
||||||
// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit
|
|
||||||
// them as literal bytes.
|
|
||||||
d += emitLiteral(dst[d:], src[nextEmit:s])
|
|
||||||
|
|
||||||
// Call emitCopy, and then see if another emitCopy could be our next
|
|
||||||
// move. Repeat until we find no match for the input immediately after
|
|
||||||
// what was consumed by the last emitCopy call.
|
|
||||||
//
|
|
||||||
// If we exit this loop normally then we need to call emitLiteral next,
|
|
||||||
// though we don't yet know how big the literal will be. We handle that
|
|
||||||
// by proceeding to the next iteration of the main loop. We also can
|
|
||||||
// exit this loop via goto if we get close to exhausting the input.
|
|
||||||
for {
|
|
||||||
// Invariant: we have a 4-byte match at s, and no need to emit any
|
|
||||||
// literal bytes prior to s.
|
|
||||||
base := s
|
|
||||||
|
|
||||||
// Extend the 4-byte match as long as possible.
|
|
||||||
//
|
|
||||||
// This is an inlined version of:
|
|
||||||
// s = extendMatch(src, candidate+4, s+4)
|
|
||||||
s += 4
|
|
||||||
for i := candidate + 4; s < len(src) && src[i] == src[s]; i, s = i+1, s+1 {
|
|
||||||
}
|
|
||||||
|
|
||||||
d += emitCopy(dst[d:], base-candidate, s-base)
|
|
||||||
nextEmit = s
|
|
||||||
if s >= sLimit {
|
|
||||||
goto emitRemainder
|
|
||||||
}
|
|
||||||
|
|
||||||
// We could immediately start working at s now, but to improve
|
|
||||||
// compression we first update the hash table at s-1 and at s. If
|
|
||||||
// another emitCopy is not our next move, also calculate nextHash
|
|
||||||
// at s+1. At least on GOARCH=amd64, these three hash calculations
|
|
||||||
// are faster as one load64 call (with some shifts) instead of
|
|
||||||
// three load32 calls.
|
|
||||||
x := load64(src, s-1)
|
|
||||||
prevHash := hash(uint32(x>>0), shift)
|
|
||||||
table[prevHash&tableMask] = uint16(s - 1)
|
|
||||||
currHash := hash(uint32(x>>8), shift)
|
|
||||||
candidate = int(table[currHash&tableMask])
|
|
||||||
table[currHash&tableMask] = uint16(s)
|
|
||||||
if uint32(x>>8) != load32(src, candidate) {
|
|
||||||
nextHash = hash(uint32(x>>16), shift)
|
|
||||||
s++
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emitRemainder:
|
|
||||||
if nextEmit < len(src) {
|
|
||||||
d += emitLiteral(dst[d:], src[nextEmit:])
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
// Copyright 2011 The Snappy-Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package snappy implements the snappy block-based compression format.
|
|
||||||
// It aims for very high speeds and reasonable compression.
|
|
||||||
//
|
|
||||||
// The C++ snappy implementation is at https://github.com/google/snappy
|
|
||||||
package snappy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"hash/crc32"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Each encoded block begins with the varint-encoded length of the decoded data,
|
|
||||||
followed by a sequence of chunks. Chunks begin and end on byte boundaries. The
|
|
||||||
first byte of each chunk is broken into its 2 least and 6 most significant bits
|
|
||||||
called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.
|
|
||||||
Zero means a literal tag. All other values mean a copy tag.
|
|
||||||
|
|
||||||
For literal tags:
|
|
||||||
- If m < 60, the next 1 + m bytes are literal bytes.
|
|
||||||
- Otherwise, let n be the little-endian unsigned integer denoted by the next
|
|
||||||
m - 59 bytes. The next 1 + n bytes after that are literal bytes.
|
|
||||||
|
|
||||||
For copy tags, length bytes are copied from offset bytes ago, in the style of
|
|
||||||
Lempel-Ziv compression algorithms. In particular:
|
|
||||||
- For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).
|
|
||||||
The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10
|
|
||||||
of the offset. The next byte is bits 0-7 of the offset.
|
|
||||||
- For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).
|
|
||||||
The length is 1 + m. The offset is the little-endian unsigned integer
|
|
||||||
denoted by the next 2 bytes.
|
|
||||||
- For l == 3, this tag is a legacy format that is no longer supported.
|
|
||||||
*/
|
|
||||||
const (
|
|
||||||
tagLiteral = 0x00
|
|
||||||
tagCopy1 = 0x01
|
|
||||||
tagCopy2 = 0x02
|
|
||||||
tagCopy4 = 0x03
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
checksumSize = 4
|
|
||||||
chunkHeaderSize = 4
|
|
||||||
magicChunk = "\xff\x06\x00\x00" + magicBody
|
|
||||||
magicBody = "sNaPpY"
|
|
||||||
|
|
||||||
// maxBlockSize is the maximum size of the input to encodeBlock. It is not
|
|
||||||
// part of the wire format per se, but some parts of the encoder assume
|
|
||||||
// that an offset fits into a uint16.
|
|
||||||
//
|
|
||||||
// Also, for the framing format (Writer type instead of Encode function),
|
|
||||||
// https://github.com/google/snappy/blob/master/framing_format.txt says
|
|
||||||
// that "the uncompressed data in a chunk must be no longer than 65536
|
|
||||||
// bytes".
|
|
||||||
maxBlockSize = 65536
|
|
||||||
|
|
||||||
// maxEncodedLenOfMaxBlockSize equals MaxEncodedLen(maxBlockSize), but is
|
|
||||||
// hard coded to be a const instead of a variable, so that obufLen can also
|
|
||||||
// be a const. Their equivalence is confirmed by
|
|
||||||
// TestMaxEncodedLenOfMaxBlockSize.
|
|
||||||
maxEncodedLenOfMaxBlockSize = 76490
|
|
||||||
|
|
||||||
obufHeaderLen = len(magicChunk) + checksumSize + chunkHeaderSize
|
|
||||||
obufLen = obufHeaderLen + maxEncodedLenOfMaxBlockSize
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
chunkTypeCompressedData = 0x00
|
|
||||||
chunkTypeUncompressedData = 0x01
|
|
||||||
chunkTypePadding = 0xfe
|
|
||||||
chunkTypeStreamIdentifier = 0xff
|
|
||||||
)
|
|
||||||
|
|
||||||
var crcTable = crc32.MakeTable(crc32.Castagnoli)
|
|
||||||
|
|
||||||
// crc implements the checksum specified in section 3 of
|
|
||||||
// https://github.com/google/snappy/blob/master/framing_format.txt
|
|
||||||
func crc(b []byte) uint32 {
|
|
||||||
c := crc32.Update(0, crcTable, b)
|
|
||||||
return uint32(c>>15|c<<17) + 0xa282ead8
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue