Compare commits
12
Commits
dev
...
v1.5.2-kernel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e43f53c93 | ||
|
|
e5bd2fdaa4 | ||
|
|
01cef9b928 | ||
|
|
5e88debd62 | ||
|
|
502afcd992 | ||
|
|
e26ddac10f | ||
|
|
e47e674cd0 | ||
|
|
791626dfb9 | ||
|
|
f4a541b021 | ||
|
|
a488ba114e | ||
|
|
e4558ffd1d | ||
|
|
97a3da1df0 |
@@ -55,10 +55,13 @@ libzstd:
|
|||||||
-DZSTD_HAVE_WEAK_SYMBOLS=0 \
|
-DZSTD_HAVE_WEAK_SYMBOLS=0 \
|
||||||
-DZSTD_TRACE=0 \
|
-DZSTD_TRACE=0 \
|
||||||
-DZSTD_NO_TRACE \
|
-DZSTD_NO_TRACE \
|
||||||
|
-DZSTD_DISABLE_ASM \
|
||||||
-DZSTD_LINUX_KERNEL
|
-DZSTD_LINUX_KERNEL
|
||||||
|
rm linux/lib/zstd/decompress/huf_decompress_amd64.S
|
||||||
mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h
|
mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h
|
||||||
mv linux/lib/zstd/zstd_errors.h linux/include/linux/
|
mv linux/lib/zstd/zstd_errors.h linux/include/linux/
|
||||||
cp linux_zstd.h linux/include/linux/zstd.h
|
cp linux_zstd.h linux/include/linux/zstd.h
|
||||||
|
cp zstd_common_module.c linux/lib/zstd
|
||||||
cp zstd_compress_module.c linux/lib/zstd
|
cp zstd_compress_module.c linux/lib/zstd
|
||||||
cp zstd_decompress_module.c linux/lib/zstd
|
cp zstd_decompress_module.c linux/lib/zstd
|
||||||
cp decompress_sources.h linux/lib/zstd
|
cp decompress_sources.h linux/lib/zstd
|
||||||
@@ -102,4 +105,5 @@ test: libzstd
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) -rf linux test/test test/static_test
|
$(RM) -rf linux
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
|||||||
@@ -10,16 +10,10 @@
|
|||||||
# ################################################################
|
# ################################################################
|
||||||
obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
|
obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
|
||||||
obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
|
obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
|
||||||
|
obj-$(CONFIG_ZSTD_COMMON) += zstd_common.o
|
||||||
ccflags-y += -Wno-error=deprecated-declarations
|
|
||||||
|
|
||||||
zstd_compress-y := \
|
zstd_compress-y := \
|
||||||
zstd_compress_module.o \
|
zstd_compress_module.o \
|
||||||
common/debug.o \
|
|
||||||
common/entropy_common.o \
|
|
||||||
common/error_private.o \
|
|
||||||
common/fse_decompress.o \
|
|
||||||
common/zstd_common.o \
|
|
||||||
compress/fse_compress.o \
|
compress/fse_compress.o \
|
||||||
compress/hist.o \
|
compress/hist.o \
|
||||||
compress/huf_compress.o \
|
compress/huf_compress.o \
|
||||||
@@ -35,13 +29,15 @@ zstd_compress-y := \
|
|||||||
|
|
||||||
zstd_decompress-y := \
|
zstd_decompress-y := \
|
||||||
zstd_decompress_module.o \
|
zstd_decompress_module.o \
|
||||||
|
decompress/huf_decompress.o \
|
||||||
|
decompress/zstd_ddict.o \
|
||||||
|
decompress/zstd_decompress.o \
|
||||||
|
decompress/zstd_decompress_block.o \
|
||||||
|
|
||||||
|
zstd_common-y := \
|
||||||
|
zstd_common_module.o \
|
||||||
common/debug.o \
|
common/debug.o \
|
||||||
common/entropy_common.o \
|
common/entropy_common.o \
|
||||||
common/error_private.o \
|
common/error_private.o \
|
||||||
common/fse_decompress.o \
|
common/fse_decompress.o \
|
||||||
common/zstd_common.o \
|
common/zstd_common.o \
|
||||||
decompress/huf_decompress.o \
|
|
||||||
decompress/huf_decompress_amd64.o \
|
|
||||||
decompress/zstd_ddict.o \
|
|
||||||
decompress/zstd_decompress.o \
|
|
||||||
decompress/zstd_decompress_block.o \
|
|
||||||
|
|||||||
@@ -45,4 +45,5 @@ clean:
|
|||||||
$(RM) -f $(LINUX_ZSTDLIB)/*.o
|
$(RM) -f $(LINUX_ZSTDLIB)/*.o
|
||||||
$(RM) -f $(LINUX_ZSTDLIB)/**/*.o
|
$(RM) -f $(LINUX_ZSTDLIB)/**/*.o
|
||||||
$(RM) -f *.o *.a
|
$(RM) -f *.o *.a
|
||||||
|
$(RM) -f static_test
|
||||||
$(RM) -f test
|
$(RM) -f test
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#define EXPORT_SYMBOL(symbol) \
|
#define EXPORT_SYMBOL(symbol) \
|
||||||
void* __##symbol = symbol
|
void* __##symbol = symbol
|
||||||
|
#define EXPORT_SYMBOL_GPL(symbol) \
|
||||||
|
void* __##symbol = symbol
|
||||||
#define MODULE_LICENSE(license)
|
#define MODULE_LICENSE(license)
|
||||||
#define MODULE_DESCRIPTION(description)
|
#define MODULE_DESCRIPTION(description)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||||
|
/*
|
||||||
|
* Copyright (c) Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under both the BSD-style license (found in the
|
||||||
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||||
|
* in the COPYING file in the root directory of this source tree).
|
||||||
|
* You may select, at your option, one of the above-listed licenses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "common/huf.h"
|
||||||
|
#include "common/fse.h"
|
||||||
|
#include "common/zstd_internal.h"
|
||||||
|
|
||||||
|
// Export symbols shared by compress and decompress into a common module
|
||||||
|
|
||||||
|
#undef ZSTD_isError /* defined within zstd_internal.h */
|
||||||
|
EXPORT_SYMBOL_GPL(FSE_readNCount);
|
||||||
|
EXPORT_SYMBOL_GPL(HUF_readStats);
|
||||||
|
EXPORT_SYMBOL_GPL(HUF_readStats_wksp);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_isError);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_getErrorName);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_getErrorCode);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_customMalloc);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_customCalloc);
|
||||||
|
EXPORT_SYMBOL_GPL(ZSTD_customFree);
|
||||||
|
|
||||||
|
MODULE_LICENSE("Dual BSD/GPL");
|
||||||
|
MODULE_DESCRIPTION("Zstd Common");
|
||||||
@@ -133,7 +133,11 @@ EXPORT_SYMBOL(zstd_init_cstream);
|
|||||||
size_t zstd_reset_cstream(zstd_cstream *cstream,
|
size_t zstd_reset_cstream(zstd_cstream *cstream,
|
||||||
unsigned long long pledged_src_size)
|
unsigned long long pledged_src_size)
|
||||||
{
|
{
|
||||||
return ZSTD_resetCStream(cstream, pledged_src_size);
|
if (pledged_src_size == 0)
|
||||||
|
pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN;
|
||||||
|
ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_reset(cstream, ZSTD_reset_session_only) );
|
||||||
|
ZSTD_FORWARD_IF_ERR( ZSTD_CCtx_setPledgedSrcSize(cstream, pledged_src_size) );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(zstd_reset_cstream);
|
EXPORT_SYMBOL(zstd_reset_cstream);
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,12 @@
|
|||||||
#define UNLIKELY(x) (x)
|
#define UNLIKELY(x) (x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
|
||||||
|
# define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
|
||||||
|
#else
|
||||||
|
# define ZSTD_UNREACHABLE { assert(0); }
|
||||||
|
#endif
|
||||||
|
|
||||||
/* disable warnings */
|
/* disable warnings */
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
# include <intrin.h> /* For Visual 2005 */
|
# include <intrin.h> /* For Visual 2005 */
|
||||||
|
|||||||
@@ -5764,7 +5764,7 @@ ZSTD_validateSequence(U32 offCode, U32 matchLength,
|
|||||||
size_t posInSrc, U32 windowLog, size_t dictSize)
|
size_t posInSrc, U32 windowLog, size_t dictSize)
|
||||||
{
|
{
|
||||||
U32 const windowSize = 1 << windowLog;
|
U32 const windowSize = 1 << windowLog;
|
||||||
/* posInSrc represents the amount of data the the decoder would decode up to this point.
|
/* posInSrc represents the amount of data the decoder would decode up to this point.
|
||||||
* As long as the amount of data decoded is less than or equal to window size, offsets may be
|
* As long as the amount of data decoded is less than or equal to window size, offsets may be
|
||||||
* larger than the total length of output decoded in order to reference the dict, even larger than
|
* larger than the total length of output decoded in order to reference the dict, even larger than
|
||||||
* window size. After output surpasses windowSize, we're limited to windowSize offsets again.
|
* window size. After output surpasses windowSize, we're limited to windowSize offsets again.
|
||||||
|
|||||||
+118
-111
@@ -1304,14 +1304,10 @@ size_t ZSTD_RowFindBestMatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef size_t (*searchMax_f)(
|
|
||||||
ZSTD_matchState_t* ms,
|
|
||||||
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct contains the functions necessary for lazy to search.
|
* Generate search functions templated on (dictMode, mls, rowLog).
|
||||||
* Currently, that is only searchMax. However, it is still valuable to have the
|
* These functions are outlined for code size & compilation time.
|
||||||
* VTable because this makes it easier to add more functions to the VTable later.
|
* ZSTD_searchMax() dispatches to the correct implementation function.
|
||||||
*
|
*
|
||||||
* TODO: The start of the search function involves loading and calculating a
|
* TODO: The start of the search function involves loading and calculating a
|
||||||
* bunch of constants from the ZSTD_matchState_t. These computations could be
|
* bunch of constants from the ZSTD_matchState_t. These computations could be
|
||||||
@@ -1329,25 +1325,25 @@ typedef size_t (*searchMax_f)(
|
|||||||
* the single segment loop. It should go in searchMax instead of its own
|
* the single segment loop. It should go in searchMax instead of its own
|
||||||
* function to avoid having multiple virtual function calls per search.
|
* function to avoid having multiple virtual function calls per search.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
|
||||||
searchMax_f searchMax;
|
|
||||||
} ZSTD_LazyVTable;
|
|
||||||
|
|
||||||
#define GEN_ZSTD_BT_VTABLE(dictMode, mls) \
|
#define ZSTD_BT_SEARCH_FN(dictMode, mls) ZSTD_BtFindBestMatch_##dictMode##_##mls
|
||||||
static size_t ZSTD_BtFindBestMatch_##dictMode##_##mls( \
|
#define ZSTD_HC_SEARCH_FN(dictMode, mls) ZSTD_HcFindBestMatch_##dictMode##_##mls
|
||||||
ZSTD_matchState_t* ms, \
|
#define ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog
|
||||||
const BYTE* ip, const BYTE* const iLimit, \
|
|
||||||
size_t* offsetPtr) \
|
|
||||||
{ \
|
|
||||||
assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
|
|
||||||
return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
|
|
||||||
} \
|
|
||||||
static const ZSTD_LazyVTable ZSTD_BtVTable_##dictMode##_##mls = { \
|
|
||||||
ZSTD_BtFindBestMatch_##dictMode##_##mls \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GEN_ZSTD_HC_VTABLE(dictMode, mls) \
|
#define ZSTD_SEARCH_FN_ATTRS FORCE_NOINLINE
|
||||||
static size_t ZSTD_HcFindBestMatch_##dictMode##_##mls( \
|
|
||||||
|
#define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls) \
|
||||||
|
ZSTD_SEARCH_FN_ATTRS size_t ZSTD_BT_SEARCH_FN(dictMode, mls)( \
|
||||||
|
ZSTD_matchState_t* ms, \
|
||||||
|
const BYTE* ip, const BYTE* const iLimit, \
|
||||||
|
size_t* offBasePtr) \
|
||||||
|
{ \
|
||||||
|
assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
|
||||||
|
return ZSTD_BtFindBestMatch(ms, ip, iLimit, offBasePtr, mls, ZSTD_##dictMode); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
#define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls) \
|
||||||
|
ZSTD_SEARCH_FN_ATTRS size_t ZSTD_HC_SEARCH_FN(dictMode, mls)( \
|
||||||
ZSTD_matchState_t* ms, \
|
ZSTD_matchState_t* ms, \
|
||||||
const BYTE* ip, const BYTE* const iLimit, \
|
const BYTE* ip, const BYTE* const iLimit, \
|
||||||
size_t* offsetPtr) \
|
size_t* offsetPtr) \
|
||||||
@@ -1355,12 +1351,9 @@ typedef struct {
|
|||||||
assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
|
assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
|
||||||
return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
|
return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
|
||||||
} \
|
} \
|
||||||
static const ZSTD_LazyVTable ZSTD_HcVTable_##dictMode##_##mls = { \
|
|
||||||
ZSTD_HcFindBestMatch_##dictMode##_##mls \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GEN_ZSTD_ROW_VTABLE(dictMode, mls, rowLog) \
|
#define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) \
|
||||||
static size_t ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog( \
|
ZSTD_SEARCH_FN_ATTRS size_t ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)( \
|
||||||
ZSTD_matchState_t* ms, \
|
ZSTD_matchState_t* ms, \
|
||||||
const BYTE* ip, const BYTE* const iLimit, \
|
const BYTE* ip, const BYTE* const iLimit, \
|
||||||
size_t* offsetPtr) \
|
size_t* offsetPtr) \
|
||||||
@@ -1369,9 +1362,6 @@ typedef struct {
|
|||||||
assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \
|
assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \
|
||||||
return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \
|
return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \
|
||||||
} \
|
} \
|
||||||
static const ZSTD_LazyVTable ZSTD_RowVTable_##dictMode##_##mls##_##rowLog = { \
|
|
||||||
ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog \
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \
|
#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \
|
||||||
X(dictMode, mls, 4) \
|
X(dictMode, mls, 4) \
|
||||||
@@ -1394,83 +1384,102 @@ typedef struct {
|
|||||||
X(__VA_ARGS__, dictMatchState) \
|
X(__VA_ARGS__, dictMatchState) \
|
||||||
X(__VA_ARGS__, dedicatedDictSearch)
|
X(__VA_ARGS__, dedicatedDictSearch)
|
||||||
|
|
||||||
/* Generate Row VTables for each combination of (dictMode, mls, rowLog) */
|
/* Generate row search fns for each combination of (dictMode, mls, rowLog) */
|
||||||
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_VTABLE)
|
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_SEARCH_FN)
|
||||||
/* Generate Binary Tree VTables for each combination of (dictMode, mls) */
|
/* Generate binary Tree search fns for each combination of (dictMode, mls) */
|
||||||
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_VTABLE)
|
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_SEARCH_FN)
|
||||||
/* Generate Hash Chain VTables for each combination of (dictMode, mls) */
|
/* Generate hash chain search fns for each combination of (dictMode, mls) */
|
||||||
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_VTABLE)
|
ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_SEARCH_FN)
|
||||||
|
|
||||||
#define GEN_ZSTD_BT_VTABLE_ARRAY(dictMode) \
|
typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e;
|
||||||
{ \
|
|
||||||
&ZSTD_BtVTable_##dictMode##_4, \
|
#define GEN_ZSTD_CALL_BT_SEARCH_FN(dictMode, mls) \
|
||||||
&ZSTD_BtVTable_##dictMode##_5, \
|
case mls: \
|
||||||
&ZSTD_BtVTable_##dictMode##_6 \
|
return ZSTD_BT_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr);
|
||||||
|
#define GEN_ZSTD_CALL_HC_SEARCH_FN(dictMode, mls) \
|
||||||
|
case mls: \
|
||||||
|
return ZSTD_HC_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr);
|
||||||
|
#define GEN_ZSTD_CALL_ROW_SEARCH_FN(dictMode, mls, rowLog) \
|
||||||
|
case rowLog: \
|
||||||
|
return ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)(ms, ip, iend, offsetPtr);
|
||||||
|
|
||||||
|
#define ZSTD_SWITCH_MLS(X, dictMode) \
|
||||||
|
switch (mls) { \
|
||||||
|
ZSTD_FOR_EACH_MLS(X, dictMode) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GEN_ZSTD_HC_VTABLE_ARRAY(dictMode) \
|
#define ZSTD_SWITCH_ROWLOG(dictMode, mls) \
|
||||||
{ \
|
case mls: \
|
||||||
&ZSTD_HcVTable_##dictMode##_4, \
|
switch (rowLog) { \
|
||||||
&ZSTD_HcVTable_##dictMode##_5, \
|
ZSTD_FOR_EACH_ROWLOG(GEN_ZSTD_CALL_ROW_SEARCH_FN, dictMode, mls) \
|
||||||
&ZSTD_HcVTable_##dictMode##_6 \
|
} \
|
||||||
}
|
ZSTD_UNREACHABLE; \
|
||||||
|
break;
|
||||||
|
|
||||||
#define GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, mls) \
|
#define ZSTD_SWITCH_SEARCH_METHOD(dictMode) \
|
||||||
{ \
|
switch (searchMethod) { \
|
||||||
&ZSTD_RowVTable_##dictMode##_##mls##_4, \
|
case search_hashChain: \
|
||||||
&ZSTD_RowVTable_##dictMode##_##mls##_5, \
|
ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_HC_SEARCH_FN, dictMode) \
|
||||||
&ZSTD_RowVTable_##dictMode##_##mls##_6 \
|
break; \
|
||||||
}
|
case search_binaryTree: \
|
||||||
|
ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_BT_SEARCH_FN, dictMode) \
|
||||||
|
break; \
|
||||||
|
case search_rowHash: \
|
||||||
|
ZSTD_SWITCH_MLS(ZSTD_SWITCH_ROWLOG, dictMode) \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
ZSTD_UNREACHABLE;
|
||||||
|
|
||||||
#define GEN_ZSTD_ROW_VTABLE_ARRAY(dictMode) \
|
/**
|
||||||
{ \
|
* Searches for the longest match at @p ip.
|
||||||
GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 4), \
|
* Dispatches to the correct implementation function based on the
|
||||||
GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 5), \
|
* (searchMethod, dictMode, mls, rowLog). We use switch statements
|
||||||
GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 6) \
|
* here instead of using an indirect function call through a function
|
||||||
}
|
* pointer because after Spectre and Meltdown mitigations, indirect
|
||||||
|
* function calls can be very costly, especially in the kernel.
|
||||||
#define GEN_ZSTD_VTABLE_ARRAY(X) \
|
*
|
||||||
{ \
|
* NOTE: dictMode and searchMethod should be templated, so those switch
|
||||||
X(noDict), \
|
* statements should be optimized out. Only the mls & rowLog switches
|
||||||
X(extDict), \
|
* should be left.
|
||||||
X(dictMatchState), \
|
*
|
||||||
X(dedicatedDictSearch) \
|
* @param ms The match state.
|
||||||
|
* @param ip The position to search at.
|
||||||
|
* @param iend The end of the input data.
|
||||||
|
* @param[out] offsetPtr Stores the match offset into this pointer.
|
||||||
|
* @param mls The minimum search length, in the range [4, 6].
|
||||||
|
* @param rowLog The row log (if applicable), in the range [4, 6].
|
||||||
|
* @param searchMethod The search method to use (templated).
|
||||||
|
* @param dictMode The dictMode (templated).
|
||||||
|
*
|
||||||
|
* @returns The length of the longest match found, or < mls if no match is found.
|
||||||
|
* If a match is found its offset is stored in @p offsetPtr.
|
||||||
|
*/
|
||||||
|
FORCE_INLINE_TEMPLATE size_t ZSTD_searchMax(
|
||||||
|
ZSTD_matchState_t* ms,
|
||||||
|
const BYTE* ip,
|
||||||
|
const BYTE* iend,
|
||||||
|
size_t* offsetPtr,
|
||||||
|
U32 const mls,
|
||||||
|
U32 const rowLog,
|
||||||
|
searchMethod_e const searchMethod,
|
||||||
|
ZSTD_dictMode_e const dictMode)
|
||||||
|
{
|
||||||
|
if (dictMode == ZSTD_noDict) {
|
||||||
|
ZSTD_SWITCH_SEARCH_METHOD(noDict)
|
||||||
|
} else if (dictMode == ZSTD_extDict) {
|
||||||
|
ZSTD_SWITCH_SEARCH_METHOD(extDict)
|
||||||
|
} else if (dictMode == ZSTD_dictMatchState) {
|
||||||
|
ZSTD_SWITCH_SEARCH_METHOD(dictMatchState)
|
||||||
|
} else if (dictMode == ZSTD_dedicatedDictSearch) {
|
||||||
|
ZSTD_SWITCH_SEARCH_METHOD(dedicatedDictSearch)
|
||||||
}
|
}
|
||||||
|
ZSTD_UNREACHABLE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* *******************************
|
/* *******************************
|
||||||
* Common parser - lazy strategy
|
* Common parser - lazy strategy
|
||||||
*********************************/
|
*********************************/
|
||||||
typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This table is indexed first by the four ZSTD_dictMode_e values, and then
|
|
||||||
* by the two searchMethod_e values. NULLs are placed for configurations
|
|
||||||
* that should never occur (extDict modes go to the other implementation
|
|
||||||
* below and there is no DDSS for binary tree search yet).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static ZSTD_LazyVTable const*
|
|
||||||
ZSTD_selectLazyVTable(ZSTD_matchState_t const* ms, searchMethod_e searchMethod, ZSTD_dictMode_e dictMode)
|
|
||||||
{
|
|
||||||
/* Fill the Hc/Bt VTable arrays with the right functions for the (dictMode, mls) combination. */
|
|
||||||
ZSTD_LazyVTable const* const hcVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_HC_VTABLE_ARRAY);
|
|
||||||
ZSTD_LazyVTable const* const btVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_BT_VTABLE_ARRAY);
|
|
||||||
/* Fill the Row VTable array with the right functions for the (dictMode, mls, rowLog) combination. */
|
|
||||||
ZSTD_LazyVTable const* const rowVTables[4][3][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_ROW_VTABLE_ARRAY);
|
|
||||||
|
|
||||||
U32 const mls = MAX(4, MIN(6, ms->cParams.minMatch));
|
|
||||||
U32 const rowLog = MAX(4, MIN(6, ms->cParams.searchLog));
|
|
||||||
switch (searchMethod) {
|
|
||||||
case search_hashChain:
|
|
||||||
return hcVTables[dictMode][mls - 4];
|
|
||||||
case search_binaryTree:
|
|
||||||
return btVTables[dictMode][mls - 4];
|
|
||||||
case search_rowHash:
|
|
||||||
return rowVTables[dictMode][mls - 4][rowLog - 4];
|
|
||||||
default:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE_TEMPLATE size_t
|
FORCE_INLINE_TEMPLATE size_t
|
||||||
ZSTD_compressBlock_lazy_generic(
|
ZSTD_compressBlock_lazy_generic(
|
||||||
@@ -1488,8 +1497,9 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
const BYTE* const base = ms->window.base;
|
const BYTE* const base = ms->window.base;
|
||||||
const U32 prefixLowestIndex = ms->window.dictLimit;
|
const U32 prefixLowestIndex = ms->window.dictLimit;
|
||||||
const BYTE* const prefixLowest = base + prefixLowestIndex;
|
const BYTE* const prefixLowest = base + prefixLowestIndex;
|
||||||
|
const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6);
|
||||||
|
const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
|
||||||
|
|
||||||
searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, dictMode)->searchMax;
|
|
||||||
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
|
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
|
||||||
|
|
||||||
const int isDMS = dictMode == ZSTD_dictMatchState;
|
const int isDMS = dictMode == ZSTD_dictMatchState;
|
||||||
@@ -1505,8 +1515,6 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
0;
|
0;
|
||||||
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
|
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
|
||||||
|
|
||||||
assert(searchMax != NULL);
|
|
||||||
|
|
||||||
DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod);
|
DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod);
|
||||||
ip += (dictAndPrefixLength == 0);
|
ip += (dictAndPrefixLength == 0);
|
||||||
if (dictMode == ZSTD_noDict) {
|
if (dictMode == ZSTD_noDict) {
|
||||||
@@ -1524,7 +1532,6 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (searchMethod == search_rowHash) {
|
if (searchMethod == search_rowHash) {
|
||||||
const U32 rowLog = MAX(4, MIN(6, ms->cParams.searchLog));
|
|
||||||
ZSTD_row_fillHashCache(ms, base, rowLog,
|
ZSTD_row_fillHashCache(ms, base, rowLog,
|
||||||
MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */),
|
MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */),
|
||||||
ms->nextToUpdate, ilimit);
|
ms->nextToUpdate, ilimit);
|
||||||
@@ -1565,7 +1572,7 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
|
|
||||||
/* first search (depth 0) */
|
/* first search (depth 0) */
|
||||||
{ size_t offsetFound = 999999999;
|
{ size_t offsetFound = 999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offsetFound, mls, rowLog, searchMethod, dictMode);
|
||||||
if (ml2 > matchLength)
|
if (ml2 > matchLength)
|
||||||
matchLength = ml2, start = ip, offcode=offsetFound;
|
matchLength = ml2, start = ip, offcode=offsetFound;
|
||||||
}
|
}
|
||||||
@@ -1604,7 +1611,7 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ size_t offset2=999999999;
|
{ size_t offset2=999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offset2, mls, rowLog, searchMethod, dictMode);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
|
||||||
if ((ml2 >= 4) && (gain2 > gain1)) {
|
if ((ml2 >= 4) && (gain2 > gain1)) {
|
||||||
@@ -1640,7 +1647,7 @@ ZSTD_compressBlock_lazy_generic(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{ size_t offset2=999999999;
|
{ size_t offset2=999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offset2, mls, rowLog, searchMethod, dictMode);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
|
||||||
if ((ml2 >= 4) && (gain2 > gain1)) {
|
if ((ml2 >= 4) && (gain2 > gain1)) {
|
||||||
@@ -1881,9 +1888,9 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|||||||
const BYTE* const dictEnd = dictBase + dictLimit;
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
||||||
const BYTE* const dictStart = dictBase + ms->window.lowLimit;
|
const BYTE* const dictStart = dictBase + ms->window.lowLimit;
|
||||||
const U32 windowLog = ms->cParams.windowLog;
|
const U32 windowLog = ms->cParams.windowLog;
|
||||||
const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5;
|
const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6);
|
||||||
|
const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
|
||||||
|
|
||||||
searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, ZSTD_extDict)->searchMax;
|
|
||||||
U32 offset_1 = rep[0], offset_2 = rep[1];
|
U32 offset_1 = rep[0], offset_2 = rep[1];
|
||||||
|
|
||||||
DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod);
|
DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod);
|
||||||
@@ -1925,7 +1932,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|||||||
|
|
||||||
/* first search (depth 0) */
|
/* first search (depth 0) */
|
||||||
{ size_t offsetFound = 999999999;
|
{ size_t offsetFound = 999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offsetFound, mls, rowLog, searchMethod, ZSTD_extDict);
|
||||||
if (ml2 > matchLength)
|
if (ml2 > matchLength)
|
||||||
matchLength = ml2, start = ip, offcode=offsetFound;
|
matchLength = ml2, start = ip, offcode=offsetFound;
|
||||||
}
|
}
|
||||||
@@ -1960,7 +1967,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|||||||
|
|
||||||
/* search match, depth 1 */
|
/* search match, depth 1 */
|
||||||
{ size_t offset2=999999999;
|
{ size_t offset2=999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offset2, mls, rowLog, searchMethod, ZSTD_extDict);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 4);
|
||||||
if ((ml2 >= 4) && (gain2 > gain1)) {
|
if ((ml2 >= 4) && (gain2 > gain1)) {
|
||||||
@@ -1992,7 +1999,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|||||||
|
|
||||||
/* search match, depth 2 */
|
/* search match, depth 2 */
|
||||||
{ size_t offset2=999999999;
|
{ size_t offset2=999999999;
|
||||||
size_t const ml2 = searchMax(ms, ip, iend, &offset2);
|
size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offset2, mls, rowLog, searchMethod, ZSTD_extDict);
|
||||||
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offset2))); /* raw approx */
|
||||||
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
|
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)STORED_TO_OFFBASE(offcode)) + 7);
|
||||||
if ((ml2 >= 4) && (gain2 > gain1)) {
|
if ((ml2 >= 4) && (gain2 > gain1)) {
|
||||||
|
|||||||
@@ -1108,7 +1108,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|||||||
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to ZSTD_nextSrcSizeToDecompress(), but when when a block input can be streamed,
|
* Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed,
|
||||||
* we allow taking a partial block as the input. Currently only raw uncompressed blocks can
|
* we allow taking a partial block as the input. Currently only raw uncompressed blocks can
|
||||||
* be streamed.
|
* be streamed.
|
||||||
*
|
*
|
||||||
|
|||||||
+2
-2
@@ -1395,7 +1395,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* o
|
|||||||
|
|
||||||
/*! ZSTD_mergeBlockDelimiters() :
|
/*! ZSTD_mergeBlockDelimiters() :
|
||||||
* Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals
|
* Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals
|
||||||
* by merging them into into the literals of the next sequence.
|
* by merging them into the literals of the next sequence.
|
||||||
*
|
*
|
||||||
* As such, the final generated result has no explicit representation of block boundaries,
|
* As such, the final generated result has no explicit representation of block boundaries,
|
||||||
* and the final last literals segment is not represented in the sequences.
|
* and the final last literals segment is not represented in the sequences.
|
||||||
@@ -1442,7 +1442,7 @@ ZSTDLIB_STATIC_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* ds
|
|||||||
/*! ZSTD_writeSkippableFrame() :
|
/*! ZSTD_writeSkippableFrame() :
|
||||||
* Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
|
* Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
|
||||||
*
|
*
|
||||||
* Skippable frames begin with a a 4-byte magic number. There are 16 possible choices of magic number,
|
* Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number,
|
||||||
* ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15.
|
* ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15.
|
||||||
* As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so
|
* As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so
|
||||||
* the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
|
* the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
|
||||||
|
|||||||
Reference in New Issue
Block a user