Source File
encode.go
Belonging Package
github.com/klauspost/compress/s2
// Copyright 2011 The Snappy-Go Authors. All rights reserved.// Copyright (c) 2019 Klaus Post. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package s2import ()// 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.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlock([:], )if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}var estblockPool [2]sync.Pool// EstimateBlockSize will perform a very fast compression// without outputting the result and return the compressed output size.// The function returns -1 if no improvement could be achieved.// Using actual compression will most often produce better compression than the estimate.func ( []byte) ( int) {if len() <= inputMargin || int64(len()) > 0xffffffff {return -1}if len() <= 1024 {const , = 2048, 0, := estblockPool[].Get().(*[]byte)if ! {= &[]byte{}}race.WriteSlice([:])defer estblockPool[].Put()= calcBlockSizeSmall(, )} else {const , = 32768, 1, := estblockPool[].Get().(*[]byte)if ! {= &[]byte{}}race.WriteSlice([:])defer estblockPool[].Put()= calcBlockSize(, )}if == 0 {return -1}// Size of the varint encoded block size.+= (bits.Len64(uint64(len())) + 7) / 7if >= len() {return -1}return}// EncodeBetter 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.//// EncodeBetter compresses better than Encode but typically with a// 10-40% speed decrease on both compression and decompression.//// The dst and src must not overlap. It is valid to pass a nil dst.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlockBetter([:], )if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}// EncodeBest 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.//// EncodeBest compresses as good as reasonably possible but with a// big speed decrease.//// The dst and src must not overlap. It is valid to pass a nil dst.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlockBest([:], , nil)if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}// EncodeSnappy 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 output is Snappy compatible and will likely decompress faster.//// The dst and src must not overlap. It is valid to pass a nil dst.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlockSnappy([:], )if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}// EncodeSnappyBetter 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 output is Snappy compatible and will likely decompress faster.//// The dst and src must not overlap. It is valid to pass a nil dst.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlockBetterSnappy([:], )if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}// EncodeSnappyBest 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 output is Snappy compatible and will likely decompress faster.//// The dst and src must not overlap. It is valid to pass a nil dst.//// The blocks will require the same amount of memory to decode as encoding,// and does not make for concurrent decoding.// Also note that blocks do not contain CRC information, so corruption may be undetected.//// If you need to encode larger amounts of data, consider using// the streaming interface which gives all of these features.func (, []byte) []byte {if := MaxEncodedLen(len()); < 0 {panic(ErrTooLarge)} else if cap() < {= make([]byte, )} else {= [:]}// The block starts with the varint-encoded length of the decompressed bytes.:= binary.PutUvarint(, uint64(len()))if len() == 0 {return [:]}if len() < minNonLiteralBlockSize {+= emitLiteral([:], )return [:]}:= encodeBlockBestSnappy([:], )if > 0 {+=return [:]}// Not compressible+= emitLiteral([:], )return [:]}// ConcatBlocks will concatenate the supplied blocks and append them to the supplied destination.// If the destination is nil or too small, a new will be allocated.// The blocks are not validated, so garbage in = garbage out.// dst may not overlap block data.// Any data in dst is preserved as is, so it will not be considered a block.func ( []byte, ...[]byte) ([]byte, error) {:= uint64(0):= 0for , := range {, , := decodedLen()if != nil {return nil,}+= uint64()+= len() -}if == 0 {= append(, 0)return , nil}if > math.MaxUint32 {return nil, ErrTooLarge}var [binary.MaxVarintLen32]byte:= binary.PutUvarint([:], ):= +if cap()-len() < {= append(make([]byte, 0, +len()), ...)}= append(, [:]...)for , := range {, , := decodedLen()if != nil {return nil,}= append(, [:]...)}return , nil}// 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 = 8// minNonLiteralBlockSize is the minimum size of the input to encodeBlock that// will be accepted by the encoder.const minNonLiteralBlockSize = 32const intReduction = 2 - (1 << (^uint(0) >> 63)) // 1 (32 bits) or 0 (64 bits)// MaxBlockSize is the maximum value where MaxEncodedLen will return a valid block size.// Blocks this big are highly discouraged, though.// Half the size on 32 bit systems.const MaxBlockSize = (1<<(32-intReduction) - 1) - binary.MaxVarintLen32 - 5// 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.// 32 bit platforms will have lower thresholds for rejecting big content.func ( int) int {:= uint64()if intReduction == 1 {// 32 bitsif > math.MaxInt32 {// Also includes negative.return -1}} else if > 0xffffffff {// 64 bits// Also includes negative.return -1}// Size of the varint encoded block size.= + uint64((bits.Len64()+7)/7)// Add maximum size of encoding block as literals.+= uint64(literalExtraSize(int64()))if intReduction == 1 {// 32 bitsif > math.MaxInt32 {return -1}} else if > 0xffffffff {// 64 bits// Also includes negative.return -1}return int()}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |