1// Copyright 2019+ Klaus Post. All rights reserved. 2// License information can be found in the LICENSE file. 3// Based on work by Yann Collet, released under BSD License. 4 5package zstd 6 7import ( 8 "github.com/klauspost/compress/huff0" 9) 10 11// history contains the information transferred between blocks. 12type history struct { 13 b []byte 14 huffTree *huff0.Scratch 15 recentOffsets [3]int 16 decoders sequenceDecs 17 windowSize int 18 maxSize int 19 error bool 20 dict *dict 21} 22 23// reset will reset the history to initial state of a frame. 24// The history must already have been initialized to the desired size. 25func (h *history) reset() { 26 h.b = h.b[:0] 27 h.error = false 28 h.recentOffsets = [3]int{1, 4, 8} 29 if f := h.decoders.litLengths.fse; f != nil && !f.preDefined { 30 fseDecoderPool.Put(f) 31 } 32 if f := h.decoders.offsets.fse; f != nil && !f.preDefined { 33 fseDecoderPool.Put(f) 34 } 35 if f := h.decoders.matchLengths.fse; f != nil && !f.preDefined { 36 fseDecoderPool.Put(f) 37 } 38 h.decoders = sequenceDecs{} 39 if h.huffTree != nil { 40 if h.dict == nil || h.dict.litDec != h.huffTree { 41 huffDecoderPool.Put(h.huffTree) 42 } 43 } 44 h.huffTree = nil 45 h.dict = nil 46 //printf("history created: %+v (l: %d, c: %d)", *h, len(h.b), cap(h.b)) 47} 48 49func (h *history) setDict(dict *dict) { 50 if dict == nil { 51 return 52 } 53 h.dict = dict 54 h.decoders.litLengths = dict.llDec 55 h.decoders.offsets = dict.ofDec 56 h.decoders.matchLengths = dict.mlDec 57 h.recentOffsets = dict.offsets 58 h.huffTree = dict.litDec 59} 60 61// append bytes to history. 62// This function will make sure there is space for it, 63// if the buffer has been allocated with enough extra space. 64func (h *history) append(b []byte) { 65 if len(b) >= h.windowSize { 66 // Discard all history by simply overwriting 67 h.b = h.b[:h.windowSize] 68 copy(h.b, b[len(b)-h.windowSize:]) 69 return 70 } 71 72 // If there is space, append it. 73 if len(b) < cap(h.b)-len(h.b) { 74 h.b = append(h.b, b...) 75 return 76 } 77 78 // Move data down so we only have window size left. 79 // We know we have less than window size in b at this point. 80 discard := len(b) + len(h.b) - h.windowSize 81 copy(h.b, h.b[discard:]) 82 h.b = h.b[:h.windowSize] 83 copy(h.b[h.windowSize-len(b):], b) 84} 85 86// append bytes to history without ever discarding anything. 87func (h *history) appendKeep(b []byte) { 88 h.b = append(h.b, b...) 89} 90