internal/pkg: decompress zstd streams
Test / Create distribution (push) Successful in 57s
Test / Sandbox (push) Successful in 3m2s
Test / ShareFS (push) Successful in 4m3s
Test / Hakurei (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 5m37s
Test / Hakurei (race detector) (push) Successful in 6m49s
Test / Flake checks (push) Successful in 1m11s
Test / Create distribution (push) Successful in 57s
Test / Sandbox (push) Successful in 3m2s
Test / ShareFS (push) Successful in 4m3s
Test / Hakurei (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 5m37s
Test / Hakurei (race detector) (push) Successful in 6m49s
Test / Flake checks (push) Successful in 1m11s
This uses internal/zstd until compress/zstd becomes available. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
package zstd
|
||||
|
||||
// window stores up to size bytes of data.
|
||||
// It is implemented as a circular buffer:
|
||||
// sequential save calls append to the data slice until
|
||||
// its length reaches configured size and after that,
|
||||
// save calls overwrite previously saved data at off
|
||||
// and update off such that it always points at
|
||||
// the byte stored before others.
|
||||
type window struct {
|
||||
size int
|
||||
data []byte
|
||||
off int
|
||||
}
|
||||
|
||||
// reset clears stored data and configures window size.
|
||||
func (w *window) reset(size int) {
|
||||
b := w.data[:0]
|
||||
if cap(b) < size {
|
||||
b = make([]byte, 0, size)
|
||||
}
|
||||
w.data = b
|
||||
w.off = 0
|
||||
w.size = size
|
||||
}
|
||||
|
||||
// len returns the number of stored bytes.
|
||||
func (w *window) len() uint32 {
|
||||
return uint32(len(w.data))
|
||||
}
|
||||
|
||||
// save stores up to size last bytes from the buf.
|
||||
func (w *window) save(buf []byte) {
|
||||
if w.size == 0 {
|
||||
return
|
||||
}
|
||||
if len(buf) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if len(buf) >= w.size {
|
||||
from := len(buf) - w.size
|
||||
w.data = append(w.data[:0], buf[from:]...)
|
||||
w.off = 0
|
||||
return
|
||||
}
|
||||
|
||||
// Update off to point to the oldest remaining byte.
|
||||
free := w.size - len(w.data)
|
||||
if free == 0 {
|
||||
n := copy(w.data[w.off:], buf)
|
||||
if n == len(buf) {
|
||||
w.off += n
|
||||
} else {
|
||||
w.off = copy(w.data, buf[n:])
|
||||
}
|
||||
} else {
|
||||
if free >= len(buf) {
|
||||
w.data = append(w.data, buf...)
|
||||
} else {
|
||||
w.data = append(w.data, buf[:free]...)
|
||||
w.off = copy(w.data, buf[free:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// appendTo appends stored bytes between from and to indices to the buf.
|
||||
// Index from must be less or equal to index to and to must be less or equal to w.len().
|
||||
func (w *window) appendTo(buf []byte, from, to uint32) []byte {
|
||||
dataLen := uint32(len(w.data))
|
||||
from += uint32(w.off)
|
||||
to += uint32(w.off)
|
||||
|
||||
wrap := false
|
||||
if from > dataLen {
|
||||
from -= dataLen
|
||||
wrap = !wrap
|
||||
}
|
||||
if to > dataLen {
|
||||
to -= dataLen
|
||||
wrap = !wrap
|
||||
}
|
||||
|
||||
if wrap {
|
||||
buf = append(buf, w.data[from:]...)
|
||||
return append(buf, w.data[:to]...)
|
||||
} else {
|
||||
return append(buf, w.data[from:to]...)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user