Files
Joe ElliottandGitHub ba1d670445 Compressed Blocks? Compressed Blocks! (#504)
* Added basic structure for compression

Signed-off-by: Joe Elliott <[email protected]>

* AppenderBuffered impl

Signed-off-by: Joe Elliott <[email protected]>

* mild commenting

Signed-off-by: Joe Elliott <[email protected]>

* moved encoding to meta json

Signed-off-by: Joe Elliott <[email protected]>

* Added pagedReader and backend.ReaderAt

Signed-off-by: Joe Elliott <[email protected]>

* dedupingfinder => pagedfinder

Signed-off-by: Joe Elliott <[email protected]>

* Abstracted away index reading.  Used pagedFinder in backend block

Signed-off-by: Joe Elliott <[email protected]>

* Abstracted PagedIterator to use indexReader

Signed-off-by: Joe Elliott <[email protected]>

* improved comments

Signed-off-by: Joe Elliott <[email protected]>

* created versioned encoding

Signed-off-by: Joe Elliott <[email protected]>

* removed findmetrics

Signed-off-by: Joe Elliott <[email protected]>

* Moved backend block to encoding

Signed-off-by: Joe Elliott <[email protected]>

* Moved indexreader records to common

Signed-off-by: Joe Elliott <[email protected]>

* Added index reader

Signed-off-by: Joe Elliott <[email protected]>

* jpe cleanup

Signed-off-by: Joe Elliott <[email protected]>

* v1 LIVES

Signed-off-by: Joe Elliott <[email protected]>

* Tests pass on v1

Signed-off-by: Joe Elliott <[email protected]>

* encoding tests pass

Signed-off-by: Joe Elliott <[email protected]>

* wooo snappy tests

Signed-off-by: Joe Elliott <[email protected]>

* Moved block config to its own struct

Signed-off-by: Joe Elliott <[email protected]>

* Add custom marshaller

Signed-off-by: Joe Elliott <[email protected]>

* updated configs added default

Signed-off-by: Joe Elliott <[email protected]>

* Test all encodings

Signed-off-by: Joe Elliott <[email protected]>

* Added benchmark.  Default to snappy

Signed-off-by: Joe Elliott <[email protected]>

* fixed panic in reader

Signed-off-by: Joe Elliott <[email protected]>

* Fleshed out benchmarks

Signed-off-by: Joe Elliott <[email protected]>

* lint

Signed-off-by: Joe Elliott <[email protected]>

* backend_block => benchmark_block

Signed-off-by: Joe Elliott <[email protected]>

* Added 256 and 1M LZ4 tests

Signed-off-by: Joe Elliott <[email protected]>

* Removed findmetrics from operational

Signed-off-by: Joe Elliott <[email protected]>

* indexreaderbytes => indexreader

Signed-off-by: Joe Elliott <[email protected]>

* jpe cleanup

Signed-off-by: Joe Elliott <[email protected]>

* Fixed bytes flushed metric

Signed-off-by: Joe Elliott <[email protected]>

* Changed default encoding

Signed-off-by: Joe Elliott <[email protected]>

* Pass tracker correctly.  Add guard code

Signed-off-by: Joe Elliott <[email protected]>

* Added marshal tests

Signed-off-by: Joe Elliott <[email protected]>

* lint

Signed-off-by: Joe Elliott <[email protected]>

* page reader tests

Signed-off-by: Joe Elliott <[email protected]>

* actually add tests

Signed-off-by: Joe Elliott <[email protected]>

* Added reader tess

Signed-off-by: Joe Elliott <[email protected]>

* changelog

Signed-off-by: Joe Elliott <[email protected]>

* zstd

Signed-off-by: Joe Elliott <[email protected]>

* vendor

Signed-off-by: Joe Elliott <[email protected]>
2021-02-05 14:58:39 -05:00

145 lines
4.6 KiB
Go

// Copyright 2018 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.
// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.
// Package fse provides Finite State Entropy encoding and decoding.
//
// Finite State Entropy encoding provides a fast near-optimal symbol encoding/decoding
// for byte blocks as implemented in zstd.
//
// See https://github.com/klauspost/compress/tree/master/fse for more information.
package fse
import (
"errors"
"fmt"
"math/bits"
)
const (
/*!MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio
* Reduced memory usage can improve speed, due to cache effect
* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
maxMemoryUsage = 14
defaultMemoryUsage = 13
maxTableLog = maxMemoryUsage - 2
maxTablesize = 1 << maxTableLog
defaultTablelog = defaultMemoryUsage - 2
minTablelog = 5
maxSymbolValue = 255
)
var (
// ErrIncompressible is returned when input is judged to be too hard to compress.
ErrIncompressible = errors.New("input is not compressible")
// ErrUseRLE is returned from the compressor when the input is a single byte value repeated.
ErrUseRLE = errors.New("input is single value repeated")
)
// Scratch provides temporary storage for compression and decompression.
type Scratch struct {
// Private
count [maxSymbolValue + 1]uint32
norm [maxSymbolValue + 1]int16
br byteReader
bits bitReader
bw bitWriter
ct cTable // Compression tables.
decTable []decSymbol // Decompression table.
maxCount int // count of the most probable symbol
// Per block parameters.
// These can be used to override compression parameters of the block.
// Do not touch, unless you know what you are doing.
// Out is output buffer.
// If the scratch is re-used before the caller is done processing the output,
// set this field to nil.
// Otherwise the output buffer will be re-used for next Compression/Decompression step
// and allocation will be avoided.
Out []byte
// DecompressLimit limits the maximum decoded size acceptable.
// If > 0 decompression will stop when approximately this many bytes
// has been decoded.
// If 0, maximum size will be 2GB.
DecompressLimit int
symbolLen uint16 // Length of active part of the symbol table.
actualTableLog uint8 // Selected tablelog.
zeroBits bool // no bits has prob > 50%.
clearCount bool // clear count
// MaxSymbolValue will override the maximum symbol value of the next block.
MaxSymbolValue uint8
// TableLog will attempt to override the tablelog for the next block.
TableLog uint8
}
// Histogram allows to populate the histogram and skip that step in the compression,
// It otherwise allows to inspect the histogram when compression is done.
// To indicate that you have populated the histogram call HistogramFinished
// with the value of the highest populated symbol, as well as the number of entries
// in the most populated entry. These are accepted at face value.
// The returned slice will always be length 256.
func (s *Scratch) Histogram() []uint32 {
return s.count[:]
}
// HistogramFinished can be called to indicate that the histogram has been populated.
// maxSymbol is the index of the highest set symbol of the next data segment.
// maxCount is the number of entries in the most populated entry.
// These are accepted at face value.
func (s *Scratch) HistogramFinished(maxSymbol uint8, maxCount int) {
s.maxCount = maxCount
s.symbolLen = uint16(maxSymbol) + 1
s.clearCount = maxCount != 0
}
// prepare will prepare and allocate scratch tables used for both compression and decompression.
func (s *Scratch) prepare(in []byte) (*Scratch, error) {
if s == nil {
s = &Scratch{}
}
if s.MaxSymbolValue == 0 {
s.MaxSymbolValue = 255
}
if s.TableLog == 0 {
s.TableLog = defaultTablelog
}
if s.TableLog > maxTableLog {
return nil, fmt.Errorf("tableLog (%d) > maxTableLog (%d)", s.TableLog, maxTableLog)
}
if cap(s.Out) == 0 {
s.Out = make([]byte, 0, len(in))
}
if s.clearCount && s.maxCount == 0 {
for i := range s.count {
s.count[i] = 0
}
s.clearCount = false
}
s.br.init(in)
if s.DecompressLimit == 0 {
// Max size 2GB.
s.DecompressLimit = (2 << 30) - 1
}
return s, nil
}
// tableStep returns the next table index.
func tableStep(tableSize uint32) uint32 {
return (tableSize >> 1) + (tableSize >> 3) + 3
}
func highBits(val uint32) (n uint32) {
return uint32(bits.Len32(val) - 1)
}