[chore]: Bump github.com/minio/minio-go/v7 from 7.0.77 to 7.0.78 (#3431)
Bumps [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) from 7.0.77 to 7.0.78. - [Release notes](https://github.com/minio/minio-go/releases) - [Commits](https://github.com/minio/minio-go/compare/v7.0.77...v7.0.78) --- updated-dependencies: - dependency-name: github.com/minio/minio-go/v7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
be3b8076ca
commit
157ee3193d
4
go.mod
4
go.mod
|
@ -42,7 +42,7 @@ require (
|
||||||
github.com/k3a/html2text v1.2.1
|
github.com/k3a/html2text v1.2.1
|
||||||
github.com/microcosm-cc/bluemonday v1.0.27
|
github.com/microcosm-cc/bluemonday v1.0.27
|
||||||
github.com/miekg/dns v1.1.62
|
github.com/miekg/dns v1.1.62
|
||||||
github.com/minio/minio-go/v7 v7.0.77
|
github.com/minio/minio-go/v7 v7.0.78
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/ncruces/go-sqlite3 v0.19.0
|
github.com/ncruces/go-sqlite3 v0.19.0
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
|
@ -158,7 +158,7 @@ require (
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -381,8 +381,8 @@ github.com/k3a/html2text v1.2.1/go.mod h1:ieEXykM67iT8lTvEWBh6fhpH4B23kB9OMKPdIB
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||||
|
@ -413,8 +413,8 @@ github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
github.com/minio/minio-go/v7 v7.0.77 h1:GaGghJRg9nwDVlNbwYjSDJT1rqltQkBFDsypWX1v3Bw=
|
github.com/minio/minio-go/v7 v7.0.78 h1:LqW2zy52fxnI4gg8C2oZviTaKHcBV36scS+RzJnxUFs=
|
||||||
github.com/minio/minio-go/v7 v7.0.77/go.mod h1:AVM3IUN6WwKzmwBxVdjzhH8xq+f57JSbbvzqvUzR6eg=
|
github.com/minio/minio-go/v7 v7.0.78/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0=
|
||||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# This is an example goreleaser.yaml file with some sane defaults.
|
version: 2
|
||||||
# Make sure to check the documentation at http://goreleaser.com
|
|
||||||
before:
|
before:
|
||||||
hooks:
|
hooks:
|
||||||
- ./gen.sh
|
- ./gen.sh
|
||||||
|
@ -99,7 +99,7 @@ archives:
|
||||||
checksum:
|
checksum:
|
||||||
name_template: 'checksums.txt'
|
name_template: 'checksums.txt'
|
||||||
snapshot:
|
snapshot:
|
||||||
name_template: "{{ .Tag }}-next"
|
version_template: "{{ .Tag }}-next"
|
||||||
changelog:
|
changelog:
|
||||||
sort: asc
|
sort: asc
|
||||||
filters:
|
filters:
|
||||||
|
|
|
@ -16,6 +16,27 @@ This package provides various compression algorithms.
|
||||||
|
|
||||||
# changelog
|
# changelog
|
||||||
|
|
||||||
|
* Sep 23rd, 2024 - [1.17.10](https://github.com/klauspost/compress/releases/tag/v1.17.10)
|
||||||
|
* gzhttp: Add TransportAlwaysDecompress option. https://github.com/klauspost/compress/pull/978
|
||||||
|
* gzhttp: Add supported decompress request body by @mirecl in https://github.com/klauspost/compress/pull/1002
|
||||||
|
* s2: Add EncodeBuffer buffer recycling callback https://github.com/klauspost/compress/pull/982
|
||||||
|
* zstd: Improve memory usage on small streaming encodes https://github.com/klauspost/compress/pull/1007
|
||||||
|
* flate: read data written with partial flush by @vajexal in https://github.com/klauspost/compress/pull/996
|
||||||
|
|
||||||
|
* Jun 12th, 2024 - [1.17.9](https://github.com/klauspost/compress/releases/tag/v1.17.9)
|
||||||
|
* s2: Reduce ReadFrom temporary allocations https://github.com/klauspost/compress/pull/949
|
||||||
|
* flate, zstd: Shave some bytes off amd64 matchLen by @greatroar in https://github.com/klauspost/compress/pull/963
|
||||||
|
* Upgrade zip/zlib to 1.22.4 upstream https://github.com/klauspost/compress/pull/970 https://github.com/klauspost/compress/pull/971
|
||||||
|
* zstd: BuildDict fails with RLE table https://github.com/klauspost/compress/pull/951
|
||||||
|
|
||||||
|
* Apr 9th, 2024 - [1.17.8](https://github.com/klauspost/compress/releases/tag/v1.17.8)
|
||||||
|
* zstd: Reject blocks where reserved values are not 0 https://github.com/klauspost/compress/pull/885
|
||||||
|
* zstd: Add RLE detection+encoding https://github.com/klauspost/compress/pull/938
|
||||||
|
|
||||||
|
* Feb 21st, 2024 - [1.17.7](https://github.com/klauspost/compress/releases/tag/v1.17.7)
|
||||||
|
* s2: Add AsyncFlush method: Complete the block without flushing by @Jille in https://github.com/klauspost/compress/pull/927
|
||||||
|
* s2: Fix literal+repeat exceeds dst crash https://github.com/klauspost/compress/pull/930
|
||||||
|
|
||||||
* Feb 5th, 2024 - [1.17.6](https://github.com/klauspost/compress/releases/tag/v1.17.6)
|
* Feb 5th, 2024 - [1.17.6](https://github.com/klauspost/compress/releases/tag/v1.17.6)
|
||||||
* zstd: Fix incorrect repeat coding in best mode https://github.com/klauspost/compress/pull/923
|
* zstd: Fix incorrect repeat coding in best mode https://github.com/klauspost/compress/pull/923
|
||||||
* s2: Fix DecodeConcurrent deadlock on errors https://github.com/klauspost/compress/pull/925
|
* s2: Fix DecodeConcurrent deadlock on errors https://github.com/klauspost/compress/pull/925
|
||||||
|
@ -81,7 +102,7 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp
|
||||||
* zstd: Various minor improvements by @greatroar in https://github.com/klauspost/compress/pull/788 https://github.com/klauspost/compress/pull/794 https://github.com/klauspost/compress/pull/795
|
* zstd: Various minor improvements by @greatroar in https://github.com/klauspost/compress/pull/788 https://github.com/klauspost/compress/pull/794 https://github.com/klauspost/compress/pull/795
|
||||||
* s2: Fix huge block overflow https://github.com/klauspost/compress/pull/779
|
* s2: Fix huge block overflow https://github.com/klauspost/compress/pull/779
|
||||||
* s2: Allow CustomEncoder fallback https://github.com/klauspost/compress/pull/780
|
* s2: Allow CustomEncoder fallback https://github.com/klauspost/compress/pull/780
|
||||||
* gzhttp: Suppport ResponseWriter Unwrap() in gzhttp handler by @jgimenez in https://github.com/klauspost/compress/pull/799
|
* gzhttp: Support ResponseWriter Unwrap() in gzhttp handler by @jgimenez in https://github.com/klauspost/compress/pull/799
|
||||||
|
|
||||||
* Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1)
|
* Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1)
|
||||||
* zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776
|
* zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776
|
||||||
|
@ -136,7 +157,7 @@ https://github.com/klauspost/compress/pull/919 https://github.com/klauspost/comp
|
||||||
* zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649
|
* zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649
|
||||||
* Add Go 1.19 - deprecate Go 1.16 https://github.com/klauspost/compress/pull/651
|
* Add Go 1.19 - deprecate Go 1.16 https://github.com/klauspost/compress/pull/651
|
||||||
* flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656
|
* flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656
|
||||||
* zstd: Improve "better" compresssion https://github.com/klauspost/compress/pull/657
|
* zstd: Improve "better" compression https://github.com/klauspost/compress/pull/657
|
||||||
* s2: Improve "best" compression https://github.com/klauspost/compress/pull/658
|
* s2: Improve "best" compression https://github.com/klauspost/compress/pull/658
|
||||||
* s2: Improve "better" compression. https://github.com/klauspost/compress/pull/635
|
* s2: Improve "better" compression. https://github.com/klauspost/compress/pull/635
|
||||||
* s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646
|
* s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646
|
||||||
|
@ -339,7 +360,7 @@ While the release has been extensively tested, it is recommended to testing when
|
||||||
* s2: Fix binaries.
|
* s2: Fix binaries.
|
||||||
|
|
||||||
* Feb 25, 2021 (v1.11.8)
|
* Feb 25, 2021 (v1.11.8)
|
||||||
* s2: Fixed occational out-of-bounds write on amd64. Upgrade recommended.
|
* s2: Fixed occasional out-of-bounds write on amd64. Upgrade recommended.
|
||||||
* s2: Add AMD64 assembly for better mode. 25-50% faster. [#315](https://github.com/klauspost/compress/pull/315)
|
* s2: Add AMD64 assembly for better mode. 25-50% faster. [#315](https://github.com/klauspost/compress/pull/315)
|
||||||
* s2: Less upfront decoder allocation. [#322](https://github.com/klauspost/compress/pull/322)
|
* s2: Less upfront decoder allocation. [#322](https://github.com/klauspost/compress/pull/322)
|
||||||
* zstd: Faster "compression" of incompressible data. [#314](https://github.com/klauspost/compress/pull/314)
|
* zstd: Faster "compression" of incompressible data. [#314](https://github.com/klauspost/compress/pull/314)
|
||||||
|
@ -518,7 +539,7 @@ While the release has been extensively tested, it is recommended to testing when
|
||||||
* Feb 19, 2016: Faster bit writer, level -2 is 15% faster, level 1 is 4% faster.
|
* Feb 19, 2016: Faster bit writer, level -2 is 15% faster, level 1 is 4% faster.
|
||||||
* Feb 19, 2016: Handle small payloads faster in level 1-3.
|
* Feb 19, 2016: Handle small payloads faster in level 1-3.
|
||||||
* Feb 19, 2016: Added faster level 2 + 3 compression modes.
|
* Feb 19, 2016: Added faster level 2 + 3 compression modes.
|
||||||
* Feb 19, 2016: [Rebalanced compression levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/), so there is a more even progresssion in terms of compression. New default level is 5.
|
* Feb 19, 2016: [Rebalanced compression levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/), so there is a more even progression in terms of compression. New default level is 5.
|
||||||
* Feb 14, 2016: Snappy: Merge upstream changes.
|
* Feb 14, 2016: Snappy: Merge upstream changes.
|
||||||
* Feb 14, 2016: Snappy: Fix aggressive skipping.
|
* Feb 14, 2016: Snappy: Fix aggressive skipping.
|
||||||
* Feb 14, 2016: Snappy: Update benchmark.
|
* Feb 14, 2016: Snappy: Update benchmark.
|
||||||
|
|
|
@ -15,7 +15,7 @@ const (
|
||||||
// It is possible, but by no way guaranteed that corrupt data will
|
// It is possible, but by no way guaranteed that corrupt data will
|
||||||
// return an error.
|
// return an error.
|
||||||
// It is up to the caller to verify integrity of the returned data.
|
// It is up to the caller to verify integrity of the returned data.
|
||||||
// Use a predefined Scrach to set maximum acceptable output size.
|
// Use a predefined Scratch to set maximum acceptable output size.
|
||||||
func Decompress(b []byte, s *Scratch) ([]byte, error) {
|
func Decompress(b []byte, s *Scratch) ([]byte, error) {
|
||||||
s, err := s.prepare(b)
|
s, err := s.prepare(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1136,7 +1136,7 @@ func (s *Scratch) matches(ct cTable, w io.Writer) {
|
||||||
errs++
|
errs++
|
||||||
}
|
}
|
||||||
if errs > 0 {
|
if errs > 0 {
|
||||||
fmt.Fprintf(w, "%d errros in base, stopping\n", errs)
|
fmt.Fprintf(w, "%d errors in base, stopping\n", errs)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Ensure that all combinations are covered.
|
// Ensure that all combinations are covered.
|
||||||
|
@ -1152,7 +1152,7 @@ func (s *Scratch) matches(ct cTable, w io.Writer) {
|
||||||
errs++
|
errs++
|
||||||
}
|
}
|
||||||
if errs > 20 {
|
if errs > 20 {
|
||||||
fmt.Fprintf(w, "%d errros, stopping\n", errs)
|
fmt.Fprintf(w, "%d errors, stopping\n", errs)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/klauspost/compress/internal/race"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Encode returns the encoded form of src. The returned slice may be a sub-
|
// Encode returns the encoded form of src. The returned slice may be a sub-
|
||||||
|
@ -52,6 +55,8 @@ func Encode(dst, src []byte) []byte {
|
||||||
return dst[:d]
|
return dst[:d]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var estblockPool [2]sync.Pool
|
||||||
|
|
||||||
// EstimateBlockSize will perform a very fast compression
|
// EstimateBlockSize will perform a very fast compression
|
||||||
// without outputting the result and return the compressed output size.
|
// without outputting the result and return the compressed output size.
|
||||||
// The function returns -1 if no improvement could be achieved.
|
// The function returns -1 if no improvement could be achieved.
|
||||||
|
@ -61,9 +66,25 @@ func EstimateBlockSize(src []byte) (d int) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if len(src) <= 1024 {
|
if len(src) <= 1024 {
|
||||||
d = calcBlockSizeSmall(src)
|
const sz, pool = 2048, 0
|
||||||
|
tmp, ok := estblockPool[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer estblockPool[pool].Put(tmp)
|
||||||
|
|
||||||
|
d = calcBlockSizeSmall(src, tmp)
|
||||||
} else {
|
} else {
|
||||||
d = calcBlockSize(src)
|
const sz, pool = 32768, 1
|
||||||
|
tmp, ok := estblockPool[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer estblockPool[pool].Put(tmp)
|
||||||
|
|
||||||
|
d = calcBlockSize(src, tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
if d == 0 {
|
if d == 0 {
|
||||||
|
|
|
@ -3,10 +3,16 @@
|
||||||
|
|
||||||
package s2
|
package s2
|
||||||
|
|
||||||
import "github.com/klauspost/compress/internal/race"
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/klauspost/compress/internal/race"
|
||||||
|
)
|
||||||
|
|
||||||
const hasAmd64Asm = true
|
const hasAmd64Asm = true
|
||||||
|
|
||||||
|
var encPools [4]sync.Pool
|
||||||
|
|
||||||
// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It
|
// 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
|
// assumes that the varint-encoded length of the decompressed bytes has already
|
||||||
// been written.
|
// been written.
|
||||||
|
@ -29,22 +35,59 @@ func encodeBlock(dst, src []byte) (d int) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(src) >= 4<<20 {
|
if len(src) >= 4<<20 {
|
||||||
return encodeBlockAsm(dst, src)
|
const sz, pool = 65536, 0
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeBlockAsm(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit12B {
|
if len(src) >= limit12B {
|
||||||
return encodeBlockAsm4MB(dst, src)
|
const sz, pool = 65536, 0
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeBlockAsm4MB(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit10B {
|
if len(src) >= limit10B {
|
||||||
return encodeBlockAsm12B(dst, src)
|
const sz, pool = 16384, 1
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeBlockAsm12B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit8B {
|
if len(src) >= limit8B {
|
||||||
return encodeBlockAsm10B(dst, src)
|
const sz, pool = 4096, 2
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeBlockAsm10B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) < minNonLiteralBlockSize {
|
if len(src) < minNonLiteralBlockSize {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return encodeBlockAsm8B(dst, src)
|
const sz, pool = 1024, 3
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
}
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeBlockAsm8B(dst, src, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
var encBetterPools [5]sync.Pool
|
||||||
|
|
||||||
// encodeBlockBetter encodes a non-empty src to a guaranteed-large-enough dst. It
|
// encodeBlockBetter encodes a non-empty src to a guaranteed-large-enough dst. It
|
||||||
// assumes that the varint-encoded length of the decompressed bytes has already
|
// assumes that the varint-encoded length of the decompressed bytes has already
|
||||||
|
@ -68,21 +111,59 @@ func encodeBlockBetter(dst, src []byte) (d int) {
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(src) > 4<<20 {
|
if len(src) > 4<<20 {
|
||||||
return encodeBetterBlockAsm(dst, src)
|
const sz, pool = 589824, 0
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeBetterBlockAsm(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit12B {
|
if len(src) >= limit12B {
|
||||||
return encodeBetterBlockAsm4MB(dst, src)
|
const sz, pool = 589824, 0
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
|
||||||
|
return encodeBetterBlockAsm4MB(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit10B {
|
if len(src) >= limit10B {
|
||||||
return encodeBetterBlockAsm12B(dst, src)
|
const sz, pool = 81920, 0
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
|
||||||
|
return encodeBetterBlockAsm12B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit8B {
|
if len(src) >= limit8B {
|
||||||
return encodeBetterBlockAsm10B(dst, src)
|
const sz, pool = 20480, 1
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeBetterBlockAsm10B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) < minNonLiteralBlockSize {
|
if len(src) < minNonLiteralBlockSize {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return encodeBetterBlockAsm8B(dst, src)
|
|
||||||
|
const sz, pool = 5120, 2
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeBetterBlockAsm8B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
|
// encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
|
||||||
|
@ -105,22 +186,57 @@ func encodeBlockSnappy(dst, src []byte) (d int) {
|
||||||
// Use 8 bit table when less than...
|
// Use 8 bit table when less than...
|
||||||
limit8B = 512
|
limit8B = 512
|
||||||
)
|
)
|
||||||
if len(src) >= 64<<10 {
|
if len(src) > 65536 {
|
||||||
return encodeSnappyBlockAsm(dst, src)
|
const sz, pool = 65536, 0
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBlockAsm(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit12B {
|
if len(src) >= limit12B {
|
||||||
return encodeSnappyBlockAsm64K(dst, src)
|
const sz, pool = 65536, 0
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBlockAsm64K(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit10B {
|
if len(src) >= limit10B {
|
||||||
return encodeSnappyBlockAsm12B(dst, src)
|
const sz, pool = 16384, 1
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBlockAsm12B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit8B {
|
if len(src) >= limit8B {
|
||||||
return encodeSnappyBlockAsm10B(dst, src)
|
const sz, pool = 4096, 2
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBlockAsm10B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) < minNonLiteralBlockSize {
|
if len(src) < minNonLiteralBlockSize {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return encodeSnappyBlockAsm8B(dst, src)
|
const sz, pool = 1024, 3
|
||||||
|
tmp, ok := encPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBlockAsm8B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
|
// encodeBlockSnappy encodes a non-empty src to a guaranteed-large-enough dst. It
|
||||||
|
@ -143,20 +259,59 @@ func encodeBlockBetterSnappy(dst, src []byte) (d int) {
|
||||||
// Use 8 bit table when less than...
|
// Use 8 bit table when less than...
|
||||||
limit8B = 512
|
limit8B = 512
|
||||||
)
|
)
|
||||||
if len(src) >= 64<<10 {
|
if len(src) > 65536 {
|
||||||
return encodeSnappyBetterBlockAsm(dst, src)
|
const sz, pool = 589824, 0
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
}
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBetterBlockAsm(dst, src, tmp)
|
||||||
|
}
|
||||||
|
|
||||||
if len(src) >= limit12B {
|
if len(src) >= limit12B {
|
||||||
return encodeSnappyBetterBlockAsm64K(dst, src)
|
const sz, pool = 294912, 4
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
|
||||||
|
return encodeSnappyBetterBlockAsm64K(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit10B {
|
if len(src) >= limit10B {
|
||||||
return encodeSnappyBetterBlockAsm12B(dst, src)
|
const sz, pool = 81920, 0
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
|
||||||
|
return encodeSnappyBetterBlockAsm12B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) >= limit8B {
|
if len(src) >= limit8B {
|
||||||
return encodeSnappyBetterBlockAsm10B(dst, src)
|
const sz, pool = 20480, 1
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBetterBlockAsm10B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
if len(src) < minNonLiteralBlockSize {
|
if len(src) < minNonLiteralBlockSize {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return encodeSnappyBetterBlockAsm8B(dst, src)
|
|
||||||
|
const sz, pool = 5120, 2
|
||||||
|
tmp, ok := encBetterPools[pool].Get().(*[sz]byte)
|
||||||
|
if !ok {
|
||||||
|
tmp = &[sz]byte{}
|
||||||
|
}
|
||||||
|
race.WriteSlice(tmp[:])
|
||||||
|
defer encBetterPools[pool].Put(tmp)
|
||||||
|
return encodeSnappyBetterBlockAsm8B(dst, src, tmp)
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ func matchLen(a []byte, b []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// input must be > inputMargin
|
// input must be > inputMargin
|
||||||
func calcBlockSize(src []byte) (d int) {
|
func calcBlockSize(src []byte, _ *[32768]byte) (d int) {
|
||||||
// Initialize the hash table.
|
// Initialize the hash table.
|
||||||
const (
|
const (
|
||||||
tableBits = 13
|
tableBits = 13
|
||||||
|
@ -503,7 +503,7 @@ emitRemainder:
|
||||||
}
|
}
|
||||||
|
|
||||||
// length must be > inputMargin.
|
// length must be > inputMargin.
|
||||||
func calcBlockSizeSmall(src []byte) (d int) {
|
func calcBlockSizeSmall(src []byte, _ *[2048]byte) (d int) {
|
||||||
// Initialize the hash table.
|
// Initialize the hash table.
|
||||||
const (
|
const (
|
||||||
tableBits = 9
|
tableBits = 9
|
||||||
|
|
|
@ -11,154 +11,154 @@ func _dummy_()
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBlockAsm(dst []byte, src []byte) int
|
func encodeBlockAsm(dst []byte, src []byte, tmp *[65536]byte) int
|
||||||
|
|
||||||
// encodeBlockAsm4MB encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBlockAsm4MB encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4194304 bytes.
|
// Maximum input 4194304 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBlockAsm4MB(dst []byte, src []byte) int
|
func encodeBlockAsm4MB(dst []byte, src []byte, tmp *[65536]byte) int
|
||||||
|
|
||||||
// encodeBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 16383 bytes.
|
// Maximum input 16383 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBlockAsm12B(dst []byte, src []byte) int
|
func encodeBlockAsm12B(dst []byte, src []byte, tmp *[16384]byte) int
|
||||||
|
|
||||||
// encodeBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4095 bytes.
|
// Maximum input 4095 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBlockAsm10B(dst []byte, src []byte) int
|
func encodeBlockAsm10B(dst []byte, src []byte, tmp *[4096]byte) int
|
||||||
|
|
||||||
// encodeBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 511 bytes.
|
// Maximum input 511 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBlockAsm8B(dst []byte, src []byte) int
|
func encodeBlockAsm8B(dst []byte, src []byte, tmp *[1024]byte) int
|
||||||
|
|
||||||
// encodeBetterBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBetterBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4294967295 bytes.
|
// Maximum input 4294967295 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBetterBlockAsm(dst []byte, src []byte) int
|
func encodeBetterBlockAsm(dst []byte, src []byte, tmp *[589824]byte) int
|
||||||
|
|
||||||
// encodeBetterBlockAsm4MB encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBetterBlockAsm4MB encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4194304 bytes.
|
// Maximum input 4194304 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBetterBlockAsm4MB(dst []byte, src []byte) int
|
func encodeBetterBlockAsm4MB(dst []byte, src []byte, tmp *[589824]byte) int
|
||||||
|
|
||||||
// encodeBetterBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBetterBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 16383 bytes.
|
// Maximum input 16383 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBetterBlockAsm12B(dst []byte, src []byte) int
|
func encodeBetterBlockAsm12B(dst []byte, src []byte, tmp *[81920]byte) int
|
||||||
|
|
||||||
// encodeBetterBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBetterBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4095 bytes.
|
// Maximum input 4095 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBetterBlockAsm10B(dst []byte, src []byte) int
|
func encodeBetterBlockAsm10B(dst []byte, src []byte, tmp *[20480]byte) int
|
||||||
|
|
||||||
// encodeBetterBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeBetterBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 511 bytes.
|
// Maximum input 511 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeBetterBlockAsm8B(dst []byte, src []byte) int
|
func encodeBetterBlockAsm8B(dst []byte, src []byte, tmp *[5120]byte) int
|
||||||
|
|
||||||
// encodeSnappyBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4294967295 bytes.
|
// Maximum input 4294967295 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBlockAsm(dst []byte, src []byte) int
|
func encodeSnappyBlockAsm(dst []byte, src []byte, tmp *[65536]byte) int
|
||||||
|
|
||||||
// encodeSnappyBlockAsm64K encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBlockAsm64K encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 65535 bytes.
|
// Maximum input 65535 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBlockAsm64K(dst []byte, src []byte) int
|
func encodeSnappyBlockAsm64K(dst []byte, src []byte, tmp *[65536]byte) int
|
||||||
|
|
||||||
// encodeSnappyBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 16383 bytes.
|
// Maximum input 16383 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBlockAsm12B(dst []byte, src []byte) int
|
func encodeSnappyBlockAsm12B(dst []byte, src []byte, tmp *[16384]byte) int
|
||||||
|
|
||||||
// encodeSnappyBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4095 bytes.
|
// Maximum input 4095 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBlockAsm10B(dst []byte, src []byte) int
|
func encodeSnappyBlockAsm10B(dst []byte, src []byte, tmp *[4096]byte) int
|
||||||
|
|
||||||
// encodeSnappyBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 511 bytes.
|
// Maximum input 511 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBlockAsm8B(dst []byte, src []byte) int
|
func encodeSnappyBlockAsm8B(dst []byte, src []byte, tmp *[1024]byte) int
|
||||||
|
|
||||||
// encodeSnappyBetterBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBetterBlockAsm encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4294967295 bytes.
|
// Maximum input 4294967295 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBetterBlockAsm(dst []byte, src []byte) int
|
func encodeSnappyBetterBlockAsm(dst []byte, src []byte, tmp *[589824]byte) int
|
||||||
|
|
||||||
// encodeSnappyBetterBlockAsm64K encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBetterBlockAsm64K encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 65535 bytes.
|
// Maximum input 65535 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBetterBlockAsm64K(dst []byte, src []byte) int
|
func encodeSnappyBetterBlockAsm64K(dst []byte, src []byte, tmp *[294912]byte) int
|
||||||
|
|
||||||
// encodeSnappyBetterBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBetterBlockAsm12B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 16383 bytes.
|
// Maximum input 16383 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBetterBlockAsm12B(dst []byte, src []byte) int
|
func encodeSnappyBetterBlockAsm12B(dst []byte, src []byte, tmp *[81920]byte) int
|
||||||
|
|
||||||
// encodeSnappyBetterBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBetterBlockAsm10B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4095 bytes.
|
// Maximum input 4095 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBetterBlockAsm10B(dst []byte, src []byte) int
|
func encodeSnappyBetterBlockAsm10B(dst []byte, src []byte, tmp *[20480]byte) int
|
||||||
|
|
||||||
// encodeSnappyBetterBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
// encodeSnappyBetterBlockAsm8B encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 511 bytes.
|
// Maximum input 511 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func encodeSnappyBetterBlockAsm8B(dst []byte, src []byte) int
|
func encodeSnappyBetterBlockAsm8B(dst []byte, src []byte, tmp *[5120]byte) int
|
||||||
|
|
||||||
// calcBlockSize encodes a non-empty src to a guaranteed-large-enough dst.
|
// calcBlockSize encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 4294967295 bytes.
|
// Maximum input 4294967295 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func calcBlockSize(src []byte) int
|
func calcBlockSize(src []byte, tmp *[32768]byte) int
|
||||||
|
|
||||||
// calcBlockSizeSmall encodes a non-empty src to a guaranteed-large-enough dst.
|
// calcBlockSizeSmall encodes a non-empty src to a guaranteed-large-enough dst.
|
||||||
// Maximum input 1024 bytes.
|
// Maximum input 1024 bytes.
|
||||||
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
// It assumes that the varint-encoded length of the decompressed bytes has already been written.
|
||||||
//
|
//
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func calcBlockSizeSmall(src []byte) int
|
func calcBlockSizeSmall(src []byte, tmp *[2048]byte) int
|
||||||
|
|
||||||
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
// emitLiteral writes a literal chunk and returns the number of bytes written.
|
||||||
//
|
//
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -83,11 +83,14 @@ type Writer struct {
|
||||||
snappy bool
|
snappy bool
|
||||||
flushOnWrite bool
|
flushOnWrite bool
|
||||||
appendIndex bool
|
appendIndex bool
|
||||||
|
bufferCB func([]byte)
|
||||||
level uint8
|
level uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
type result struct {
|
type result struct {
|
||||||
b []byte
|
b []byte
|
||||||
|
// return when writing
|
||||||
|
ret []byte
|
||||||
// Uncompressed start offset
|
// Uncompressed start offset
|
||||||
startOffset int64
|
startOffset int64
|
||||||
}
|
}
|
||||||
|
@ -146,6 +149,10 @@ func (w *Writer) Reset(writer io.Writer) {
|
||||||
for write := range toWrite {
|
for write := range toWrite {
|
||||||
// Wait for the data to be available.
|
// Wait for the data to be available.
|
||||||
input := <-write
|
input := <-write
|
||||||
|
if input.ret != nil && w.bufferCB != nil {
|
||||||
|
w.bufferCB(input.ret)
|
||||||
|
input.ret = nil
|
||||||
|
}
|
||||||
in := input.b
|
in := input.b
|
||||||
if len(in) > 0 {
|
if len(in) > 0 {
|
||||||
if w.err(nil) == nil {
|
if w.err(nil) == nil {
|
||||||
|
@ -341,7 +348,8 @@ func (w *Writer) AddSkippableBlock(id uint8, data []byte) (err error) {
|
||||||
// but the input buffer cannot be written to by the caller
|
// but the input buffer cannot be written to by the caller
|
||||||
// until Flush or Close has been called when concurrency != 1.
|
// until Flush or Close has been called when concurrency != 1.
|
||||||
//
|
//
|
||||||
// If you cannot control that, use the regular Write function.
|
// Use the WriterBufferDone to receive a callback when the buffer is done
|
||||||
|
// Processing.
|
||||||
//
|
//
|
||||||
// Note that input is not buffered.
|
// Note that input is not buffered.
|
||||||
// This means that each write will result in discrete blocks being created.
|
// This means that each write will result in discrete blocks being created.
|
||||||
|
@ -364,6 +372,9 @@ func (w *Writer) EncodeBuffer(buf []byte) (err error) {
|
||||||
}
|
}
|
||||||
if w.concurrency == 1 {
|
if w.concurrency == 1 {
|
||||||
_, err := w.writeSync(buf)
|
_, err := w.writeSync(buf)
|
||||||
|
if w.bufferCB != nil {
|
||||||
|
w.bufferCB(buf)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +389,7 @@ func (w *Writer) EncodeBuffer(buf []byte) (err error) {
|
||||||
hWriter <- result{startOffset: w.uncompWritten, b: magicChunkBytes}
|
hWriter <- result{startOffset: w.uncompWritten, b: magicChunkBytes}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
orgBuf := buf
|
||||||
for len(buf) > 0 {
|
for len(buf) > 0 {
|
||||||
// Cut input.
|
// Cut input.
|
||||||
uncompressed := buf
|
uncompressed := buf
|
||||||
|
@ -397,6 +408,9 @@ func (w *Writer) EncodeBuffer(buf []byte) (err error) {
|
||||||
startOffset: w.uncompWritten,
|
startOffset: w.uncompWritten,
|
||||||
}
|
}
|
||||||
w.uncompWritten += int64(len(uncompressed))
|
w.uncompWritten += int64(len(uncompressed))
|
||||||
|
if len(buf) == 0 && w.bufferCB != nil {
|
||||||
|
res.ret = orgBuf
|
||||||
|
}
|
||||||
go func() {
|
go func() {
|
||||||
race.ReadSlice(uncompressed)
|
race.ReadSlice(uncompressed)
|
||||||
|
|
||||||
|
@ -922,7 +936,7 @@ func WriterBetterCompression() WriterOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriterBestCompression will enable better compression.
|
// WriterBestCompression will enable better compression.
|
||||||
// EncodeBetter compresses better than Encode but typically with a
|
// EncodeBest compresses better than Encode but typically with a
|
||||||
// big speed decrease on compression.
|
// big speed decrease on compression.
|
||||||
func WriterBestCompression() WriterOption {
|
func WriterBestCompression() WriterOption {
|
||||||
return func(w *Writer) error {
|
return func(w *Writer) error {
|
||||||
|
@ -941,6 +955,17 @@ func WriterUncompressed() WriterOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriterBufferDone will perform a callback when EncodeBuffer has finished
|
||||||
|
// writing a buffer to the output and the buffer can safely be reused.
|
||||||
|
// If the buffer was split into several blocks, it will be sent after the last block.
|
||||||
|
// Callbacks will not be done concurrently.
|
||||||
|
func WriterBufferDone(fn func(b []byte)) WriterOption {
|
||||||
|
return func(w *Writer) error {
|
||||||
|
w.bufferCB = fn
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WriterBlockSize allows to override the default block size.
|
// WriterBlockSize allows to override the default block size.
|
||||||
// Blocks will be this size or smaller.
|
// Blocks will be this size or smaller.
|
||||||
// Minimum size is 4KB and maximum size is 4MB.
|
// Minimum size is 4KB and maximum size is 4MB.
|
||||||
|
|
|
@ -598,7 +598,9 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {
|
||||||
printf("RLE set to 0x%x, code: %v", symb, v)
|
printf("RLE set to 0x%x, code: %v", symb, v)
|
||||||
}
|
}
|
||||||
case compModeFSE:
|
case compModeFSE:
|
||||||
|
if debugDecoder {
|
||||||
println("Reading table for", tableIndex(i))
|
println("Reading table for", tableIndex(i))
|
||||||
|
}
|
||||||
if seq.fse == nil || seq.fse.preDefined {
|
if seq.fse == nil || seq.fse.preDefined {
|
||||||
seq.fse = fseDecoderPool.Get().(*fseDecoder)
|
seq.fse = fseDecoderPool.Get().(*fseDecoder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,9 +179,9 @@ encodeLoop:
|
||||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
length := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -210,12 +210,12 @@ encodeLoop:
|
||||||
|
|
||||||
// Index match start+1 (long) -> s - 1
|
// Index match start+1 (long) -> s - 1
|
||||||
index0 := s + repOff
|
index0 := s + repOff
|
||||||
s += lenght + repOff
|
s += length + repOff
|
||||||
|
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
@ -241,9 +241,9 @@ encodeLoop:
|
||||||
if false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {
|
if false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)
|
length := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -270,11 +270,11 @@ encodeLoop:
|
||||||
}
|
}
|
||||||
blk.sequences = append(blk.sequences, seq)
|
blk.sequences = append(blk.sequences, seq)
|
||||||
|
|
||||||
s += lenght + repOff2
|
s += length + repOff2
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
@ -708,9 +708,9 @@ encodeLoop:
|
||||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
length := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -738,12 +738,12 @@ encodeLoop:
|
||||||
blk.sequences = append(blk.sequences, seq)
|
blk.sequences = append(blk.sequences, seq)
|
||||||
|
|
||||||
// Index match start+1 (long) -> s - 1
|
// Index match start+1 (long) -> s - 1
|
||||||
s += lenght + repOff
|
s += length + repOff
|
||||||
|
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
@ -772,9 +772,9 @@ encodeLoop:
|
||||||
if false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {
|
if false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)
|
length := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -801,11 +801,11 @@ encodeLoop:
|
||||||
}
|
}
|
||||||
blk.sequences = append(blk.sequences, seq)
|
blk.sequences = append(blk.sequences, seq)
|
||||||
|
|
||||||
s += lenght + repOff2
|
s += length + repOff2
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
|
|
@ -138,9 +138,9 @@ encodeLoop:
|
||||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
length := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -166,11 +166,11 @@ encodeLoop:
|
||||||
println("repeat sequence", seq, "next s:", s)
|
println("repeat sequence", seq, "next s:", s)
|
||||||
}
|
}
|
||||||
blk.sequences = append(blk.sequences, seq)
|
blk.sequences = append(blk.sequences, seq)
|
||||||
s += lenght + repOff
|
s += length + repOff
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
@ -798,9 +798,9 @@ encodeLoop:
|
||||||
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
if repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {
|
||||||
// Consider history as well.
|
// Consider history as well.
|
||||||
var seq seq
|
var seq seq
|
||||||
lenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
length := 4 + e.matchlen(s+4+repOff, repIndex+4, src)
|
||||||
|
|
||||||
seq.matchLen = uint32(lenght - zstdMinMatch)
|
seq.matchLen = uint32(length - zstdMinMatch)
|
||||||
|
|
||||||
// We might be able to match backwards.
|
// We might be able to match backwards.
|
||||||
// Extend as long as we can.
|
// Extend as long as we can.
|
||||||
|
@ -826,11 +826,11 @@ encodeLoop:
|
||||||
println("repeat sequence", seq, "next s:", s)
|
println("repeat sequence", seq, "next s:", s)
|
||||||
}
|
}
|
||||||
blk.sequences = append(blk.sequences, seq)
|
blk.sequences = append(blk.sequences, seq)
|
||||||
s += lenght + repOff
|
s += length + repOff
|
||||||
nextEmit = s
|
nextEmit = s
|
||||||
if s >= sLimit {
|
if s >= sLimit {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("repeat ended", s, lenght)
|
println("repeat ended", s, length)
|
||||||
|
|
||||||
}
|
}
|
||||||
break encodeLoop
|
break encodeLoop
|
||||||
|
|
|
@ -6,6 +6,7 @@ package zstd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
@ -149,6 +150,9 @@ func (e *Encoder) ResetContentSize(w io.Writer, size int64) {
|
||||||
// and write CRC if requested.
|
// and write CRC if requested.
|
||||||
func (e *Encoder) Write(p []byte) (n int, err error) {
|
func (e *Encoder) Write(p []byte) (n int, err error) {
|
||||||
s := &e.state
|
s := &e.state
|
||||||
|
if s.eofWritten {
|
||||||
|
return 0, ErrEncoderClosed
|
||||||
|
}
|
||||||
for len(p) > 0 {
|
for len(p) > 0 {
|
||||||
if len(p)+len(s.filling) < e.o.blockSize {
|
if len(p)+len(s.filling) < e.o.blockSize {
|
||||||
if e.o.crc {
|
if e.o.crc {
|
||||||
|
@ -202,7 +206,7 @@ func (e *Encoder) nextBlock(final bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if final && len(s.filling) > 0 {
|
if final && len(s.filling) > 0 {
|
||||||
s.current = e.EncodeAll(s.filling, s.current[:0])
|
s.current = e.encodeAll(s.encoder, s.filling, s.current[:0])
|
||||||
var n2 int
|
var n2 int
|
||||||
n2, s.err = s.w.Write(s.current)
|
n2, s.err = s.w.Write(s.current)
|
||||||
if s.err != nil {
|
if s.err != nil {
|
||||||
|
@ -288,6 +292,9 @@ func (e *Encoder) nextBlock(final bool) error {
|
||||||
s.filling, s.current, s.previous = s.previous[:0], s.filling, s.current
|
s.filling, s.current, s.previous = s.previous[:0], s.filling, s.current
|
||||||
s.nInput += int64(len(s.current))
|
s.nInput += int64(len(s.current))
|
||||||
s.wg.Add(1)
|
s.wg.Add(1)
|
||||||
|
if final {
|
||||||
|
s.eofWritten = true
|
||||||
|
}
|
||||||
go func(src []byte) {
|
go func(src []byte) {
|
||||||
if debugEncoder {
|
if debugEncoder {
|
||||||
println("Adding block,", len(src), "bytes, final:", final)
|
println("Adding block,", len(src), "bytes, final:", final)
|
||||||
|
@ -303,9 +310,6 @@ func (e *Encoder) nextBlock(final bool) error {
|
||||||
blk := enc.Block()
|
blk := enc.Block()
|
||||||
enc.Encode(blk, src)
|
enc.Encode(blk, src)
|
||||||
blk.last = final
|
blk.last = final
|
||||||
if final {
|
|
||||||
s.eofWritten = true
|
|
||||||
}
|
|
||||||
// Wait for pending writes.
|
// Wait for pending writes.
|
||||||
s.wWg.Wait()
|
s.wWg.Wait()
|
||||||
if s.writeErr != nil {
|
if s.writeErr != nil {
|
||||||
|
@ -401,12 +405,20 @@ func (e *Encoder) Flush() error {
|
||||||
if len(s.filling) > 0 {
|
if len(s.filling) > 0 {
|
||||||
err := e.nextBlock(false)
|
err := e.nextBlock(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Ignore Flush after Close.
|
||||||
|
if errors.Is(s.err, ErrEncoderClosed) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.wg.Wait()
|
s.wg.Wait()
|
||||||
s.wWg.Wait()
|
s.wWg.Wait()
|
||||||
if s.err != nil {
|
if s.err != nil {
|
||||||
|
// Ignore Flush after Close.
|
||||||
|
if errors.Is(s.err, ErrEncoderClosed) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return s.err
|
return s.err
|
||||||
}
|
}
|
||||||
return s.writeErr
|
return s.writeErr
|
||||||
|
@ -422,6 +434,9 @@ func (e *Encoder) Close() error {
|
||||||
}
|
}
|
||||||
err := e.nextBlock(true)
|
err := e.nextBlock(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(s.err, ErrEncoderClosed) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if s.frameContentSize > 0 {
|
if s.frameContentSize > 0 {
|
||||||
|
@ -459,6 +474,11 @@ func (e *Encoder) Close() error {
|
||||||
}
|
}
|
||||||
_, s.err = s.w.Write(frame)
|
_, s.err = s.w.Write(frame)
|
||||||
}
|
}
|
||||||
|
if s.err == nil {
|
||||||
|
s.err = ErrEncoderClosed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return s.err
|
return s.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +489,15 @@ func (e *Encoder) Close() error {
|
||||||
// Data compressed with EncodeAll can be decoded with the Decoder,
|
// Data compressed with EncodeAll can be decoded with the Decoder,
|
||||||
// using either a stream or DecodeAll.
|
// using either a stream or DecodeAll.
|
||||||
func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
||||||
|
e.init.Do(e.initialize)
|
||||||
|
enc := <-e.encoders
|
||||||
|
defer func() {
|
||||||
|
e.encoders <- enc
|
||||||
|
}()
|
||||||
|
return e.encodeAll(enc, src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) encodeAll(enc encoder, src, dst []byte) []byte {
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
if e.o.fullZero {
|
if e.o.fullZero {
|
||||||
// Add frame header.
|
// Add frame header.
|
||||||
|
@ -491,13 +520,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
e.init.Do(e.initialize)
|
|
||||||
enc := <-e.encoders
|
|
||||||
defer func() {
|
|
||||||
// Release encoder reference to last block.
|
|
||||||
// If a non-single block is needed the encoder will reset again.
|
|
||||||
e.encoders <- enc
|
|
||||||
}()
|
|
||||||
// Use single segments when above minimum window and below window size.
|
// Use single segments when above minimum window and below window size.
|
||||||
single := len(src) <= e.o.windowSize && len(src) > MinWindowSize
|
single := len(src) <= e.o.windowSize && len(src) > MinWindowSize
|
||||||
if e.o.single != nil {
|
if e.o.single != nil {
|
||||||
|
|
|
@ -146,7 +146,9 @@ func (d *frameDec) reset(br byteBuffer) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if debugDecoder {
|
||||||
printf("raw: %x, mantissa: %d, exponent: %d\n", wd, wd&7, wd>>3)
|
printf("raw: %x, mantissa: %d, exponent: %d\n", wd, wd&7, wd>>3)
|
||||||
|
}
|
||||||
windowLog := 10 + (wd >> 3)
|
windowLog := 10 + (wd >> 3)
|
||||||
windowBase := uint64(1) << windowLog
|
windowBase := uint64(1) << windowLog
|
||||||
windowAdd := (windowBase / 8) * uint64(wd&0x7)
|
windowAdd := (windowBase / 8) * uint64(wd&0x7)
|
||||||
|
|
|
@ -146,7 +146,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
|
||||||
return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize)
|
return true, fmt.Errorf("output bigger than max block size (%d)", maxBlockSize)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode)
|
return true, fmt.Errorf("sequenceDecs_decode returned erroneous code %d", errCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.seqSize += ctx.litRemain
|
s.seqSize += ctx.litRemain
|
||||||
|
@ -292,7 +292,7 @@ func (s *sequenceDecs) decode(seqs []seqVals) error {
|
||||||
return io.ErrUnexpectedEOF
|
return io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode)
|
return fmt.Errorf("sequenceDecs_decode_amd64 returned erroneous code %d", errCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.litRemain < 0 {
|
if ctx.litRemain < 0 {
|
||||||
|
|
|
@ -1814,7 +1814,7 @@ TEXT ·sequenceDecs_decodeSync_amd64(SB), $64-32
|
||||||
MOVQ 40(SP), AX
|
MOVQ 40(SP), AX
|
||||||
ADDQ AX, 48(SP)
|
ADDQ AX, 48(SP)
|
||||||
|
|
||||||
// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)
|
// Calculate pointer to s.out[cap(s.out)] (a past-end pointer)
|
||||||
ADDQ R10, 32(SP)
|
ADDQ R10, 32(SP)
|
||||||
|
|
||||||
// outBase += outPosition
|
// outBase += outPosition
|
||||||
|
@ -2376,7 +2376,7 @@ TEXT ·sequenceDecs_decodeSync_bmi2(SB), $64-32
|
||||||
MOVQ 40(SP), CX
|
MOVQ 40(SP), CX
|
||||||
ADDQ CX, 48(SP)
|
ADDQ CX, 48(SP)
|
||||||
|
|
||||||
// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)
|
// Calculate pointer to s.out[cap(s.out)] (a past-end pointer)
|
||||||
ADDQ R9, 32(SP)
|
ADDQ R9, 32(SP)
|
||||||
|
|
||||||
// outBase += outPosition
|
// outBase += outPosition
|
||||||
|
@ -2896,7 +2896,7 @@ TEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $64-32
|
||||||
MOVQ 40(SP), AX
|
MOVQ 40(SP), AX
|
||||||
ADDQ AX, 48(SP)
|
ADDQ AX, 48(SP)
|
||||||
|
|
||||||
// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)
|
// Calculate pointer to s.out[cap(s.out)] (a past-end pointer)
|
||||||
ADDQ R10, 32(SP)
|
ADDQ R10, 32(SP)
|
||||||
|
|
||||||
// outBase += outPosition
|
// outBase += outPosition
|
||||||
|
@ -3560,7 +3560,7 @@ TEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $64-32
|
||||||
MOVQ 40(SP), CX
|
MOVQ 40(SP), CX
|
||||||
ADDQ CX, 48(SP)
|
ADDQ CX, 48(SP)
|
||||||
|
|
||||||
// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)
|
// Calculate pointer to s.out[cap(s.out)] (a past-end pointer)
|
||||||
ADDQ R9, 32(SP)
|
ADDQ R9, 32(SP)
|
||||||
|
|
||||||
// outBase += outPosition
|
// outBase += outPosition
|
||||||
|
|
|
@ -88,6 +88,10 @@ var (
|
||||||
// Close has been called.
|
// Close has been called.
|
||||||
ErrDecoderClosed = errors.New("decoder used after Close")
|
ErrDecoderClosed = errors.New("decoder used after Close")
|
||||||
|
|
||||||
|
// ErrEncoderClosed will be returned if the Encoder was used after
|
||||||
|
// Close has been called.
|
||||||
|
ErrEncoderClosed = errors.New("encoder used after Close")
|
||||||
|
|
||||||
// ErrDecoderNilInput is returned when a nil Reader was provided
|
// ErrDecoderNilInput is returned when a nil Reader was provided
|
||||||
// and an operation other than Reset/DecodeAll/Close was attempted.
|
// and an operation other than Reset/DecodeAll/Close was attempted.
|
||||||
ErrDecoderNilInput = errors.New("nil input provided as reader")
|
ErrDecoderNilInput = errors.New("nil input provided as reader")
|
||||||
|
|
|
@ -32,6 +32,10 @@ functional-test:
|
||||||
@GO111MODULE=on go build -race functional_tests.go
|
@GO111MODULE=on go build -race functional_tests.go
|
||||||
@SERVER_ENDPOINT=localhost:9000 ACCESS_KEY=minioadmin SECRET_KEY=minioadmin ENABLE_HTTPS=1 MINT_MODE=full ./functional_tests
|
@SERVER_ENDPOINT=localhost:9000 ACCESS_KEY=minioadmin SECRET_KEY=minioadmin ENABLE_HTTPS=1 MINT_MODE=full ./functional_tests
|
||||||
|
|
||||||
|
functional-test-notls:
|
||||||
|
@GO111MODULE=on go build -race functional_tests.go
|
||||||
|
@SERVER_ENDPOINT=localhost:9000 ACCESS_KEY=minioadmin SECRET_KEY=minioadmin ENABLE_HTTPS=0 MINT_MODE=full ./functional_tests
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@echo "Cleaning up all the generated files"
|
@echo "Cleaning up all the generated files"
|
||||||
@find . -name '*.test' | xargs rm -fv
|
@find . -name '*.test' | xargs rm -fv
|
||||||
|
|
|
@ -45,6 +45,8 @@ const (
|
||||||
ReplicationStatusFailed ReplicationStatus = "FAILED"
|
ReplicationStatusFailed ReplicationStatus = "FAILED"
|
||||||
// ReplicationStatusReplica indicates object is a replica of a source
|
// ReplicationStatusReplica indicates object is a replica of a source
|
||||||
ReplicationStatusReplica ReplicationStatus = "REPLICA"
|
ReplicationStatusReplica ReplicationStatus = "REPLICA"
|
||||||
|
// ReplicationStatusReplicaEdge indicates object is a replica of a edge source
|
||||||
|
ReplicationStatusReplicaEdge ReplicationStatus = "REPLICA-EDGE"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Empty returns true if no replication status set.
|
// Empty returns true if no replication status set.
|
||||||
|
|
|
@ -128,7 +128,7 @@ type Options struct {
|
||||||
// Global constants.
|
// Global constants.
|
||||||
const (
|
const (
|
||||||
libraryName = "minio-go"
|
libraryName = "minio-go"
|
||||||
libraryVersion = "v7.0.77"
|
libraryVersion = "v7.0.78"
|
||||||
)
|
)
|
||||||
|
|
||||||
// User Agent should always following the below style.
|
// User Agent should always following the below style.
|
||||||
|
|
|
@ -3565,16 +3565,10 @@ func validateObjectAttributeRequest(OA *minio.ObjectAttributes, opts *minio.Obje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasFullObjectChecksum := true
|
hasFullObjectChecksum := (OA.Checksum.ChecksumCRC32 != "" ||
|
||||||
if OA.Checksum.ChecksumCRC32 == "" {
|
OA.Checksum.ChecksumCRC32C != "" ||
|
||||||
if OA.Checksum.ChecksumCRC32C == "" {
|
OA.Checksum.ChecksumSHA1 != "" ||
|
||||||
if OA.Checksum.ChecksumSHA1 == "" {
|
OA.Checksum.ChecksumSHA256 != "")
|
||||||
if OA.Checksum.ChecksumSHA256 == "" {
|
|
||||||
hasFullObjectChecksum = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.HasFullChecksum {
|
if test.HasFullChecksum {
|
||||||
if !hasFullObjectChecksum {
|
if !hasFullObjectChecksum {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -85,29 +86,59 @@ type STSWebIdentity struct {
|
||||||
// assuming.
|
// assuming.
|
||||||
RoleARN string
|
RoleARN string
|
||||||
|
|
||||||
|
// Policy is the policy where the credentials should be limited too.
|
||||||
|
Policy string
|
||||||
|
|
||||||
// roleSessionName is the identifier for the assumed role session.
|
// roleSessionName is the identifier for the assumed role session.
|
||||||
roleSessionName string
|
roleSessionName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSTSWebIdentity returns a pointer to a new
|
// NewSTSWebIdentity returns a pointer to a new
|
||||||
// Credentials object wrapping the STSWebIdentity.
|
// Credentials object wrapping the STSWebIdentity.
|
||||||
func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdentityToken, error)) (*Credentials, error) {
|
func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdentityToken, error), opts ...func(*STSWebIdentity)) (*Credentials, error) {
|
||||||
if stsEndpoint == "" {
|
if stsEndpoint == "" {
|
||||||
return nil, errors.New("STS endpoint cannot be empty")
|
return nil, errors.New("STS endpoint cannot be empty")
|
||||||
}
|
}
|
||||||
if getWebIDTokenExpiry == nil {
|
if getWebIDTokenExpiry == nil {
|
||||||
return nil, errors.New("Web ID token and expiry retrieval function should be defined")
|
return nil, errors.New("Web ID token and expiry retrieval function should be defined")
|
||||||
}
|
}
|
||||||
return New(&STSWebIdentity{
|
i := &STSWebIdentity{
|
||||||
Client: &http.Client{
|
Client: &http.Client{
|
||||||
Transport: http.DefaultTransport,
|
Transport: http.DefaultTransport,
|
||||||
},
|
},
|
||||||
STSEndpoint: stsEndpoint,
|
STSEndpoint: stsEndpoint,
|
||||||
GetWebIDTokenExpiry: getWebIDTokenExpiry,
|
GetWebIDTokenExpiry: getWebIDTokenExpiry,
|
||||||
}), nil
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(i)
|
||||||
|
}
|
||||||
|
return New(i), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string,
|
// NewKubernetesIdentity returns a pointer to a new
|
||||||
|
// Credentials object using the Kubernetes service account
|
||||||
|
func NewKubernetesIdentity(stsEndpoint string, opts ...func(*STSWebIdentity)) (*Credentials, error) {
|
||||||
|
return NewSTSWebIdentity(stsEndpoint, func() (*WebIdentityToken, error) {
|
||||||
|
token, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &WebIdentityToken{
|
||||||
|
Token: string(token),
|
||||||
|
}, nil
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPolicy option will enforce that the returned credentials
|
||||||
|
// will be scoped down to the specified policy
|
||||||
|
func WithPolicy(policy string) func(*STSWebIdentity) {
|
||||||
|
return func(i *STSWebIdentity) {
|
||||||
|
i.Policy = policy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string, policy string,
|
||||||
getWebIDTokenExpiry func() (*WebIdentityToken, error),
|
getWebIDTokenExpiry func() (*WebIdentityToken, error),
|
||||||
) (AssumeRoleWithWebIdentityResponse, error) {
|
) (AssumeRoleWithWebIdentityResponse, error) {
|
||||||
idToken, err := getWebIDTokenExpiry()
|
idToken, err := getWebIDTokenExpiry()
|
||||||
|
@ -133,6 +164,9 @@ func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSession
|
||||||
if idToken.Expiry > 0 {
|
if idToken.Expiry > 0 {
|
||||||
v.Set("DurationSeconds", fmt.Sprintf("%d", idToken.Expiry))
|
v.Set("DurationSeconds", fmt.Sprintf("%d", idToken.Expiry))
|
||||||
}
|
}
|
||||||
|
if policy != "" {
|
||||||
|
v.Set("Policy", policy)
|
||||||
|
}
|
||||||
v.Set("Version", STSVersion)
|
v.Set("Version", STSVersion)
|
||||||
|
|
||||||
u, err := url.Parse(endpoint)
|
u, err := url.Parse(endpoint)
|
||||||
|
@ -183,7 +217,7 @@ func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSession
|
||||||
// Retrieve retrieves credentials from the MinIO service.
|
// Retrieve retrieves credentials from the MinIO service.
|
||||||
// Error will be returned if the request fails.
|
// Error will be returned if the request fails.
|
||||||
func (m *STSWebIdentity) Retrieve() (Value, error) {
|
func (m *STSWebIdentity) Retrieve() (Value, error) {
|
||||||
a, err := getWebIdentityCredentials(m.Client, m.STSEndpoint, m.RoleARN, m.roleSessionName, m.GetWebIDTokenExpiry)
|
a, err := getWebIdentityCredentials(m.Client, m.STSEndpoint, m.RoleARN, m.roleSessionName, m.Policy, m.GetWebIDTokenExpiry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Value{}, err
|
return Value{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ const (
|
||||||
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#tag-restrictions
|
// https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html#tag-restrictions
|
||||||
// borrowed from this article and also testing various ASCII characters following regex
|
// borrowed from this article and also testing various ASCII characters following regex
|
||||||
// is supported by AWS S3 for both tags and values.
|
// is supported by AWS S3 for both tags and values.
|
||||||
var validTagKeyValue = regexp.MustCompile(`^[a-zA-Z0-9-+\-._:/@ ]+$`)
|
var validTagKeyValue = regexp.MustCompile(`^[a-zA-Z0-9-+\-._:/@ =]+$`)
|
||||||
|
|
||||||
func checkKey(key string) error {
|
func checkKey(key string) error {
|
||||||
if len(key) == 0 {
|
if len(key) == 0 {
|
||||||
|
|
|
@ -441,8 +441,8 @@ github.com/json-iterator/go
|
||||||
# github.com/k3a/html2text v1.2.1
|
# github.com/k3a/html2text v1.2.1
|
||||||
## explicit; go 1.16
|
## explicit; go 1.16
|
||||||
github.com/k3a/html2text
|
github.com/k3a/html2text
|
||||||
# github.com/klauspost/compress v1.17.9
|
# github.com/klauspost/compress v1.17.11
|
||||||
## explicit; go 1.20
|
## explicit; go 1.21
|
||||||
github.com/klauspost/compress
|
github.com/klauspost/compress
|
||||||
github.com/klauspost/compress/fse
|
github.com/klauspost/compress/fse
|
||||||
github.com/klauspost/compress/huff0
|
github.com/klauspost/compress/huff0
|
||||||
|
@ -486,8 +486,8 @@ github.com/miekg/dns
|
||||||
# github.com/minio/md5-simd v1.1.2
|
# github.com/minio/md5-simd v1.1.2
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/minio/md5-simd
|
github.com/minio/md5-simd
|
||||||
# github.com/minio/minio-go/v7 v7.0.77
|
# github.com/minio/minio-go/v7 v7.0.78
|
||||||
## explicit; go 1.21
|
## explicit; go 1.22
|
||||||
github.com/minio/minio-go/v7
|
github.com/minio/minio-go/v7
|
||||||
github.com/minio/minio-go/v7/pkg/cors
|
github.com/minio/minio-go/v7/pkg/cors
|
||||||
github.com/minio/minio-go/v7/pkg/credentials
|
github.com/minio/minio-go/v7/pkg/credentials
|
||||||
|
|
Loading…
Reference in New Issue