Skip to content

Commit

Permalink
[zstd] Move Bulk & Ctx to use decompressSizeHint
Browse files Browse the repository at this point in the history
  • Loading branch information
Viq111 committed Apr 6, 2022
1 parent 489b911 commit ea44f5f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 39 deletions.
9 changes: 2 additions & 7 deletions zstd_bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ var (
ErrEmptyDictionary = errors.New("Dictionary is empty")
// ErrBadDictionary is returned when cannot load the given dictionary
ErrBadDictionary = errors.New("Cannot load dictionary")
// ErrContentSize is returned when cannot determine the content size
ErrContentSize = errors.New("Cannot determine the content size")
)

// BulkProcessor implements Bulk processing dictionary API.
Expand Down Expand Up @@ -111,12 +109,9 @@ func (p *BulkProcessor) Decompress(dst, src []byte) ([]byte, error) {
if len(src) == 0 {
return nil, ErrEmptySlice
}
contentSize := uint64(C.ZSTD_getFrameContentSize(unsafe.Pointer(&src[0]), C.size_t(len(src))))
if contentSize == C.ZSTD_CONTENTSIZE_ERROR || contentSize == C.ZSTD_CONTENTSIZE_UNKNOWN {
return nil, ErrContentSize
}

if cap(dst) >= int(contentSize) {
contentSize := decompressSizeHint(src)
if cap(dst) >= contentSize {
dst = dst[0:contentSize]
} else {
dst = make([]byte, contentSize)
Expand Down
48 changes: 16 additions & 32 deletions zstd_ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,43 +96,27 @@ func (c *ctx) Decompress(dst, src []byte) ([]byte, error) {
if len(src) == 0 {
return []byte{}, ErrEmptySlice
}
decompress := func(dst, src []byte) ([]byte, error) {

cWritten := C.ZSTD_decompressDCtx(
c.dctx,
unsafe.Pointer(&dst[0]),
C.size_t(len(dst)),
unsafe.Pointer(&src[0]),
C.size_t(len(src)))

written := int(cWritten)
// Check error
if err := getError(written); err != nil {
return nil, err
}
return dst[:written], nil
bound := decompressSizeHint(src)
if cap(dst) >= bound {
dst = dst[0:cap(dst)]
} else {
dst = make([]byte, bound)
}

if len(dst) == 0 {
// Attempt to use zStd to determine decompressed size (may result in error or 0)
size := int(C.size_t(C.ZSTD_getDecompressedSize(unsafe.Pointer(&src[0]), C.size_t(len(src)))))

if err := getError(size); err != nil {
return nil, err
}
written := int(C.ZSTD_decompressDCtx(
c.dctx,
unsafe.Pointer(&dst[0]),
C.size_t(len(dst)),
unsafe.Pointer(&src[0]),
C.size_t(len(src))))

if size > 0 {
dst = make([]byte, size)
} else {
dst = make([]byte, len(src)*3) // starting guess
}
err := getError(written)
if err == nil {
return dst[:written], nil
}
for i := 0; i < 3; i++ { // 3 tries to allocate a bigger buffer
result, err := decompress(dst, src)
if !IsDstSizeTooSmallError(err) {
return result, err
}
dst = make([]byte, len(dst)*2) // Grow buffer by 2
if !IsDstSizeTooSmallError(err) {
return nil, err
}

// We failed getting a dst buffer of correct size, use stream API
Expand Down

0 comments on commit ea44f5f

Please sign in to comment.