zstd.c
Go to the documentation of this file.
1 
10 /*
11  * Copyright (c) Meta Platforms, Inc. and affiliates.
12  * All rights reserved.
13  *
14  * This source code is licensed under both the BSD-style license (found in the
15  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
16  * in the COPYING file in the root directory of this source tree).
17  * You may select, at your option, one of the above-listed licenses.
18  */
19 /*
20  * Settings to bake for the single library file.
21  *
22  * Note: It's important that none of these affects 'zstd.h' (only the
23  * implementation files we're amalgamating).
24  *
25  * Note: MEM_MODULE stops xxhash redefining BYTE, U16, etc., which are also
26  * defined in mem.h (breaking C99 compatibility).
27  *
28  * Note: the undefs for xxHash allow Zstd's implementation to coincide with
29  * standalone xxHash usage (with global defines).
30  *
31  * Note: if you enable ZSTD_LEGACY_SUPPORT the combine.py script will need
32  * re-running without the "-x legacy/zstd_legacy.h" option (it excludes the
33  * legacy support at the source level).
34  *
35  * Note: multithreading is enabled for all platforms apart from Emscripten.
36  */
37 #define DEBUGLEVEL 0
38 #define MEM_MODULE
39 #undef XXH_NAMESPACE
40 #define XXH_NAMESPACE ZSTD_
41 #undef XXH_PRIVATE_API
42 #define XXH_PRIVATE_API
43 #undef XXH_INLINE_ALL
44 #define XXH_INLINE_ALL
45 #define ZSTD_LEGACY_SUPPORT 0
46 #ifndef __EMSCRIPTEN__
47 #define ZSTD_MULTITHREAD
48 #endif
49 #define ZSTD_TRACE 0
50 /* TODO: Can't amalgamate ASM function */
51 #define ZSTD_DISABLE_ASM 1
52 
53 /* Include zstd_deps.h first with all the options we need enabled. */
54 #define ZSTD_DEPS_NEED_MALLOC
55 #define ZSTD_DEPS_NEED_MATH64
56 /**** start inlining common/zstd_deps.h ****/
57 /*
58  * Copyright (c) Meta Platforms, Inc. and affiliates.
59  * All rights reserved.
60  *
61  * This source code is licensed under both the BSD-style license (found in the
62  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
63  * in the COPYING file in the root directory of this source tree).
64  * You may select, at your option, one of the above-listed licenses.
65  */
66 
67 /* This file provides common libc dependencies that zstd requires.
68  * The purpose is to allow replacing this file with a custom implementation
69  * to compile zstd without libc support.
70  */
71 
72 /* Need:
73  * NULL
74  * INT_MAX
75  * UINT_MAX
76  * ZSTD_memcpy()
77  * ZSTD_memset()
78  * ZSTD_memmove()
79  */
80 #ifndef ZSTD_DEPS_COMMON
81 #define ZSTD_DEPS_COMMON
82 
83 #include <limits.h>
84 #include <stddef.h>
85 #include <string.h>
86 
87 #if defined(__GNUC__) && __GNUC__ >= 4
88 # define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l))
89 # define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l))
90 # define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l))
91 #else
92 # define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l))
93 # define ZSTD_memmove(d,s,l) memmove((d),(s),(l))
94 # define ZSTD_memset(p,v,l) memset((p),(v),(l))
95 #endif
96 
97 #endif /* ZSTD_DEPS_COMMON */
98 
99 /* Need:
100  * ZSTD_malloc()
101  * ZSTD_free()
102  * ZSTD_calloc()
103  */
104 #ifdef ZSTD_DEPS_NEED_MALLOC
105 #ifndef ZSTD_DEPS_MALLOC
106 #define ZSTD_DEPS_MALLOC
107 
108 #include <stdlib.h>
109 
110 #define ZSTD_malloc(s) malloc(s)
111 #define ZSTD_calloc(n,s) calloc((n), (s))
112 #define ZSTD_free(p) free((p))
113 
114 #endif /* ZSTD_DEPS_MALLOC */
115 #endif /* ZSTD_DEPS_NEED_MALLOC */
116 
117 /*
118  * Provides 64-bit math support.
119  * Need:
120  * U64 ZSTD_div64(U64 dividend, U32 divisor)
121  */
122 #ifdef ZSTD_DEPS_NEED_MATH64
123 #ifndef ZSTD_DEPS_MATH64
124 #define ZSTD_DEPS_MATH64
125 
126 #define ZSTD_div64(dividend, divisor) ((dividend) / (divisor))
127 
128 #endif /* ZSTD_DEPS_MATH64 */
129 #endif /* ZSTD_DEPS_NEED_MATH64 */
130 
131 /* Need:
132  * assert()
133  */
134 #ifdef ZSTD_DEPS_NEED_ASSERT
135 #ifndef ZSTD_DEPS_ASSERT
136 #define ZSTD_DEPS_ASSERT
137 
138 #include <assert.h>
139 
140 #endif /* ZSTD_DEPS_ASSERT */
141 #endif /* ZSTD_DEPS_NEED_ASSERT */
142 
143 /* Need:
144  * ZSTD_DEBUG_PRINT()
145  */
146 #ifdef ZSTD_DEPS_NEED_IO
147 #ifndef ZSTD_DEPS_IO
148 #define ZSTD_DEPS_IO
149 
150 #include <stdio.h>
151 #define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__)
152 
153 #endif /* ZSTD_DEPS_IO */
154 #endif /* ZSTD_DEPS_NEED_IO */
155 
156 /* Only requested when <stdint.h> is known to be present.
157  * Need:
158  * intptr_t
159  */
160 #ifdef ZSTD_DEPS_NEED_STDINT
161 #ifndef ZSTD_DEPS_STDINT
162 #define ZSTD_DEPS_STDINT
163 
164 #include <stdint.h>
165 
166 #endif /* ZSTD_DEPS_STDINT */
167 #endif /* ZSTD_DEPS_NEED_STDINT */
168 /**** ended inlining common/zstd_deps.h ****/
169 
170 /**** start inlining common/debug.c ****/
171 /* ******************************************************************
172  * debug
173  * Part of FSE library
174  * Copyright (c) Meta Platforms, Inc. and affiliates.
175  *
176  * You can contact the author at :
177  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
178  *
179  * This source code is licensed under both the BSD-style license (found in the
180  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
181  * in the COPYING file in the root directory of this source tree).
182  * You may select, at your option, one of the above-listed licenses.
183 ****************************************************************** */
184 
185 
186 /*
187  * This module only hosts one global variable
188  * which can be used to dynamically influence the verbosity of traces,
189  * such as DEBUGLOG and RAWLOG
190  */
191 
192 /**** start inlining debug.h ****/
193 /* ******************************************************************
194  * debug
195  * Part of FSE library
196  * Copyright (c) Meta Platforms, Inc. and affiliates.
197  *
198  * You can contact the author at :
199  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
200  *
201  * This source code is licensed under both the BSD-style license (found in the
202  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
203  * in the COPYING file in the root directory of this source tree).
204  * You may select, at your option, one of the above-listed licenses.
205 ****************************************************************** */
206 
207 
208 /*
209  * The purpose of this header is to enable debug functions.
210  * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time,
211  * and DEBUG_STATIC_ASSERT() for compile-time.
212  *
213  * By default, DEBUGLEVEL==0, which means run-time debug is disabled.
214  *
215  * Level 1 enables assert() only.
216  * Starting level 2, traces can be generated and pushed to stderr.
217  * The higher the level, the more verbose the traces.
218  *
219  * It's possible to dynamically adjust level using variable g_debug_level,
220  * which is only declared if DEBUGLEVEL>=2,
221  * and is a global variable, not multi-thread protected (use with care)
222  */
223 
224 #ifndef DEBUG_H_12987983217
225 #define DEBUG_H_12987983217
226 
227 #if defined (__cplusplus)
228 extern "C" {
229 #endif
230 
231 
232 /* static assert is triggered at compile time, leaving no runtime artefact.
233  * static assert only works with compile-time constants.
234  * Also, this variant can only be used inside a function. */
235 #define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1])
236 
237 
238 /* DEBUGLEVEL is expected to be defined externally,
239  * typically through compiler command line.
240  * Value must be a number. */
241 #ifndef DEBUGLEVEL
242 # define DEBUGLEVEL 0
243 #endif
244 
245 
246 /* recommended values for DEBUGLEVEL :
247  * 0 : release mode, no debug, all run-time checks disabled
248  * 1 : enables assert() only, no display
249  * 2 : reserved, for currently active debug path
250  * 3 : events once per object lifetime (CCtx, CDict, etc.)
251  * 4 : events once per frame
252  * 5 : events once per block
253  * 6 : events once per sequence (verbose)
254  * 7+: events at every position (*very* verbose)
255  *
256  * It's generally inconvenient to output traces > 5.
257  * In which case, it's possible to selectively trigger high verbosity levels
258  * by modifying g_debug_level.
259  */
260 
261 #if (DEBUGLEVEL>=1)
262 # define ZSTD_DEPS_NEED_ASSERT
263 /**** skipping file: zstd_deps.h ****/
264 #else
265 # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */
266 # define assert(condition) ((void)0) /* disable assert (default) */
267 # endif
268 #endif
269 
270 #if (DEBUGLEVEL>=2)
271 # define ZSTD_DEPS_NEED_IO
272 /**** skipping file: zstd_deps.h ****/
273 extern int g_debuglevel; /* the variable is only declared,
274  it actually lives in debug.c,
275  and is shared by the whole process.
276  It's not thread-safe.
277  It's useful when enabling very verbose levels
278  on selective conditions (such as position in src) */
279 
280 # define RAWLOG(l, ...) { \
281  if (l<=g_debuglevel) { \
282  ZSTD_DEBUG_PRINT(__VA_ARGS__); \
283  } }
284 # define DEBUGLOG(l, ...) { \
285  if (l<=g_debuglevel) { \
286  ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \
287  ZSTD_DEBUG_PRINT(" \n"); \
288  } }
289 #else
290 # define RAWLOG(l, ...) {} /* disabled */
291 # define DEBUGLOG(l, ...) {} /* disabled */
292 #endif
293 
294 
295 #if defined (__cplusplus)
296 }
297 #endif
298 
299 #endif /* DEBUG_H_12987983217 */
300 /**** ended inlining debug.h ****/
301 
303 /**** ended inlining common/debug.c ****/
304 /**** start inlining common/entropy_common.c ****/
305 /* ******************************************************************
306  * Common functions of New Generation Entropy library
307  * Copyright (c) Meta Platforms, Inc. and affiliates.
308  *
309  * You can contact the author at :
310  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
311  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
312  *
313  * This source code is licensed under both the BSD-style license (found in the
314  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
315  * in the COPYING file in the root directory of this source tree).
316  * You may select, at your option, one of the above-listed licenses.
317 ****************************************************************** */
318 
319 /* *************************************
320 * Dependencies
321 ***************************************/
322 /**** start inlining mem.h ****/
323 /*
324  * Copyright (c) Meta Platforms, Inc. and affiliates.
325  * All rights reserved.
326  *
327  * This source code is licensed under both the BSD-style license (found in the
328  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
329  * in the COPYING file in the root directory of this source tree).
330  * You may select, at your option, one of the above-listed licenses.
331  */
332 
333 #ifndef MEM_H_MODULE
334 #define MEM_H_MODULE
335 
336 #if defined (__cplusplus)
337 extern "C" {
338 #endif
339 
340 /*-****************************************
341 * Dependencies
342 ******************************************/
343 #include <stddef.h> /* size_t, ptrdiff_t */
344 /**** start inlining compiler.h ****/
345 /*
346  * Copyright (c) Meta Platforms, Inc. and affiliates.
347  * All rights reserved.
348  *
349  * This source code is licensed under both the BSD-style license (found in the
350  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
351  * in the COPYING file in the root directory of this source tree).
352  * You may select, at your option, one of the above-listed licenses.
353  */
354 
355 #ifndef ZSTD_COMPILER_H
356 #define ZSTD_COMPILER_H
357 
358 /**** start inlining portability_macros.h ****/
359 /*
360  * Copyright (c) Meta Platforms, Inc. and affiliates.
361  * All rights reserved.
362  *
363  * This source code is licensed under both the BSD-style license (found in the
364  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
365  * in the COPYING file in the root directory of this source tree).
366  * You may select, at your option, one of the above-listed licenses.
367  */
368 
369 #ifndef ZSTD_PORTABILITY_MACROS_H
370 #define ZSTD_PORTABILITY_MACROS_H
371 
382 /* compat. with non-clang compilers */
383 #ifndef __has_attribute
384  #define __has_attribute(x) 0
385 #endif
386 
387 /* compat. with non-clang compilers */
388 #ifndef __has_builtin
389 # define __has_builtin(x) 0
390 #endif
391 
392 /* compat. with non-clang compilers */
393 #ifndef __has_feature
394 # define __has_feature(x) 0
395 #endif
396 
397 /* detects whether we are being compiled under msan */
398 #ifndef ZSTD_MEMORY_SANITIZER
399 # if __has_feature(memory_sanitizer)
400 # define ZSTD_MEMORY_SANITIZER 1
401 # else
402 # define ZSTD_MEMORY_SANITIZER 0
403 # endif
404 #endif
405 
406 /* detects whether we are being compiled under asan */
407 #ifndef ZSTD_ADDRESS_SANITIZER
408 # if __has_feature(address_sanitizer)
409 # define ZSTD_ADDRESS_SANITIZER 1
410 # elif defined(__SANITIZE_ADDRESS__)
411 # define ZSTD_ADDRESS_SANITIZER 1
412 # else
413 # define ZSTD_ADDRESS_SANITIZER 0
414 # endif
415 #endif
416 
417 /* detects whether we are being compiled under dfsan */
418 #ifndef ZSTD_DATAFLOW_SANITIZER
419 # if __has_feature(dataflow_sanitizer)
420 # define ZSTD_DATAFLOW_SANITIZER 1
421 # else
422 # define ZSTD_DATAFLOW_SANITIZER 0
423 # endif
424 #endif
425 
426 /* Mark the internal assembly functions as hidden */
427 #ifdef __ELF__
428 # define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
429 #else
430 # define ZSTD_HIDE_ASM_FUNCTION(func)
431 #endif
432 
433 /* Enable runtime BMI2 dispatch based on the CPU.
434  * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
435  */
436 #ifndef DYNAMIC_BMI2
437  #if ((defined(__clang__) && __has_attribute(__target__)) \
438  || (defined(__GNUC__) \
439  && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
440  && (defined(__x86_64__) || defined(_M_X64)) \
441  && !defined(__BMI2__)
442  # define DYNAMIC_BMI2 1
443  #else
444  # define DYNAMIC_BMI2 0
445  #endif
446 #endif
447 
459 #if defined(__GNUC__)
460 # if defined(__linux__) || defined(__linux) || defined(__APPLE__)
461 # if ZSTD_MEMORY_SANITIZER
462 # define ZSTD_ASM_SUPPORTED 0
463 # elif ZSTD_DATAFLOW_SANITIZER
464 # define ZSTD_ASM_SUPPORTED 0
465 # else
466 # define ZSTD_ASM_SUPPORTED 1
467 # endif
468 # else
469 # define ZSTD_ASM_SUPPORTED 0
470 # endif
471 #else
472 # define ZSTD_ASM_SUPPORTED 0
473 #endif
474 
486 #if !defined(ZSTD_DISABLE_ASM) && \
487  ZSTD_ASM_SUPPORTED && \
488  defined(__x86_64__) && \
489  (DYNAMIC_BMI2 || defined(__BMI2__))
490 # define ZSTD_ENABLE_ASM_X86_64_BMI2 1
491 #else
492 # define ZSTD_ENABLE_ASM_X86_64_BMI2 0
493 #endif
494 
495 /*
496  * For x86 ELF targets, add .note.gnu.property section for Intel CET in
497  * assembly sources when CET is enabled.
498  *
499  * Additionally, any function that may be called indirectly must begin
500  * with ZSTD_CET_ENDBRANCH.
501  */
502 #if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \
503  && defined(__has_include)
504 # if __has_include(<cet.h>)
505 # include <cet.h>
506 # define ZSTD_CET_ENDBRANCH _CET_ENDBR
507 # endif
508 #endif
509 
510 #ifndef ZSTD_CET_ENDBRANCH
511 # define ZSTD_CET_ENDBRANCH
512 #endif
513 
514 #endif /* ZSTD_PORTABILITY_MACROS_H */
515 /**** ended inlining portability_macros.h ****/
516 
517 /*-*******************************************************
518 * Compiler specifics
519 *********************************************************/
520 /* force inlining */
521 
522 #if !defined(ZSTD_NO_INLINE)
523 #if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
524 # define INLINE_KEYWORD inline
525 #else
526 # define INLINE_KEYWORD
527 #endif
528 
529 #if defined(__GNUC__) || defined(__ICCARM__)
530 # define FORCE_INLINE_ATTR __attribute__((always_inline))
531 #elif defined(_MSC_VER)
532 # define FORCE_INLINE_ATTR __forceinline
533 #else
534 # define FORCE_INLINE_ATTR
535 #endif
536 
537 #else
538 
539 #define INLINE_KEYWORD
540 #define FORCE_INLINE_ATTR
541 
542 #endif
543 
549 #if defined(_MSC_VER)
550 # define WIN_CDECL __cdecl
551 #else
552 # define WIN_CDECL
553 #endif
554 
560 #define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
561 
572 #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
573 # define HINT_INLINE static INLINE_KEYWORD
574 #else
575 # define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
576 #endif
577 
578 /* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
579 #if defined(__GNUC__)
580 # define UNUSED_ATTR __attribute__((unused))
581 #else
582 # define UNUSED_ATTR
583 #endif
584 
585 /* force no inlining */
586 #ifdef _MSC_VER
587 # define FORCE_NOINLINE static __declspec(noinline)
588 #else
589 # if defined(__GNUC__) || defined(__ICCARM__)
590 # define FORCE_NOINLINE static __attribute__((__noinline__))
591 # else
592 # define FORCE_NOINLINE static
593 # endif
594 #endif
595 
596 
597 /* target attribute */
598 #if defined(__GNUC__) || defined(__ICCARM__)
599 # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
600 #else
601 # define TARGET_ATTRIBUTE(target)
602 #endif
603 
604 /* Target attribute for BMI2 dynamic dispatch.
605  * Enable lzcnt, bmi, and bmi2.
606  * We test for bmi1 & bmi2. lzcnt is included in bmi1.
607  */
608 #define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
609 
610 /* prefetch
611  * can be disabled, by declaring NO_PREFETCH build macro */
612 #if defined(NO_PREFETCH)
613 # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
614 # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
615 #else
616 # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
617 # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
618 # define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
619 # define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
620 # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
621 # define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
622 # define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
623 # elif defined(__aarch64__)
624 # define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
625 # define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
626 # else
627 # define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
628 # define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
629 # endif
630 #endif /* NO_PREFETCH */
631 
632 #define CACHELINE_SIZE 64
633 
634 #define PREFETCH_AREA(p, s) { \
635  const char* const _ptr = (const char*)(p); \
636  size_t const _size = (size_t)(s); \
637  size_t _pos; \
638  for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
639  PREFETCH_L2(_ptr + _pos); \
640  } \
641 }
642 
643 /* vectorization
644  * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
645  * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
646 #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
647 # if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
648 # define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
649 # else
650 # define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")")
651 # endif
652 #else
653 # define DONT_VECTORIZE
654 #endif
655 
656 /* Tell the compiler that a branch is likely or unlikely.
657  * Only use these macros if it causes the compiler to generate better code.
658  * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc
659  * and clang, please do.
660  */
661 #if defined(__GNUC__)
662 #define LIKELY(x) (__builtin_expect((x), 1))
663 #define UNLIKELY(x) (__builtin_expect((x), 0))
664 #else
665 #define LIKELY(x) (x)
666 #define UNLIKELY(x) (x)
667 #endif
668 
669 #if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
670 # define ZSTD_UNREACHABLE { assert(0), __builtin_unreachable(); }
671 #else
672 # define ZSTD_UNREACHABLE { assert(0); }
673 #endif
674 
675 /* disable warnings */
676 #ifdef _MSC_VER /* Visual Studio */
677 # include <intrin.h> /* For Visual 2005 */
678 # pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
679 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
680 # pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
681 # pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
682 # pragma warning(disable : 4324) /* disable: C4324: padded structure */
683 #endif
684 
685 /*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/
686 #ifndef STATIC_BMI2
687 # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))
688 # ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
689 # define STATIC_BMI2 1
690 # endif
691 # elif defined(__BMI2__) && defined(__x86_64__) && defined(__GNUC__)
692 # define STATIC_BMI2 1
693 # endif
694 #endif
695 
696 #ifndef STATIC_BMI2
697  #define STATIC_BMI2 0
698 #endif
699 
700 /* compile time determination of SIMD support */
701 #if !defined(ZSTD_NO_INTRINSICS)
702 # if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
703 # define ZSTD_ARCH_X86_SSE2
704 # endif
705 # if defined(__ARM_NEON) || defined(_M_ARM64)
706 # define ZSTD_ARCH_ARM_NEON
707 # endif
708 #
709 # if defined(ZSTD_ARCH_X86_SSE2)
710 # include <emmintrin.h>
711 # elif defined(ZSTD_ARCH_ARM_NEON)
712 # include <arm_neon.h>
713 # endif
714 #endif
715 
716 /* C-language Attributes are added in C23. */
717 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
718 # define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
719 #else
720 # define ZSTD_HAS_C_ATTRIBUTE(x) 0
721 #endif
722 
723 /* Only use C++ attributes in C++. Some compilers report support for C++
724  * attributes when compiling with C.
725  */
726 #if defined(__cplusplus) && defined(__has_cpp_attribute)
727 # define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
728 #else
729 # define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
730 #endif
731 
732 /* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
733  * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
734  * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
735  * - Else: __attribute__((__fallthrough__))
736  */
737 #ifndef ZSTD_FALLTHROUGH
738 # if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
739 # define ZSTD_FALLTHROUGH [[fallthrough]]
740 # elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
741 # define ZSTD_FALLTHROUGH [[fallthrough]]
742 # elif __has_attribute(__fallthrough__)
743 /* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
744  * gcc complains about: a label can only be part of a statement and a declaration is not a statement.
745  */
746 # define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
747 # else
748 # define ZSTD_FALLTHROUGH
749 # endif
750 #endif
751 
752 /*-**************************************************************
753 * Alignment check
754 *****************************************************************/
755 
756 /* this test was initially positioned in mem.h,
757  * but this file is removed (or replaced) for linux kernel
758  * so it's now hosted in compiler.h,
759  * which remains valid for both user & kernel spaces.
760  */
761 
762 #ifndef ZSTD_ALIGNOF
763 # if defined(__GNUC__) || defined(_MSC_VER)
764 /* covers gcc, clang & MSVC */
765 /* note : this section must come first, before C11,
766  * due to a limitation in the kernel source generator */
767 # define ZSTD_ALIGNOF(T) __alignof(T)
768 
769 # elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
770 /* C11 support */
771 # include <stdalign.h>
772 # define ZSTD_ALIGNOF(T) alignof(T)
773 
774 # else
775 /* No known support for alignof() - imperfect backup */
776 # define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
777 
778 # endif
779 #endif /* ZSTD_ALIGNOF */
780 
781 /*-**************************************************************
782 * Sanitizer
783 *****************************************************************/
784 
785 /* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an
786  * abundance of caution, disable our custom poisoning on mingw. */
787 #ifdef __MINGW32__
788 #ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE
789 #define ZSTD_ASAN_DONT_POISON_WORKSPACE 1
790 #endif
791 #ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE
792 #define ZSTD_MSAN_DONT_POISON_WORKSPACE 1
793 #endif
794 #endif
795 
796 #if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE)
797 /* Not all platforms that support msan provide sanitizers/msan_interface.h.
798  * We therefore declare the functions we need ourselves, rather than trying to
799  * include the header file... */
800 #include <stddef.h> /* size_t */
801 #define ZSTD_DEPS_NEED_STDINT
802 /**** skipping file: zstd_deps.h ****/
803 
804 /* Make memory region fully initialized (without changing its contents). */
805 void __msan_unpoison(const volatile void *a, size_t size);
806 
807 /* Make memory region fully uninitialized (without changing its contents).
808  This is a legacy interface that does not update origin information. Use
809  __msan_allocated_memory() instead. */
810 void __msan_poison(const volatile void *a, size_t size);
811 
812 /* Returns the offset of the first (at least partially) poisoned byte in the
813  memory range, or -1 if the whole range is good. */
814 intptr_t __msan_test_shadow(const volatile void *x, size_t size);
815 
816 /* Print shadow and origin for the memory range to stderr in a human-readable
817  format. */
818 void __msan_print_shadow(const volatile void *x, size_t size);
819 #endif
820 
821 #if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE)
822 /* Not all platforms that support asan provide sanitizers/asan_interface.h.
823  * We therefore declare the functions we need ourselves, rather than trying to
824  * include the header file... */
825 #include <stddef.h> /* size_t */
826 
841 void __asan_poison_memory_region(void const volatile *addr, size_t size);
842 
856 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
857 #endif
858 
859 #endif /* ZSTD_COMPILER_H */
860 /**** ended inlining compiler.h ****/
861 /**** skipping file: debug.h ****/
862 /**** skipping file: zstd_deps.h ****/
863 
864 
865 /*-****************************************
866 * Compiler specifics
867 ******************************************/
868 #if defined(_MSC_VER) /* Visual Studio */
869 # include <stdlib.h> /* _byteswap_ulong */
870 # include <intrin.h> /* _byteswap_* */
871 #endif
872 #if defined(__GNUC__)
873 # define MEM_STATIC static __inline __attribute__((unused))
874 #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
875 # define MEM_STATIC static inline
876 #elif defined(_MSC_VER)
877 # define MEM_STATIC static __inline
878 #else
879 # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
880 #endif
881 
882 /*-**************************************************************
883 * Basic Types
884 *****************************************************************/
885 #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
886 # if defined(_AIX)
887 # include <inttypes.h>
888 # else
889 # include <stdint.h> /* intptr_t */
890 # endif
891  typedef uint8_t BYTE;
892  typedef uint8_t U8;
893  typedef int8_t S8;
894  typedef uint16_t U16;
895  typedef int16_t S16;
896  typedef uint32_t U32;
897  typedef int32_t S32;
898  typedef uint64_t U64;
899  typedef int64_t S64;
900 #else
901 # include <limits.h>
902 #if CHAR_BIT != 8
903 # error "this implementation requires char to be exactly 8-bit type"
904 #endif
905  typedef unsigned char BYTE;
906  typedef unsigned char U8;
907  typedef signed char S8;
908 #if USHRT_MAX != 65535
909 # error "this implementation requires short to be exactly 16-bit type"
910 #endif
911  typedef unsigned short U16;
912  typedef signed short S16;
913 #if UINT_MAX != 4294967295
914 # error "this implementation requires int to be exactly 32-bit type"
915 #endif
916  typedef unsigned int U32;
917  typedef signed int S32;
918 /* note : there are no limits defined for long long type in C90.
919  * limits exist in C99, however, in such case, <stdint.h> is preferred */
920  typedef unsigned long long U64;
921  typedef signed long long S64;
922 #endif
923 
924 
925 /*-**************************************************************
926 * Memory I/O API
927 *****************************************************************/
928 /*=== Static platform detection ===*/
929 MEM_STATIC unsigned MEM_32bits(void);
930 MEM_STATIC unsigned MEM_64bits(void);
931 MEM_STATIC unsigned MEM_isLittleEndian(void);
932 
933 /*=== Native unaligned read/write ===*/
934 MEM_STATIC U16 MEM_read16(const void* memPtr);
935 MEM_STATIC U32 MEM_read32(const void* memPtr);
936 MEM_STATIC U64 MEM_read64(const void* memPtr);
937 MEM_STATIC size_t MEM_readST(const void* memPtr);
938 
939 MEM_STATIC void MEM_write16(void* memPtr, U16 value);
940 MEM_STATIC void MEM_write32(void* memPtr, U32 value);
941 MEM_STATIC void MEM_write64(void* memPtr, U64 value);
942 
943 /*=== Little endian unaligned read/write ===*/
944 MEM_STATIC U16 MEM_readLE16(const void* memPtr);
945 MEM_STATIC U32 MEM_readLE24(const void* memPtr);
946 MEM_STATIC U32 MEM_readLE32(const void* memPtr);
947 MEM_STATIC U64 MEM_readLE64(const void* memPtr);
948 MEM_STATIC size_t MEM_readLEST(const void* memPtr);
949 
950 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
951 MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
952 MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
953 MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
954 MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
955 
956 /*=== Big endian unaligned read/write ===*/
957 MEM_STATIC U32 MEM_readBE32(const void* memPtr);
958 MEM_STATIC U64 MEM_readBE64(const void* memPtr);
959 MEM_STATIC size_t MEM_readBEST(const void* memPtr);
960 
961 MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
962 MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
963 MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
964 
965 /*=== Byteswap ===*/
968 MEM_STATIC size_t MEM_swapST(size_t in);
969 
970 
971 /*-**************************************************************
972 * Memory I/O Implementation
973 *****************************************************************/
974 /* MEM_FORCE_MEMORY_ACCESS : For accessing unaligned memory:
975  * Method 0 : always use `memcpy()`. Safe and portable.
976  * Method 1 : Use compiler extension to set unaligned access.
977  * Method 2 : direct access. This method is portable but violate C standard.
978  * It can generate buggy code on targets depending on alignment.
979  * Default : method 1 if supported, else method 0
980  */
981 #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
982 # ifdef __GNUC__
983 # define MEM_FORCE_MEMORY_ACCESS 1
984 # endif
985 #endif
986 
987 MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
988 MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
989 
991 {
992 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
993  return 1;
994 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
995  return 0;
996 #elif defined(__clang__) && __LITTLE_ENDIAN__
997  return 1;
998 #elif defined(__clang__) && __BIG_ENDIAN__
999  return 0;
1000 #elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86)
1001  return 1;
1002 #elif defined(__DMC__) && defined(_M_IX86)
1003  return 1;
1004 #else
1005  const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
1006  return one.c[0];
1007 #endif
1008 }
1009 
1010 #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
1011 
1012 /* violates C standard, by lying on structure alignment.
1013 Only use if no other choice to achieve best performance on target platform */
1014 MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
1015 MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
1016 MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
1017 MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
1018 
1019 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
1020 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
1021 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
1022 
1023 #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
1024 
1025 typedef __attribute__((aligned(1))) U16 unalign16;
1026 typedef __attribute__((aligned(1))) U32 unalign32;
1027 typedef __attribute__((aligned(1))) U64 unalign64;
1028 typedef __attribute__((aligned(1))) size_t unalignArch;
1029 
1030 MEM_STATIC U16 MEM_read16(const void* ptr) { return *(const unalign16*)ptr; }
1031 MEM_STATIC U32 MEM_read32(const void* ptr) { return *(const unalign32*)ptr; }
1032 MEM_STATIC U64 MEM_read64(const void* ptr) { return *(const unalign64*)ptr; }
1033 MEM_STATIC size_t MEM_readST(const void* ptr) { return *(const unalignArch*)ptr; }
1034 
1035 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(unalign16*)memPtr = value; }
1036 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(unalign32*)memPtr = value; }
1037 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(unalign64*)memPtr = value; }
1038 
1039 #else
1040 
1041 /* default method, safe and standard.
1042  can sometimes prove slower */
1043 
1044 MEM_STATIC U16 MEM_read16(const void* memPtr)
1045 {
1046  U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
1047 }
1048 
1049 MEM_STATIC U32 MEM_read32(const void* memPtr)
1050 {
1051  U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
1052 }
1053 
1054 MEM_STATIC U64 MEM_read64(const void* memPtr)
1055 {
1056  U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
1057 }
1058 
1059 MEM_STATIC size_t MEM_readST(const void* memPtr)
1060 {
1061  size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
1062 }
1063 
1064 MEM_STATIC void MEM_write16(void* memPtr, U16 value)
1065 {
1066  ZSTD_memcpy(memPtr, &value, sizeof(value));
1067 }
1068 
1069 MEM_STATIC void MEM_write32(void* memPtr, U32 value)
1070 {
1071  ZSTD_memcpy(memPtr, &value, sizeof(value));
1072 }
1073 
1074 MEM_STATIC void MEM_write64(void* memPtr, U64 value)
1075 {
1076  ZSTD_memcpy(memPtr, &value, sizeof(value));
1077 }
1078 
1079 #endif /* MEM_FORCE_MEMORY_ACCESS */
1080 
1082 {
1083  return ((in << 24) & 0xff000000 ) |
1084  ((in << 8) & 0x00ff0000 ) |
1085  ((in >> 8) & 0x0000ff00 ) |
1086  ((in >> 24) & 0x000000ff );
1087 }
1088 
1090 {
1091 #if defined(_MSC_VER) /* Visual Studio */
1092  return _byteswap_ulong(in);
1093 #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
1094  || (defined(__clang__) && __has_builtin(__builtin_bswap32))
1095  return __builtin_bswap32(in);
1096 #else
1097  return MEM_swap32_fallback(in);
1098 #endif
1099 }
1100 
1102 {
1103  return ((in << 56) & 0xff00000000000000ULL) |
1104  ((in << 40) & 0x00ff000000000000ULL) |
1105  ((in << 24) & 0x0000ff0000000000ULL) |
1106  ((in << 8) & 0x000000ff00000000ULL) |
1107  ((in >> 8) & 0x00000000ff000000ULL) |
1108  ((in >> 24) & 0x0000000000ff0000ULL) |
1109  ((in >> 40) & 0x000000000000ff00ULL) |
1110  ((in >> 56) & 0x00000000000000ffULL);
1111 }
1112 
1114 {
1115 #if defined(_MSC_VER) /* Visual Studio */
1116  return _byteswap_uint64(in);
1117 #elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
1118  || (defined(__clang__) && __has_builtin(__builtin_bswap64))
1119  return __builtin_bswap64(in);
1120 #else
1121  return MEM_swap64_fallback(in);
1122 #endif
1123 }
1124 
1125 MEM_STATIC size_t MEM_swapST(size_t in)
1126 {
1127  if (MEM_32bits())
1128  return (size_t)MEM_swap32((U32)in);
1129  else
1130  return (size_t)MEM_swap64((U64)in);
1131 }
1132 
1133 /*=== Little endian r/w ===*/
1134 
1135 MEM_STATIC U16 MEM_readLE16(const void* memPtr)
1136 {
1137  if (MEM_isLittleEndian())
1138  return MEM_read16(memPtr);
1139  else {
1140  const BYTE* p = (const BYTE*)memPtr;
1141  return (U16)(p[0] + (p[1]<<8));
1142  }
1143 }
1144 
1145 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
1146 {
1147  if (MEM_isLittleEndian()) {
1148  MEM_write16(memPtr, val);
1149  } else {
1150  BYTE* p = (BYTE*)memPtr;
1151  p[0] = (BYTE)val;
1152  p[1] = (BYTE)(val>>8);
1153  }
1154 }
1155 
1156 MEM_STATIC U32 MEM_readLE24(const void* memPtr)
1157 {
1158  return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16);
1159 }
1160 
1161 MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
1162 {
1163  MEM_writeLE16(memPtr, (U16)val);
1164  ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
1165 }
1166 
1167 MEM_STATIC U32 MEM_readLE32(const void* memPtr)
1168 {
1169  if (MEM_isLittleEndian())
1170  return MEM_read32(memPtr);
1171  else
1172  return MEM_swap32(MEM_read32(memPtr));
1173 }
1174 
1175 MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
1176 {
1177  if (MEM_isLittleEndian())
1178  MEM_write32(memPtr, val32);
1179  else
1180  MEM_write32(memPtr, MEM_swap32(val32));
1181 }
1182 
1183 MEM_STATIC U64 MEM_readLE64(const void* memPtr)
1184 {
1185  if (MEM_isLittleEndian())
1186  return MEM_read64(memPtr);
1187  else
1188  return MEM_swap64(MEM_read64(memPtr));
1189 }
1190 
1191 MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
1192 {
1193  if (MEM_isLittleEndian())
1194  MEM_write64(memPtr, val64);
1195  else
1196  MEM_write64(memPtr, MEM_swap64(val64));
1197 }
1198 
1199 MEM_STATIC size_t MEM_readLEST(const void* memPtr)
1200 {
1201  if (MEM_32bits())
1202  return (size_t)MEM_readLE32(memPtr);
1203  else
1204  return (size_t)MEM_readLE64(memPtr);
1205 }
1206 
1207 MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
1208 {
1209  if (MEM_32bits())
1210  MEM_writeLE32(memPtr, (U32)val);
1211  else
1212  MEM_writeLE64(memPtr, (U64)val);
1213 }
1214 
1215 /*=== Big endian r/w ===*/
1216 
1217 MEM_STATIC U32 MEM_readBE32(const void* memPtr)
1218 {
1219  if (MEM_isLittleEndian())
1220  return MEM_swap32(MEM_read32(memPtr));
1221  else
1222  return MEM_read32(memPtr);
1223 }
1224 
1225 MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
1226 {
1227  if (MEM_isLittleEndian())
1228  MEM_write32(memPtr, MEM_swap32(val32));
1229  else
1230  MEM_write32(memPtr, val32);
1231 }
1232 
1233 MEM_STATIC U64 MEM_readBE64(const void* memPtr)
1234 {
1235  if (MEM_isLittleEndian())
1236  return MEM_swap64(MEM_read64(memPtr));
1237  else
1238  return MEM_read64(memPtr);
1239 }
1240 
1241 MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
1242 {
1243  if (MEM_isLittleEndian())
1244  MEM_write64(memPtr, MEM_swap64(val64));
1245  else
1246  MEM_write64(memPtr, val64);
1247 }
1248 
1249 MEM_STATIC size_t MEM_readBEST(const void* memPtr)
1250 {
1251  if (MEM_32bits())
1252  return (size_t)MEM_readBE32(memPtr);
1253  else
1254  return (size_t)MEM_readBE64(memPtr);
1255 }
1256 
1257 MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
1258 {
1259  if (MEM_32bits())
1260  MEM_writeBE32(memPtr, (U32)val);
1261  else
1262  MEM_writeBE64(memPtr, (U64)val);
1263 }
1264 
1265 /* code only tested on 32 and 64 bits systems */
1266 MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
1267 
1268 
1269 #if defined (__cplusplus)
1270 }
1271 #endif
1272 
1273 #endif /* MEM_H_MODULE */
1274 /**** ended inlining mem.h ****/
1275 /**** start inlining error_private.h ****/
1276 /*
1277  * Copyright (c) Meta Platforms, Inc. and affiliates.
1278  * All rights reserved.
1279  *
1280  * This source code is licensed under both the BSD-style license (found in the
1281  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
1282  * in the COPYING file in the root directory of this source tree).
1283  * You may select, at your option, one of the above-listed licenses.
1284  */
1285 
1286 /* Note : this module is expected to remain private, do not expose it */
1287 
1288 #ifndef ERROR_H_MODULE
1289 #define ERROR_H_MODULE
1290 
1291 #if defined (__cplusplus)
1292 extern "C" {
1293 #endif
1294 
1295 
1296 /* ****************************************
1297 * Dependencies
1298 ******************************************/
1299 /**** start inlining ../zstd_errors.h ****/
1300 /*
1301  * Copyright (c) Meta Platforms, Inc. and affiliates.
1302  * All rights reserved.
1303  *
1304  * This source code is licensed under both the BSD-style license (found in the
1305  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
1306  * in the COPYING file in the root directory of this source tree).
1307  * You may select, at your option, one of the above-listed licenses.
1308  */
1309 
1310 #ifndef ZSTD_ERRORS_H_398273423
1311 #define ZSTD_ERRORS_H_398273423
1312 
1313 #if defined (__cplusplus)
1314 extern "C" {
1315 #endif
1316 
1317 /*===== dependency =====*/
1318 #include <stddef.h> /* size_t */
1319 
1320 
1321 /* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
1322 #ifndef ZSTDERRORLIB_VISIBLE
1323  /* Backwards compatibility with old macro name */
1324 # ifdef ZSTDERRORLIB_VISIBILITY
1325 # define ZSTDERRORLIB_VISIBLE ZSTDERRORLIB_VISIBILITY
1326 # elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
1327 # define ZSTDERRORLIB_VISIBLE __attribute__ ((visibility ("default")))
1328 # else
1329 # define ZSTDERRORLIB_VISIBLE
1330 # endif
1331 #endif
1332 
1333 #ifndef ZSTDERRORLIB_HIDDEN
1334 # if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
1335 # define ZSTDERRORLIB_HIDDEN __attribute__ ((visibility ("hidden")))
1336 # else
1337 # define ZSTDERRORLIB_HIDDEN
1338 # endif
1339 #endif
1340 
1341 #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
1342 # define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBLE
1343 #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
1344 # define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
1345 #else
1346 # define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBLE
1347 #endif
1348 
1349 /*-*********************************************
1350  * Error codes list
1351  *-*********************************************
1352  * Error codes _values_ are pinned down since v1.3.1 only.
1353  * Therefore, don't rely on values if you may link to any version < v1.3.1.
1354  *
1355  * Only values < 100 are considered stable.
1356  *
1357  * note 1 : this API shall be used with static linking only.
1358  * dynamic linking is not yet officially supported.
1359  * note 2 : Prefer relying on the enum than on its value whenever possible
1360  * This is the only supported way to use the error list < v1.3.1
1361  * note 3 : ZSTD_isError() is always correct, whatever the library version.
1362  **********************************************/
1363 typedef enum {
1392  /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */
1399  ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
1400 } ZSTD_ErrorCode;
1401 
1405 ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
1409 #if defined (__cplusplus)
1410 }
1411 #endif
1412 
1413 #endif /* ZSTD_ERRORS_H_398273423 */
1414 /**** ended inlining ../zstd_errors.h ****/
1415 /**** skipping file: compiler.h ****/
1416 /**** skipping file: debug.h ****/
1417 /**** skipping file: zstd_deps.h ****/
1418 
1419 
1420 /* ****************************************
1421 * Compiler-specific
1422 ******************************************/
1423 #if defined(__GNUC__)
1424 # define ERR_STATIC static __attribute__((unused))
1425 #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
1426 # define ERR_STATIC static inline
1427 #elif defined(_MSC_VER)
1428 # define ERR_STATIC static __inline
1429 #else
1430 # define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
1431 #endif
1432 
1433 
1434 /*-****************************************
1435 * Customization (error_public.h)
1436 ******************************************/
1438 #define PREFIX(name) ZSTD_error_##name
1439 
1440 
1441 /*-****************************************
1442 * Error codes handling
1443 ******************************************/
1444 #undef ERROR /* already defined on Visual Studio */
1445 #define ERROR(name) ZSTD_ERROR(name)
1446 #define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
1447 
1448 ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
1449 
1450 ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
1451 
1452 /* check and forward error code */
1453 #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
1454 #define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
1455 
1456 
1457 /*-****************************************
1458 * Error Strings
1459 ******************************************/
1460 
1461 const char* ERR_getErrorString(ERR_enum code); /* error_private.c */
1462 
1463 ERR_STATIC const char* ERR_getErrorName(size_t code)
1464 {
1465  return ERR_getErrorString(ERR_getErrorCode(code));
1466 }
1467 
1478 void _force_has_format_string(const char *format, ...) {
1479  (void)format;
1480 }
1481 
1488 #define _FORCE_HAS_FORMAT_STRING(...) \
1489  if (0) { \
1490  _force_has_format_string(__VA_ARGS__); \
1491  }
1492 
1493 #define ERR_QUOTE(str) #str
1494 
1502 #define RETURN_ERROR_IF(cond, err, ...) \
1503  if (cond) { \
1504  RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
1505  __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
1506  _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
1507  RAWLOG(3, ": " __VA_ARGS__); \
1508  RAWLOG(3, "\n"); \
1509  return ERROR(err); \
1510  }
1511 
1517 #define RETURN_ERROR(err, ...) \
1518  do { \
1519  RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
1520  __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
1521  _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
1522  RAWLOG(3, ": " __VA_ARGS__); \
1523  RAWLOG(3, "\n"); \
1524  return ERROR(err); \
1525  } while(0);
1526 
1532 #define FORWARD_IF_ERROR(err, ...) \
1533  do { \
1534  size_t const err_code = (err); \
1535  if (ERR_isError(err_code)) { \
1536  RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
1537  __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
1538  _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
1539  RAWLOG(3, ": " __VA_ARGS__); \
1540  RAWLOG(3, "\n"); \
1541  return err_code; \
1542  } \
1543  } while(0);
1544 
1545 #if defined (__cplusplus)
1546 }
1547 #endif
1548 
1549 #endif /* ERROR_H_MODULE */
1550 /**** ended inlining error_private.h ****/
1551 #define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
1552 /**** start inlining fse.h ****/
1553 /* ******************************************************************
1554  * FSE : Finite State Entropy codec
1555  * Public Prototypes declaration
1556  * Copyright (c) Meta Platforms, Inc. and affiliates.
1557  *
1558  * You can contact the author at :
1559  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
1560  *
1561  * This source code is licensed under both the BSD-style license (found in the
1562  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
1563  * in the COPYING file in the root directory of this source tree).
1564  * You may select, at your option, one of the above-listed licenses.
1565 ****************************************************************** */
1566 
1567 #if defined (__cplusplus)
1568 extern "C" {
1569 #endif
1570 
1571 #ifndef FSE_H
1572 #define FSE_H
1573 
1574 
1575 /*-*****************************************
1576 * Dependencies
1577 ******************************************/
1578 /**** skipping file: zstd_deps.h ****/
1579 
1580 
1581 /*-*****************************************
1582 * FSE_PUBLIC_API : control library symbols visibility
1583 ******************************************/
1584 #if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
1585 # define FSE_PUBLIC_API __attribute__ ((visibility ("default")))
1586 #elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
1587 # define FSE_PUBLIC_API __declspec(dllexport)
1588 #elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
1589 # define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
1590 #else
1591 # define FSE_PUBLIC_API
1592 #endif
1593 
1594 /*------ Version ------*/
1595 #define FSE_VERSION_MAJOR 0
1596 #define FSE_VERSION_MINOR 9
1597 #define FSE_VERSION_RELEASE 0
1598 
1599 #define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
1600 #define FSE_QUOTE(str) #str
1601 #define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
1602 #define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
1603 
1604 #define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
1605 FSE_PUBLIC_API unsigned FSE_versionNumber(void);
1608 /*-*****************************************
1609 * Tool functions
1610 ******************************************/
1611 FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */
1612 
1613 /* Error Management */
1614 FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
1615 FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */
1616 
1617 
1618 /*-*****************************************
1619 * FSE detailed API
1620 ******************************************/
1639 /* *** COMPRESSION *** */
1640 
1645 FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
1646 
1658 FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,
1659  const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount);
1660 
1664 FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
1665 
1670 FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize,
1671  const short* normalizedCounter,
1672  unsigned maxSymbolValue, unsigned tableLog);
1673 
1676 typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
1677 
1681 FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
1682 
1688 FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
1689 
1734 /* *** DECOMPRESSION *** */
1735 
1741 FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter,
1742  unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
1743  const void* rBuffer, size_t rBuffSize);
1744 
1748 FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter,
1749  unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
1750  const void* rBuffer, size_t rBuffSize, int bmi2);
1751 
1752 typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
1753 
1782 #endif /* FSE_H */
1783 
1784 #if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
1785 #define FSE_H_FSE_STATIC_LINKING_ONLY
1786 
1787 /* *** Dependency *** */
1788 /**** start inlining bitstream.h ****/
1789 /* ******************************************************************
1790  * bitstream
1791  * Part of FSE library
1792  * Copyright (c) Meta Platforms, Inc. and affiliates.
1793  *
1794  * You can contact the author at :
1795  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
1796  *
1797  * This source code is licensed under both the BSD-style license (found in the
1798  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
1799  * in the COPYING file in the root directory of this source tree).
1800  * You may select, at your option, one of the above-listed licenses.
1801 ****************************************************************** */
1802 #ifndef BITSTREAM_H_MODULE
1803 #define BITSTREAM_H_MODULE
1804 
1805 #if defined (__cplusplus)
1806 extern "C" {
1807 #endif
1808 /*
1809 * This API consists of small unitary functions, which must be inlined for best performance.
1810 * Since link-time-optimization is not available for all compilers,
1811 * these functions are defined into a .h to be included.
1812 */
1813 
1814 /*-****************************************
1815 * Dependencies
1816 ******************************************/
1817 /**** skipping file: mem.h ****/
1818 /**** skipping file: compiler.h ****/
1819 /**** skipping file: debug.h ****/
1820 /**** skipping file: error_private.h ****/
1821 /**** start inlining bits.h ****/
1822 /*
1823  * Copyright (c) Meta Platforms, Inc. and affiliates.
1824  * All rights reserved.
1825  *
1826  * This source code is licensed under both the BSD-style license (found in the
1827  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
1828  * in the COPYING file in the root directory of this source tree).
1829  * You may select, at your option, one of the above-listed licenses.
1830  */
1831 
1832 #ifndef ZSTD_BITS_H
1833 #define ZSTD_BITS_H
1834 
1835 /**** skipping file: mem.h ****/
1836 
1838 {
1839  assert(val != 0);
1840  {
1841  static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3,
1842  30, 22, 20, 15, 25, 17, 4, 8,
1843  31, 27, 13, 23, 21, 19, 16, 7,
1844  26, 12, 18, 6, 11, 5, 10, 9};
1845  return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27];
1846  }
1847 }
1848 
1850 {
1851  assert(val != 0);
1852 # if defined(_MSC_VER)
1853 # if STATIC_BMI2 == 1
1854  return (unsigned)_tzcnt_u32(val);
1855 # else
1856  if (val != 0) {
1857  unsigned long r;
1858  _BitScanForward(&r, val);
1859  return (unsigned)r;
1860  } else {
1861  /* Should not reach this code path */
1862  __assume(0);
1863  }
1864 # endif
1865 # elif defined(__GNUC__) && (__GNUC__ >= 4)
1866  return (unsigned)__builtin_ctz(val);
1867 # else
1869 # endif
1870 }
1871 
1873  assert(val != 0);
1874  {
1875  static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29,
1876  11, 14, 16, 18, 22, 25, 3, 30,
1877  8, 12, 20, 28, 15, 17, 24, 7,
1878  19, 27, 23, 6, 26, 5, 4, 31};
1879  val |= val >> 1;
1880  val |= val >> 2;
1881  val |= val >> 4;
1882  val |= val >> 8;
1883  val |= val >> 16;
1884  return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27];
1885  }
1886 }
1887 
1889 {
1890  assert(val != 0);
1891 # if defined(_MSC_VER)
1892 # if STATIC_BMI2 == 1
1893  return (unsigned)_lzcnt_u32(val);
1894 # else
1895  if (val != 0) {
1896  unsigned long r;
1897  _BitScanReverse(&r, val);
1898  return (unsigned)(31 - r);
1899  } else {
1900  /* Should not reach this code path */
1901  __assume(0);
1902  }
1903 # endif
1904 # elif defined(__GNUC__) && (__GNUC__ >= 4)
1905  return (unsigned)__builtin_clz(val);
1906 # else
1908 # endif
1909 }
1910 
1912 {
1913  assert(val != 0);
1914 # if defined(_MSC_VER) && defined(_WIN64)
1915 # if STATIC_BMI2 == 1
1916  return (unsigned)_tzcnt_u64(val);
1917 # else
1918  if (val != 0) {
1919  unsigned long r;
1920  _BitScanForward64(&r, val);
1921  return (unsigned)r;
1922  } else {
1923  /* Should not reach this code path */
1924  __assume(0);
1925  }
1926 # endif
1927 # elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__)
1928  return (unsigned)__builtin_ctzll(val);
1929 # else
1930  {
1931  U32 mostSignificantWord = (U32)(val >> 32);
1932  U32 leastSignificantWord = (U32)val;
1933  if (leastSignificantWord == 0) {
1934  return 32 + ZSTD_countTrailingZeros32(mostSignificantWord);
1935  } else {
1936  return ZSTD_countTrailingZeros32(leastSignificantWord);
1937  }
1938  }
1939 # endif
1940 }
1941 
1943 {
1944  assert(val != 0);
1945 # if defined(_MSC_VER) && defined(_WIN64)
1946 # if STATIC_BMI2 == 1
1947  return (unsigned)_lzcnt_u64(val);
1948 # else
1949  if (val != 0) {
1950  unsigned long r;
1951  _BitScanReverse64(&r, val);
1952  return (unsigned)(63 - r);
1953  } else {
1954  /* Should not reach this code path */
1955  __assume(0);
1956  }
1957 # endif
1958 # elif defined(__GNUC__) && (__GNUC__ >= 4)
1959  return (unsigned)(__builtin_clzll(val));
1960 # else
1961  {
1962  U32 mostSignificantWord = (U32)(val >> 32);
1963  U32 leastSignificantWord = (U32)val;
1964  if (mostSignificantWord == 0) {
1965  return 32 + ZSTD_countLeadingZeros32(leastSignificantWord);
1966  } else {
1967  return ZSTD_countLeadingZeros32(mostSignificantWord);
1968  }
1969  }
1970 # endif
1971 }
1972 
1973 MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
1974 {
1975  if (MEM_isLittleEndian()) {
1976  if (MEM_64bits()) {
1977  return ZSTD_countTrailingZeros64((U64)val) >> 3;
1978  } else {
1979  return ZSTD_countTrailingZeros32((U32)val) >> 3;
1980  }
1981  } else { /* Big Endian CPU */
1982  if (MEM_64bits()) {
1983  return ZSTD_countLeadingZeros64((U64)val) >> 3;
1984  } else {
1985  return ZSTD_countLeadingZeros32((U32)val) >> 3;
1986  }
1987  }
1988 }
1989 
1990 MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
1991 {
1992  assert(val != 0);
1993  return 31 - ZSTD_countLeadingZeros32(val);
1994 }
1995 
1996 /* ZSTD_rotateRight_*():
1997  * Rotates a bitfield to the right by "count" bits.
1998  * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts
1999  */
2000 MEM_STATIC
2002  assert(count < 64);
2003  count &= 0x3F; /* for fickle pattern recognition */
2004  return (value >> count) | (U64)(value << ((0U - count) & 0x3F));
2005 }
2006 
2007 MEM_STATIC
2009  assert(count < 32);
2010  count &= 0x1F; /* for fickle pattern recognition */
2011  return (value >> count) | (U32)(value << ((0U - count) & 0x1F));
2012 }
2013 
2014 MEM_STATIC
2016  assert(count < 16);
2017  count &= 0x0F; /* for fickle pattern recognition */
2018  return (value >> count) | (U16)(value << ((0U - count) & 0x0F));
2019 }
2020 
2021 #endif /* ZSTD_BITS_H */
2022 /**** ended inlining bits.h ****/
2023 
2024 
2025 /*=========================================
2026 * Target specific
2027 =========================================*/
2028 #ifndef ZSTD_NO_INTRINSICS
2029 # if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__)
2030 # include <immintrin.h> /* support for bextr (experimental)/bzhi */
2031 # elif defined(__ICCARM__)
2032 # include <intrinsics.h>
2033 # endif
2034 #endif
2035 
2036 #define STREAM_ACCUMULATOR_MIN_32 25
2037 #define STREAM_ACCUMULATOR_MIN_64 57
2038 #define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
2039 
2040 
2041 /*-******************************************
2042 * bitStream encoding API (write forward)
2043 ********************************************/
2044 /* bitStream can mix input from multiple sources.
2045  * A critical property of these streams is that they encode and decode in **reverse** direction.
2046  * So the first bit sequence you add will be the last to be read, like a LIFO stack.
2047  */
2048 typedef struct {
2050  unsigned bitPos;
2051  char* startPtr;
2052  char* ptr;
2053  char* endPtr;
2054 } BIT_CStream_t;
2055 
2056 MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
2057 MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
2060 
2061 /* Start with initCStream, providing the size of buffer to write into.
2062 * bitStream will never write outside of this buffer.
2063 * `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
2064 *
2065 * bits are first added to a local register.
2066 * Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
2067 * Writing data into memory is an explicit operation, performed by the flushBits function.
2068 * Hence keep track how many bits are potentially stored into local register to avoid register overflow.
2069 * After a flushBits, a maximum of 7 bits might still be stored into local register.
2070 *
2071 * Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
2072 *
2073 * Last operation is to close the bitStream.
2074 * The function returns the final size of CStream in bytes.
2075 * If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
2076 */
2077 
2078 
2079 /*-********************************************
2080 * bitStream decoding API (read backward)
2081 **********************************************/
2082 typedef struct {
2084  unsigned bitsConsumed;
2085  const char* ptr;
2086  const char* start;
2087  const char* limitPtr;
2088 } BIT_DStream_t;
2089 
2090 typedef enum { BIT_DStream_unfinished = 0,
2093  BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */
2094  /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
2095 
2096 MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
2097 MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
2099 MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
2100 
2101 
2102 /* Start by invoking BIT_initDStream().
2103 * A chunk of the bitStream is then stored into a local register.
2104 * Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
2105 * You can then retrieve bitFields stored into the local register, **in reverse order**.
2106 * Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
2107 * A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
2108 * Otherwise, it can be less than that, so proceed accordingly.
2109 * Checking if DStream has reached its end can be performed with BIT_endOfDStream().
2110 */
2111 
2112 
2113 /*-****************************************
2114 * unsafe API
2115 ******************************************/
2116 MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
2117 /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
2118 
2120 /* unsafe version; does not check buffer overflow */
2121 
2122 MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
2123 /* faster, but works only if nbBits >= 1 */
2124 
2125 /*===== Local Constants =====*/
2126 static const unsigned BIT_mask[] = {
2127  0, 1, 3, 7, 0xF, 0x1F,
2128  0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
2129  0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
2130  0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
2131  0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
2132  0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
2133 #define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
2134 
2135 /*-**************************************************************
2136 * bitStream encoding
2137 ****************************************************************/
2143  void* startPtr, size_t dstCapacity)
2144 {
2145  bitC->bitContainer = 0;
2146  bitC->bitPos = 0;
2147  bitC->startPtr = (char*)startPtr;
2148  bitC->ptr = bitC->startPtr;
2149  bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
2150  if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
2151  return 0;
2152 }
2153 
2154 MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
2155 {
2156 #if defined(STATIC_BMI2) && STATIC_BMI2 == 1 && !defined(ZSTD_NO_INTRINSICS)
2157  return _bzhi_u64(bitContainer, nbBits);
2158 #else
2159  assert(nbBits < BIT_MASK_SIZE);
2160  return bitContainer & BIT_mask[nbBits];
2161 #endif
2162 }
2163 
2168  size_t value, unsigned nbBits)
2169 {
2171  assert(nbBits < BIT_MASK_SIZE);
2172  assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
2173  bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos;
2174  bitC->bitPos += nbBits;
2175 }
2176 
2181  size_t value, unsigned nbBits)
2182 {
2183  assert((value>>nbBits) == 0);
2184  assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
2185  bitC->bitContainer |= value << bitC->bitPos;
2186  bitC->bitPos += nbBits;
2187 }
2188 
2193 {
2194  size_t const nbBytes = bitC->bitPos >> 3;
2195  assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
2196  assert(bitC->ptr <= bitC->endPtr);
2197  MEM_writeLEST(bitC->ptr, bitC->bitContainer);
2198  bitC->ptr += nbBytes;
2199  bitC->bitPos &= 7;
2200  bitC->bitContainer >>= nbBytes*8;
2201 }
2202 
2209 {
2210  size_t const nbBytes = bitC->bitPos >> 3;
2211  assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
2212  assert(bitC->ptr <= bitC->endPtr);
2213  MEM_writeLEST(bitC->ptr, bitC->bitContainer);
2214  bitC->ptr += nbBytes;
2215  if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
2216  bitC->bitPos &= 7;
2217  bitC->bitContainer >>= nbBytes*8;
2218 }
2219 
2224 {
2225  BIT_addBitsFast(bitC, 1, 1); /* endMark */
2226  BIT_flushBits(bitC);
2227  if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
2228  return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
2229 }
2230 
2231 
2232 /*-********************************************************
2233 * bitStream decoding
2234 **********************************************************/
2241 MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
2242 {
2243  if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
2244 
2245  bitD->start = (const char*)srcBuffer;
2246  bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
2247 
2248  if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
2249  bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
2250  bitD->bitContainer = MEM_readLEST(bitD->ptr);
2251  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
2252  bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
2253  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
2254  } else {
2255  bitD->ptr = bitD->start;
2256  bitD->bitContainer = *(const BYTE*)(bitD->start);
2257  switch(srcSize)
2258  {
2259  case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
2261 
2262  case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
2264 
2265  case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
2267 
2268  case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
2270 
2271  case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
2273 
2274  case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
2276 
2277  default: break;
2278  }
2279  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
2280  bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
2281  if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
2282  }
2283  bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
2284  }
2285 
2286  return srcSize;
2287 }
2288 
2289 MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
2290 {
2291  return bitContainer >> start;
2292 }
2293 
2294 MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
2295 {
2296  U32 const regMask = sizeof(bitContainer)*8 - 1;
2297  /* if start > regMask, bitstream is corrupted, and result is undefined */
2298  assert(nbBits < BIT_MASK_SIZE);
2299  /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
2300  * than accessing memory. When bmi2 instruction is not present, we consider
2301  * such cpus old (pre-Haswell, 2013) and their performance is not of that
2302  * importance.
2303  */
2304 #if defined(__x86_64__) || defined(_M_X86)
2305  return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
2306 #else
2307  return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
2308 #endif
2309 }
2310 
2318 {
2319  /* arbitrate between double-shift and shift+mask */
2320 #if 1
2321  /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
2322  * bitstream is likely corrupted, and result is undefined */
2323  return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
2324 #else
2325  /* this code path is slower on my os-x laptop */
2326  U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
2327  return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
2328 #endif
2329 }
2330 
2333 MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
2334 {
2335  U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
2336  assert(nbBits >= 1);
2337  return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
2338 }
2339 
2341 {
2342  bitD->bitsConsumed += nbBits;
2343 }
2344 
2350 {
2351  size_t const value = BIT_lookBits(bitD, nbBits);
2352  BIT_skipBits(bitD, nbBits);
2353  return value;
2354 }
2355 
2358 MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
2359 {
2360  size_t const value = BIT_lookBitsFast(bitD, nbBits);
2361  assert(nbBits >= 1);
2362  BIT_skipBits(bitD, nbBits);
2363  return value;
2364 }
2365 
2373 {
2374  if (UNLIKELY(bitD->ptr < bitD->limitPtr))
2375  return BIT_DStream_overflow;
2376  assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
2377  bitD->ptr -= bitD->bitsConsumed >> 3;
2378  bitD->bitsConsumed &= 7;
2379  bitD->bitContainer = MEM_readLEST(bitD->ptr);
2380  return BIT_DStream_unfinished;
2381 }
2382 
2389 {
2390  if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
2391  return BIT_DStream_overflow;
2392 
2393  if (bitD->ptr >= bitD->limitPtr) {
2394  return BIT_reloadDStreamFast(bitD);
2395  }
2396  if (bitD->ptr == bitD->start) {
2397  if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
2398  return BIT_DStream_completed;
2399  }
2400  /* start < ptr < limitPtr */
2401  { U32 nbBytes = bitD->bitsConsumed >> 3;
2403  if (bitD->ptr - nbBytes < bitD->start) {
2404  nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
2405  result = BIT_DStream_endOfBuffer;
2406  }
2407  bitD->ptr -= nbBytes;
2408  bitD->bitsConsumed -= nbBytes*8;
2409  bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
2410  return result;
2411  }
2412 }
2413 
2418 {
2419  return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
2420 }
2421 
2422 #if defined (__cplusplus)
2423 }
2424 #endif
2425 
2426 #endif /* BITSTREAM_H_MODULE */
2427 /**** ended inlining bitstream.h ****/
2428 
2429 
2430 /* *****************************************
2431 * Static allocation
2432 *******************************************/
2433 /* FSE buffer bounds */
2434 #define FSE_NCOUNTBOUND 512
2435 #define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)
2436 #define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
2437 
2438 /* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
2439 #define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2))
2440 #define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog)))
2441 
2442 /* or use the size to malloc() space directly. Pay attention to alignment restrictions though */
2443 #define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable))
2444 #define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable))
2445 
2446 
2447 /* *****************************************
2448  * FSE advanced API
2449  ***************************************** */
2450 
2451 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
2454 size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
2457 /* FSE_buildCTable_wksp() :
2458  * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
2459  * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`.
2460  * See FSE_buildCTable_wksp() for breakdown of workspace usage.
2461  */
2462 #define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */)
2463 #define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog))
2464 size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
2465 
2466 #define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8)
2467 #define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned))
2468 FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
2471 #define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + 1 + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1)
2472 #define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned))
2473 size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2);
2477 typedef enum {
2481  } FSE_repeat;
2482 
2483 /* *****************************************
2484 * FSE symbol compression API
2485 *******************************************/
2490 typedef struct {
2491  ptrdiff_t value;
2492  const void* stateTable;
2493  const void* symbolTT;
2494  unsigned stateLog;
2495 } FSE_CState_t;
2496 
2497 static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
2498 
2499 static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
2500 
2501 static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);
2502 
2547 /* *****************************************
2548 * FSE symbol decompression API
2549 *******************************************/
2550 typedef struct {
2551  size_t state;
2552  const void* table; /* precise table may vary, depending on U16 */
2553 } FSE_DState_t;
2554 
2555 
2556 static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);
2557 
2558 static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
2559 
2560 static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
2561 
2612 /* *****************************************
2613 * FSE unsafe API
2614 *******************************************/
2615 static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
2616 /* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
2617 
2618 
2619 /* *****************************************
2620 * Implementation of inlined functions
2621 *******************************************/
2622 typedef struct {
2625 } FSE_symbolCompressionTransform; /* total 8 bytes */
2626 
2628 {
2629  const void* ptr = ct;
2630  const U16* u16ptr = (const U16*) ptr;
2631  const U32 tableLog = MEM_read16(ptr);
2632  statePtr->value = (ptrdiff_t)1<<tableLog;
2633  statePtr->stateTable = u16ptr+2;
2634  statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1);
2635  statePtr->stateLog = tableLog;
2636 }
2637 
2638 
2642 MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
2643 {
2644  FSE_initCState(statePtr, ct);
2645  { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
2646  const U16* stateTable = (const U16*)(statePtr->stateTable);
2647  U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
2648  statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
2649  statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
2650  }
2651 }
2652 
2653 MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol)
2654 {
2655  FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
2656  const U16* const stateTable = (const U16*)(statePtr->stateTable);
2657  U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
2658  BIT_addBits(bitC, statePtr->value, nbBitsOut);
2659  statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
2660 }
2661 
2663 {
2664  BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
2665  BIT_flushBits(bitC);
2666 }
2667 
2668 
2669 /* FSE_getMaxNbBits() :
2670  * Approximate maximum cost of a symbol, in bits.
2671  * Fractional get rounded up (i.e. a symbol with a normalized frequency of 3 gives the same result as a frequency of 2)
2672  * note 1 : assume symbolValue is valid (<= maxSymbolValue)
2673  * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */
2674 MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue)
2675 {
2676  const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;
2677  return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16;
2678 }
2679 
2680 /* FSE_bitCost() :
2681  * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits)
2682  * note 1 : assume symbolValue is valid (<= maxSymbolValue)
2683  * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */
2684 MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog)
2685 {
2686  const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;
2687  U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16;
2688  U32 const threshold = (minNbBits+1) << 16;
2689  assert(tableLog < 16);
2690  assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */
2691  { U32 const tableSize = 1 << tableLog;
2692  U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize);
2693  U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */
2694  U32 const bitMultiplier = 1 << accuracyLog;
2695  assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold);
2696  assert(normalizedDeltaFromThreshold <= bitMultiplier);
2697  return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold;
2698  }
2699 }
2700 
2701 
2702 /* ====== Decompression ====== */
2703 
2704 typedef struct {
2707 } FSE_DTableHeader; /* sizeof U32 */
2708 
2709 typedef struct
2710 {
2711  unsigned short newState;
2712  unsigned char symbol;
2713  unsigned char nbBits;
2714 } FSE_decode_t; /* size == U32 */
2715 
2717 {
2718  const void* ptr = dt;
2719  const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
2720  DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
2721  BIT_reloadDStream(bitD);
2722  DStatePtr->table = dt + 1;
2723 }
2724 
2726 {
2727  FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
2728  return DInfo.symbol;
2729 }
2730 
2732 {
2733  FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
2734  U32 const nbBits = DInfo.nbBits;
2735  size_t const lowBits = BIT_readBits(bitD, nbBits);
2736  DStatePtr->state = DInfo.newState + lowBits;
2737 }
2738 
2740 {
2741  FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
2742  U32 const nbBits = DInfo.nbBits;
2743  BYTE const symbol = DInfo.symbol;
2744  size_t const lowBits = BIT_readBits(bitD, nbBits);
2745 
2746  DStatePtr->state = DInfo.newState + lowBits;
2747  return symbol;
2748 }
2749 
2753 {
2754  FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
2755  U32 const nbBits = DInfo.nbBits;
2756  BYTE const symbol = DInfo.symbol;
2757  size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
2758 
2759  DStatePtr->state = DInfo.newState + lowBits;
2760  return symbol;
2761 }
2762 
2763 MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
2764 {
2765  return DStatePtr->state == 0;
2766 }
2767 
2768 
2769 
2770 #ifndef FSE_COMMONDEFS_ONLY
2771 
2772 /* **************************************************************
2773 * Tuning parameters
2774 ****************************************************************/
2780 #ifndef FSE_MAX_MEMORY_USAGE
2781 # define FSE_MAX_MEMORY_USAGE 14
2782 #endif
2783 #ifndef FSE_DEFAULT_MEMORY_USAGE
2784 # define FSE_DEFAULT_MEMORY_USAGE 13
2785 #endif
2786 #if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE)
2787 # error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE"
2788 #endif
2789 
2793 #ifndef FSE_MAX_SYMBOL_VALUE
2794 # define FSE_MAX_SYMBOL_VALUE 255
2795 #endif
2796 
2797 /* **************************************************************
2798 * template functions type & suffix
2799 ****************************************************************/
2800 #define FSE_FUNCTION_TYPE BYTE
2801 #define FSE_FUNCTION_EXTENSION
2802 #define FSE_DECODE_TYPE FSE_decode_t
2803 
2804 
2805 #endif /* !FSE_COMMONDEFS_ONLY */
2806 
2807 
2808 /* ***************************************************************
2809 * Constants
2810 *****************************************************************/
2811 #define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
2812 #define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
2813 #define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
2814 #define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
2815 #define FSE_MIN_TABLELOG 5
2816 
2817 #define FSE_TABLELOG_ABSOLUTE_MAX 15
2818 #if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
2819 # error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
2820 #endif
2821 
2822 #define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3)
2823 
2824 
2825 #endif /* FSE_STATIC_LINKING_ONLY */
2826 
2827 
2828 #if defined (__cplusplus)
2829 }
2830 #endif
2831 /**** ended inlining fse.h ****/
2832 /**** start inlining huf.h ****/
2833 /* ******************************************************************
2834  * huff0 huffman codec,
2835  * part of Finite State Entropy library
2836  * Copyright (c) Meta Platforms, Inc. and affiliates.
2837  *
2838  * You can contact the author at :
2839  * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
2840  *
2841  * This source code is licensed under both the BSD-style license (found in the
2842  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
2843  * in the COPYING file in the root directory of this source tree).
2844  * You may select, at your option, one of the above-listed licenses.
2845 ****************************************************************** */
2846 
2847 #if defined (__cplusplus)
2848 extern "C" {
2849 #endif
2850 
2851 #ifndef HUF_H_298734234
2852 #define HUF_H_298734234
2853 
2854 /* *** Dependencies *** */
2855 /**** skipping file: zstd_deps.h ****/
2856 /**** skipping file: mem.h ****/
2857 #define FSE_STATIC_LINKING_ONLY
2858 /**** skipping file: fse.h ****/
2859 
2860 
2861 /* *** Tool functions *** */
2862 #define HUF_BLOCKSIZE_MAX (128 * 1024)
2863 size_t HUF_compressBound(size_t size);
2865 /* Error Management */
2866 unsigned HUF_isError(size_t code);
2867 const char* HUF_getErrorName(size_t code);
2870 #define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */)
2871 #define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64))
2872 
2873 /* *** Constants *** */
2874 #define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */
2875 #define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */
2876 #define HUF_SYMBOLVALUE_MAX 255
2877 
2878 #define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
2879 #if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
2880 # error "HUF_TABLELOG_MAX is too large !"
2881 #endif
2882 
2883 
2884 /* ****************************************
2885 * Static allocation
2886 ******************************************/
2887 /* HUF buffer bounds */
2888 #define HUF_CTABLEBOUND 129
2889 #define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */
2890 #define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
2891 
2892 /* static allocation of HUF's Compression Table */
2893 /* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */
2894 typedef size_t HUF_CElt; /* consider it an incomplete type */
2895 #define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */
2896 #define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t))
2897 #define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
2898  HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */
2899 
2900 /* static allocation of HUF's DTable */
2901 typedef U32 HUF_DTable;
2902 #define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
2903 #define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \
2904  HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
2905 #define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
2906  HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
2907 
2908 
2909 /* ****************************************
2910 * Advanced decompression functions
2911 ******************************************/
2912 
2917 typedef enum {
2922  HUF_flags_bmi2 = (1 << 0),
2948 } HUF_flags_e;
2949 
2950 
2951 /* ****************************************
2952  * HUF detailed API
2953  * ****************************************/
2954 #define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra
2955 
2967 unsigned HUF_minTableLog(unsigned symbolCardinality);
2968 unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue);
2969 unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace,
2970  size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */
2971 size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize);
2972 size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);
2973 size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
2974 int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
2975 
2976 typedef enum {
2980  } HUF_repeat;
2981 
2988 size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
2989  const void* src, size_t srcSize,
2990  unsigned maxSymbolValue, unsigned tableLog,
2991  void* workSpace, size_t wkspSize,
2992  HUF_CElt* hufTable, HUF_repeat* repeat, int flags);
2993 
2998 #define HUF_CTABLE_WORKSPACE_SIZE_U32 ((4 * (HUF_SYMBOLVALUE_MAX + 1)) + 192)
2999 #define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))
3000 size_t HUF_buildCTable_wksp (HUF_CElt* tree,
3001  const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
3002  void* workSpace, size_t wkspSize);
3003 
3009 size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
3010  U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
3011  const void* src, size_t srcSize);
3012 
3018 #define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1)
3019 #define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned))
3020 size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,
3021  U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
3022  const void* src, size_t srcSize,
3023  void* workspace, size_t wkspSize,
3024  int flags);
3025 
3028 size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
3029 
3033 U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue);
3034 
3035 /*
3036  * HUF_decompress() does the following:
3037  * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics
3038  * 2. build Huffman table from save, using HUF_readDTableX?()
3039  * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable()
3040  */
3041 
3047 U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
3048 
3059 #define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9))
3060 #define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
3061 
3062 
3063 /* ====================== */
3064 /* single stream variants */
3065 /* ====================== */
3066 
3067 size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags);
3074 size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
3075  const void* src, size_t srcSize,
3076  unsigned maxSymbolValue, unsigned tableLog,
3077  void* workSpace, size_t wkspSize,
3078  HUF_CElt* hufTable, HUF_repeat* repeat, int flags);
3079 
3080 size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
3081 #ifndef HUF_FORCE_DECOMPRESS_X1
3082 size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
3083 #endif
3084 
3085 /* BMI2 variants.
3086  * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
3087  */
3088 size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags);
3089 #ifndef HUF_FORCE_DECOMPRESS_X2
3090 size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
3091 #endif
3092 size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags);
3093 size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags);
3094 #ifndef HUF_FORCE_DECOMPRESS_X2
3095 size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);
3096 #endif
3097 #ifndef HUF_FORCE_DECOMPRESS_X1
3098 size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags);
3099 #endif
3100 
3101 #endif /* HUF_H_298734234 */
3102 
3103 #if defined (__cplusplus)
3104 }
3105 #endif
3106 /**** ended inlining huf.h ****/
3107 /**** skipping file: bits.h ****/
3108 
3109 
3110 /*=== Version ===*/
3111 unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
3112 
3113 
3114 /*=== Error Management ===*/
3115 unsigned FSE_isError(size_t code) { return ERR_isError(code); }
3116 const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
3117 
3118 unsigned HUF_isError(size_t code) { return ERR_isError(code); }
3119 const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
3120 
3121 
3122 /*-**************************************************************
3123 * FSE NCount encoding-decoding
3124 ****************************************************************/
3126 size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
3127  const void* headerBuffer, size_t hbSize)
3128 {
3129  const BYTE* const istart = (const BYTE*) headerBuffer;
3130  const BYTE* const iend = istart + hbSize;
3131  const BYTE* ip = istart;
3132  int nbBits;
3133  int remaining;
3134  int threshold;
3135  U32 bitStream;
3136  int bitCount;
3137  unsigned charnum = 0;
3138  unsigned const maxSV1 = *maxSVPtr + 1;
3139  int previous0 = 0;
3140 
3141  if (hbSize < 8) {
3142  /* This function only works when hbSize >= 8 */
3143  char buffer[8] = {0};
3144  ZSTD_memcpy(buffer, headerBuffer, hbSize);
3145  { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr,
3146  buffer, sizeof(buffer));
3147  if (FSE_isError(countSize)) return countSize;
3148  if (countSize > hbSize) return ERROR(corruption_detected);
3149  return countSize;
3150  } }
3151  assert(hbSize >= 8);
3152 
3153  /* init */
3154  ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */
3155  bitStream = MEM_readLE32(ip);
3156  nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
3157  if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
3158  bitStream >>= 4;
3159  bitCount = 4;
3160  *tableLogPtr = nbBits;
3161  remaining = (1<<nbBits)+1;
3162  threshold = 1<<nbBits;
3163  nbBits++;
3164 
3165  for (;;) {
3166  if (previous0) {
3167  /* Count the number of repeats. Each time the
3168  * 2-bit repeat code is 0b11 there is another
3169  * repeat.
3170  * Avoid UB by setting the high bit to 1.
3171  */
3172  int repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
3173  while (repeats >= 12) {
3174  charnum += 3 * 12;
3175  if (LIKELY(ip <= iend-7)) {
3176  ip += 3;
3177  } else {
3178  bitCount -= (int)(8 * (iend - 7 - ip));
3179  bitCount &= 31;
3180  ip = iend - 4;
3181  }
3182  bitStream = MEM_readLE32(ip) >> bitCount;
3183  repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1;
3184  }
3185  charnum += 3 * repeats;
3186  bitStream >>= 2 * repeats;
3187  bitCount += 2 * repeats;
3188 
3189  /* Add the final repeat which isn't 0b11. */
3190  assert((bitStream & 3) < 3);
3191  charnum += bitStream & 3;
3192  bitCount += 2;
3193 
3194  /* This is an error, but break and return an error
3195  * at the end, because returning out of a loop makes
3196  * it harder for the compiler to optimize.
3197  */
3198  if (charnum >= maxSV1) break;
3199 
3200  /* We don't need to set the normalized count to 0
3201  * because we already memset the whole buffer to 0.
3202  */
3203 
3204  if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
3205  assert((bitCount >> 3) <= 3); /* For first condition to work */
3206  ip += bitCount>>3;
3207  bitCount &= 7;
3208  } else {
3209  bitCount -= (int)(8 * (iend - 4 - ip));
3210  bitCount &= 31;
3211  ip = iend - 4;
3212  }
3213  bitStream = MEM_readLE32(ip) >> bitCount;
3214  }
3215  {
3216  int const max = (2*threshold-1) - remaining;
3217  int count;
3218 
3219  if ((bitStream & (threshold-1)) < (U32)max) {
3220  count = bitStream & (threshold-1);
3221  bitCount += nbBits-1;
3222  } else {
3223  count = bitStream & (2*threshold-1);
3224  if (count >= threshold) count -= max;
3225  bitCount += nbBits;
3226  }
3227 
3228  count--; /* extra accuracy */
3229  /* When it matters (small blocks), this is a
3230  * predictable branch, because we don't use -1.
3231  */
3232  if (count >= 0) {
3233  remaining -= count;
3234  } else {
3235  assert(count == -1);
3236  remaining += count;
3237  }
3238  normalizedCounter[charnum++] = (short)count;
3239  previous0 = !count;
3240 
3241  assert(threshold > 1);
3242  if (remaining < threshold) {
3243  /* This branch can be folded into the
3244  * threshold update condition because we
3245  * know that threshold > 1.
3246  */
3247  if (remaining <= 1) break;
3248  nbBits = ZSTD_highbit32(remaining) + 1;
3249  threshold = 1 << (nbBits - 1);
3250  }
3251  if (charnum >= maxSV1) break;
3252 
3253  if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
3254  ip += bitCount>>3;
3255  bitCount &= 7;
3256  } else {
3257  bitCount -= (int)(8 * (iend - 4 - ip));
3258  bitCount &= 31;
3259  ip = iend - 4;
3260  }
3261  bitStream = MEM_readLE32(ip) >> bitCount;
3262  } }
3263  if (remaining != 1) return ERROR(corruption_detected);
3264  /* Only possible when there are too many zeros. */
3265  if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall);
3266  if (bitCount > 32) return ERROR(corruption_detected);
3267  *maxSVPtr = charnum-1;
3268 
3269  ip += (bitCount+7)>>3;
3270  return ip-istart;
3271 }
3272 
3273 /* Avoids the FORCE_INLINE of the _body() function. */
3275  short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
3276  const void* headerBuffer, size_t hbSize)
3277 {
3278  return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
3279 }
3280 
3281 #if DYNAMIC_BMI2
3282 BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2(
3283  short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
3284  const void* headerBuffer, size_t hbSize)
3285 {
3286  return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
3287 }
3288 #endif
3289 
3291  short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
3292  const void* headerBuffer, size_t hbSize, int bmi2)
3293 {
3294 #if DYNAMIC_BMI2
3295  if (bmi2) {
3296  return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
3297  }
3298 #endif
3299  (void)bmi2;
3300  return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
3301 }
3302 
3304  short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
3305  const void* headerBuffer, size_t hbSize)
3306 {
3307  return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0);
3308 }
3309 
3310 
3318 size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
3319  U32* nbSymbolsPtr, U32* tableLogPtr,
3320  const void* src, size_t srcSize)
3321 {
3323  return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0);
3324 }
3325 
3326 FORCE_INLINE_TEMPLATE size_t
3327 HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
3328  U32* nbSymbolsPtr, U32* tableLogPtr,
3329  const void* src, size_t srcSize,
3330  void* workSpace, size_t wkspSize,
3331  int bmi2)
3332 {
3333  U32 weightTotal;
3334  const BYTE* ip = (const BYTE*) src;
3335  size_t iSize;
3336  size_t oSize;
3337 
3338  if (!srcSize) return ERROR(srcSize_wrong);
3339  iSize = ip[0];
3340  /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
3341 
3342  if (iSize >= 128) { /* special header */
3343  oSize = iSize - 127;
3344  iSize = ((oSize+1)/2);
3345  if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
3346  if (oSize >= hwSize) return ERROR(corruption_detected);
3347  ip += 1;
3348  { U32 n;
3349  for (n=0; n<oSize; n+=2) {
3350  huffWeight[n] = ip[n/2] >> 4;
3351  huffWeight[n+1] = ip[n/2] & 15;
3352  } } }
3353  else { /* header compressed with FSE (normal case) */
3354  if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
3355  /* max (hwSize-1) values decoded, as last one is implied */
3356  oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2);
3357  if (FSE_isError(oSize)) return oSize;
3358  }
3359 
3360  /* collect weight stats */
3361  ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
3362  weightTotal = 0;
3363  { U32 n; for (n=0; n<oSize; n++) {
3364  if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
3365  rankStats[huffWeight[n]]++;
3366  weightTotal += (1 << huffWeight[n]) >> 1;
3367  } }
3368  if (weightTotal == 0) return ERROR(corruption_detected);
3369 
3370  /* get last non-null symbol weight (implied, total must be 2^n) */
3371  { U32 const tableLog = ZSTD_highbit32(weightTotal) + 1;
3372  if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
3373  *tableLogPtr = tableLog;
3374  /* determine last weight */
3375  { U32 const total = 1 << tableLog;
3376  U32 const rest = total - weightTotal;
3377  U32 const verif = 1 << ZSTD_highbit32(rest);
3378  U32 const lastWeight = ZSTD_highbit32(rest) + 1;
3379  if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
3380  huffWeight[oSize] = (BYTE)lastWeight;
3381  rankStats[lastWeight]++;
3382  } }
3383 
3384  /* check tree construction validity */
3385  if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
3386 
3387  /* results */
3388  *nbSymbolsPtr = (U32)(oSize+1);
3389  return iSize+1;
3390 }
3391 
3392 /* Avoids the FORCE_INLINE of the _body() function. */
3393 static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats,
3394  U32* nbSymbolsPtr, U32* tableLogPtr,
3395  const void* src, size_t srcSize,
3396  void* workSpace, size_t wkspSize)
3397 {
3398  return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0);
3399 }
3400 
3401 #if DYNAMIC_BMI2
3402 static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
3403  U32* nbSymbolsPtr, U32* tableLogPtr,
3404  const void* src, size_t srcSize,
3405  void* workSpace, size_t wkspSize)
3406 {
3407  return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1);
3408 }
3409 #endif
3410 
3411 size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,
3412  U32* nbSymbolsPtr, U32* tableLogPtr,
3413  const void* src, size_t srcSize,
3414  void* workSpace, size_t wkspSize,
3415  int flags)
3416 {
3417 #if DYNAMIC_BMI2
3418  if (flags & HUF_flags_bmi2) {
3419  return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
3420  }
3421 #endif
3422  (void)flags;
3423  return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
3424 }
3425 /**** ended inlining common/entropy_common.c ****/
3426 /**** start inlining common/error_private.c ****/
3427 /*
3428  * Copyright (c) Meta Platforms, Inc. and affiliates.
3429  * All rights reserved.
3430  *
3431  * This source code is licensed under both the BSD-style license (found in the
3432  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
3433  * in the COPYING file in the root directory of this source tree).
3434  * You may select, at your option, one of the above-listed licenses.
3435  */
3436 
3437 /* The purpose of this file is to have a single list of error strings embedded in binary */
3438 
3439 /**** skipping file: error_private.h ****/
3440 
3441 const char* ERR_getErrorString(ERR_enum code)
3442 {
3443 #ifdef ZSTD_STRIP_ERROR_STRINGS
3444  (void)code;
3445  return "Error strings stripped";
3446 #else
3447  static const char* const notErrorCode = "Unspecified error code";
3448  switch( code )
3449  {
3450  case PREFIX(no_error): return "No error detected";
3451  case PREFIX(GENERIC): return "Error (generic)";
3452  case PREFIX(prefix_unknown): return "Unknown frame descriptor";
3453  case PREFIX(version_unsupported): return "Version not supported";
3454  case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
3455  case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
3456  case PREFIX(corruption_detected): return "Data corruption detected";
3457  case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
3458  case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification";
3459  case PREFIX(parameter_unsupported): return "Unsupported parameter";
3460  case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters";
3461  case PREFIX(parameter_outOfBound): return "Parameter is out of bound";
3462  case PREFIX(init_missing): return "Context should be init first";
3463  case PREFIX(memory_allocation): return "Allocation error : not enough memory";
3464  case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough";
3465  case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
3466  case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
3467  case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
3468  case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
3469  case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected";
3470  case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
3471  case PREFIX(dictionary_wrong): return "Dictionary mismatch";
3472  case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples";
3473  case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
3474  case PREFIX(srcSize_wrong): return "Src size is incorrect";
3475  case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer";
3476  case PREFIX(noForwardProgress_destFull): return "Operation made no progress over multiple calls, due to output buffer being full";
3477  case PREFIX(noForwardProgress_inputEmpty): return "Operation made no progress over multiple calls, due to input being empty";
3478  /* following error codes are not stable and may be removed or changed in a future version */
3479  case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
3480  case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
3481  case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
3482  case PREFIX(srcBuffer_wrong): return "Source buffer is wrong";
3483  case PREFIX(sequenceProducer_failed): return "Block-level external sequence producer returned an error code";
3484  case PREFIX(externalSequences_invalid): return "External sequences are not valid";
3485  case PREFIX(maxCode):
3486  default: return notErrorCode;
3487  }
3488 #endif
3489 }
3490 /**** ended inlining common/error_private.c ****/
3491 /**** start inlining common/fse_decompress.c ****/
3492 /* ******************************************************************
3493  * FSE : Finite State Entropy decoder
3494  * Copyright (c) Meta Platforms, Inc. and affiliates.
3495  *
3496  * You can contact the author at :
3497  * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
3498  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
3499  *
3500  * This source code is licensed under both the BSD-style license (found in the
3501  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
3502  * in the COPYING file in the root directory of this source tree).
3503  * You may select, at your option, one of the above-listed licenses.
3504 ****************************************************************** */
3505 
3506 
3507 /* **************************************************************
3508 * Includes
3509 ****************************************************************/
3510 /**** skipping file: debug.h ****/
3511 /**** skipping file: bitstream.h ****/
3512 /**** skipping file: compiler.h ****/
3513 #define FSE_STATIC_LINKING_ONLY
3514 /**** skipping file: fse.h ****/
3515 /**** skipping file: error_private.h ****/
3516 #define ZSTD_DEPS_NEED_MALLOC
3517 /**** skipping file: zstd_deps.h ****/
3518 /**** skipping file: bits.h ****/
3519 
3520 
3521 /* **************************************************************
3522 * Error Management
3523 ****************************************************************/
3524 #define FSE_isError ERR_isError
3525 #define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
3526 
3527 
3528 /* **************************************************************
3529 * Templates
3530 ****************************************************************/
3531 /*
3532  designed to be included
3533  for type-specific functions (template emulation in C)
3534  Objective is to write these functions only once, for improved maintenance
3535 */
3536 
3537 /* safety checks */
3538 #ifndef FSE_FUNCTION_EXTENSION
3539 # error "FSE_FUNCTION_EXTENSION must be defined"
3540 #endif
3541 #ifndef FSE_FUNCTION_TYPE
3542 # error "FSE_FUNCTION_TYPE must be defined"
3543 #endif
3544 
3545 /* Function names */
3546 #define FSE_CAT(X,Y) X##Y
3547 #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
3548 #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
3549 
3550 static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
3551 {
3552  void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
3553  FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
3554  U16* symbolNext = (U16*)workSpace;
3555  BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1);
3556 
3557  U32 const maxSV1 = maxSymbolValue + 1;
3558  U32 const tableSize = 1 << tableLog;
3559  U32 highThreshold = tableSize-1;
3560 
3561  /* Sanity Checks */
3562  if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge);
3563  if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
3564  if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
3565 
3566  /* Init, lay down lowprob symbols */
3567  { FSE_DTableHeader DTableH;
3568  DTableH.tableLog = (U16)tableLog;
3569  DTableH.fastMode = 1;
3570  { S16 const largeLimit= (S16)(1 << (tableLog-1));
3571  U32 s;
3572  for (s=0; s<maxSV1; s++) {
3573  if (normalizedCounter[s]==-1) {
3574  tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
3575  symbolNext[s] = 1;
3576  } else {
3577  if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
3578  symbolNext[s] = normalizedCounter[s];
3579  } } }
3580  ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
3581  }
3582 
3583  /* Spread symbols */
3584  if (highThreshold == tableSize - 1) {
3585  size_t const tableMask = tableSize-1;
3586  size_t const step = FSE_TABLESTEP(tableSize);
3587  /* First lay down the symbols in order.
3588  * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
3589  * misses since small blocks generally have small table logs, so nearly
3590  * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
3591  * our buffer to handle the over-write.
3592  */
3593  {
3594  U64 const add = 0x0101010101010101ull;
3595  size_t pos = 0;
3596  U64 sv = 0;
3597  U32 s;
3598  for (s=0; s<maxSV1; ++s, sv += add) {
3599  int i;
3600  int const n = normalizedCounter[s];
3601  MEM_write64(spread + pos, sv);
3602  for (i = 8; i < n; i += 8) {
3603  MEM_write64(spread + pos + i, sv);
3604  }
3605  pos += n;
3606  }
3607  }
3608  /* Now we spread those positions across the table.
3609  * The benefit of doing it in two stages is that we avoid the
3610  * variable size inner loop, which caused lots of branch misses.
3611  * Now we can run through all the positions without any branch misses.
3612  * We unroll the loop twice, since that is what empirically worked best.
3613  */
3614  {
3615  size_t position = 0;
3616  size_t s;
3617  size_t const unroll = 2;
3618  assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
3619  for (s = 0; s < (size_t)tableSize; s += unroll) {
3620  size_t u;
3621  for (u = 0; u < unroll; ++u) {
3622  size_t const uPosition = (position + (u * step)) & tableMask;
3623  tableDecode[uPosition].symbol = spread[s + u];
3624  }
3625  position = (position + (unroll * step)) & tableMask;
3626  }
3627  assert(position == 0);
3628  }
3629  } else {
3630  U32 const tableMask = tableSize-1;
3631  U32 const step = FSE_TABLESTEP(tableSize);
3632  U32 s, position = 0;
3633  for (s=0; s<maxSV1; s++) {
3634  int i;
3635  for (i=0; i<normalizedCounter[s]; i++) {
3636  tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
3637  position = (position + step) & tableMask;
3638  while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
3639  } }
3640  if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
3641  }
3642 
3643  /* Build Decoding table */
3644  { U32 u;
3645  for (u=0; u<tableSize; u++) {
3646  FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
3647  U32 const nextState = symbolNext[symbol]++;
3648  tableDecode[u].nbBits = (BYTE) (tableLog - ZSTD_highbit32(nextState) );
3649  tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
3650  } }
3651 
3652  return 0;
3653 }
3654 
3655 size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
3656 {
3657  return FSE_buildDTable_internal(dt, normalizedCounter, maxSymbolValue, tableLog, workSpace, wkspSize);
3658 }
3659 
3660 
3661 #ifndef FSE_COMMONDEFS_ONLY
3662 
3663 /*-*******************************************************
3664 * Decompression (Byte symbols)
3665 *********************************************************/
3666 
3668  void* dst, size_t maxDstSize,
3669  const void* cSrc, size_t cSrcSize,
3670  const FSE_DTable* dt, const unsigned fast)
3671 {
3672  BYTE* const ostart = (BYTE*) dst;
3673  BYTE* op = ostart;
3674  BYTE* const omax = op + maxDstSize;
3675  BYTE* const olimit = omax-3;
3676 
3677  BIT_DStream_t bitD;
3678  FSE_DState_t state1;
3679  FSE_DState_t state2;
3680 
3681  /* Init */
3682  CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
3683 
3684  FSE_initDState(&state1, &bitD, dt);
3685  FSE_initDState(&state2, &bitD, dt);
3686 
3687 #define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
3688 
3689  /* 4 symbols per loop */
3690  for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
3691  op[0] = FSE_GETSYMBOL(&state1);
3692 
3693  if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
3694  BIT_reloadDStream(&bitD);
3695 
3696  op[1] = FSE_GETSYMBOL(&state2);
3697 
3698  if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
3699  { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
3700 
3701  op[2] = FSE_GETSYMBOL(&state1);
3702 
3703  if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
3704  BIT_reloadDStream(&bitD);
3705 
3706  op[3] = FSE_GETSYMBOL(&state2);
3707  }
3708 
3709  /* tail */
3710  /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
3711  while (1) {
3712  if (op>(omax-2)) return ERROR(dstSize_tooSmall);
3713  *op++ = FSE_GETSYMBOL(&state1);
3715  *op++ = FSE_GETSYMBOL(&state2);
3716  break;
3717  }
3718 
3719  if (op>(omax-2)) return ERROR(dstSize_tooSmall);
3720  *op++ = FSE_GETSYMBOL(&state2);
3722  *op++ = FSE_GETSYMBOL(&state1);
3723  break;
3724  } }
3725 
3726  return op-ostart;
3727 }
3728 
3729 typedef struct {
3730  short ncount[FSE_MAX_SYMBOL_VALUE + 1];
3731  FSE_DTable dtable[1]; /* Dynamically sized */
3733 
3734 
3736  void* dst, size_t dstCapacity,
3737  const void* cSrc, size_t cSrcSize,
3738  unsigned maxLog, void* workSpace, size_t wkspSize,
3739  int bmi2)
3740 {
3741  const BYTE* const istart = (const BYTE*)cSrc;
3742  const BYTE* ip = istart;
3743  unsigned tableLog;
3744  unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
3745  FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
3746 
3747  DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
3748  if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
3749 
3750  /* normal FSE decoding mode */
3751  {
3752  size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
3753  if (FSE_isError(NCountLength)) return NCountLength;
3754  if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
3755  assert(NCountLength <= cSrcSize);
3756  ip += NCountLength;
3757  cSrcSize -= NCountLength;
3758  }
3759 
3760  if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge);
3761  assert(sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog) <= wkspSize);
3762  workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
3763  wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
3764 
3765  CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
3766 
3767  {
3768  const void* ptr = wksp->dtable;
3769  const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
3770  const U32 fastMode = DTableH->fastMode;
3771 
3772  /* select fast mode (static) */
3773  if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1);
3774  return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0);
3775  }
3776 }
3777 
3778 /* Avoids the FORCE_INLINE of the _body() function. */
3779 static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
3780 {
3781  return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0);
3782 }
3783 
3784 #if DYNAMIC_BMI2
3785 BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
3786 {
3787  return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1);
3788 }
3789 #endif
3790 
3791 size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2)
3792 {
3793 #if DYNAMIC_BMI2
3794  if (bmi2) {
3795  return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
3796  }
3797 #endif
3798  (void)bmi2;
3799  return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
3800 }
3801 
3802 #endif /* FSE_COMMONDEFS_ONLY */
3803 /**** ended inlining common/fse_decompress.c ****/
3804 /**** start inlining common/threading.c ****/
3822 /**** start inlining threading.h ****/
3836 #ifndef THREADING_H_938743
3837 #define THREADING_H_938743
3838 
3839 /**** skipping file: debug.h ****/
3840 
3841 #if defined (__cplusplus)
3842 extern "C" {
3843 #endif
3844 
3845 #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
3846 
3850 #ifdef WINVER
3851 # undef WINVER
3852 #endif
3853 #define WINVER 0x0600
3854 
3855 #ifdef _WIN32_WINNT
3856 # undef _WIN32_WINNT
3857 #endif
3858 #define _WIN32_WINNT 0x0600
3859 
3860 #ifndef WIN32_LEAN_AND_MEAN
3861 # define WIN32_LEAN_AND_MEAN
3862 #endif
3863 
3864 #undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
3865 #include <windows.h>
3866 #undef ERROR
3867 #define ERROR(name) ZSTD_ERROR(name)
3868 
3869 
3870 /* mutex */
3871 #define ZSTD_pthread_mutex_t CRITICAL_SECTION
3872 #define ZSTD_pthread_mutex_init(a, b) ((void)(b), InitializeCriticalSection((a)), 0)
3873 #define ZSTD_pthread_mutex_destroy(a) DeleteCriticalSection((a))
3874 #define ZSTD_pthread_mutex_lock(a) EnterCriticalSection((a))
3875 #define ZSTD_pthread_mutex_unlock(a) LeaveCriticalSection((a))
3876 
3877 /* condition variable */
3878 #define ZSTD_pthread_cond_t CONDITION_VARIABLE
3879 #define ZSTD_pthread_cond_init(a, b) ((void)(b), InitializeConditionVariable((a)), 0)
3880 #define ZSTD_pthread_cond_destroy(a) ((void)(a))
3881 #define ZSTD_pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
3882 #define ZSTD_pthread_cond_signal(a) WakeConditionVariable((a))
3883 #define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a))
3884 
3885 /* ZSTD_pthread_create() and ZSTD_pthread_join() */
3886 typedef HANDLE ZSTD_pthread_t;
3887 
3888 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
3889  void* (*start_routine) (void*), void* arg);
3890 
3892 
3898 #elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
3899 /* === POSIX Systems === */
3900 # include <pthread.h>
3901 
3902 #if DEBUGLEVEL < 1
3903 
3904 #define ZSTD_pthread_mutex_t pthread_mutex_t
3905 #define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b))
3906 #define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a))
3907 #define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock((a))
3908 #define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock((a))
3909 
3910 #define ZSTD_pthread_cond_t pthread_cond_t
3911 #define ZSTD_pthread_cond_init(a, b) pthread_cond_init((a), (b))
3912 #define ZSTD_pthread_cond_destroy(a) pthread_cond_destroy((a))
3913 #define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait((a), (b))
3914 #define ZSTD_pthread_cond_signal(a) pthread_cond_signal((a))
3915 #define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast((a))
3916 
3917 #define ZSTD_pthread_t pthread_t
3918 #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
3919 #define ZSTD_pthread_join(a) pthread_join((a),NULL)
3920 
3921 #else /* DEBUGLEVEL >= 1 */
3922 
3923 /* Debug implementation of threading.
3924  * In this implementation we use pointers for mutexes and condition variables.
3925  * This way, if we forget to init/destroy them the program will crash or ASAN
3926  * will report leaks.
3927  */
3928 
3929 #define ZSTD_pthread_mutex_t pthread_mutex_t*
3930 int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr);
3932 #define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock(*(a))
3933 #define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock(*(a))
3934 
3935 #define ZSTD_pthread_cond_t pthread_cond_t*
3936 int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr);
3938 #define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait(*(a), *(b))
3939 #define ZSTD_pthread_cond_signal(a) pthread_cond_signal(*(a))
3940 #define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast(*(a))
3941 
3942 #define ZSTD_pthread_t pthread_t
3943 #define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
3944 #define ZSTD_pthread_join(a) pthread_join((a),NULL)
3945 
3946 #endif
3947 
3948 #else /* ZSTD_MULTITHREAD not defined */
3949 /* No multithreading support */
3950 
3951 typedef int ZSTD_pthread_mutex_t;
3952 #define ZSTD_pthread_mutex_init(a, b) ((void)(a), (void)(b), 0)
3953 #define ZSTD_pthread_mutex_destroy(a) ((void)(a))
3954 #define ZSTD_pthread_mutex_lock(a) ((void)(a))
3955 #define ZSTD_pthread_mutex_unlock(a) ((void)(a))
3956 
3957 typedef int ZSTD_pthread_cond_t;
3958 #define ZSTD_pthread_cond_init(a, b) ((void)(a), (void)(b), 0)
3959 #define ZSTD_pthread_cond_destroy(a) ((void)(a))
3960 #define ZSTD_pthread_cond_wait(a, b) ((void)(a), (void)(b))
3961 #define ZSTD_pthread_cond_signal(a) ((void)(a))
3962 #define ZSTD_pthread_cond_broadcast(a) ((void)(a))
3963 
3964 /* do not use ZSTD_pthread_t */
3965 
3966 #endif /* ZSTD_MULTITHREAD */
3967 
3968 #if defined (__cplusplus)
3969 }
3970 #endif
3971 
3972 #endif /* THREADING_H_938743 */
3973 /**** ended inlining threading.h ****/
3974 
3975 /* create fake symbol to avoid empty translation unit warning */
3977 
3978 #if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
3979 
3985 /* === Dependencies === */
3986 #include <process.h>
3987 #include <errno.h>
3988 
3989 
3990 /* === Implementation === */
3991 
3992 typedef struct {
3993  void* (*start_routine)(void*);
3994  void* arg;
3995  int initialized;
3996  ZSTD_pthread_cond_t initialized_cond;
3997  ZSTD_pthread_mutex_t initialized_mutex;
3998 } ZSTD_thread_params_t;
3999 
4000 static unsigned __stdcall worker(void *arg)
4001 {
4002  void* (*start_routine)(void*);
4003  void* thread_arg;
4004 
4005  /* Initialized thread_arg and start_routine and signal main thread that we don't need it
4006  * to wait any longer.
4007  */
4008  {
4009  ZSTD_thread_params_t* thread_param = (ZSTD_thread_params_t*)arg;
4010  thread_arg = thread_param->arg;
4011  start_routine = thread_param->start_routine;
4012 
4013  /* Signal main thread that we are running and do not depend on its memory anymore */
4014  ZSTD_pthread_mutex_lock(&thread_param->initialized_mutex);
4015  thread_param->initialized = 1;
4016  ZSTD_pthread_cond_signal(&thread_param->initialized_cond);
4017  ZSTD_pthread_mutex_unlock(&thread_param->initialized_mutex);
4018  }
4019 
4020  start_routine(thread_arg);
4021 
4022  return 0;
4023 }
4024 
4025 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
4026  void* (*start_routine) (void*), void* arg)
4027 {
4028  ZSTD_thread_params_t thread_param;
4029  (void)unused;
4030 
4031  thread_param.start_routine = start_routine;
4032  thread_param.arg = arg;
4033  thread_param.initialized = 0;
4034  *thread = NULL;
4035 
4036  /* Setup thread initialization synchronization */
4037  if(ZSTD_pthread_cond_init(&thread_param.initialized_cond, NULL)) {
4038  /* Should never happen on Windows */
4039  return -1;
4040  }
4041  if(ZSTD_pthread_mutex_init(&thread_param.initialized_mutex, NULL)) {
4042  /* Should never happen on Windows */
4043  ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
4044  return -1;
4045  }
4046 
4047  /* Spawn thread */
4048  *thread = (HANDLE)_beginthreadex(NULL, 0, worker, &thread_param, 0, NULL);
4049  if (!thread) {
4050  ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
4051  ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
4052  return errno;
4053  }
4054 
4055  /* Wait for thread to be initialized */
4056  ZSTD_pthread_mutex_lock(&thread_param.initialized_mutex);
4057  while(!thread_param.initialized) {
4058  ZSTD_pthread_cond_wait(&thread_param.initialized_cond, &thread_param.initialized_mutex);
4059  }
4060  ZSTD_pthread_mutex_unlock(&thread_param.initialized_mutex);
4061  ZSTD_pthread_mutex_destroy(&thread_param.initialized_mutex);
4062  ZSTD_pthread_cond_destroy(&thread_param.initialized_cond);
4063 
4064  return 0;
4065 }
4066 
4068 {
4069  DWORD result;
4070 
4071  if (!thread) return 0;
4072 
4073  result = WaitForSingleObject(thread, INFINITE);
4074  CloseHandle(thread);
4075 
4076  switch (result) {
4077  case WAIT_OBJECT_0:
4078  return 0;
4079  case WAIT_ABANDONED:
4080  return EINVAL;
4081  default:
4082  return GetLastError();
4083  }
4084 }
4085 
4086 #endif /* ZSTD_MULTITHREAD */
4087 
4088 #if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
4089 
4090 #define ZSTD_DEPS_NEED_MALLOC
4091 /**** skipping file: zstd_deps.h ****/
4092 
4093 int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
4094 {
4095  *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
4096  if (!*mutex)
4097  return 1;
4098  return pthread_mutex_init(*mutex, attr);
4099 }
4100 
4102 {
4103  if (!*mutex)
4104  return 0;
4105  {
4106  int const ret = pthread_mutex_destroy(*mutex);
4107  ZSTD_free(*mutex);
4108  return ret;
4109  }
4110 }
4111 
4112 int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
4113 {
4114  *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
4115  if (!*cond)
4116  return 1;
4117  return pthread_cond_init(*cond, attr);
4118 }
4119 
4121 {
4122  if (!*cond)
4123  return 0;
4124  {
4125  int const ret = pthread_cond_destroy(*cond);
4126  ZSTD_free(*cond);
4127  return ret;
4128  }
4129 }
4130 
4131 #endif
4132 /**** ended inlining common/threading.c ****/
4133 /**** start inlining common/pool.c ****/
4134 /*
4135  * Copyright (c) Meta Platforms, Inc. and affiliates.
4136  * All rights reserved.
4137  *
4138  * This source code is licensed under both the BSD-style license (found in the
4139  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4140  * in the COPYING file in the root directory of this source tree).
4141  * You may select, at your option, one of the above-listed licenses.
4142  */
4143 
4144 
4145 /* ====== Dependencies ======= */
4146 /**** start inlining ../common/allocations.h ****/
4147 /*
4148  * Copyright (c) Meta Platforms, Inc. and affiliates.
4149  * All rights reserved.
4150  *
4151  * This source code is licensed under both the BSD-style license (found in the
4152  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4153  * in the COPYING file in the root directory of this source tree).
4154  * You may select, at your option, one of the above-listed licenses.
4155  */
4156 
4157 /* This file provides custom allocation primitives
4158  */
4159 
4160 #define ZSTD_DEPS_NEED_MALLOC
4161 /**** skipping file: zstd_deps.h ****/
4162 
4163 /**** skipping file: mem.h ****/
4164 #define ZSTD_STATIC_LINKING_ONLY
4165 /**** *NOT* inlining ../zstd.h ****/
4166 #include "../zstd.h" /* ZSTD_customMem */
4167 
4168 #ifndef ZSTD_ALLOCATIONS_H
4169 #define ZSTD_ALLOCATIONS_H
4170 
4171 /* custom memory allocation functions */
4172 
4173 MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
4174 {
4175  if (customMem.customAlloc)
4176  return customMem.customAlloc(customMem.opaque, size);
4177  return ZSTD_malloc(size);
4178 }
4179 
4180 MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
4181 {
4182  if (customMem.customAlloc) {
4183  /* calloc implemented as malloc+memset;
4184  * not as efficient as calloc, but next best guess for custom malloc */
4185  void* const ptr = customMem.customAlloc(customMem.opaque, size);
4186  ZSTD_memset(ptr, 0, size);
4187  return ptr;
4188  }
4189  return ZSTD_calloc(1, size);
4190 }
4191 
4192 MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem)
4193 {
4194  if (ptr!=NULL) {
4195  if (customMem.customFree)
4196  customMem.customFree(customMem.opaque, ptr);
4197  else
4198  ZSTD_free(ptr);
4199  }
4200 }
4201 
4202 #endif /* ZSTD_ALLOCATIONS_H */
4203 /**** ended inlining ../common/allocations.h ****/
4204 /**** skipping file: zstd_deps.h ****/
4205 /**** skipping file: debug.h ****/
4206 /**** start inlining pool.h ****/
4207 /*
4208  * Copyright (c) Meta Platforms, Inc. and affiliates.
4209  * All rights reserved.
4210  *
4211  * This source code is licensed under both the BSD-style license (found in the
4212  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4213  * in the COPYING file in the root directory of this source tree).
4214  * You may select, at your option, one of the above-listed licenses.
4215  */
4216 
4217 #ifndef POOL_H
4218 #define POOL_H
4219 
4220 #if defined (__cplusplus)
4221 extern "C" {
4222 #endif
4223 
4224 
4225 /**** skipping file: zstd_deps.h ****/
4226 #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
4227 /**** skipping file: ../zstd.h ****/
4228 
4229 typedef struct POOL_ctx_s POOL_ctx;
4230 
4237 POOL_ctx* POOL_create(size_t numThreads, size_t queueSize);
4238 
4239 POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
4240  ZSTD_customMem customMem);
4241 
4245 void POOL_free(POOL_ctx* ctx);
4246 
4247 
4251 void POOL_joinJobs(POOL_ctx* ctx);
4252 
4262 int POOL_resize(POOL_ctx* ctx, size_t numThreads);
4263 
4268 size_t POOL_sizeof(const POOL_ctx* ctx);
4269 
4273 typedef void (*POOL_function)(void*);
4274 
4281 void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);
4282 
4283 
4289 int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque);
4290 
4291 
4292 #if defined (__cplusplus)
4293 }
4294 #endif
4295 
4296 #endif
4297 /**** ended inlining pool.h ****/
4298 
4299 /* ====== Compiler specifics ====== */
4300 #if defined(_MSC_VER)
4301 # pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
4302 #endif
4303 
4304 
4305 #ifdef ZSTD_MULTITHREAD
4306 
4307 /**** skipping file: threading.h ****/
4308 
4309 /* A job is a function and an opaque argument */
4310 typedef struct POOL_job_s {
4311  POOL_function function;
4312  void *opaque;
4313 } POOL_job;
4314 
4315 struct POOL_ctx_s {
4316  ZSTD_customMem customMem;
4317  /* Keep track of the threads */
4320  size_t threadLimit;
4321 
4322  /* The queue is a circular buffer */
4324  size_t queueHead;
4325  size_t queueTail;
4326  size_t queueSize;
4327 
4328  /* The number of threads working on jobs */
4330  /* Indicates if the queue is empty */
4332 
4333  /* The mutex protects the queue */
4335  /* Condition variable for pushers to wait on when the queue is full */
4337  /* Condition variables for poppers to wait on when the queue is empty */
4339  /* Indicates if the queue is shutting down */
4341 };
4342 
4343 /* POOL_thread() :
4344  * Work thread for the thread pool.
4345  * Waits for jobs and executes them.
4346  * @returns : NULL on failure else non-null.
4347  */
4348 static void* POOL_thread(void* opaque) {
4349  POOL_ctx* const ctx = (POOL_ctx*)opaque;
4350  if (!ctx) { return NULL; }
4351  for (;;) {
4352  /* Lock the mutex and wait for a non-empty queue or until shutdown */
4354 
4355  while ( ctx->queueEmpty
4356  || (ctx->numThreadsBusy >= ctx->threadLimit) ) {
4357  if (ctx->shutdown) {
4358  /* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit),
4359  * a few threads will be shutdown while !queueEmpty,
4360  * but enough threads will remain active to finish the queue */
4362  return opaque;
4363  }
4365  }
4366  /* Pop a job off the queue */
4367  { POOL_job const job = ctx->queue[ctx->queueHead];
4368  ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
4369  ctx->numThreadsBusy++;
4370  ctx->queueEmpty = (ctx->queueHead == ctx->queueTail);
4371  /* Unlock the mutex, signal a pusher, and run the job */
4374 
4375  job.function(job.opaque);
4376 
4377  /* If the intended queue size was 0, signal after finishing job */
4379  ctx->numThreadsBusy--;
4382  }
4383  } /* for (;;) */
4384  assert(0); /* Unreachable */
4385 }
4386 
4387 /* ZSTD_createThreadPool() : public access point */
4388 POOL_ctx* ZSTD_createThreadPool(size_t numThreads) {
4389  return POOL_create (numThreads, 0);
4390 }
4391 
4392 POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
4393  return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
4394 }
4395 
4396 POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
4397  ZSTD_customMem customMem)
4398 {
4399  POOL_ctx* ctx;
4400  /* Check parameters */
4401  if (!numThreads) { return NULL; }
4402  /* Allocate the context and zero initialize */
4403  ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem);
4404  if (!ctx) { return NULL; }
4405  /* Initialize the job queue.
4406  * It needs one extra space since one space is wasted to differentiate
4407  * empty and full queues.
4408  */
4409  ctx->queueSize = queueSize + 1;
4410  ctx->queue = (POOL_job*)ZSTD_customCalloc(ctx->queueSize * sizeof(POOL_job), customMem);
4411  ctx->queueHead = 0;
4412  ctx->queueTail = 0;
4413  ctx->numThreadsBusy = 0;
4414  ctx->queueEmpty = 1;
4415  {
4416  int error = 0;
4417  error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
4418  error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
4419  error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
4420  if (error) { POOL_free(ctx); return NULL; }
4421  }
4422  ctx->shutdown = 0;
4423  /* Allocate space for the thread handles */
4424  ctx->threads = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
4425  ctx->threadCapacity = 0;
4426  ctx->customMem = customMem;
4427  /* Check for errors */
4428  if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
4429  /* Initialize the threads */
4430  { size_t i;
4431  for (i = 0; i < numThreads; ++i) {
4432  if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
4433  ctx->threadCapacity = i;
4434  POOL_free(ctx);
4435  return NULL;
4436  } }
4437  ctx->threadCapacity = numThreads;
4438  ctx->threadLimit = numThreads;
4439  }
4440  return ctx;
4441 }
4442 
4446 static void POOL_join(POOL_ctx* ctx) {
4447  /* Shut down the queue */
4449  ctx->shutdown = 1;
4451  /* Wake up sleeping threads */
4454  /* Join all of the threads */
4455  { size_t i;
4456  for (i = 0; i < ctx->threadCapacity; ++i) {
4457  ZSTD_pthread_join(ctx->threads[i]); /* note : could fail */
4458  } }
4459 }
4460 
4461 void POOL_free(POOL_ctx *ctx) {
4462  if (!ctx) { return; }
4463  POOL_join(ctx);
4467  ZSTD_customFree(ctx->queue, ctx->customMem);
4468  ZSTD_customFree(ctx->threads, ctx->customMem);
4469  ZSTD_customFree(ctx, ctx->customMem);
4470 }
4471 
4477  while(!ctx->queueEmpty || ctx->numThreadsBusy > 0) {
4479  }
4481 }
4482 
4483 void ZSTD_freeThreadPool (ZSTD_threadPool* pool) {
4484  POOL_free (pool);
4485 }
4486 
4487 size_t POOL_sizeof(const POOL_ctx* ctx) {
4488  if (ctx==NULL) return 0; /* supports sizeof NULL */
4489  return sizeof(*ctx)
4490  + ctx->queueSize * sizeof(POOL_job)
4491  + ctx->threadCapacity * sizeof(ZSTD_pthread_t);
4492 }
4493 
4494 
4495 /* @return : 0 on success, 1 on error */
4496 static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
4497 {
4498  if (numThreads <= ctx->threadCapacity) {
4499  if (!numThreads) return 1;
4500  ctx->threadLimit = numThreads;
4501  return 0;
4502  }
4503  /* numThreads > threadCapacity */
4504  { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customCalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
4505  if (!threadPool) return 1;
4506  /* replace existing thread pool */
4507  ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
4508  ZSTD_customFree(ctx->threads, ctx->customMem);
4509  ctx->threads = threadPool;
4510  /* Initialize additional threads */
4511  { size_t threadId;
4512  for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
4513  if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
4514  ctx->threadCapacity = threadId;
4515  return 1;
4516  } }
4517  } }
4518  /* successfully expanded */
4519  ctx->threadCapacity = numThreads;
4520  ctx->threadLimit = numThreads;
4521  return 0;
4522 }
4523 
4524 /* @return : 0 on success, 1 on error */
4525 int POOL_resize(POOL_ctx* ctx, size_t numThreads)
4526 {
4527  int result;
4528  if (ctx==NULL) return 1;
4530  result = POOL_resize_internal(ctx, numThreads);
4533  return result;
4534 }
4535 
4542 static int isQueueFull(POOL_ctx const* ctx) {
4543  if (ctx->queueSize > 1) {
4544  return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
4545  } else {
4546  return (ctx->numThreadsBusy == ctx->threadLimit) ||
4547  !ctx->queueEmpty;
4548  }
4549 }
4550 
4551 
4552 static void
4553 POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
4554 {
4555  POOL_job job;
4556  job.function = function;
4557  job.opaque = opaque;
4558  assert(ctx != NULL);
4559  if (ctx->shutdown) return;
4560 
4561  ctx->queueEmpty = 0;
4562  ctx->queue[ctx->queueTail] = job;
4563  ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
4565 }
4566 
4567 void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
4568 {
4569  assert(ctx != NULL);
4571  /* Wait until there is space in the queue for the new job */
4572  while (isQueueFull(ctx) && (!ctx->shutdown)) {
4574  }
4575  POOL_add_internal(ctx, function, opaque);
4577 }
4578 
4579 
4580 int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
4581 {
4582  assert(ctx != NULL);
4584  if (isQueueFull(ctx)) {
4586  return 0;
4587  }
4588  POOL_add_internal(ctx, function, opaque);
4590  return 1;
4591 }
4592 
4593 
4594 #else /* ZSTD_MULTITHREAD not defined */
4595 
4596 /* ========================== */
4597 /* No multi-threading support */
4598 /* ========================== */
4599 
4600 
4601 /* We don't need any data, but if it is empty, malloc() might return NULL. */
4602 struct POOL_ctx_s {
4603  int dummy;
4604 };
4605 static POOL_ctx g_poolCtx;
4606 
4607 POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
4608  return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
4609 }
4610 
4611 POOL_ctx*
4612 POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem)
4613 {
4614  (void)numThreads;
4615  (void)queueSize;
4616  (void)customMem;
4617  return &g_poolCtx;
4618 }
4619 
4620 void POOL_free(POOL_ctx* ctx) {
4621  assert(!ctx || ctx == &g_poolCtx);
4622  (void)ctx;
4623 }
4624 
4625 void POOL_joinJobs(POOL_ctx* ctx){
4626  assert(!ctx || ctx == &g_poolCtx);
4627  (void)ctx;
4628 }
4629 
4630 int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
4631  (void)ctx; (void)numThreads;
4632  return 0;
4633 }
4634 
4635 void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
4636  (void)ctx;
4637  function(opaque);
4638 }
4639 
4640 int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
4641  (void)ctx;
4642  function(opaque);
4643  return 1;
4644 }
4645 
4646 size_t POOL_sizeof(const POOL_ctx* ctx) {
4647  if (ctx==NULL) return 0; /* supports sizeof NULL */
4648  assert(ctx == &g_poolCtx);
4649  return sizeof(*ctx);
4650 }
4651 
4652 #endif /* ZSTD_MULTITHREAD */
4653 /**** ended inlining common/pool.c ****/
4654 /**** start inlining common/zstd_common.c ****/
4655 /*
4656  * Copyright (c) Meta Platforms, Inc. and affiliates.
4657  * All rights reserved.
4658  *
4659  * This source code is licensed under both the BSD-style license (found in the
4660  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4661  * in the COPYING file in the root directory of this source tree).
4662  * You may select, at your option, one of the above-listed licenses.
4663  */
4664 
4665 
4666 
4667 /*-*************************************
4668 * Dependencies
4669 ***************************************/
4670 #define ZSTD_DEPS_NEED_MALLOC
4671 /**** skipping file: error_private.h ****/
4672 /**** start inlining zstd_internal.h ****/
4673 /*
4674  * Copyright (c) Meta Platforms, Inc. and affiliates.
4675  * All rights reserved.
4676  *
4677  * This source code is licensed under both the BSD-style license (found in the
4678  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4679  * in the COPYING file in the root directory of this source tree).
4680  * You may select, at your option, one of the above-listed licenses.
4681  */
4682 
4683 #ifndef ZSTD_CCOMMON_H_MODULE
4684 #define ZSTD_CCOMMON_H_MODULE
4685 
4686 /* this module contains definitions which must be identical
4687  * across compression, decompression and dictBuilder.
4688  * It also contains a few functions useful to at least 2 of them
4689  * and which benefit from being inlined */
4690 
4691 /*-*************************************
4692 * Dependencies
4693 ***************************************/
4694 /**** skipping file: compiler.h ****/
4695 /**** start inlining cpu.h ****/
4696 /*
4697  * Copyright (c) Meta Platforms, Inc. and affiliates.
4698  * All rights reserved.
4699  *
4700  * This source code is licensed under both the BSD-style license (found in the
4701  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4702  * in the COPYING file in the root directory of this source tree).
4703  * You may select, at your option, one of the above-listed licenses.
4704  */
4705 
4706 #ifndef ZSTD_COMMON_CPU_H
4707 #define ZSTD_COMMON_CPU_H
4708 
4714 /**** skipping file: mem.h ****/
4715 
4716 #ifdef _MSC_VER
4717 #include <intrin.h>
4718 #endif
4719 
4720 typedef struct {
4725 } ZSTD_cpuid_t;
4726 
4728  U32 f1c = 0;
4729  U32 f1d = 0;
4730  U32 f7b = 0;
4731  U32 f7c = 0;
4732 #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
4733  int reg[4];
4734  __cpuid((int*)reg, 0);
4735  {
4736  int const n = reg[0];
4737  if (n >= 1) {
4738  __cpuid((int*)reg, 1);
4739  f1c = (U32)reg[2];
4740  f1d = (U32)reg[3];
4741  }
4742  if (n >= 7) {
4743  __cpuidex((int*)reg, 7, 0);
4744  f7b = (U32)reg[1];
4745  f7c = (U32)reg[2];
4746  }
4747  }
4748 #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
4749  /* The following block like the normal cpuid branch below, but gcc
4750  * reserves ebx for use of its pic register so we must specially
4751  * handle the save and restore to avoid clobbering the register
4752  */
4753  U32 n;
4754  __asm__(
4755  "pushl %%ebx\n\t"
4756  "cpuid\n\t"
4757  "popl %%ebx\n\t"
4758  : "=a"(n)
4759  : "a"(0)
4760  : "ecx", "edx");
4761  if (n >= 1) {
4762  U32 f1a;
4763  __asm__(
4764  "pushl %%ebx\n\t"
4765  "cpuid\n\t"
4766  "popl %%ebx\n\t"
4767  : "=a"(f1a), "=c"(f1c), "=d"(f1d)
4768  : "a"(1));
4769  }
4770  if (n >= 7) {
4771  __asm__(
4772  "pushl %%ebx\n\t"
4773  "cpuid\n\t"
4774  "movl %%ebx, %%eax\n\t"
4775  "popl %%ebx"
4776  : "=a"(f7b), "=c"(f7c)
4777  : "a"(7), "c"(0)
4778  : "edx");
4779  }
4780 #elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
4781  U32 n;
4782  __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
4783  if (n >= 1) {
4784  U32 f1a;
4785  __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
4786  }
4787  if (n >= 7) {
4788  U32 f7a;
4789  __asm__("cpuid"
4790  : "=a"(f7a), "=b"(f7b), "=c"(f7c)
4791  : "a"(7), "c"(0)
4792  : "edx");
4793  }
4794 #endif
4795  {
4796  ZSTD_cpuid_t cpuid;
4797  cpuid.f1c = f1c;
4798  cpuid.f1d = f1d;
4799  cpuid.f7b = f7b;
4800  cpuid.f7c = f7c;
4801  return cpuid;
4802  }
4803 }
4804 
4805 #define X(name, r, bit) \
4806  MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
4807  return ((cpuid.r) & (1U << bit)) != 0; \
4808  }
4809 
4810 /* cpuid(1): Processor Info and Feature Bits. */
4811 #define C(name, bit) X(name, f1c, bit)
4812  C(sse3, 0)
4813  C(pclmuldq, 1)
4814  C(dtes64, 2)
4815  C(monitor, 3)
4816  C(dscpl, 4)
4817  C(vmx, 5)
4818  C(smx, 6)
4819  C(eist, 7)
4820  C(tm2, 8)
4821  C(ssse3, 9)
4822  C(cnxtid, 10)
4823  C(fma, 12)
4824  C(cx16, 13)
4825  C(xtpr, 14)
4826  C(pdcm, 15)
4827  C(pcid, 17)
4828  C(dca, 18)
4829  C(sse41, 19)
4830  C(sse42, 20)
4831  C(x2apic, 21)
4832  C(movbe, 22)
4833  C(popcnt, 23)
4834  C(tscdeadline, 24)
4835  C(aes, 25)
4836  C(xsave, 26)
4837  C(osxsave, 27)
4838  C(avx, 28)
4839  C(f16c, 29)
4840  C(rdrand, 30)
4841 #undef C
4842 #define D(name, bit) X(name, f1d, bit)
4843  D(fpu, 0)
4844  D(vme, 1)
4845  D(de, 2)
4846  D(pse, 3)
4847  D(tsc, 4)
4848  D(msr, 5)
4849  D(pae, 6)
4850  D(mce, 7)
4851  D(cx8, 8)
4852  D(apic, 9)
4853  D(sep, 11)
4854  D(mtrr, 12)
4855  D(pge, 13)
4856  D(mca, 14)
4857  D(cmov, 15)
4858  D(pat, 16)
4859  D(pse36, 17)
4860  D(psn, 18)
4861  D(clfsh, 19)
4862  D(ds, 21)
4863  D(acpi, 22)
4864  D(mmx, 23)
4865  D(fxsr, 24)
4866  D(sse, 25)
4867  D(sse2, 26)
4868  D(ss, 27)
4869  D(htt, 28)
4870  D(tm, 29)
4871  D(pbe, 31)
4872 #undef D
4873 
4874 /* cpuid(7): Extended Features. */
4875 #define B(name, bit) X(name, f7b, bit)
4876  B(bmi1, 3)
4877  B(hle, 4)
4878  B(avx2, 5)
4879  B(smep, 7)
4880  B(bmi2, 8)
4881  B(erms, 9)
4882  B(invpcid, 10)
4883  B(rtm, 11)
4884  B(mpx, 14)
4885  B(avx512f, 16)
4886  B(avx512dq, 17)
4887  B(rdseed, 18)
4888  B(adx, 19)
4889  B(smap, 20)
4890  B(avx512ifma, 21)
4891  B(pcommit, 22)
4892  B(clflushopt, 23)
4893  B(clwb, 24)
4894  B(avx512pf, 26)
4895  B(avx512er, 27)
4896  B(avx512cd, 28)
4897  B(sha, 29)
4898  B(avx512bw, 30)
4899  B(avx512vl, 31)
4900 #undef B
4901 #define C(name, bit) X(name, f7c, bit)
4902  C(prefetchwt1, 0)
4903  C(avx512vbmi, 1)
4904 #undef C
4905 
4906 #undef X
4907 
4908 #endif /* ZSTD_COMMON_CPU_H */
4909 /**** ended inlining cpu.h ****/
4910 /**** skipping file: mem.h ****/
4911 /**** skipping file: debug.h ****/
4912 /**** skipping file: error_private.h ****/
4913 #define ZSTD_STATIC_LINKING_ONLY
4914 /**** skipping file: ../zstd.h ****/
4915 #define FSE_STATIC_LINKING_ONLY
4916 /**** skipping file: fse.h ****/
4917 /**** skipping file: huf.h ****/
4918 #ifndef XXH_STATIC_LINKING_ONLY
4919 # define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
4920 #endif
4921 /**** start inlining xxhash.h ****/
4922 /*
4923  * xxHash - Fast Hash algorithm
4924  * Copyright (c) Meta Platforms, Inc. and affiliates.
4925  *
4926  * You can contact the author at :
4927  * - xxHash homepage: https://cyan4973.github.io/xxHash/
4928  * - xxHash source repository : https://github.com/Cyan4973/xxHash
4929  *
4930  * This source code is licensed under both the BSD-style license (found in the
4931  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
4932  * in the COPYING file in the root directory of this source tree).
4933  * You may select, at your option, one of the above-listed licenses.
4934 */
4935 
4936 
4937 #ifndef XXH_NO_XXH3
4938 # define XXH_NO_XXH3
4939 #endif
4940 
4941 #ifndef XXH_NAMESPACE
4942 # define XXH_NAMESPACE ZSTD_
4943 #endif
4944 
4951 /* TODO: update */
4952 /* Notice extracted from xxHash homepage:
4953 
4954 xxHash is an extremely fast hash algorithm, running at RAM speed limits.
4955 It also successfully passes all tests from the SMHasher suite.
4956 
4957 Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
4958 
4959 Name Speed Q.Score Author
4960 xxHash 5.4 GB/s 10
4961 CrapWow 3.2 GB/s 2 Andrew
4962 MurmurHash 3a 2.7 GB/s 10 Austin Appleby
4963 SpookyHash 2.0 GB/s 10 Bob Jenkins
4964 SBox 1.4 GB/s 9 Bret Mulvey
4965 Lookup3 1.2 GB/s 9 Bob Jenkins
4966 SuperFastHash 1.2 GB/s 1 Paul Hsieh
4967 CityHash64 1.05 GB/s 10 Pike & Alakuijala
4968 FNV 0.55 GB/s 5 Fowler, Noll, Vo
4969 CRC32 0.43 GB/s 9
4970 MD5-32 0.33 GB/s 10 Ronald L. Rivest
4971 SHA1-32 0.28 GB/s 10
4972 
4973 Q.Score is a measure of quality of the hash function.
4974 It depends on successfully passing SMHasher test set.
4975 10 is a perfect score.
4976 
4977 Note: SMHasher's CRC32 implementation is not the fastest one.
4978 Other speed-oriented implementations can be faster,
4979 especially in combination with PCLMUL instruction:
4980 https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735
4981 
4982 A 64-bit version, named XXH64, is available since r35.
4983 It offers much better speed, but for 64-bit applications only.
4984 Name Speed on 64 bits Speed on 32 bits
4985 XXH64 13.8 GB/s 1.9 GB/s
4986 XXH32 6.8 GB/s 6.0 GB/s
4987 */
4988 
4989 #if defined (__cplusplus)
4990 extern "C" {
4991 #endif
4992 
4993 /* ****************************
4994  * INLINE mode
4995  ******************************/
5012 #if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
5013  && !defined(XXH_INLINE_ALL_31684351384)
5014  /* this section should be traversed only once */
5015 # define XXH_INLINE_ALL_31684351384
5016  /* give access to the advanced API, required to compile implementations */
5017 # undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */
5018 # define XXH_STATIC_LINKING_ONLY
5019  /* make all functions private */
5020 # undef XXH_PUBLIC_API
5021 # if defined(__GNUC__)
5022 # define XXH_PUBLIC_API static __inline __attribute__((unused))
5023 # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
5024 # define XXH_PUBLIC_API static inline
5025 # elif defined(_MSC_VER)
5026 # define XXH_PUBLIC_API static __inline
5027 # else
5028  /* note: this version may generate warnings for unused static functions */
5029 # define XXH_PUBLIC_API static
5030 # endif
5031 
5032  /*
5033  * This part deals with the special case where a unit wants to inline xxHash,
5034  * but "xxhash.h" has previously been included without XXH_INLINE_ALL,
5035  * such as part of some previously included *.h header file.
5036  * Without further action, the new include would just be ignored,
5037  * and functions would effectively _not_ be inlined (silent failure).
5038  * The following macros solve this situation by prefixing all inlined names,
5039  * avoiding naming collision with previous inclusions.
5040  */
5041  /* Before that, we unconditionally #undef all symbols,
5042  * in case they were already defined with XXH_NAMESPACE.
5043  * They will then be redefined for XXH_INLINE_ALL
5044  */
5045 # undef XXH_versionNumber
5046  /* XXH32 */
5047 # undef XXH32
5048 # undef XXH32_createState
5049 # undef XXH32_freeState
5050 # undef XXH32_reset
5051 # undef XXH32_update
5052 # undef XXH32_digest
5053 # undef XXH32_copyState
5054 # undef XXH32_canonicalFromHash
5055 # undef XXH32_hashFromCanonical
5056  /* XXH64 */
5057 # undef XXH64
5058 # undef XXH64_createState
5059 # undef XXH64_freeState
5060 # undef XXH64_reset
5061 # undef XXH64_update
5062 # undef XXH64_digest
5063 # undef XXH64_copyState
5064 # undef XXH64_canonicalFromHash
5065 # undef XXH64_hashFromCanonical
5066  /* XXH3_64bits */
5067 # undef XXH3_64bits
5068 # undef XXH3_64bits_withSecret
5069 # undef XXH3_64bits_withSeed
5070 # undef XXH3_64bits_withSecretandSeed
5071 # undef XXH3_createState
5072 # undef XXH3_freeState
5073 # undef XXH3_copyState
5074 # undef XXH3_64bits_reset
5075 # undef XXH3_64bits_reset_withSeed
5076 # undef XXH3_64bits_reset_withSecret
5077 # undef XXH3_64bits_update
5078 # undef XXH3_64bits_digest
5079 # undef XXH3_generateSecret
5080  /* XXH3_128bits */
5081 # undef XXH128
5082 # undef XXH3_128bits
5083 # undef XXH3_128bits_withSeed
5084 # undef XXH3_128bits_withSecret
5085 # undef XXH3_128bits_reset
5086 # undef XXH3_128bits_reset_withSeed
5087 # undef XXH3_128bits_reset_withSecret
5088 # undef XXH3_128bits_reset_withSecretandSeed
5089 # undef XXH3_128bits_update
5090 # undef XXH3_128bits_digest
5091 # undef XXH128_isEqual
5092 # undef XXH128_cmp
5093 # undef XXH128_canonicalFromHash
5094 # undef XXH128_hashFromCanonical
5095  /* Finally, free the namespace itself */
5096 # undef XXH_NAMESPACE
5097 
5098  /* employ the namespace for XXH_INLINE_ALL */
5099 # define XXH_NAMESPACE XXH_INLINE_
5100  /*
5101  * Some identifiers (enums, type names) are not symbols,
5102  * but they must nonetheless be renamed to avoid redeclaration.
5103  * Alternative solution: do not redeclare them.
5104  * However, this requires some #ifdefs, and has a more dispersed impact.
5105  * Meanwhile, renaming can be achieved in a single place.
5106  */
5107 # define XXH_IPREF(Id) XXH_NAMESPACE ## Id
5108 # define XXH_OK XXH_IPREF(XXH_OK)
5109 # define XXH_ERROR XXH_IPREF(XXH_ERROR)
5110 # define XXH_errorcode XXH_IPREF(XXH_errorcode)
5111 # define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)
5112 # define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)
5113 # define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)
5114 # define XXH32_state_s XXH_IPREF(XXH32_state_s)
5115 # define XXH32_state_t XXH_IPREF(XXH32_state_t)
5116 # define XXH64_state_s XXH_IPREF(XXH64_state_s)
5117 # define XXH64_state_t XXH_IPREF(XXH64_state_t)
5118 # define XXH3_state_s XXH_IPREF(XXH3_state_s)
5119 # define XXH3_state_t XXH_IPREF(XXH3_state_t)
5120 # define XXH128_hash_t XXH_IPREF(XXH128_hash_t)
5121  /* Ensure the header is parsed again, even if it was previously included */
5122 # undef XXHASH_H_5627135585666179
5123 # undef XXHASH_H_STATIC_13879238742
5124 #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
5125 
5126 
5127 
5128 /* ****************************************************************
5129  * Stable API
5130  *****************************************************************/
5131 #ifndef XXHASH_H_5627135585666179
5132 #define XXHASH_H_5627135585666179 1
5133 
5134 
5140 /* specific declaration modes for Windows */
5141 #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
5142 # if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
5143 # ifdef XXH_EXPORT
5144 # define XXH_PUBLIC_API __declspec(dllexport)
5145 # elif XXH_IMPORT
5146 # define XXH_PUBLIC_API __declspec(dllimport)
5147 # endif
5148 # else
5149 # define XXH_PUBLIC_API /* do nothing */
5150 # endif
5151 #endif
5152 
5153 #ifdef XXH_DOXYGEN
5154 
5167 # define XXH_NAMESPACE /* YOUR NAME HERE */
5168 # undef XXH_NAMESPACE
5169 #endif
5170 
5171 #ifdef XXH_NAMESPACE
5172 # define XXH_CAT(A,B) A##B
5173 # define XXH_NAME2(A,B) XXH_CAT(A,B)
5174 # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
5175 /* XXH32 */
5176 # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
5177 # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
5178 # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
5179 # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
5180 # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
5181 # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
5182 # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
5183 # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
5184 # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
5185 /* XXH64 */
5186 # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
5187 # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
5188 # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
5189 # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
5190 # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
5191 # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
5192 # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
5193 # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
5194 # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
5195 /* XXH3_64bits */
5196 # define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)
5197 # define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)
5198 # define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)
5199 # define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed)
5200 # define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)
5201 # define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)
5202 # define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)
5203 # define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)
5204 # define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)
5205 # define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)
5206 # define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed)
5207 # define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)
5208 # define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)
5209 # define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)
5210 # define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed)
5211 /* XXH3_128bits */
5212 # define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)
5213 # define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)
5214 # define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)
5215 # define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)
5216 # define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed)
5217 # define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)
5218 # define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)
5219 # define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)
5220 # define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed)
5221 # define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)
5222 # define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)
5223 # define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)
5224 # define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp)
5225 # define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash)
5226 # define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical)
5227 #endif
5228 
5229 
5230 /* *************************************
5231 * Version
5232 ***************************************/
5233 #define XXH_VERSION_MAJOR 0
5234 #define XXH_VERSION_MINOR 8
5235 #define XXH_VERSION_RELEASE 1
5236 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
5237 
5246 XXH_PUBLIC_API unsigned XXH_versionNumber (void);
5247 
5248 
5249 /* ****************************
5250 * Common basic types
5251 ******************************/
5252 #include <stddef.h> /* size_t */
5253 typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
5254 
5255 
5256 /*-**********************************************************************
5257 * 32-bit hash
5258 ************************************************************************/
5259 #if defined(XXH_DOXYGEN) /* Don't show <stdint.h> include */
5260 
5265 typedef uint32_t XXH32_hash_t;
5266 
5267 #elif !defined (__VMS) \
5268  && (defined (__cplusplus) \
5269  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
5270 # include <stdint.h>
5271  typedef uint32_t XXH32_hash_t;
5272 
5273 #else
5274 # include <limits.h>
5275 # if UINT_MAX == 0xFFFFFFFFUL
5276  typedef unsigned int XXH32_hash_t;
5277 # else
5278 # if ULONG_MAX == 0xFFFFFFFFUL
5279  typedef unsigned long XXH32_hash_t;
5280 # else
5281 # error "unsupported platform: need a 32-bit type"
5282 # endif
5283 # endif
5284 #endif
5285 
5325 XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
5326 
5384 
5408 XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
5409 
5424 
5443 XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
5444 
5460 
5461 /******* Canonical representation *******/
5462 
5463 /*
5464  * The default return values from XXH functions are unsigned 32 and 64 bit
5465  * integers.
5466  * This the simplest and fastest format for further post-processing.
5467  *
5468  * However, this leaves open the question of what is the order on the byte level,
5469  * since little and big endian conventions will store the same number differently.
5470  *
5471  * The canonical representation settles this issue by mandating big-endian
5472  * convention, the same convention as human-readable numbers (large digits first).
5473  *
5474  * When writing hash values to storage, sending them over a network, or printing
5475  * them, it's highly recommended to use the canonical representation to ensure
5476  * portability across a wider range of systems, present and future.
5477  *
5478  * The following functions allow transformation of hash values to and from
5479  * canonical format.
5480  */
5481 
5485 typedef struct {
5486  unsigned char digest[4];
5488 
5499 
5511 
5512 
5513 #ifdef __has_attribute
5514 # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
5515 #else
5516 # define XXH_HAS_ATTRIBUTE(x) 0
5517 #endif
5518 
5519 /* C-language Attributes are added in C23. */
5520 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
5521 # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
5522 #else
5523 # define XXH_HAS_C_ATTRIBUTE(x) 0
5524 #endif
5525 
5526 #if defined(__cplusplus) && defined(__has_cpp_attribute)
5527 # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
5528 #else
5529 # define XXH_HAS_CPP_ATTRIBUTE(x) 0
5530 #endif
5531 
5532 /*
5533 Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
5534 introduced in CPP17 and C23.
5535 CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
5536 C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
5537 */
5538 #if XXH_HAS_C_ATTRIBUTE(x)
5539 # define XXH_FALLTHROUGH [[fallthrough]]
5540 #elif XXH_HAS_CPP_ATTRIBUTE(x)
5541 # define XXH_FALLTHROUGH [[fallthrough]]
5542 #elif XXH_HAS_ATTRIBUTE(__fallthrough__)
5543 # define XXH_FALLTHROUGH __attribute__ ((fallthrough))
5544 #else
5545 # define XXH_FALLTHROUGH
5546 #endif
5547 
5554 #ifndef XXH_NO_LONG_LONG
5555 /*-**********************************************************************
5556 * 64-bit hash
5557 ************************************************************************/
5558 #if defined(XXH_DOXYGEN) /* don't include <stdint.h> */
5559 
5564 typedef uint64_t XXH64_hash_t;
5565 #elif !defined (__VMS) \
5566  && (defined (__cplusplus) \
5567  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
5568 # include <stdint.h>
5569  typedef uint64_t XXH64_hash_t;
5570 #else
5571 # include <limits.h>
5572 # if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL
5573  /* LP64 ABI says uint64_t is unsigned long */
5574  typedef unsigned long XXH64_hash_t;
5575 # else
5576  /* the following type must have a width of 64-bit */
5577  typedef unsigned long long XXH64_hash_t;
5578 # endif
5579 #endif
5580 
5619 XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
5620 
5621 /******* Streaming *******/
5627 typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
5630 XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
5631 
5633 XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
5635 
5636 /******* Canonical representation *******/
5637 typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
5640 
5641 #ifndef XXH_NO_XXH3
5642 
5687 /*-**********************************************************************
5688 * XXH3 64-bit variant
5689 ************************************************************************/
5690 
5691 /* XXH3_64bits():
5692  * default 64-bit variant, using default secret and default seed of 0.
5693  * It's the fastest variant. */
5694 XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
5695 
5696 /*
5697  * XXH3_64bits_withSeed():
5698  * This variant generates a custom secret on the fly
5699  * based on default secret altered using the `seed` value.
5700  * While this operation is decently fast, note that it's not completely free.
5701  * Note: seed==0 produces the same results as XXH3_64bits().
5702  */
5703 XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
5704 
5712 #define XXH3_SECRET_SIZE_MIN 136
5713 
5714 /*
5715  * XXH3_64bits_withSecret():
5716  * It's possible to provide any blob of bytes as a "secret" to generate the hash.
5717  * This makes it more difficult for an external actor to prepare an intentional collision.
5718  * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
5719  * However, the quality of the secret impacts the dispersion of the hash algorithm.
5720  * Therefore, the secret _must_ look like a bunch of random bytes.
5721  * Avoid "trivial" or structured data such as repeated sequences or a text document.
5722  * Whenever in doubt about the "randomness" of the blob of bytes,
5723  * consider employing "XXH3_generateSecret()" instead (see below).
5724  * It will generate a proper high entropy secret derived from the blob of bytes.
5725  * Another advantage of using XXH3_generateSecret() is that
5726  * it guarantees that all bits within the initial blob of bytes
5727  * will impact every bit of the output.
5728  * This is not necessarily the case when using the blob of bytes directly
5729  * because, when hashing _small_ inputs, only a portion of the secret is employed.
5730  */
5731 XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
5732 
5733 
5734 /******* Streaming *******/
5735 /*
5736  * Streaming requires state maintenance.
5737  * This operation costs memory and CPU.
5738  * As a consequence, streaming is slower than one-shot hashing.
5739  * For better performance, prefer one-shot functions whenever applicable.
5740  */
5741 
5747 typedef struct XXH3_state_s XXH3_state_t;
5750 XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
5751 
5752 /*
5753  * XXH3_64bits_reset():
5754  * Initialize with default parameters.
5755  * digest will be equivalent to `XXH3_64bits()`.
5756  */
5758 /*
5759  * XXH3_64bits_reset_withSeed():
5760  * Generate a custom secret from `seed`, and store it into `statePtr`.
5761  * digest will be equivalent to `XXH3_64bits_withSeed()`.
5762  */
5764 /*
5765  * XXH3_64bits_reset_withSecret():
5766  * `secret` is referenced, it _must outlive_ the hash streaming session.
5767  * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
5768  * and the quality of produced hash values depends on secret's entropy
5769  * (secret's content should look like a bunch of random bytes).
5770  * When in doubt about the randomness of a candidate `secret`,
5771  * consider employing `XXH3_generateSecret()` instead (see below).
5772  */
5773 XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
5774 
5775 XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
5777 
5778 /* note : canonical representation of XXH3 is the same as XXH64
5779  * since they both produce XXH64_hash_t values */
5780 
5781 
5782 /*-**********************************************************************
5783 * XXH3 128-bit variant
5784 ************************************************************************/
5785 
5792 typedef struct {
5793  XXH64_hash_t low64;
5794  XXH64_hash_t high64;
5795 } XXH128_hash_t;
5796 
5797 XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);
5798 XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
5799 XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
5800 
5801 /******* Streaming *******/
5802 /*
5803  * Streaming requires state maintenance.
5804  * This operation costs memory and CPU.
5805  * As a consequence, streaming is slower than one-shot hashing.
5806  * For better performance, prefer one-shot functions whenever applicable.
5807  *
5808  * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits().
5809  * Use already declared XXH3_createState() and XXH3_freeState().
5810  *
5811  * All reset and streaming functions have same meaning as their 64-bit counterpart.
5812  */
5813 
5816 XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
5817 
5818 XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
5820 
5821 /* Following helper functions make it possible to compare XXH128_hast_t values.
5822  * Since XXH128_hash_t is a structure, this capability is not offered by the language.
5823  * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */
5824 
5830 
5840 XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
5841 
5842 
5843 /******* Canonical representation *******/
5844 typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
5847 
5848 
5849 #endif /* !XXH_NO_XXH3 */
5850 #endif /* XXH_NO_LONG_LONG */
5851 
5855 #endif /* XXHASH_H_5627135585666179 */
5856 
5857 
5858 
5859 #if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)
5860 #define XXHASH_H_STATIC_13879238742
5861 /* ****************************************************************************
5862  * This section contains declarations which are not guaranteed to remain stable.
5863  * They may change in future versions, becoming incompatible with a different
5864  * version of the library.
5865  * These declarations should only be used with static linking.
5866  * Never use them in association with dynamic linking!
5867  ***************************************************************************** */
5868 
5869 /*
5870  * These definitions are only present to allow static allocation
5871  * of XXH states, on stack or in a struct, for example.
5872  * Never **ever** access their members directly.
5873  */
5874 
5894 }; /* typedef'd to XXH32_state_t */
5895 
5896 
5897 #ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */
5898 
5918 }; /* typedef'd to XXH64_state_t */
5919 
5920 
5921 #ifndef XXH_NO_XXH3
5922 
5923 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
5924 # include <stdalign.h>
5925 # define XXH_ALIGN(n) alignas(n)
5926 #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
5927 /* In C++ alignas() is a keyword */
5928 # define XXH_ALIGN(n) alignas(n)
5929 #elif defined(__GNUC__)
5930 # define XXH_ALIGN(n) __attribute__ ((aligned(n)))
5931 #elif defined(_MSC_VER)
5932 # define XXH_ALIGN(n) __declspec(align(n))
5933 #else
5934 # define XXH_ALIGN(n) /* disabled */
5935 #endif
5936 
5937 /* Old GCC versions only accept the attribute after the type in structures. */
5938 #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \
5939  && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \
5940  && defined(__GNUC__)
5941 # define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
5942 #else
5943 # define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type
5944 #endif
5945 
5953 #define XXH3_INTERNALBUFFER_SIZE 256
5954 
5962 #define XXH3_SECRET_DEFAULT_SIZE 192
5963 
5986 struct XXH3_state_s {
5987  XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
5989  XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
5991  XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
5993  XXH32_hash_t bufferedSize;
5995  XXH32_hash_t useSeed;
5997  size_t nbStripesSoFar;
5999  XXH64_hash_t totalLen;
6001  size_t nbStripesPerBlock;
6003  size_t secretLimit;
6005  XXH64_hash_t seed;
6007  XXH64_hash_t reserved64;
6009  const unsigned char* extSecret;
6012  /* note: there may be some padding at the end due to alignment on 64 bytes */
6013 }; /* typedef'd to XXH3_state_t */
6014 
6015 #undef XXH_ALIGN_MEMBER
6016 
6028 #define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
6029 
6030 
6031 /* XXH128() :
6032  * simple alias to pre-selected XXH3_128bits variant
6033  */
6034 XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
6035 
6036 
6037 /* === Experimental API === */
6038 /* Symbols defined below must be considered tied to a specific library version. */
6039 
6040 /*
6041  * XXH3_generateSecret():
6042  *
6043  * Derive a high-entropy secret from any user-defined content, named customSeed.
6044  * The generated secret can be used in combination with `*_withSecret()` functions.
6045  * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,
6046  * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
6047  *
6048  * The function accepts as input a custom seed of any length and any content,
6049  * and derives from it a high-entropy secret of length @secretSize
6050  * into an already allocated buffer @secretBuffer.
6051  * @secretSize must be >= XXH3_SECRET_SIZE_MIN
6052  *
6053  * The generated secret can then be used with any `*_withSecret()` variant.
6054  * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
6055  * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
6056  * are part of this list. They all accept a `secret` parameter
6057  * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
6058  * _and_ feature very high entropy (consist of random-looking bytes).
6059  * These conditions can be a high bar to meet, so
6060  * XXH3_generateSecret() can be employed to ensure proper quality.
6061  *
6062  * customSeed can be anything. It can have any size, even small ones,
6063  * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
6064  * The resulting `secret` will nonetheless provide all required qualities.
6065  *
6066  * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
6067  */
6068 XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
6069 
6070 
6071 /*
6072  * XXH3_generateSecret_fromSeed():
6073  *
6074  * Generate the same secret as the _withSeed() variants.
6075  *
6076  * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
6077  * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
6078  *
6079  * The generated secret can be used in combination with
6080  *`*_withSecret()` and `_withSecretandSeed()` variants.
6081  * This generator is notably useful in combination with `_withSecretandSeed()`,
6082  * as a way to emulate a faster `_withSeed()` variant.
6083  */
6084 XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
6085 
6086 /*
6087  * *_withSecretandSeed() :
6088  * These variants generate hash values using either
6089  * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
6090  * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
6091  *
6092  * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
6093  * `_withSeed()` has to generate the secret on the fly for "large" keys.
6094  * It's fast, but can be perceptible for "not so large" keys (< 1 KB).
6095  * `_withSecret()` has to generate the masks on the fly for "small" keys,
6096  * which requires more instructions than _withSeed() variants.
6097  * Therefore, _withSecretandSeed variant combines the best of both worlds.
6098  *
6099  * When @secret has been generated by XXH3_generateSecret_fromSeed(),
6100  * this variant produces *exactly* the same results as `_withSeed()` variant,
6101  * hence offering only a pure speed benefit on "large" input,
6102  * by skipping the need to regenerate the secret for every large input.
6103  *
6104  * Another usage scenario is to hash the secret to a 64-bit hash value,
6105  * for example with XXH3_64bits(), which then becomes the seed,
6106  * and then employ both the seed and the secret in _withSecretandSeed().
6107  * On top of speed, an added benefit is that each bit in the secret
6108  * has a 50% chance to swap each bit in the output,
6109  * via its impact to the seed.
6110  * This is not guaranteed when using the secret directly in "small data" scenarios,
6111  * because only portions of the secret are employed for small data.
6112  */
6114 XXH3_64bits_withSecretandSeed(const void* data, size_t len,
6115  const void* secret, size_t secretSize,
6116  XXH64_hash_t seed);
6117 
6119 XXH3_128bits_withSecretandSeed(const void* data, size_t len,
6120  const void* secret, size_t secretSize,
6121  XXH64_hash_t seed64);
6122 
6125  const void* secret, size_t secretSize,
6126  XXH64_hash_t seed64);
6127 
6130  const void* secret, size_t secretSize,
6131  XXH64_hash_t seed64);
6132 
6133 
6134 #endif /* XXH_NO_XXH3 */
6135 #endif /* XXH_NO_LONG_LONG */
6136 #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
6137 # define XXH_IMPLEMENTATION
6138 #endif
6139 
6140 #endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */
6141 
6142 
6143 /* ======================================================================== */
6144 /* ======================================================================== */
6145 /* ======================================================================== */
6146 
6147 
6148 /*-**********************************************************************
6149  * xxHash implementation
6150  *-**********************************************************************
6151  * xxHash's implementation used to be hosted inside xxhash.c.
6152  *
6153  * However, inlining requires implementation to be visible to the compiler,
6154  * hence be included alongside the header.
6155  * Previously, implementation was hosted inside xxhash.c,
6156  * which was then #included when inlining was activated.
6157  * This construction created issues with a few build and install systems,
6158  * as it required xxhash.c to be stored in /include directory.
6159  *
6160  * xxHash implementation is now directly integrated within xxhash.h.
6161  * As a consequence, xxhash.c is no longer needed in /include.
6162  *
6163  * xxhash.c is still available and is still useful.
6164  * In a "normal" setup, when xxhash is not inlined,
6165  * xxhash.h only exposes the prototypes and public symbols,
6166  * while xxhash.c can be built into an object file xxhash.o
6167  * which can then be linked into the final binary.
6168  ************************************************************************/
6169 
6170 #if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \
6171  || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)
6172 # define XXH_IMPLEM_13a8737387
6173 
6174 /* *************************************
6175 * Tuning parameters
6176 ***************************************/
6177 
6184 #ifdef XXH_DOXYGEN
6185 
6190 # define XXH_NO_LONG_LONG
6191 # undef XXH_NO_LONG_LONG /* don't actually */
6192 
6242 # define XXH_FORCE_MEMORY_ACCESS 0
6243 
6270 # define XXH_FORCE_ALIGN_CHECK 0
6271 
6292 # define XXH_NO_INLINE_HINTS 0
6293 
6304 # define XXH32_ENDJMP 0
6305 
6313 # define XXH_OLD_NAMES
6314 # undef XXH_OLD_NAMES /* don't actually use, it is ugly. */
6315 #endif /* XXH_DOXYGEN */
6316 
6320 #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
6321  /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */
6322 # if !defined(__clang__) && \
6323 ( \
6324  (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
6325  ( \
6326  defined(__GNUC__) && ( \
6327  (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
6328  ( \
6329  defined(__mips__) && \
6330  (__mips <= 5 || __mips_isa_rev < 6) && \
6331  (!defined(__mips16) || defined(__mips_mips16e2)) \
6332  ) \
6333  ) \
6334  ) \
6335 )
6336 # define XXH_FORCE_MEMORY_ACCESS 1
6337 # endif
6338 #endif
6339 
6340 #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
6341 # if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \
6342  || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */
6343 # define XXH_FORCE_ALIGN_CHECK 0
6344 # else
6345 # define XXH_FORCE_ALIGN_CHECK 1
6346 # endif
6347 #endif
6348 
6349 #ifndef XXH_NO_INLINE_HINTS
6350 # if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \
6351  || defined(__NO_INLINE__) /* -O0, -fno-inline */
6352 # define XXH_NO_INLINE_HINTS 1
6353 # else
6354 # define XXH_NO_INLINE_HINTS 0
6355 # endif
6356 #endif
6357 
6358 #ifndef XXH32_ENDJMP
6359 /* generally preferable for performance */
6360 # define XXH32_ENDJMP 0
6361 #endif
6362 
6369 /* *************************************
6370 * Includes & Memory related functions
6371 ***************************************/
6372 /* Modify the local functions below should you wish to use some other memory routines */
6373 /* for ZSTD_malloc(), ZSTD_free() */
6374 #define ZSTD_DEPS_NEED_MALLOC
6375 /**** skipping file: zstd_deps.h ****/
6376 static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); }
6377 static void XXH_free (void* p) { ZSTD_free(p); }
6378 static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); }
6379 
6380 
6381 /* *************************************
6382 * Compiler Specific Options
6383 ***************************************/
6384 #ifdef _MSC_VER /* Visual Studio warning fix */
6385 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
6386 #endif
6387 
6388 #if XXH_NO_INLINE_HINTS /* disable inlining hints */
6389 # if defined(__GNUC__) || defined(__clang__)
6390 # define XXH_FORCE_INLINE static __attribute__((unused))
6391 # else
6392 # define XXH_FORCE_INLINE static
6393 # endif
6394 # define XXH_NO_INLINE static
6395 /* enable inlining hints */
6396 #elif defined(__GNUC__) || defined(__clang__)
6397 # define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
6398 # define XXH_NO_INLINE static __attribute__((noinline))
6399 #elif defined(_MSC_VER) /* Visual Studio */
6400 # define XXH_FORCE_INLINE static __forceinline
6401 # define XXH_NO_INLINE static __declspec(noinline)
6402 #elif defined (__cplusplus) \
6403  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */
6404 # define XXH_FORCE_INLINE static inline
6405 # define XXH_NO_INLINE static
6406 #else
6407 # define XXH_FORCE_INLINE static
6408 # define XXH_NO_INLINE static
6409 #endif
6410 
6411 
6412 
6413 /* *************************************
6414 * Debug
6415 ***************************************/
6424 #ifndef XXH_DEBUGLEVEL
6425 # ifdef DEBUGLEVEL /* backwards compat */
6426 # define XXH_DEBUGLEVEL DEBUGLEVEL
6427 # else
6428 # define XXH_DEBUGLEVEL 0
6429 # endif
6430 #endif
6431 
6432 #if (XXH_DEBUGLEVEL>=1)
6433 # include <assert.h> /* note: can still be disabled with NDEBUG */
6434 # define XXH_ASSERT(c) assert(c)
6435 #else
6436 # define XXH_ASSERT(c) ((void)0)
6437 #endif
6438 
6439 /* note: use after variable declarations */
6440 #ifndef XXH_STATIC_ASSERT
6441 # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
6442 # include <assert.h>
6443 # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
6444 # elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
6445 # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
6446 # else
6447 # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
6448 # endif
6449 # define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
6450 #endif
6451 
6468 #if defined(__GNUC__) || defined(__clang__)
6469 # define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))
6470 #else
6471 # define XXH_COMPILER_GUARD(var) ((void)0)
6472 #endif
6473 
6474 /* *************************************
6475 * Basic Types
6476 ***************************************/
6477 #if !defined (__VMS) \
6478  && (defined (__cplusplus) \
6479  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
6480 # include <stdint.h>
6481  typedef uint8_t xxh_u8;
6482 #else
6483  typedef unsigned char xxh_u8;
6484 #endif
6486 
6487 #ifdef XXH_OLD_NAMES
6488 # define BYTE xxh_u8
6489 # define U8 xxh_u8
6490 # define U32 xxh_u32
6491 #endif
6492 
6493 /* *** Memory access *** */
6494 
6545 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
6546 /*
6547  * Manual byteshift. Best for old compilers which don't inline memcpy.
6548  * We actually directly use XXH_readLE32 and XXH_readBE32.
6549  */
6550 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
6551 
6552 /*
6553  * Force direct memory access. Only works on CPU which support unaligned memory
6554  * access in hardware.
6555  */
6556 static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }
6557 
6558 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
6559 
6560 /*
6561  * __pack instructions are safer but compiler specific, hence potentially
6562  * problematic for some compilers.
6563  *
6564  * Currently only defined for GCC and ICC.
6565  */
6566 #ifdef XXH_OLD_NAMES
6567 typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;
6568 #endif
6569 static xxh_u32 XXH_read32(const void* ptr)
6570 {
6571  typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign;
6572  return ((const xxh_unalign*)ptr)->u32;
6573 }
6574 
6575 #else
6576 
6577 /*
6578  * Portable and safe solution. Generally efficient.
6579  * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
6580  */
6581 static xxh_u32 XXH_read32(const void* memPtr)
6582 {
6583  xxh_u32 val;
6584  XXH_memcpy(&val, memPtr, sizeof(val));
6585  return val;
6586 }
6587 
6588 #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
6589 
6590 
6591 /* *** Endianness *** */
6592 
6609 #ifndef XXH_CPU_LITTLE_ENDIAN
6610 /*
6611  * Try to detect endianness automatically, to avoid the nonstandard behavior
6612  * in `XXH_isLittleEndian()`
6613  */
6614 # if defined(_WIN32) /* Windows is always little endian */ \
6615  || defined(__LITTLE_ENDIAN__) \
6616  || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
6617 # define XXH_CPU_LITTLE_ENDIAN 1
6618 # elif defined(__BIG_ENDIAN__) \
6619  || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
6620 # define XXH_CPU_LITTLE_ENDIAN 0
6621 # else
6622 
6628 static int XXH_isLittleEndian(void)
6629 {
6630  /*
6631  * Portable and well-defined behavior.
6632  * Don't use static: it is detrimental to performance.
6633  */
6634  const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };
6635  return one.c[0];
6636 }
6637 # define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
6638 # endif
6639 #endif
6640 
6641 
6642 
6643 
6644 /* ****************************************
6645 * Compiler-specific Functions and Macros
6646 ******************************************/
6647 #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
6648 
6649 #ifdef __has_builtin
6650 # define XXH_HAS_BUILTIN(x) __has_builtin(x)
6651 #else
6652 # define XXH_HAS_BUILTIN(x) 0
6653 #endif
6654 
6668 #if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \
6669  && XXH_HAS_BUILTIN(__builtin_rotateleft64)
6670 # define XXH_rotl32 __builtin_rotateleft32
6671 # define XXH_rotl64 __builtin_rotateleft64
6672 /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */
6673 #elif defined(_MSC_VER)
6674 # define XXH_rotl32(x,r) _rotl(x,r)
6675 # define XXH_rotl64(x,r) _rotl64(x,r)
6676 #else
6677 # define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
6678 # define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
6679 #endif
6680 
6689 #if defined(_MSC_VER) /* Visual Studio */
6690 # define XXH_swap32 _byteswap_ulong
6691 #elif XXH_GCC_VERSION >= 403
6692 # define XXH_swap32 __builtin_bswap32
6693 #else
6695 {
6696  return ((x << 24) & 0xff000000 ) |
6697  ((x << 8) & 0x00ff0000 ) |
6698  ((x >> 8) & 0x0000ff00 ) |
6699  ((x >> 24) & 0x000000ff );
6700 }
6701 #endif
6702 
6703 
6704 /* ***************************
6705 * Memory reads
6706 *****************************/
6707 
6712 typedef enum {
6715 } XXH_alignment;
6716 
6717 /*
6718  * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load.
6719  *
6720  * This is ideal for older compilers which don't inline memcpy.
6721  */
6722 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
6723 
6724 XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)
6725 {
6726  const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
6727  return bytePtr[0]
6728  | ((xxh_u32)bytePtr[1] << 8)
6729  | ((xxh_u32)bytePtr[2] << 16)
6730  | ((xxh_u32)bytePtr[3] << 24);
6731 }
6732 
6733 XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)
6734 {
6735  const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
6736  return bytePtr[3]
6737  | ((xxh_u32)bytePtr[2] << 8)
6738  | ((xxh_u32)bytePtr[1] << 16)
6739  | ((xxh_u32)bytePtr[0] << 24);
6740 }
6741 
6742 #else
6744 {
6746 }
6747 
6748 static xxh_u32 XXH_readBE32(const void* ptr)
6749 {
6751 }
6752 #endif
6753 
6756 {
6757  if (align==XXH_unaligned) {
6758  return XXH_readLE32(ptr);
6759  } else {
6760  return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
6761  }
6762 }
6763 
6764 
6765 /* *************************************
6766 * Misc
6767 ***************************************/
6770 
6771 
6772 /* *******************************************************************
6773 * 32-bit hash functions
6774 *********************************************************************/
6781  /* #define instead of static const, to be used as initializers */
6782 #define XXH_PRIME32_1 0x9E3779B1U
6783 #define XXH_PRIME32_2 0x85EBCA77U
6784 #define XXH_PRIME32_3 0xC2B2AE3DU
6785 #define XXH_PRIME32_4 0x27D4EB2FU
6786 #define XXH_PRIME32_5 0x165667B1U
6788 #ifdef XXH_OLD_NAMES
6789 # define PRIME32_1 XXH_PRIME32_1
6790 # define PRIME32_2 XXH_PRIME32_2
6791 # define PRIME32_3 XXH_PRIME32_3
6792 # define PRIME32_4 XXH_PRIME32_4
6793 # define PRIME32_5 XXH_PRIME32_5
6794 #endif
6795 
6808 {
6809  acc += input * XXH_PRIME32_2;
6810  acc = XXH_rotl32(acc, 13);
6811  acc *= XXH_PRIME32_1;
6812 #if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
6813  /*
6814  * UGLY HACK:
6815  * A compiler fence is the only thing that prevents GCC and Clang from
6816  * autovectorizing the XXH32 loop (pragmas and attributes don't work for some
6817  * reason) without globally disabling SSE4.1.
6818  *
6819  * The reason we want to avoid vectorization is because despite working on
6820  * 4 integers at a time, there are multiple factors slowing XXH32 down on
6821  * SSE4:
6822  * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on
6823  * newer chips!) making it slightly slower to multiply four integers at
6824  * once compared to four integers independently. Even when pmulld was
6825  * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE
6826  * just to multiply unless doing a long operation.
6827  *
6828  * - Four instructions are required to rotate,
6829  * movqda tmp, v // not required with VEX encoding
6830  * pslld tmp, 13 // tmp <<= 13
6831  * psrld v, 19 // x >>= 19
6832  * por v, tmp // x |= tmp
6833  * compared to one for scalar:
6834  * roll v, 13 // reliably fast across the board
6835  * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason
6836  *
6837  * - Instruction level parallelism is actually more beneficial here because
6838  * the SIMD actually serializes this operation: While v1 is rotating, v2
6839  * can load data, while v3 can multiply. SSE forces them to operate
6840  * together.
6841  *
6842  * This is also enabled on AArch64, as Clang autovectorizes it incorrectly
6843  * and it is pointless writing a NEON implementation that is basically the
6844  * same speed as scalar for XXH32.
6845  */
6846  XXH_COMPILER_GUARD(acc);
6847 #endif
6848  return acc;
6849 }
6850 
6862 {
6863  h32 ^= h32 >> 15;
6864  h32 *= XXH_PRIME32_2;
6865  h32 ^= h32 >> 13;
6866  h32 *= XXH_PRIME32_3;
6867  h32 ^= h32 >> 16;
6868  return(h32);
6869 }
6870 
6871 #define XXH_get32bits(p) XXH_readLE32_align(p, align)
6872 
6887 static xxh_u32
6889 {
6890 #define XXH_PROCESS1 do { \
6891  h32 += (*ptr++) * XXH_PRIME32_5; \
6892  h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \
6893 } while (0)
6894 
6895 #define XXH_PROCESS4 do { \
6896  h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \
6897  ptr += 4; \
6898  h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
6899 } while (0)
6900 
6901  if (ptr==NULL) XXH_ASSERT(len == 0);
6902 
6903  /* Compact rerolled version; generally faster */
6904  if (!XXH32_ENDJMP) {
6905  len &= 15;
6906  while (len >= 4) {
6907  XXH_PROCESS4;
6908  len -= 4;
6909  }
6910  while (len > 0) {
6911  XXH_PROCESS1;
6912  --len;
6913  }
6914  return XXH32_avalanche(h32);
6915  } else {
6916  switch(len&15) /* or switch(bEnd - p) */ {
6917  case 12: XXH_PROCESS4;
6919  case 8: XXH_PROCESS4;
6921  case 4: XXH_PROCESS4;
6922  return XXH32_avalanche(h32);
6923 
6924  case 13: XXH_PROCESS4;
6926  case 9: XXH_PROCESS4;
6928  case 5: XXH_PROCESS4;
6929  XXH_PROCESS1;
6930  return XXH32_avalanche(h32);
6931 
6932  case 14: XXH_PROCESS4;
6934  case 10: XXH_PROCESS4;
6936  case 6: XXH_PROCESS4;
6937  XXH_PROCESS1;
6938  XXH_PROCESS1;
6939  return XXH32_avalanche(h32);
6940 
6941  case 15: XXH_PROCESS4;
6943  case 11: XXH_PROCESS4;
6945  case 7: XXH_PROCESS4;
6947  case 3: XXH_PROCESS1;
6949  case 2: XXH_PROCESS1;
6951  case 1: XXH_PROCESS1;
6953  case 0: return XXH32_avalanche(h32);
6954  }
6955  XXH_ASSERT(0);
6956  return h32; /* reaching this point is deemed impossible */
6957  }
6958 }
6959 
6960 #ifdef XXH_OLD_NAMES
6961 # define PROCESS1 XXH_PROCESS1
6962 # define PROCESS4 XXH_PROCESS4
6963 #else
6964 # undef XXH_PROCESS1
6965 # undef XXH_PROCESS4
6966 #endif
6967 
6977 XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
6978 {
6979  xxh_u32 h32;
6980 
6981  if (input==NULL) XXH_ASSERT(len == 0);
6982 
6983  if (len>=16) {
6984  const xxh_u8* const bEnd = input + len;
6985  const xxh_u8* const limit = bEnd - 15;
6986  xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
6987  xxh_u32 v2 = seed + XXH_PRIME32_2;
6988  xxh_u32 v3 = seed + 0;
6989  xxh_u32 v4 = seed - XXH_PRIME32_1;
6990 
6991  do {
6992  v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
6993  v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
6994  v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
6995  v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
6996  } while (input < limit);
6997 
6998  h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
6999  + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
7000  } else {
7001  h32 = seed + XXH_PRIME32_5;
7002  }
7003 
7004  h32 += (xxh_u32)len;
7005 
7006  return XXH32_finalize(h32, input, len&15, align);
7007 }
7008 
7010 XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
7011 {
7012 #if 0
7013  /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
7015  XXH32_reset(&state, seed);
7016  XXH32_update(&state, (const xxh_u8*)input, len);
7017  return XXH32_digest(&state);
7018 #else
7019  if (XXH_FORCE_ALIGN_CHECK) {
7020  if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
7021  return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
7022  } }
7023 
7024  return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
7025 #endif
7026 }
7027 
7028 
7029 
7030 /******* Hash streaming *******/
7035 {
7036  return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
7037 }
7040 {
7041  XXH_free(statePtr);
7042  return XXH_OK;
7043 }
7044 
7047 {
7048  XXH_memcpy(dstState, srcState, sizeof(*dstState));
7049 }
7050 
7053 {
7054  XXH_ASSERT(statePtr != NULL);
7055  memset(statePtr, 0, sizeof(*statePtr));
7056  statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
7057  statePtr->v[1] = seed + XXH_PRIME32_2;
7058  statePtr->v[2] = seed + 0;
7059  statePtr->v[3] = seed - XXH_PRIME32_1;
7060  return XXH_OK;
7061 }
7062 
7063 
7066 XXH32_update(XXH32_state_t* state, const void* input, size_t len)
7067 {
7068  if (input==NULL) {
7069  XXH_ASSERT(len == 0);
7070  return XXH_OK;
7071  }
7072 
7073  { const xxh_u8* p = (const xxh_u8*)input;
7074  const xxh_u8* const bEnd = p + len;
7075 
7076  state->total_len_32 += (XXH32_hash_t)len;
7077  state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
7078 
7079  if (state->memsize + len < 16) { /* fill in tmp buffer */
7080  XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
7081  state->memsize += (XXH32_hash_t)len;
7082  return XXH_OK;
7083  }
7084 
7085  if (state->memsize) { /* some data left from previous update */
7086  XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
7087  { const xxh_u32* p32 = state->mem32;
7088  state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
7089  state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
7090  state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
7091  state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
7092  }
7093  p += 16-state->memsize;
7094  state->memsize = 0;
7095  }
7096 
7097  if (p <= bEnd-16) {
7098  const xxh_u8* const limit = bEnd - 16;
7099 
7100  do {
7101  state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
7102  state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
7103  state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
7104  state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
7105  } while (p<=limit);
7106 
7107  }
7108 
7109  if (p < bEnd) {
7110  XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
7111  state->memsize = (unsigned)(bEnd-p);
7112  }
7113  }
7114 
7115  return XXH_OK;
7116 }
7117 
7118 
7121 {
7122  xxh_u32 h32;
7123 
7124  if (state->large_len) {
7125  h32 = XXH_rotl32(state->v[0], 1)
7126  + XXH_rotl32(state->v[1], 7)
7127  + XXH_rotl32(state->v[2], 12)
7128  + XXH_rotl32(state->v[3], 18);
7129  } else {
7130  h32 = state->v[2] /* == seed */ + XXH_PRIME32_5;
7131  }
7132 
7133  h32 += state->total_len_32;
7134 
7135  return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
7136 }
7137 
7138 
7139 /******* Canonical representation *******/
7140 
7156 {
7157  /* XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); */
7159  XXH_memcpy(dst, &hash, sizeof(*dst));
7160 }
7163 {
7164  return XXH_readBE32(src);
7165 }
7166 
7167 
7168 #ifndef XXH_NO_LONG_LONG
7169 
7170 /* *******************************************************************
7171 * 64-bit hash functions
7172 *********************************************************************/
7178 /******* Memory access *******/
7179 
7181 
7182 #ifdef XXH_OLD_NAMES
7183 # define U64 xxh_u64
7184 #endif
7185 
7186 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
7187 /*
7188  * Manual byteshift. Best for old compilers which don't inline memcpy.
7189  * We actually directly use XXH_readLE64 and XXH_readBE64.
7190  */
7191 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
7192 
7193 /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
7194 static xxh_u64 XXH_read64(const void* memPtr)
7195 {
7196  return *(const xxh_u64*) memPtr;
7197 }
7198 
7199 #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
7200 
7201 /*
7202  * __pack instructions are safer, but compiler specific, hence potentially
7203  * problematic for some compilers.
7204  *
7205  * Currently only defined for GCC and ICC.
7206  */
7207 #ifdef XXH_OLD_NAMES
7208 typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64;
7209 #endif
7210 static xxh_u64 XXH_read64(const void* ptr)
7211 {
7212  typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64;
7213  return ((const xxh_unalign64*)ptr)->u64;
7214 }
7215 
7216 #else
7217 
7218 /*
7219  * Portable and safe solution. Generally efficient.
7220  * see: https://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
7221  */
7222 static xxh_u64 XXH_read64(const void* memPtr)
7223 {
7224  xxh_u64 val;
7225  XXH_memcpy(&val, memPtr, sizeof(val));
7226  return val;
7227 }
7228 
7229 #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
7230 
7231 #if defined(_MSC_VER) /* Visual Studio */
7232 # define XXH_swap64 _byteswap_uint64
7233 #elif XXH_GCC_VERSION >= 403
7234 # define XXH_swap64 __builtin_bswap64
7235 #else
7237 {
7238  return ((x << 56) & 0xff00000000000000ULL) |
7239  ((x << 40) & 0x00ff000000000000ULL) |
7240  ((x << 24) & 0x0000ff0000000000ULL) |
7241  ((x << 8) & 0x000000ff00000000ULL) |
7242  ((x >> 8) & 0x00000000ff000000ULL) |
7243  ((x >> 24) & 0x0000000000ff0000ULL) |
7244  ((x >> 40) & 0x000000000000ff00ULL) |
7245  ((x >> 56) & 0x00000000000000ffULL);
7246 }
7247 #endif
7248 
7249 
7250 /* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */
7251 #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
7252 
7253 XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr)
7254 {
7255  const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
7256  return bytePtr[0]
7257  | ((xxh_u64)bytePtr[1] << 8)
7258  | ((xxh_u64)bytePtr[2] << 16)
7259  | ((xxh_u64)bytePtr[3] << 24)
7260  | ((xxh_u64)bytePtr[4] << 32)
7261  | ((xxh_u64)bytePtr[5] << 40)
7262  | ((xxh_u64)bytePtr[6] << 48)
7263  | ((xxh_u64)bytePtr[7] << 56);
7264 }
7265 
7266 XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr)
7267 {
7268  const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
7269  return bytePtr[7]
7270  | ((xxh_u64)bytePtr[6] << 8)
7271  | ((xxh_u64)bytePtr[5] << 16)
7272  | ((xxh_u64)bytePtr[4] << 24)
7273  | ((xxh_u64)bytePtr[3] << 32)
7274  | ((xxh_u64)bytePtr[2] << 40)
7275  | ((xxh_u64)bytePtr[1] << 48)
7276  | ((xxh_u64)bytePtr[0] << 56);
7277 }
7278 
7279 #else
7281 {
7283 }
7284 
7285 static xxh_u64 XXH_readBE64(const void* ptr)
7286 {
7288 }
7289 #endif
7290 
7293 {
7294  if (align==XXH_unaligned)
7295  return XXH_readLE64(ptr);
7296  else
7297  return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
7298 }
7299 
7300 
7301 /******* xxh64 *******/
7308 /* #define rather that static const, to be used as initializers */
7309 #define XXH_PRIME64_1 0x9E3779B185EBCA87ULL
7310 #define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL
7311 #define XXH_PRIME64_3 0x165667B19E3779F9ULL
7312 #define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL
7313 #define XXH_PRIME64_5 0x27D4EB2F165667C5ULL
7315 #ifdef XXH_OLD_NAMES
7316 # define PRIME64_1 XXH_PRIME64_1
7317 # define PRIME64_2 XXH_PRIME64_2
7318 # define PRIME64_3 XXH_PRIME64_3
7319 # define PRIME64_4 XXH_PRIME64_4
7320 # define PRIME64_5 XXH_PRIME64_5
7321 #endif
7322 
7324 {
7325  acc += input * XXH_PRIME64_2;
7326  acc = XXH_rotl64(acc, 31);
7327  acc *= XXH_PRIME64_1;
7328  return acc;
7329 }
7330 
7332 {
7333  val = XXH64_round(0, val);
7334  acc ^= val;
7335  acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
7336  return acc;
7337 }
7338 
7340 {
7341  h64 ^= h64 >> 33;
7342  h64 *= XXH_PRIME64_2;
7343  h64 ^= h64 >> 29;
7344  h64 *= XXH_PRIME64_3;
7345  h64 ^= h64 >> 32;
7346  return h64;
7347 }
7348 
7349 
7350 #define XXH_get64bits(p) XXH_readLE64_align(p, align)
7351 
7352 static xxh_u64
7354 {
7355  if (ptr==NULL) XXH_ASSERT(len == 0);
7356  len &= 31;
7357  while (len >= 8) {
7358  xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
7359  ptr += 8;
7360  h64 ^= k1;
7361  h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
7362  len -= 8;
7363  }
7364  if (len >= 4) {
7365  h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
7366  ptr += 4;
7367  h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
7368  len -= 4;
7369  }
7370  while (len > 0) {
7371  h64 ^= (*ptr++) * XXH_PRIME64_5;
7372  h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1;
7373  --len;
7374  }
7375  return XXH64_avalanche(h64);
7376 }
7377 
7378 #ifdef XXH_OLD_NAMES
7379 # define PROCESS1_64 XXH_PROCESS1_64
7380 # define PROCESS4_64 XXH_PROCESS4_64
7381 # define PROCESS8_64 XXH_PROCESS8_64
7382 #else
7383 # undef XXH_PROCESS1_64
7384 # undef XXH_PROCESS4_64
7385 # undef XXH_PROCESS8_64
7386 #endif
7387 
7389 XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
7390 {
7391  xxh_u64 h64;
7392  if (input==NULL) XXH_ASSERT(len == 0);
7393 
7394  if (len>=32) {
7395  const xxh_u8* const bEnd = input + len;
7396  const xxh_u8* const limit = bEnd - 31;
7397  xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
7398  xxh_u64 v2 = seed + XXH_PRIME64_2;
7399  xxh_u64 v3 = seed + 0;
7400  xxh_u64 v4 = seed - XXH_PRIME64_1;
7401 
7402  do {
7403  v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
7404  v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
7405  v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
7406  v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
7407  } while (input<limit);
7408 
7409  h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
7410  h64 = XXH64_mergeRound(h64, v1);
7411  h64 = XXH64_mergeRound(h64, v2);
7412  h64 = XXH64_mergeRound(h64, v3);
7413  h64 = XXH64_mergeRound(h64, v4);
7414 
7415  } else {
7416  h64 = seed + XXH_PRIME64_5;
7417  }
7418 
7419  h64 += (xxh_u64) len;
7420 
7421  return XXH64_finalize(h64, input, len, align);
7422 }
7423 
7424 
7426 XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
7427 {
7428 #if 0
7429  /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
7431  XXH64_reset(&state, seed);
7432  XXH64_update(&state, (const xxh_u8*)input, len);
7433  return XXH64_digest(&state);
7434 #else
7435  if (XXH_FORCE_ALIGN_CHECK) {
7436  if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
7437  return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
7438  } }
7439 
7440  return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
7441 
7442 #endif
7443 }
7444 
7445 /******* Hash Streaming *******/
7446 
7449 {
7450  return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
7451 }
7454 {
7455  XXH_free(statePtr);
7456  return XXH_OK;
7457 }
7458 
7461 {
7462  XXH_memcpy(dstState, srcState, sizeof(*dstState));
7463 }
7464 
7467 {
7468  XXH_ASSERT(statePtr != NULL);
7469  memset(statePtr, 0, sizeof(*statePtr));
7470  statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
7471  statePtr->v[1] = seed + XXH_PRIME64_2;
7472  statePtr->v[2] = seed + 0;
7473  statePtr->v[3] = seed - XXH_PRIME64_1;
7474  return XXH_OK;
7475 }
7476 
7479 XXH64_update (XXH64_state_t* state, const void* input, size_t len)
7480 {
7481  if (input==NULL) {
7482  XXH_ASSERT(len == 0);
7483  return XXH_OK;
7484  }
7485 
7486  { const xxh_u8* p = (const xxh_u8*)input;
7487  const xxh_u8* const bEnd = p + len;
7488 
7489  state->total_len += len;
7490 
7491  if (state->memsize + len < 32) { /* fill in tmp buffer */
7492  XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
7493  state->memsize += (xxh_u32)len;
7494  return XXH_OK;
7495  }
7496 
7497  if (state->memsize) { /* tmp buffer is full */
7498  XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
7499  state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
7500  state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
7501  state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
7502  state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
7503  p += 32 - state->memsize;
7504  state->memsize = 0;
7505  }
7506 
7507  if (p+32 <= bEnd) {
7508  const xxh_u8* const limit = bEnd - 32;
7509 
7510  do {
7511  state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
7512  state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
7513  state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
7514  state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
7515  } while (p<=limit);
7516 
7517  }
7518 
7519  if (p < bEnd) {
7520  XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
7521  state->memsize = (unsigned)(bEnd-p);
7522  }
7523  }
7524 
7525  return XXH_OK;
7526 }
7527 
7528 
7531 {
7532  xxh_u64 h64;
7533 
7534  if (state->total_len >= 32) {
7535  h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
7536  h64 = XXH64_mergeRound(h64, state->v[0]);
7537  h64 = XXH64_mergeRound(h64, state->v[1]);
7538  h64 = XXH64_mergeRound(h64, state->v[2]);
7539  h64 = XXH64_mergeRound(h64, state->v[3]);
7540  } else {
7541  h64 = state->v[2] /*seed*/ + XXH_PRIME64_5;
7542  }
7543 
7544  h64 += (xxh_u64) state->total_len;
7545 
7546  return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
7547 }
7548 
7549 
7550 /******* Canonical representation *******/
7551 
7554 {
7555  /* XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); */
7557  XXH_memcpy(dst, &hash, sizeof(*dst));
7558 }
7559 
7562 {
7563  return XXH_readBE64(src);
7564 }
7565 
7566 #ifndef XXH_NO_XXH3
7567 
7568 /* *********************************************************************
7569 * XXH3
7570 * New generation hash designed for speed on small keys and vectorization
7571 ************************************************************************ */
7579 /* === Compiler specifics === */
7580 
7581 #if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
7582 # define XXH_RESTRICT /* disable */
7583 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
7584 # define XXH_RESTRICT restrict
7585 #else
7586 /* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */
7587 # define XXH_RESTRICT /* disable */
7588 #endif
7589 
7590 #if (defined(__GNUC__) && (__GNUC__ >= 3)) \
7591  || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
7592  || defined(__clang__)
7593 # define XXH_likely(x) __builtin_expect(x, 1)
7594 # define XXH_unlikely(x) __builtin_expect(x, 0)
7595 #else
7596 # define XXH_likely(x) (x)
7597 # define XXH_unlikely(x) (x)
7598 #endif
7599 
7600 #if defined(__GNUC__) || defined(__clang__)
7601 # if defined(__ARM_NEON__) || defined(__ARM_NEON) \
7602  || defined(__aarch64__) || defined(_M_ARM) \
7603  || defined(_M_ARM64) || defined(_M_ARM64EC)
7604 # define inline __inline__ /* circumvent a clang bug */
7605 # include <arm_neon.h>
7606 # undef inline
7607 # elif defined(__AVX2__)
7608 # include <immintrin.h>
7609 # elif defined(__SSE2__)
7610 # include <emmintrin.h>
7611 # endif
7612 #endif
7613 
7614 #if defined(_MSC_VER)
7615 # include <intrin.h>
7616 #endif
7617 
7618 /*
7619  * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
7620  * remaining a true 64-bit/128-bit hash function.
7621  *
7622  * This is done by prioritizing a subset of 64-bit operations that can be
7623  * emulated without too many steps on the average 32-bit machine.
7624  *
7625  * For example, these two lines seem similar, and run equally fast on 64-bit:
7626  *
7627  * xxh_u64 x;
7628  * x ^= (x >> 47); // good
7629  * x ^= (x >> 13); // bad
7630  *
7631  * However, to a 32-bit machine, there is a major difference.
7632  *
7633  * x ^= (x >> 47) looks like this:
7634  *
7635  * x.lo ^= (x.hi >> (47 - 32));
7636  *
7637  * while x ^= (x >> 13) looks like this:
7638  *
7639  * // note: funnel shifts are not usually cheap.
7640  * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
7641  * x.hi ^= (x.hi >> 13);
7642  *
7643  * The first one is significantly faster than the second, simply because the
7644  * shift is larger than 32. This means:
7645  * - All the bits we need are in the upper 32 bits, so we can ignore the lower
7646  * 32 bits in the shift.
7647  * - The shift result will always fit in the lower 32 bits, and therefore,
7648  * we can ignore the upper 32 bits in the xor.
7649  *
7650  * Thanks to this optimization, XXH3 only requires these features to be efficient:
7651  *
7652  * - Usable unaligned access
7653  * - A 32-bit or 64-bit ALU
7654  * - If 32-bit, a decent ADC instruction
7655  * - A 32 or 64-bit multiply with a 64-bit result
7656  * - For the 128-bit variant, a decent byteswap helps short inputs.
7657  *
7658  * The first two are already required by XXH32, and almost all 32-bit and 64-bit
7659  * platforms which can run XXH32 can run XXH3 efficiently.
7660  *
7661  * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
7662  * notable exception.
7663  *
7664  * First of all, Thumb-1 lacks support for the UMULL instruction which
7665  * performs the important long multiply. This means numerous __aeabi_lmul
7666  * calls.
7667  *
7668  * Second of all, the 8 functional registers are just not enough.
7669  * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
7670  * Lo registers, and this shuffling results in thousands more MOVs than A32.
7671  *
7672  * A32 and T32 don't have this limitation. They can access all 14 registers,
7673  * do a 32->64 multiply with UMULL, and the flexible operand allowing free
7674  * shifts is helpful, too.
7675  *
7676  * Therefore, we do a quick sanity check.
7677  *
7678  * If compiling Thumb-1 for a target which supports ARM instructions, we will
7679  * emit a warning, as it is not a "sane" platform to compile for.
7680  *
7681  * Usually, if this happens, it is because of an accident and you probably need
7682  * to specify -march, as you likely meant to compile for a newer architecture.
7683  *
7684  * Credit: large sections of the vectorial and asm source code paths
7685  * have been contributed by @easyaspi314
7686  */
7687 #if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM)
7688 # warning "XXH3 is highly inefficient without ARM or Thumb-2."
7689 #endif
7690 
7691 /* ==========================================
7692  * Vectorization detection
7693  * ========================================== */
7694 
7695 #ifdef XXH_DOXYGEN
7696 
7706 # define XXH_VECTOR XXH_SCALAR
7707 
7716 enum XXH_VECTOR_TYPE /* fake enum */ {
7717  XXH_SCALAR = 0,
7718  XXH_SSE2 = 1,
7724  XXH_AVX2 = 2,
7725  XXH_AVX512 = 3,
7726  XXH_NEON = 4,
7727  XXH_VSX = 5,
7728 };
7738 # define XXH_ACC_ALIGN 8
7739 #endif
7740 
7741 /* Actual definition */
7742 #ifndef XXH_DOXYGEN
7743 # define XXH_SCALAR 0
7744 # define XXH_SSE2 1
7745 # define XXH_AVX2 2
7746 # define XXH_AVX512 3
7747 # define XXH_NEON 4
7748 # define XXH_VSX 5
7749 #endif
7750 
7751 #ifndef XXH_VECTOR /* can be defined on command line */
7752 # if ( \
7753  defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
7754  || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \
7755  ) && ( \
7756  defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
7757  || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
7758  )
7759 # define XXH_VECTOR XXH_NEON
7760 # elif defined(__AVX512F__)
7761 # define XXH_VECTOR XXH_AVX512
7762 # elif defined(__AVX2__)
7763 # define XXH_VECTOR XXH_AVX2
7764 # elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
7765 # define XXH_VECTOR XXH_SSE2
7766 # elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
7767  || (defined(__s390x__) && defined(__VEC__)) \
7768  && defined(__GNUC__) /* TODO: IBM XL */
7769 # define XXH_VECTOR XXH_VSX
7770 # else
7771 # define XXH_VECTOR XXH_SCALAR
7772 # endif
7773 #endif
7774 
7775 /*
7776  * Controls the alignment of the accumulator,
7777  * for compatibility with aligned vector loads, which are usually faster.
7778  */
7779 #ifndef XXH_ACC_ALIGN
7780 # if defined(XXH_X86DISPATCH)
7781 # define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */
7782 # elif XXH_VECTOR == XXH_SCALAR /* scalar */
7783 # define XXH_ACC_ALIGN 8
7784 # elif XXH_VECTOR == XXH_SSE2 /* sse2 */
7785 # define XXH_ACC_ALIGN 16
7786 # elif XXH_VECTOR == XXH_AVX2 /* avx2 */
7787 # define XXH_ACC_ALIGN 32
7788 # elif XXH_VECTOR == XXH_NEON /* neon */
7789 # define XXH_ACC_ALIGN 16
7790 # elif XXH_VECTOR == XXH_VSX /* vsx */
7791 # define XXH_ACC_ALIGN 16
7792 # elif XXH_VECTOR == XXH_AVX512 /* avx512 */
7793 # define XXH_ACC_ALIGN 64
7794 # endif
7795 #endif
7796 
7797 #if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \
7798  || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512
7799 # define XXH_SEC_ALIGN XXH_ACC_ALIGN
7800 #else
7801 # define XXH_SEC_ALIGN 8
7802 #endif
7803 
7804 /*
7805  * UGLY HACK:
7806  * GCC usually generates the best code with -O3 for xxHash.
7807  *
7808  * However, when targeting AVX2, it is overzealous in its unrolling resulting
7809  * in code roughly 3/4 the speed of Clang.
7810  *
7811  * There are other issues, such as GCC splitting _mm256_loadu_si256 into
7812  * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which
7813  * only applies to Sandy and Ivy Bridge... which don't even support AVX2.
7814  *
7815  * That is why when compiling the AVX2 version, it is recommended to use either
7816  * -O2 -mavx2 -march=haswell
7817  * or
7818  * -O2 -mavx2 -mno-avx256-split-unaligned-load
7819  * for decent performance, or to use Clang instead.
7820  *
7821  * Fortunately, we can control the first one with a pragma that forces GCC into
7822  * -O2, but the other one we can't control without "failed to inline always
7823  * inline function due to target mismatch" warnings.
7824  */
7825 #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
7826  && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
7827  && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
7828 # pragma GCC push_options
7829 # pragma GCC optimize("-O2")
7830 #endif
7831 
7832 
7833 #if XXH_VECTOR == XXH_NEON
7834 /*
7835  * NEON's setup for vmlal_u32 is a little more complicated than it is on
7836  * SSE2, AVX2, and VSX.
7837  *
7838  * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast.
7839  *
7840  * To do the same operation, the 128-bit 'Q' register needs to be split into
7841  * two 64-bit 'D' registers, performing this operation::
7842  *
7843  * [ a | b ]
7844  * | '---------. .--------' |
7845  * | x |
7846  * | .---------' '--------. |
7847  * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ]
7848  *
7849  * Due to significant changes in aarch64, the fastest method for aarch64 is
7850  * completely different than the fastest method for ARMv7-A.
7851  *
7852  * ARMv7-A treats D registers as unions overlaying Q registers, so modifying
7853  * D11 will modify the high half of Q5. This is similar to how modifying AH
7854  * will only affect bits 8-15 of AX on x86.
7855  *
7856  * VZIP takes two registers, and puts even lanes in one register and odd lanes
7857  * in the other.
7858  *
7859  * On ARMv7-A, this strangely modifies both parameters in place instead of
7860  * taking the usual 3-operand form.
7861  *
7862  * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the
7863  * lower and upper halves of the Q register to end up with the high and low
7864  * halves where we want - all in one instruction.
7865  *
7866  * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] }
7867  *
7868  * Unfortunately we need inline assembly for this: Instructions modifying two
7869  * registers at once is not possible in GCC or Clang's IR, and they have to
7870  * create a copy.
7871  *
7872  * aarch64 requires a different approach.
7873  *
7874  * In order to make it easier to write a decent compiler for aarch64, many
7875  * quirks were removed, such as conditional execution.
7876  *
7877  * NEON was also affected by this.
7878  *
7879  * aarch64 cannot access the high bits of a Q-form register, and writes to a
7880  * D-form register zero the high bits, similar to how writes to W-form scalar
7881  * registers (or DWORD registers on x86_64) work.
7882  *
7883  * The formerly free vget_high intrinsics now require a vext (with a few
7884  * exceptions)
7885  *
7886  * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent
7887  * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one
7888  * operand.
7889  *
7890  * The equivalent of the VZIP.32 on the lower and upper halves would be this
7891  * mess:
7892  *
7893  * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] }
7894  * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] }
7895  * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] }
7896  *
7897  * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN):
7898  *
7899  * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32);
7900  * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF);
7901  *
7902  * This is available on ARMv7-A, but is less efficient than a single VZIP.32.
7903  */
7904 
7914 # if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \
7915  && (defined(__GNUC__) || defined(__clang__)) \
7916  && (defined(__arm__) || defined(__thumb__) || defined(_M_ARM))
7917 # define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
7918  do { \
7919  /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \
7920  /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \
7921  /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \
7922  __asm__("vzip.32 %e0, %f0" : "+w" (in)); \
7923  (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \
7924  (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \
7925  } while (0)
7926 # else
7927 # define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
7928  do { \
7929  (outLo) = vmovn_u64 (in); \
7930  (outHi) = vshrn_n_u64 ((in), 32); \
7931  } while (0)
7932 # endif
7933 
7971 # ifndef XXH3_NEON_LANES
7972 # if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \
7973  && !defined(__OPTIMIZE_SIZE__)
7974 # define XXH3_NEON_LANES 6
7975 # else
7976 # define XXH3_NEON_LANES XXH_ACC_NB
7977 # endif
7978 # endif
7979 #endif /* XXH_VECTOR == XXH_NEON */
7980 
7981 /*
7982  * VSX and Z Vector helpers.
7983  *
7984  * This is very messy, and any pull requests to clean this up are welcome.
7985  *
7986  * There are a lot of problems with supporting VSX and s390x, due to
7987  * inconsistent intrinsics, spotty coverage, and multiple endiannesses.
7988  */
7989 #if XXH_VECTOR == XXH_VSX
7990 # if defined(__s390x__)
7991 # include <s390intrin.h>
7992 # else
7993 /* gcc's altivec.h can have the unwanted consequence to unconditionally
7994  * #define bool, vector, and pixel keywords,
7995  * with bad consequences for programs already using these keywords for other purposes.
7996  * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined.
7997  * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler,
7998  * but it seems that, in some cases, it isn't.
7999  * Force the build macro to be defined, so that keywords are not altered.
8000  */
8001 # if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__)
8002 # define __APPLE_ALTIVEC__
8003 # endif
8004 # include <altivec.h>
8005 # endif
8006 
8007 typedef __vector unsigned long long xxh_u64x2;
8008 typedef __vector unsigned char xxh_u8x16;
8009 typedef __vector unsigned xxh_u32x4;
8010 
8011 # ifndef XXH_VSX_BE
8012 # if defined(__BIG_ENDIAN__) \
8013  || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
8014 # define XXH_VSX_BE 1
8015 # elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__
8016 # warning "-maltivec=be is not recommended. Please use native endianness."
8017 # define XXH_VSX_BE 1
8018 # else
8019 # define XXH_VSX_BE 0
8020 # endif
8021 # endif /* !defined(XXH_VSX_BE) */
8022 
8023 # if XXH_VSX_BE
8024 # if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
8025 # define XXH_vec_revb vec_revb
8026 # else
8027 
8030 XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
8031 {
8032  xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
8033  0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
8034  return vec_perm(val, val, vByteSwap);
8035 }
8036 # endif
8037 # endif /* XXH_VSX_BE */
8038 
8042 XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
8043 {
8044  xxh_u64x2 ret;
8045  XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2));
8046 # if XXH_VSX_BE
8047  ret = XXH_vec_revb(ret);
8048 # endif
8049  return ret;
8050 }
8051 
8052 /*
8053  * vec_mulo and vec_mule are very problematic intrinsics on PowerPC
8054  *
8055  * These intrinsics weren't added until GCC 8, despite existing for a while,
8056  * and they are endian dependent. Also, their meaning swap depending on version.
8057  * */
8058 # if defined(__s390x__)
8059  /* s390x is always big endian, no issue on this platform */
8060 # define XXH_vec_mulo vec_mulo
8061 # define XXH_vec_mule vec_mule
8062 # elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw)
8063 /* Clang has a better way to control this, we can just use the builtin which doesn't swap. */
8064 # define XXH_vec_mulo __builtin_altivec_vmulouw
8065 # define XXH_vec_mule __builtin_altivec_vmuleuw
8066 # else
8067 /* gcc needs inline assembly */
8068 /* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */
8069 XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b)
8070 {
8071  xxh_u64x2 result;
8072  __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
8073  return result;
8074 }
8075 XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
8076 {
8077  xxh_u64x2 result;
8078  __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
8079  return result;
8080 }
8081 # endif /* XXH_vec_mulo, XXH_vec_mule */
8082 #endif /* XXH_VECTOR == XXH_VSX */
8083 
8084 
8085 /* prefetch
8086  * can be disabled, by declaring XXH_NO_PREFETCH build macro */
8087 #if defined(XXH_NO_PREFETCH)
8088 # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
8089 #else
8090 # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
8091 # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
8092 # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
8093 # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
8094 # define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
8095 # else
8096 # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
8097 # endif
8098 #endif /* XXH_NO_PREFETCH */
8099 
8100 
8101 /* ==========================================
8102  * XXH3 default settings
8103  * ========================================== */
8104 
8105 #define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
8106 
8107 #if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
8108 # error "default keyset is not large enough"
8109 #endif
8110 
8112 XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
8113  0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
8114  0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
8115  0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
8116  0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
8117  0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
8118  0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
8119  0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
8120  0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
8121  0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
8122  0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
8123  0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
8124  0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
8125 };
8126 
8127 
8128 #ifdef XXH_OLD_NAMES
8129 # define kSecret XXH3_kSecret
8130 #endif
8131 
8132 #ifdef XXH_DOXYGEN
8133 
8150 XXH_mult32to64(xxh_u64 x, xxh_u64 y)
8151 {
8152  return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF);
8153 }
8154 #elif defined(_MSC_VER) && defined(_M_IX86)
8155 # define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y))
8156 #else
8157 /*
8158  * Downcast + upcast is usually better than masking on older compilers like
8159  * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers.
8160  *
8161  * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands
8162  * and perform a full 64x64 multiply -- entirely redundant on 32-bit.
8163  */
8164 # define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y))
8165 #endif
8166 
8176 static XXH128_hash_t
8177 XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
8178 {
8179  /*
8180  * GCC/Clang __uint128_t method.
8181  *
8182  * On most 64-bit targets, GCC and Clang define a __uint128_t type.
8183  * This is usually the best way as it usually uses a native long 64-bit
8184  * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64.
8185  *
8186  * Usually.
8187  *
8188  * Despite being a 32-bit platform, Clang (and emscripten) define this type
8189  * despite not having the arithmetic for it. This results in a laggy
8190  * compiler builtin call which calculates a full 128-bit multiply.
8191  * In that case it is best to use the portable one.
8192  * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677
8193  */
8194 #if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \
8195  && defined(__SIZEOF_INT128__) \
8196  || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
8197 
8198  __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs;
8199  XXH128_hash_t r128;
8200  r128.low64 = (xxh_u64)(product);
8201  r128.high64 = (xxh_u64)(product >> 64);
8202  return r128;
8203 
8204  /*
8205  * MSVC for x64's _umul128 method.
8206  *
8207  * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct);
8208  *
8209  * This compiles to single operand MUL on x64.
8210  */
8211 #elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC)
8212 
8213 #ifndef _MSC_VER
8214 # pragma intrinsic(_umul128)
8215 #endif
8216  xxh_u64 product_high;
8217  xxh_u64 const product_low = _umul128(lhs, rhs, &product_high);
8218  XXH128_hash_t r128;
8219  r128.low64 = product_low;
8220  r128.high64 = product_high;
8221  return r128;
8222 
8223  /*
8224  * MSVC for ARM64's __umulh method.
8225  *
8226  * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method.
8227  */
8228 #elif defined(_M_ARM64) || defined(_M_ARM64EC)
8229 
8230 #ifndef _MSC_VER
8231 # pragma intrinsic(__umulh)
8232 #endif
8233  XXH128_hash_t r128;
8234  r128.low64 = lhs * rhs;
8235  r128.high64 = __umulh(lhs, rhs);
8236  return r128;
8237 
8238 #else
8239  /*
8240  * Portable scalar method. Optimized for 32-bit and 64-bit ALUs.
8241  *
8242  * This is a fast and simple grade school multiply, which is shown below
8243  * with base 10 arithmetic instead of base 0x100000000.
8244  *
8245  * 9 3 // D2 lhs = 93
8246  * x 7 5 // D2 rhs = 75
8247  * ----------
8248  * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15
8249  * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45
8250  * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21
8251  * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63
8252  * ---------
8253  * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27
8254  * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67
8255  * ---------
8256  * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975
8257  *
8258  * The reasons for adding the products like this are:
8259  * 1. It avoids manual carry tracking. Just like how
8260  * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX.
8261  * This avoids a lot of complexity.
8262  *
8263  * 2. It hints for, and on Clang, compiles to, the powerful UMAAL
8264  * instruction available in ARM's Digital Signal Processing extension
8265  * in 32-bit ARMv6 and later, which is shown below:
8266  *
8267  * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm)
8268  * {
8269  * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm;
8270  * *RdLo = (xxh_u32)(product & 0xFFFFFFFF);
8271  * *RdHi = (xxh_u32)(product >> 32);
8272  * }
8273  *
8274  * This instruction was designed for efficient long multiplication, and
8275  * allows this to be calculated in only 4 instructions at speeds
8276  * comparable to some 64-bit ALUs.
8277  *
8278  * 3. It isn't terrible on other platforms. Usually this will be a couple
8279  * of 32-bit ADD/ADCs.
8280  */
8281 
8282  /* First calculate all of the cross products. */
8283  xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
8284  xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
8285  xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
8286  xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32);
8287 
8288  /* Now add the products together. These will never overflow. */
8289  xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
8290  xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
8291  xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
8292 
8293  XXH128_hash_t r128;
8294  r128.low64 = lower;
8295  r128.high64 = upper;
8296  return r128;
8297 #endif
8298 }
8299 
8310 static xxh_u64
8311 XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
8312 {
8313  XXH128_hash_t product = XXH_mult64to128(lhs, rhs);
8314  return product.low64 ^ product.high64;
8315 }
8316 
8318 XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
8319 {
8320  XXH_ASSERT(0 <= shift && shift < 64);
8321  return v64 ^ (v64 >> shift);
8322 }
8323 
8324 /*
8325  * This is a fast avalanche stage,
8326  * suitable when input bits are already partially mixed
8327  */
8328 static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
8329 {
8330  h64 = XXH_xorshift64(h64, 37);
8331  h64 *= 0x165667919E3779F9ULL;
8332  h64 = XXH_xorshift64(h64, 32);
8333  return h64;
8334 }
8335 
8336 /*
8337  * This is a stronger avalanche,
8338  * inspired by Pelle Evensen's rrmxmx
8339  * preferable when input has not been previously mixed
8340  */
8341 static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
8342 {
8343  /* this mix is inspired by Pelle Evensen's rrmxmx */
8344  h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
8345  h64 *= 0x9FB21C651E98DF25ULL;
8346  h64 ^= (h64 >> 35) + len ;
8347  h64 *= 0x9FB21C651E98DF25ULL;
8348  return XXH_xorshift64(h64, 28);
8349 }
8350 
8351 
8352 /* ==========================================
8353  * Short keys
8354  * ==========================================
8355  * One of the shortcomings of XXH32 and XXH64 was that their performance was
8356  * sub-optimal on short lengths. It used an iterative algorithm which strongly
8357  * favored lengths that were a multiple of 4 or 8.
8358  *
8359  * Instead of iterating over individual inputs, we use a set of single shot
8360  * functions which piece together a range of lengths and operate in constant time.
8361  *
8362  * Additionally, the number of multiplies has been significantly reduced. This
8363  * reduces latency, especially when emulating 64-bit multiplies on 32-bit.
8364  *
8365  * Depending on the platform, this may or may not be faster than XXH32, but it
8366  * is almost guaranteed to be faster than XXH64.
8367  */
8368 
8369 /*
8370  * At very short lengths, there isn't enough input to fully hide secrets, or use
8371  * the entire secret.
8372  *
8373  * There is also only a limited amount of mixing we can do before significantly
8374  * impacting performance.
8375  *
8376  * Therefore, we use different sections of the secret and always mix two secret
8377  * samples with an XOR. This should have no effect on performance on the
8378  * seedless or withSeed variants because everything _should_ be constant folded
8379  * by modern compilers.
8380  *
8381  * The XOR mixing hides individual parts of the secret and increases entropy.
8382  *
8383  * This adds an extra layer of strength for custom secrets.
8384  */
8386 XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
8387 {
8388  XXH_ASSERT(input != NULL);
8389  XXH_ASSERT(1 <= len && len <= 3);
8390  XXH_ASSERT(secret != NULL);
8391  /*
8392  * len = 1: combined = { input[0], 0x01, input[0], input[0] }
8393  * len = 2: combined = { input[1], 0x02, input[0], input[1] }
8394  * len = 3: combined = { input[2], 0x03, input[0], input[1] }
8395  */
8396  { xxh_u8 const c1 = input[0];
8397  xxh_u8 const c2 = input[len >> 1];
8398  xxh_u8 const c3 = input[len - 1];
8399  xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24)
8400  | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
8401  xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
8402  xxh_u64 const keyed = (xxh_u64)combined ^ bitflip;
8403  return XXH64_avalanche(keyed);
8404  }
8405 }
8406 
8408 XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
8409 {
8410  XXH_ASSERT(input != NULL);
8411  XXH_ASSERT(secret != NULL);
8412  XXH_ASSERT(4 <= len && len <= 8);
8413  seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
8414  { xxh_u32 const input1 = XXH_readLE32(input);
8415  xxh_u32 const input2 = XXH_readLE32(input + len - 4);
8416  xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed;
8417  xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32);
8418  xxh_u64 const keyed = input64 ^ bitflip;
8419  return XXH3_rrmxmx(keyed, len);
8420  }
8421 }
8422 
8424 XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
8425 {
8426  XXH_ASSERT(input != NULL);
8427  XXH_ASSERT(secret != NULL);
8428  XXH_ASSERT(9 <= len && len <= 16);
8429  { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed;
8430  xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed;
8431  xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1;
8432  xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2;
8433  xxh_u64 const acc = len
8434  + XXH_swap64(input_lo) + input_hi
8435  + XXH3_mul128_fold64(input_lo, input_hi);
8436  return XXH3_avalanche(acc);
8437  }
8438 }
8439 
8441 XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
8442 {
8443  XXH_ASSERT(len <= 16);
8444  { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed);
8445  if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed);
8446  if (len) return XXH3_len_1to3_64b(input, len, secret, seed);
8447  return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64)));
8448  }
8449 }
8450 
8451 /*
8452  * DISCLAIMER: There are known *seed-dependent* multicollisions here due to
8453  * multiplication by zero, affecting hashes of lengths 17 to 240.
8454  *
8455  * However, they are very unlikely.
8456  *
8457  * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all
8458  * unseeded non-cryptographic hashes, it does not attempt to defend itself
8459  * against specially crafted inputs, only random inputs.
8460  *
8461  * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes
8462  * cancelling out the secret is taken an arbitrary number of times (addressed
8463  * in XXH3_accumulate_512), this collision is very unlikely with random inputs
8464  * and/or proper seeding:
8465  *
8466  * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a
8467  * function that is only called up to 16 times per hash with up to 240 bytes of
8468  * input.
8469  *
8470  * This is not too bad for a non-cryptographic hash function, especially with
8471  * only 64 bit outputs.
8472  *
8473  * The 128-bit variant (which trades some speed for strength) is NOT affected
8474  * by this, although it is always a good idea to use a proper seed if you care
8475  * about strength.
8476  */
8477 XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
8478  const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64)
8479 {
8480 #if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
8481  && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \
8482  && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */
8483  /*
8484  * UGLY HACK:
8485  * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in
8486  * slower code.
8487  *
8488  * By forcing seed64 into a register, we disrupt the cost model and
8489  * cause it to scalarize. See `XXH32_round()`
8490  *
8491  * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600,
8492  * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on
8493  * GCC 9.2, despite both emitting scalar code.
8494  *
8495  * GCC generates much better scalar code than Clang for the rest of XXH3,
8496  * which is why finding a more optimal codepath is an interest.
8497  */
8498  XXH_COMPILER_GUARD(seed64);
8499 #endif
8500  { xxh_u64 const input_lo = XXH_readLE64(input);
8501  xxh_u64 const input_hi = XXH_readLE64(input+8);
8502  return XXH3_mul128_fold64(
8503  input_lo ^ (XXH_readLE64(secret) + seed64),
8504  input_hi ^ (XXH_readLE64(secret+8) - seed64)
8505  );
8506  }
8507 }
8508 
8509 /* For mid range keys, XXH3 uses a Mum-hash variant. */
8511 XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
8512  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
8513  XXH64_hash_t seed)
8514 {
8515  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
8516  XXH_ASSERT(16 < len && len <= 128);
8517 
8518  { xxh_u64 acc = len * XXH_PRIME64_1;
8519  if (len > 32) {
8520  if (len > 64) {
8521  if (len > 96) {
8522  acc += XXH3_mix16B(input+48, secret+96, seed);
8523  acc += XXH3_mix16B(input+len-64, secret+112, seed);
8524  }
8525  acc += XXH3_mix16B(input+32, secret+64, seed);
8526  acc += XXH3_mix16B(input+len-48, secret+80, seed);
8527  }
8528  acc += XXH3_mix16B(input+16, secret+32, seed);
8529  acc += XXH3_mix16B(input+len-32, secret+48, seed);
8530  }
8531  acc += XXH3_mix16B(input+0, secret+0, seed);
8532  acc += XXH3_mix16B(input+len-16, secret+16, seed);
8533 
8534  return XXH3_avalanche(acc);
8535  }
8536 }
8537 
8538 #define XXH3_MIDSIZE_MAX 240
8539 
8541 XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
8542  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
8543  XXH64_hash_t seed)
8544 {
8545  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
8546  XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
8547 
8548  #define XXH3_MIDSIZE_STARTOFFSET 3
8549  #define XXH3_MIDSIZE_LASTOFFSET 17
8550 
8551  { xxh_u64 acc = len * XXH_PRIME64_1;
8552  int const nbRounds = (int)len / 16;
8553  int i;
8554  for (i=0; i<8; i++) {
8555  acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed);
8556  }
8557  acc = XXH3_avalanche(acc);
8558  XXH_ASSERT(nbRounds >= 8);
8559 #if defined(__clang__) /* Clang */ \
8560  && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
8561  && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
8562  /*
8563  * UGLY HACK:
8564  * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86.
8565  * In everywhere else, it uses scalar code.
8566  *
8567  * For 64->128-bit multiplies, even if the NEON was 100% optimal, it
8568  * would still be slower than UMAAL (see XXH_mult64to128).
8569  *
8570  * Unfortunately, Clang doesn't handle the long multiplies properly and
8571  * converts them to the nonexistent "vmulq_u64" intrinsic, which is then
8572  * scalarized into an ugly mess of VMOV.32 instructions.
8573  *
8574  * This mess is difficult to avoid without turning autovectorization
8575  * off completely, but they are usually relatively minor and/or not
8576  * worth it to fix.
8577  *
8578  * This loop is the easiest to fix, as unlike XXH32, this pragma
8579  * _actually works_ because it is a loop vectorization instead of an
8580  * SLP vectorization.
8581  */
8582  #pragma clang loop vectorize(disable)
8583 #endif
8584  for (i=8 ; i < nbRounds; i++) {
8585  acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
8586  }
8587  /* last bytes */
8588  acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
8589  return XXH3_avalanche(acc);
8590  }
8591 }
8592 
8593 
8594 /* ======= Long Keys ======= */
8595 
8596 #define XXH_STRIPE_LEN 64
8597 #define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */
8598 #define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64))
8599 
8600 #ifdef XXH_OLD_NAMES
8601 # define STRIPE_LEN XXH_STRIPE_LEN
8602 # define ACC_NB XXH_ACC_NB
8603 #endif
8604 
8605 XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
8606 {
8607  if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
8608  XXH_memcpy(dst, &v64, sizeof(v64));
8609 }
8610 
8611 /* Several intrinsic functions below are supposed to accept __int64 as argument,
8612  * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ .
8613  * However, several environments do not define __int64 type,
8614  * requiring a workaround.
8615  */
8616 #if !defined (__VMS) \
8617  && (defined (__cplusplus) \
8618  || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
8619  typedef int64_t xxh_i64;
8620 #else
8621  /* the following type must have a width of 64-bit */
8622  typedef long long xxh_i64;
8623 #endif
8624 
8625 
8626 /*
8627  * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized.
8628  *
8629  * It is a hardened version of UMAC, based off of FARSH's implementation.
8630  *
8631  * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD
8632  * implementations, and it is ridiculously fast.
8633  *
8634  * We harden it by mixing the original input to the accumulators as well as the product.
8635  *
8636  * This means that in the (relatively likely) case of a multiply by zero, the
8637  * original input is preserved.
8638  *
8639  * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve
8640  * cross-pollination, as otherwise the upper and lower halves would be
8641  * essentially independent.
8642  *
8643  * This doesn't matter on 64-bit hashes since they all get merged together in
8644  * the end, so we skip the extra step.
8645  *
8646  * Both XXH3_64bits and XXH3_128bits use this subroutine.
8647  */
8648 
8649 #if (XXH_VECTOR == XXH_AVX512) \
8650  || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0)
8651 
8652 #ifndef XXH_TARGET_AVX512
8653 # define XXH_TARGET_AVX512 /* disable attribute target */
8654 #endif
8655 
8656 XXH_FORCE_INLINE XXH_TARGET_AVX512 void
8657 XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc,
8658  const void* XXH_RESTRICT input,
8659  const void* XXH_RESTRICT secret)
8660 {
8661  __m512i* const xacc = (__m512i *) acc;
8662  XXH_ASSERT((((size_t)acc) & 63) == 0);
8663  XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
8664 
8665  {
8666  /* data_vec = input[0]; */
8667  __m512i const data_vec = _mm512_loadu_si512 (input);
8668  /* key_vec = secret[0]; */
8669  __m512i const key_vec = _mm512_loadu_si512 (secret);
8670  /* data_key = data_vec ^ key_vec; */
8671  __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
8672  /* data_key_lo = data_key >> 32; */
8673  __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
8674  /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
8675  __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo);
8676  /* xacc[0] += swap(data_vec); */
8677  __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2));
8678  __m512i const sum = _mm512_add_epi64(*xacc, data_swap);
8679  /* xacc[0] += product; */
8680  *xacc = _mm512_add_epi64(product, sum);
8681  }
8682 }
8683 
8684 /*
8685  * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing.
8686  *
8687  * Multiplication isn't perfect, as explained by Google in HighwayHash:
8688  *
8689  * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to
8690  * // varying degrees. In descending order of goodness, bytes
8691  * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32.
8692  * // As expected, the upper and lower bytes are much worse.
8693  *
8694  * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291
8695  *
8696  * Since our algorithm uses a pseudorandom secret to add some variance into the
8697  * mix, we don't need to (or want to) mix as often or as much as HighwayHash does.
8698  *
8699  * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid
8700  * extraction.
8701  *
8702  * Both XXH3_64bits and XXH3_128bits use this subroutine.
8703  */
8704 
8705 XXH_FORCE_INLINE XXH_TARGET_AVX512 void
8706 XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
8707 {
8708  XXH_ASSERT((((size_t)acc) & 63) == 0);
8709  XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
8710  { __m512i* const xacc = (__m512i*) acc;
8711  const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1);
8712 
8713  /* xacc[0] ^= (xacc[0] >> 47) */
8714  __m512i const acc_vec = *xacc;
8715  __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47);
8716  __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted);
8717  /* xacc[0] ^= secret; */
8718  __m512i const key_vec = _mm512_loadu_si512 (secret);
8719  __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
8720 
8721  /* xacc[0] *= XXH_PRIME32_1; */
8722  __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
8723  __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32);
8724  __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32);
8725  *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32));
8726  }
8727 }
8728 
8729 XXH_FORCE_INLINE XXH_TARGET_AVX512 void
8730 XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
8731 {
8732  XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0);
8733  XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64);
8734  XXH_ASSERT(((size_t)customSecret & 63) == 0);
8735  (void)(&XXH_writeLE64);
8736  { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i);
8737  __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64));
8738 
8739  const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret);
8740  __m512i* const dest = ( __m512i*) customSecret;
8741  int i;
8742  XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */
8743  XXH_ASSERT(((size_t)dest & 63) == 0);
8744  for (i=0; i < nbRounds; ++i) {
8745  /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*',
8746  * this will warn "discards 'const' qualifier". */
8747  union {
8748  const __m512i* cp;
8749  void* p;
8750  } remote_const_void;
8751  remote_const_void.cp = src + i;
8752  dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed);
8753  } }
8754 }
8755 
8756 #endif
8757 
8758 #if (XXH_VECTOR == XXH_AVX2) \
8759  || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0)
8760 
8761 #ifndef XXH_TARGET_AVX2
8762 # define XXH_TARGET_AVX2 /* disable attribute target */
8763 #endif
8764 
8765 XXH_FORCE_INLINE XXH_TARGET_AVX2 void
8766 XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc,
8767  const void* XXH_RESTRICT input,
8768  const void* XXH_RESTRICT secret)
8769 {
8770  XXH_ASSERT((((size_t)acc) & 31) == 0);
8771  { __m256i* const xacc = (__m256i *) acc;
8772  /* Unaligned. This is mainly for pointer arithmetic, and because
8773  * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
8774  const __m256i* const xinput = (const __m256i *) input;
8775  /* Unaligned. This is mainly for pointer arithmetic, and because
8776  * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
8777  const __m256i* const xsecret = (const __m256i *) secret;
8778 
8779  size_t i;
8780  for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
8781  /* data_vec = xinput[i]; */
8782  __m256i const data_vec = _mm256_loadu_si256 (xinput+i);
8783  /* key_vec = xsecret[i]; */
8784  __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
8785  /* data_key = data_vec ^ key_vec; */
8786  __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
8787  /* data_key_lo = data_key >> 32; */
8788  __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
8789  /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
8790  __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo);
8791  /* xacc[i] += swap(data_vec); */
8792  __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2));
8793  __m256i const sum = _mm256_add_epi64(xacc[i], data_swap);
8794  /* xacc[i] += product; */
8795  xacc[i] = _mm256_add_epi64(product, sum);
8796  } }
8797 }
8798 
8799 XXH_FORCE_INLINE XXH_TARGET_AVX2 void
8800 XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
8801 {
8802  XXH_ASSERT((((size_t)acc) & 31) == 0);
8803  { __m256i* const xacc = (__m256i*) acc;
8804  /* Unaligned. This is mainly for pointer arithmetic, and because
8805  * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
8806  const __m256i* const xsecret = (const __m256i *) secret;
8807  const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1);
8808 
8809  size_t i;
8810  for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
8811  /* xacc[i] ^= (xacc[i] >> 47) */
8812  __m256i const acc_vec = xacc[i];
8813  __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47);
8814  __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted);
8815  /* xacc[i] ^= xsecret; */
8816  __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
8817  __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
8818 
8819  /* xacc[i] *= XXH_PRIME32_1; */
8820  __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
8821  __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32);
8822  __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32);
8823  xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32));
8824  }
8825  }
8826 }
8827 
8828 XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
8829 {
8830  XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0);
8831  XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6);
8832  XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
8833  (void)(&XXH_writeLE64);
8834  XXH_PREFETCH(customSecret);
8835  { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
8836 
8837  const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret);
8838  __m256i* dest = ( __m256i*) customSecret;
8839 
8840 # if defined(__GNUC__) || defined(__clang__)
8841  /*
8842  * On GCC & Clang, marking 'dest' as modified will cause the compiler:
8843  * - do not extract the secret from sse registers in the internal loop
8844  * - use less common registers, and avoid pushing these reg into stack
8845  */
8847 # endif
8848  XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */
8849  XXH_ASSERT(((size_t)dest & 31) == 0);
8850 
8851  /* GCC -O2 need unroll loop manually */
8852  dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed);
8853  dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed);
8854  dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed);
8855  dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed);
8856  dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed);
8857  dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed);
8858  }
8859 }
8860 
8861 #endif
8862 
8863 /* x86dispatch always generates SSE2 */
8864 #if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH)
8865 
8866 #ifndef XXH_TARGET_SSE2
8867 # define XXH_TARGET_SSE2 /* disable attribute target */
8868 #endif
8869 
8870 XXH_FORCE_INLINE XXH_TARGET_SSE2 void
8871 XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc,
8872  const void* XXH_RESTRICT input,
8873  const void* XXH_RESTRICT secret)
8874 {
8875  /* SSE2 is just a half-scale version of the AVX2 version. */
8876  XXH_ASSERT((((size_t)acc) & 15) == 0);
8877  { __m128i* const xacc = (__m128i *) acc;
8878  /* Unaligned. This is mainly for pointer arithmetic, and because
8879  * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
8880  const __m128i* const xinput = (const __m128i *) input;
8881  /* Unaligned. This is mainly for pointer arithmetic, and because
8882  * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
8883  const __m128i* const xsecret = (const __m128i *) secret;
8884 
8885  size_t i;
8886  for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
8887  /* data_vec = xinput[i]; */
8888  __m128i const data_vec = _mm_loadu_si128 (xinput+i);
8889  /* key_vec = xsecret[i]; */
8890  __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
8891  /* data_key = data_vec ^ key_vec; */
8892  __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
8893  /* data_key_lo = data_key >> 32; */
8894  __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
8895  /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
8896  __m128i const product = _mm_mul_epu32 (data_key, data_key_lo);
8897  /* xacc[i] += swap(data_vec); */
8898  __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2));
8899  __m128i const sum = _mm_add_epi64(xacc[i], data_swap);
8900  /* xacc[i] += product; */
8901  xacc[i] = _mm_add_epi64(product, sum);
8902  } }
8903 }
8904 
8905 XXH_FORCE_INLINE XXH_TARGET_SSE2 void
8906 XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
8907 {
8908  XXH_ASSERT((((size_t)acc) & 15) == 0);
8909  { __m128i* const xacc = (__m128i*) acc;
8910  /* Unaligned. This is mainly for pointer arithmetic, and because
8911  * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
8912  const __m128i* const xsecret = (const __m128i *) secret;
8913  const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1);
8914 
8915  size_t i;
8916  for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
8917  /* xacc[i] ^= (xacc[i] >> 47) */
8918  __m128i const acc_vec = xacc[i];
8919  __m128i const shifted = _mm_srli_epi64 (acc_vec, 47);
8920  __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted);
8921  /* xacc[i] ^= xsecret[i]; */
8922  __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
8923  __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
8924 
8925  /* xacc[i] *= XXH_PRIME32_1; */
8926  __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
8927  __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32);
8928  __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32);
8929  xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32));
8930  }
8931  }
8932 }
8933 
8934 XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
8935 {
8936  XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
8937  (void)(&XXH_writeLE64);
8938  { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i);
8939 
8940 # if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
8941  /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
8942  XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
8943  __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
8944 # else
8945  __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
8946 # endif
8947  int i;
8948 
8949  const void* const src16 = XXH3_kSecret;
8950  __m128i* dst16 = (__m128i*) customSecret;
8951 # if defined(__GNUC__) || defined(__clang__)
8952  /*
8953  * On GCC & Clang, marking 'dest' as modified will cause the compiler:
8954  * - do not extract the secret from sse registers in the internal loop
8955  * - use less common registers, and avoid pushing these reg into stack
8956  */
8957  XXH_COMPILER_GUARD(dst16);
8958 # endif
8959  XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */
8960  XXH_ASSERT(((size_t)dst16 & 15) == 0);
8961 
8962  for (i=0; i < nbRounds; ++i) {
8963  dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed);
8964  } }
8965 }
8966 
8967 #endif
8968 
8969 #if (XXH_VECTOR == XXH_NEON)
8970 
8971 /* forward declarations for the scalar routines */
8972 XXH_FORCE_INLINE void
8973 XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input,
8974  void const* XXH_RESTRICT secret, size_t lane);
8975 
8976 XXH_FORCE_INLINE void
8977 XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
8978  void const* XXH_RESTRICT secret, size_t lane);
8979 
8990 XXH_FORCE_INLINE void
8991 XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
8992  const void* XXH_RESTRICT input,
8993  const void* XXH_RESTRICT secret)
8994 {
8995  XXH_ASSERT((((size_t)acc) & 15) == 0);
8996  XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0);
8997  {
8998  uint64x2_t* const xacc = (uint64x2_t *) acc;
8999  /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
9000  uint8_t const* const xinput = (const uint8_t *) input;
9001  uint8_t const* const xsecret = (const uint8_t *) secret;
9002 
9003  size_t i;
9004  /* NEON for the first few lanes (these loops are normally interleaved) */
9005  for (i=0; i < XXH3_NEON_LANES / 2; i++) {
9006  /* data_vec = xinput[i]; */
9007  uint8x16_t data_vec = vld1q_u8(xinput + (i * 16));
9008  /* key_vec = xsecret[i]; */
9009  uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16));
9010  uint64x2_t data_key;
9011  uint32x2_t data_key_lo, data_key_hi;
9012  /* xacc[i] += swap(data_vec); */
9013  uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec);
9014  uint64x2_t const swapped = vextq_u64(data64, data64, 1);
9015  xacc[i] = vaddq_u64 (xacc[i], swapped);
9016  /* data_key = data_vec ^ key_vec; */
9017  data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec));
9018  /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF);
9019  * data_key_hi = (uint32x2_t) (data_key >> 32);
9020  * data_key = UNDEFINED; */
9021  XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
9022  /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */
9023  xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi);
9024 
9025  }
9026  /* Scalar for the remainder. This may be a zero iteration loop. */
9027  for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
9028  XXH3_scalarRound(acc, input, secret, i);
9029  }
9030  }
9031 }
9032 
9033 XXH_FORCE_INLINE void
9034 XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
9035 {
9036  XXH_ASSERT((((size_t)acc) & 15) == 0);
9037 
9038  { uint64x2_t* xacc = (uint64x2_t*) acc;
9039  uint8_t const* xsecret = (uint8_t const*) secret;
9040  uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1);
9041 
9042  size_t i;
9043  /* NEON for the first few lanes (these loops are normally interleaved) */
9044  for (i=0; i < XXH3_NEON_LANES / 2; i++) {
9045  /* xacc[i] ^= (xacc[i] >> 47); */
9046  uint64x2_t acc_vec = xacc[i];
9047  uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47);
9048  uint64x2_t data_vec = veorq_u64 (acc_vec, shifted);
9049 
9050  /* xacc[i] ^= xsecret[i]; */
9051  uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16));
9052  uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec));
9053 
9054  /* xacc[i] *= XXH_PRIME32_1 */
9055  uint32x2_t data_key_lo, data_key_hi;
9056  /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF);
9057  * data_key_hi = (uint32x2_t) (xacc[i] >> 32);
9058  * xacc[i] = UNDEFINED; */
9059  XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
9060  { /*
9061  * prod_hi = (data_key >> 32) * XXH_PRIME32_1;
9062  *
9063  * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will
9064  * incorrectly "optimize" this:
9065  * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b));
9066  * shifted = vshll_n_u32(tmp, 32);
9067  * to this:
9068  * tmp = "vmulq_u64"(a, b); // no such thing!
9069  * shifted = vshlq_n_u64(tmp, 32);
9070  *
9071  * However, unlike SSE, Clang lacks a 64-bit multiply routine
9072  * for NEON, and it scalarizes two 64-bit multiplies instead.
9073  *
9074  * vmull_u32 has the same timing as vmul_u32, and it avoids
9075  * this bug completely.
9076  * See https://bugs.llvm.org/show_bug.cgi?id=39967
9077  */
9078  uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime);
9079  /* xacc[i] = prod_hi << 32; */
9080  xacc[i] = vshlq_n_u64(prod_hi, 32);
9081  /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */
9082  xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime);
9083  }
9084  }
9085  /* Scalar for the remainder. This may be a zero iteration loop. */
9086  for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
9087  XXH3_scalarScrambleRound(acc, secret, i);
9088  }
9089  }
9090 }
9091 
9092 #endif
9093 
9094 #if (XXH_VECTOR == XXH_VSX)
9095 
9096 XXH_FORCE_INLINE void
9097 XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
9098  const void* XXH_RESTRICT input,
9099  const void* XXH_RESTRICT secret)
9100 {
9101  /* presumed aligned */
9102  unsigned int* const xacc = (unsigned int*) acc;
9103  xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */
9104  xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */
9105  xxh_u64x2 const v32 = { 32, 32 };
9106  size_t i;
9107  for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
9108  /* data_vec = xinput[i]; */
9109  xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i);
9110  /* key_vec = xsecret[i]; */
9111  xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
9112  xxh_u64x2 const data_key = data_vec ^ key_vec;
9113  /* shuffled = (data_key << 32) | (data_key >> 32); */
9114  xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
9115  /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */
9116  xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
9117  /* acc_vec = xacc[i]; */
9118  xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i);
9119  acc_vec += product;
9120 
9121  /* swap high and low halves */
9122 #ifdef __s390x__
9123  acc_vec += vec_permi(data_vec, data_vec, 2);
9124 #else
9125  acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
9126 #endif
9127  /* xacc[i] = acc_vec; */
9128  vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i);
9129  }
9130 }
9131 
9132 XXH_FORCE_INLINE void
9133 XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
9134 {
9135  XXH_ASSERT((((size_t)acc) & 15) == 0);
9136 
9137  { xxh_u64x2* const xacc = (xxh_u64x2*) acc;
9138  const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret;
9139  /* constants */
9140  xxh_u64x2 const v32 = { 32, 32 };
9141  xxh_u64x2 const v47 = { 47, 47 };
9142  xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 };
9143  size_t i;
9144  for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
9145  /* xacc[i] ^= (xacc[i] >> 47); */
9146  xxh_u64x2 const acc_vec = xacc[i];
9147  xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47);
9148 
9149  /* xacc[i] ^= xsecret[i]; */
9150  xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
9151  xxh_u64x2 const data_key = data_vec ^ key_vec;
9152 
9153  /* xacc[i] *= XXH_PRIME32_1 */
9154  /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */
9155  xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime);
9156  /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */
9157  xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime);
9158  xacc[i] = prod_odd + (prod_even << v32);
9159  } }
9160 }
9161 
9162 #endif
9163 
9164 /* scalar variants - universal */
9165 
9173 XXH_FORCE_INLINE void
9174 XXH3_scalarRound(void* XXH_RESTRICT acc,
9175  void const* XXH_RESTRICT input,
9176  void const* XXH_RESTRICT secret,
9177  size_t lane)
9178 {
9179  xxh_u64* xacc = (xxh_u64*) acc;
9180  xxh_u8 const* xinput = (xxh_u8 const*) input;
9181  xxh_u8 const* xsecret = (xxh_u8 const*) secret;
9182  XXH_ASSERT(lane < XXH_ACC_NB);
9183  XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0);
9184  {
9185  xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8);
9186  xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8);
9187  xacc[lane ^ 1] += data_val; /* swap adjacent lanes */
9188  xacc[lane] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32);
9189  }
9190 }
9191 
9196 XXH_FORCE_INLINE void
9197 XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
9198  const void* XXH_RESTRICT input,
9199  const void* XXH_RESTRICT secret)
9200 {
9201  size_t i;
9202  for (i=0; i < XXH_ACC_NB; i++) {
9203  XXH3_scalarRound(acc, input, secret, i);
9204  }
9205 }
9206 
9214 XXH_FORCE_INLINE void
9215 XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
9216  void const* XXH_RESTRICT secret,
9217  size_t lane)
9218 {
9219  xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
9220  const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
9221  XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
9222  XXH_ASSERT(lane < XXH_ACC_NB);
9223  {
9224  xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8);
9225  xxh_u64 acc64 = xacc[lane];
9226  acc64 = XXH_xorshift64(acc64, 47);
9227  acc64 ^= key64;
9228  acc64 *= XXH_PRIME32_1;
9229  xacc[lane] = acc64;
9230  }
9231 }
9232 
9237 XXH_FORCE_INLINE void
9238 XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
9239 {
9240  size_t i;
9241  for (i=0; i < XXH_ACC_NB; i++) {
9242  XXH3_scalarScrambleRound(acc, secret, i);
9243  }
9244 }
9245 
9246 XXH_FORCE_INLINE void
9247 XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
9248 {
9249  /*
9250  * We need a separate pointer for the hack below,
9251  * which requires a non-const pointer.
9252  * Any decent compiler will optimize this out otherwise.
9253  */
9254  const xxh_u8* kSecretPtr = XXH3_kSecret;
9255  XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
9256 
9257 #if defined(__clang__) && defined(__aarch64__)
9258  /*
9259  * UGLY HACK:
9260  * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are
9261  * placed sequentially, in order, at the top of the unrolled loop.
9262  *
9263  * While MOVK is great for generating constants (2 cycles for a 64-bit
9264  * constant compared to 4 cycles for LDR), it fights for bandwidth with
9265  * the arithmetic instructions.
9266  *
9267  * I L S
9268  * MOVK
9269  * MOVK
9270  * MOVK
9271  * MOVK
9272  * ADD
9273  * SUB STR
9274  * STR
9275  * By forcing loads from memory (as the asm line causes Clang to assume
9276  * that XXH3_kSecretPtr has been changed), the pipelines are used more
9277  * efficiently:
9278  * I L S
9279  * LDR
9280  * ADD LDR
9281  * SUB STR
9282  * STR
9283  *
9284  * See XXH3_NEON_LANES for details on the pipsline.
9285  *
9286  * XXH3_64bits_withSeed, len == 256, Snapdragon 835
9287  * without hack: 2654.4 MB/s
9288  * with hack: 3202.9 MB/s
9289  */
9290  XXH_COMPILER_GUARD(kSecretPtr);
9291 #endif
9292  /*
9293  * Note: in debug mode, this overrides the asm optimization
9294  * and Clang will emit MOVK chains again.
9295  */
9296  XXH_ASSERT(kSecretPtr == XXH3_kSecret);
9297 
9298  { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16;
9299  int i;
9300  for (i=0; i < nbRounds; i++) {
9301  /*
9302  * The asm hack causes Clang to assume that kSecretPtr aliases with
9303  * customSecret, and on aarch64, this prevented LDP from merging two
9304  * loads together for free. Putting the loads together before the stores
9305  * properly generates LDP.
9306  */
9307  xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64;
9308  xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64;
9309  XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo);
9310  XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi);
9311  } }
9312 }
9313 
9314 
9315 typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*);
9316 typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*);
9317 typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
9318 
9319 
9320 #if (XXH_VECTOR == XXH_AVX512)
9321 
9322 #define XXH3_accumulate_512 XXH3_accumulate_512_avx512
9323 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx512
9324 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx512
9325 
9326 #elif (XXH_VECTOR == XXH_AVX2)
9327 
9328 #define XXH3_accumulate_512 XXH3_accumulate_512_avx2
9329 #define XXH3_scrambleAcc XXH3_scrambleAcc_avx2
9330 #define XXH3_initCustomSecret XXH3_initCustomSecret_avx2
9331 
9332 #elif (XXH_VECTOR == XXH_SSE2)
9333 
9334 #define XXH3_accumulate_512 XXH3_accumulate_512_sse2
9335 #define XXH3_scrambleAcc XXH3_scrambleAcc_sse2
9336 #define XXH3_initCustomSecret XXH3_initCustomSecret_sse2
9337 
9338 #elif (XXH_VECTOR == XXH_NEON)
9339 
9340 #define XXH3_accumulate_512 XXH3_accumulate_512_neon
9341 #define XXH3_scrambleAcc XXH3_scrambleAcc_neon
9342 #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
9343 
9344 #elif (XXH_VECTOR == XXH_VSX)
9345 
9346 #define XXH3_accumulate_512 XXH3_accumulate_512_vsx
9347 #define XXH3_scrambleAcc XXH3_scrambleAcc_vsx
9348 #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
9349 
9350 #else /* scalar */
9351 
9352 #define XXH3_accumulate_512 XXH3_accumulate_512_scalar
9353 #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
9354 #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
9355 
9356 #endif
9357 
9358 
9359 
9360 #ifndef XXH_PREFETCH_DIST
9361 # ifdef __clang__
9362 # define XXH_PREFETCH_DIST 320
9363 # else
9364 # if (XXH_VECTOR == XXH_AVX512)
9365 # define XXH_PREFETCH_DIST 512
9366 # else
9367 # define XXH_PREFETCH_DIST 384
9368 # endif
9369 # endif /* __clang__ */
9370 #endif /* XXH_PREFETCH_DIST */
9371 
9372 /*
9373  * XXH3_accumulate()
9374  * Loops over XXH3_accumulate_512().
9375  * Assumption: nbStripes will not overflow the secret size
9376  */
9377 XXH_FORCE_INLINE void
9378 XXH3_accumulate( xxh_u64* XXH_RESTRICT acc,
9379  const xxh_u8* XXH_RESTRICT input,
9380  const xxh_u8* XXH_RESTRICT secret,
9381  size_t nbStripes,
9382  XXH3_f_accumulate_512 f_acc512)
9383 {
9384  size_t n;
9385  for (n = 0; n < nbStripes; n++ ) {
9386  const xxh_u8* const in = input + n*XXH_STRIPE_LEN;
9387  XXH_PREFETCH(in + XXH_PREFETCH_DIST);
9388  f_acc512(acc,
9389  in,
9390  secret + n*XXH_SECRET_CONSUME_RATE);
9391  }
9392 }
9393 
9394 XXH_FORCE_INLINE void
9395 XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc,
9396  const xxh_u8* XXH_RESTRICT input, size_t len,
9397  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
9398  XXH3_f_accumulate_512 f_acc512,
9399  XXH3_f_scrambleAcc f_scramble)
9400 {
9401  size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE;
9402  size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock;
9403  size_t const nb_blocks = (len - 1) / block_len;
9404 
9405  size_t n;
9406 
9407  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
9408 
9409  for (n = 0; n < nb_blocks; n++) {
9410  XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512);
9411  f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN);
9412  }
9413 
9414  /* last partial block */
9415  XXH_ASSERT(len > XXH_STRIPE_LEN);
9416  { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN;
9417  XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE));
9418  XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512);
9419 
9420  /* last stripe */
9421  { const xxh_u8* const p = input + len - XXH_STRIPE_LEN;
9422 #define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */
9423  f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START);
9424  } }
9425 }
9426 
9428 XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret)
9429 {
9430  return XXH3_mul128_fold64(
9431  acc[0] ^ XXH_readLE64(secret),
9432  acc[1] ^ XXH_readLE64(secret+8) );
9433 }
9434 
9435 static XXH64_hash_t
9436 XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start)
9437 {
9438  xxh_u64 result64 = start;
9439  size_t i = 0;
9440 
9441  for (i = 0; i < 4; i++) {
9442  result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i);
9443 #if defined(__clang__) /* Clang */ \
9444  && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \
9445  && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
9446  && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
9447  /*
9448  * UGLY HACK:
9449  * Prevent autovectorization on Clang ARMv7-a. Exact same problem as
9450  * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b.
9451  * XXH3_64bits, len == 256, Snapdragon 835:
9452  * without hack: 2063.7 MB/s
9453  * with hack: 2560.7 MB/s
9454  */
9455  XXH_COMPILER_GUARD(result64);
9456 #endif
9457  }
9458 
9459  return XXH3_avalanche(result64);
9460 }
9461 
9462 #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
9463  XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
9464 
9466 XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
9467  const void* XXH_RESTRICT secret, size_t secretSize,
9468  XXH3_f_accumulate_512 f_acc512,
9469  XXH3_f_scrambleAcc f_scramble)
9470 {
9471  XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
9472 
9473  XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble);
9474 
9475  /* converge into final hash */
9476  XXH_STATIC_ASSERT(sizeof(acc) == 64);
9477  /* do not align on 8, so that the secret is different from the accumulator */
9478 #define XXH_SECRET_MERGEACCS_START 11
9479  XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
9480  return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1);
9481 }
9482 
9483 /*
9484  * It's important for performance to transmit secret's size (when it's static)
9485  * so that the compiler can properly optimize the vectorized loop.
9486  * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set.
9487  */
9489 XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
9490  XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
9491 {
9492  (void)seed64;
9493  return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc);
9494 }
9495 
9496 /*
9497  * It's preferable for performance that XXH3_hashLong is not inlined,
9498  * as it results in a smaller function for small data, easier to the instruction cache.
9499  * Note that inside this no_inline function, we do inline the internal loop,
9500  * and provide a statically defined secret size to allow optimization of vector loop.
9501  */
9503 XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
9504  XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
9505 {
9506  (void)seed64; (void)secret; (void)secretLen;
9507  return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc);
9508 }
9509 
9510 /*
9511  * XXH3_hashLong_64b_withSeed():
9512  * Generate a custom key based on alteration of default XXH3_kSecret with the seed,
9513  * and then use this key for long mode hashing.
9514  *
9515  * This operation is decently fast but nonetheless costs a little bit of time.
9516  * Try to avoid it whenever possible (typically when seed==0).
9517  *
9518  * It's important for performance that XXH3_hashLong is not inlined. Not sure
9519  * why (uop cache maybe?), but the difference is large and easily measurable.
9520  */
9522 XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len,
9523  XXH64_hash_t seed,
9524  XXH3_f_accumulate_512 f_acc512,
9525  XXH3_f_scrambleAcc f_scramble,
9526  XXH3_f_initCustomSecret f_initSec)
9527 {
9528  if (seed == 0)
9529  return XXH3_hashLong_64b_internal(input, len,
9530  XXH3_kSecret, sizeof(XXH3_kSecret),
9531  f_acc512, f_scramble);
9532  { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
9533  f_initSec(secret, seed);
9534  return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret),
9535  f_acc512, f_scramble);
9536  }
9537 }
9538 
9539 /*
9540  * It's important for performance that XXH3_hashLong is not inlined.
9541  */
9543 XXH3_hashLong_64b_withSeed(const void* input, size_t len,
9544  XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen)
9545 {
9546  (void)secret; (void)secretLen;
9547  return XXH3_hashLong_64b_withSeed_internal(input, len, seed,
9548  XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
9549 }
9550 
9551 
9552 typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t,
9553  XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t);
9554 
9556 XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
9557  XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
9558  XXH3_hashLong64_f f_hashLong)
9559 {
9560  XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
9561  /*
9562  * If an action is to be taken if `secretLen` condition is not respected,
9563  * it should be done here.
9564  * For now, it's a contract pre-condition.
9565  * Adding a check and a branch here would cost performance at every hash.
9566  * Also, note that function signature doesn't offer room to return an error.
9567  */
9568  if (len <= 16)
9569  return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
9570  if (len <= 128)
9571  return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
9572  if (len <= XXH3_MIDSIZE_MAX)
9573  return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
9574  return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen);
9575 }
9576 
9577 
9578 /* === Public entry point === */
9579 
9581 XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len)
9582 {
9583  return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
9584 }
9585 
9588 XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
9589 {
9590  return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
9591 }
9592 
9595 XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
9596 {
9597  return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
9598 }
9599 
9601 XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
9602 {
9603  if (len <= XXH3_MIDSIZE_MAX)
9604  return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
9605  return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
9606 }
9607 
9608 
9609 /* === XXH3 streaming === */
9610 
9611 /*
9612  * Malloc's a pointer that is always aligned to align.
9613  *
9614  * This must be freed with `XXH_alignedFree()`.
9615  *
9616  * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte
9617  * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2
9618  * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON.
9619  *
9620  * This underalignment previously caused a rather obvious crash which went
9621  * completely unnoticed due to XXH3_createState() not actually being tested.
9622  * Credit to RedSpah for noticing this bug.
9623  *
9624  * The alignment is done manually: Functions like posix_memalign or _mm_malloc
9625  * are avoided: To maintain portability, we would have to write a fallback
9626  * like this anyways, and besides, testing for the existence of library
9627  * functions without relying on external build tools is impossible.
9628  *
9629  * The method is simple: Overallocate, manually align, and store the offset
9630  * to the original behind the returned pointer.
9631  *
9632  * Align must be a power of 2 and 8 <= align <= 128.
9633  */
9634 static void* XXH_alignedMalloc(size_t s, size_t align)
9635 {
9636  XXH_ASSERT(align <= 128 && align >= 8); /* range check */
9637  XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
9638  XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */
9639  { /* Overallocate to make room for manual realignment and an offset byte */
9640  xxh_u8* base = (xxh_u8*)XXH_malloc(s + align);
9641  if (base != NULL) {
9642  /*
9643  * Get the offset needed to align this pointer.
9644  *
9645  * Even if the returned pointer is aligned, there will always be
9646  * at least one byte to store the offset to the original pointer.
9647  */
9648  size_t offset = align - ((size_t)base & (align - 1)); /* base % align */
9649  /* Add the offset for the now-aligned pointer */
9650  xxh_u8* ptr = base + offset;
9651 
9652  XXH_ASSERT((size_t)ptr % align == 0);
9653 
9654  /* Store the offset immediately before the returned pointer. */
9655  ptr[-1] = (xxh_u8)offset;
9656  return ptr;
9657  }
9658  return NULL;
9659  }
9660 }
9661 /*
9662  * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass
9663  * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout.
9664  */
9665 static void XXH_alignedFree(void* p)
9666 {
9667  if (p != NULL) {
9668  xxh_u8* ptr = (xxh_u8*)p;
9669  /* Get the offset byte we added in XXH_malloc. */
9670  xxh_u8 offset = ptr[-1];
9671  /* Free the original malloc'd pointer */
9672  xxh_u8* base = ptr - offset;
9673  XXH_free(base);
9674  }
9675 }
9678 {
9679  XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
9680  if (state==NULL) return NULL;
9681  XXH3_INITSTATE(state);
9682  return state;
9683 }
9684 
9687 {
9688  XXH_alignedFree(statePtr);
9689  return XXH_OK;
9690 }
9691 
9693 XXH_PUBLIC_API void
9694 XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
9695 {
9696  XXH_memcpy(dst_state, src_state, sizeof(*dst_state));
9697 }
9698 
9699 static void
9700 XXH3_reset_internal(XXH3_state_t* statePtr,
9701  XXH64_hash_t seed,
9702  const void* secret, size_t secretSize)
9703 {
9704  size_t const initStart = offsetof(XXH3_state_t, bufferedSize);
9705  size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart;
9706  XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart);
9707  XXH_ASSERT(statePtr != NULL);
9708  /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */
9709  memset((char*)statePtr + initStart, 0, initLength);
9710  statePtr->acc[0] = XXH_PRIME32_3;
9711  statePtr->acc[1] = XXH_PRIME64_1;
9712  statePtr->acc[2] = XXH_PRIME64_2;
9713  statePtr->acc[3] = XXH_PRIME64_3;
9714  statePtr->acc[4] = XXH_PRIME64_4;
9715  statePtr->acc[5] = XXH_PRIME32_2;
9716  statePtr->acc[6] = XXH_PRIME64_5;
9717  statePtr->acc[7] = XXH_PRIME32_1;
9718  statePtr->seed = seed;
9719  statePtr->useSeed = (seed != 0);
9720  statePtr->extSecret = (const unsigned char*)secret;
9721  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
9722  statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
9723  statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
9724 }
9725 
9729 {
9730  if (statePtr == NULL) return XXH_ERROR;
9731  XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
9732  return XXH_OK;
9733 }
9734 
9737 XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
9738 {
9739  if (statePtr == NULL) return XXH_ERROR;
9740  XXH3_reset_internal(statePtr, 0, secret, secretSize);
9741  if (secret == NULL) return XXH_ERROR;
9742  if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
9743  return XXH_OK;
9744 }
9745 
9749 {
9750  if (statePtr == NULL) return XXH_ERROR;
9751  if (seed==0) return XXH3_64bits_reset(statePtr);
9752  if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
9753  XXH3_initCustomSecret(statePtr->customSecret, seed);
9754  XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
9755  return XXH_OK;
9756 }
9757 
9760 XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
9761 {
9762  if (statePtr == NULL) return XXH_ERROR;
9763  if (secret == NULL) return XXH_ERROR;
9764  if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
9765  XXH3_reset_internal(statePtr, seed64, secret, secretSize);
9766  statePtr->useSeed = 1; /* always, even if seed64==0 */
9767  return XXH_OK;
9768 }
9769 
9770 /* Note : when XXH3_consumeStripes() is invoked,
9771  * there must be a guarantee that at least one more byte must be consumed from input
9772  * so that the function can blindly consume all stripes using the "normal" secret segment */
9773 XXH_FORCE_INLINE void
9774 XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
9775  size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock,
9776  const xxh_u8* XXH_RESTRICT input, size_t nbStripes,
9777  const xxh_u8* XXH_RESTRICT secret, size_t secretLimit,
9778  XXH3_f_accumulate_512 f_acc512,
9779  XXH3_f_scrambleAcc f_scramble)
9780 {
9781  XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */
9782  XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock);
9783  if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) {
9784  /* need a scrambling operation */
9785  size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr;
9786  size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock;
9787  XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512);
9788  f_scramble(acc, secret + secretLimit);
9789  XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512);
9790  *nbStripesSoFarPtr = nbStripesAfterBlock;
9791  } else {
9792  XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512);
9793  *nbStripesSoFarPtr += nbStripes;
9794  }
9795 }
9796 
9797 #ifndef XXH3_STREAM_USE_STACK
9798 # ifndef __clang__ /* clang doesn't need additional stack space */
9799 # define XXH3_STREAM_USE_STACK 1
9800 # endif
9801 #endif
9802 /*
9803  * Both XXH3_64bits_update and XXH3_128bits_update use this routine.
9804  */
9806 XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
9807  const xxh_u8* XXH_RESTRICT input, size_t len,
9808  XXH3_f_accumulate_512 f_acc512,
9809  XXH3_f_scrambleAcc f_scramble)
9810 {
9811  if (input==NULL) {
9812  XXH_ASSERT(len == 0);
9813  return XXH_OK;
9814  }
9815 
9816  XXH_ASSERT(state != NULL);
9817  { const xxh_u8* const bEnd = input + len;
9818  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
9819 #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
9820  /* For some reason, gcc and MSVC seem to suffer greatly
9821  * when operating accumulators directly into state.
9822  * Operating into stack space seems to enable proper optimization.
9823  * clang, on the other hand, doesn't seem to need this trick */
9824  XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc));
9825 #else
9826  xxh_u64* XXH_RESTRICT const acc = state->acc;
9827 #endif
9828  state->totalLen += len;
9829  XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
9830 
9831  /* small input : just fill in tmp buffer */
9832  if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) {
9833  XXH_memcpy(state->buffer + state->bufferedSize, input, len);
9834  state->bufferedSize += (XXH32_hash_t)len;
9835  return XXH_OK;
9836  }
9837 
9838  /* total input is now > XXH3_INTERNALBUFFER_SIZE */
9839  #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
9840  XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */
9841 
9842  /*
9843  * Internal buffer is partially filled (always, except at beginning)
9844  * Complete it, then consume it.
9845  */
9846  if (state->bufferedSize) {
9847  size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
9848  XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize);
9849  input += loadSize;
9850  XXH3_consumeStripes(acc,
9851  &state->nbStripesSoFar, state->nbStripesPerBlock,
9852  state->buffer, XXH3_INTERNALBUFFER_STRIPES,
9853  secret, state->secretLimit,
9854  f_acc512, f_scramble);
9855  state->bufferedSize = 0;
9856  }
9857  XXH_ASSERT(input < bEnd);
9858 
9859  /* large input to consume : ingest per full block */
9860  if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) {
9861  size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN;
9862  XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar);
9863  /* join to current block's end */
9864  { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar;
9865  XXH_ASSERT(nbStripesToEnd <= nbStripes);
9866  XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512);
9867  f_scramble(acc, secret + state->secretLimit);
9868  state->nbStripesSoFar = 0;
9869  input += nbStripesToEnd * XXH_STRIPE_LEN;
9870  nbStripes -= nbStripesToEnd;
9871  }
9872  /* consume per entire blocks */
9873  while(nbStripes >= state->nbStripesPerBlock) {
9874  XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512);
9875  f_scramble(acc, secret + state->secretLimit);
9876  input += state->nbStripesPerBlock * XXH_STRIPE_LEN;
9877  nbStripes -= state->nbStripesPerBlock;
9878  }
9879  /* consume last partial block */
9880  XXH3_accumulate(acc, input, secret, nbStripes, f_acc512);
9881  input += nbStripes * XXH_STRIPE_LEN;
9882  XXH_ASSERT(input < bEnd); /* at least some bytes left */
9883  state->nbStripesSoFar = nbStripes;
9884  /* buffer predecessor of last partial stripe */
9885  XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
9886  XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN);
9887  } else {
9888  /* content to consume <= block size */
9889  /* Consume input by a multiple of internal buffer size */
9890  if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) {
9891  const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
9892  do {
9893  XXH3_consumeStripes(acc,
9894  &state->nbStripesSoFar, state->nbStripesPerBlock,
9895  input, XXH3_INTERNALBUFFER_STRIPES,
9896  secret, state->secretLimit,
9897  f_acc512, f_scramble);
9898  input += XXH3_INTERNALBUFFER_SIZE;
9899  } while (input<limit);
9900  /* buffer predecessor of last partial stripe */
9901  XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
9902  }
9903  }
9904 
9905  /* Some remaining input (always) : buffer it */
9906  XXH_ASSERT(input < bEnd);
9907  XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE);
9908  XXH_ASSERT(state->bufferedSize == 0);
9909  XXH_memcpy(state->buffer, input, (size_t)(bEnd-input));
9910  state->bufferedSize = (XXH32_hash_t)(bEnd-input);
9911 #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
9912  /* save stack accumulators into state */
9913  memcpy(state->acc, acc, sizeof(acc));
9914 #endif
9915  }
9916 
9917  return XXH_OK;
9918 }
9919 
9922 XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
9923 {
9924  return XXH3_update(state, (const xxh_u8*)input, len,
9925  XXH3_accumulate_512, XXH3_scrambleAcc);
9926 }
9927 
9928 
9929 XXH_FORCE_INLINE void
9930 XXH3_digest_long (XXH64_hash_t* acc,
9931  const XXH3_state_t* state,
9932  const unsigned char* secret)
9933 {
9934  /*
9935  * Digest on a local copy. This way, the state remains unaltered, and it can
9936  * continue ingesting more input afterwards.
9937  */
9938  XXH_memcpy(acc, state->acc, sizeof(state->acc));
9939  if (state->bufferedSize >= XXH_STRIPE_LEN) {
9940  size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
9941  size_t nbStripesSoFar = state->nbStripesSoFar;
9942  XXH3_consumeStripes(acc,
9943  &nbStripesSoFar, state->nbStripesPerBlock,
9944  state->buffer, nbStripes,
9945  secret, state->secretLimit,
9946  XXH3_accumulate_512, XXH3_scrambleAcc);
9947  /* last stripe */
9948  XXH3_accumulate_512(acc,
9949  state->buffer + state->bufferedSize - XXH_STRIPE_LEN,
9950  secret + state->secretLimit - XXH_SECRET_LASTACC_START);
9951  } else { /* bufferedSize < XXH_STRIPE_LEN */
9952  xxh_u8 lastStripe[XXH_STRIPE_LEN];
9953  size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
9954  XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */
9955  XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
9956  XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
9957  XXH3_accumulate_512(acc,
9958  lastStripe,
9959  secret + state->secretLimit - XXH_SECRET_LASTACC_START);
9960  }
9961 }
9962 
9965 {
9966  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
9967  if (state->totalLen > XXH3_MIDSIZE_MAX) {
9968  XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
9969  XXH3_digest_long(acc, state, secret);
9970  return XXH3_mergeAccs(acc,
9971  secret + XXH_SECRET_MERGEACCS_START,
9972  (xxh_u64)state->totalLen * XXH_PRIME64_1);
9973  }
9974  /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
9975  if (state->useSeed)
9976  return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
9977  return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
9978  secret, state->secretLimit + XXH_STRIPE_LEN);
9979 }
9980 
9981 
9982 
9983 /* ==========================================
9984  * XXH3 128 bits (a.k.a XXH128)
9985  * ==========================================
9986  * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
9987  * even without counting the significantly larger output size.
9988  *
9989  * For example, extra steps are taken to avoid the seed-dependent collisions
9990  * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
9991  *
9992  * This strength naturally comes at the cost of some speed, especially on short
9993  * lengths. Note that longer hashes are about as fast as the 64-bit version
9994  * due to it using only a slight modification of the 64-bit loop.
9995  *
9996  * XXH128 is also more oriented towards 64-bit machines. It is still extremely
9997  * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
9998  */
9999 
10001 XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
10002 {
10003  /* A doubled version of 1to3_64b with different constants. */
10004  XXH_ASSERT(input != NULL);
10005  XXH_ASSERT(1 <= len && len <= 3);
10006  XXH_ASSERT(secret != NULL);
10007  /*
10008  * len = 1: combinedl = { input[0], 0x01, input[0], input[0] }
10009  * len = 2: combinedl = { input[1], 0x02, input[0], input[1] }
10010  * len = 3: combinedl = { input[2], 0x03, input[0], input[1] }
10011  */
10012  { xxh_u8 const c1 = input[0];
10013  xxh_u8 const c2 = input[len >> 1];
10014  xxh_u8 const c3 = input[len - 1];
10015  xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24)
10016  | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
10017  xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13);
10018  xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
10019  xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed;
10020  xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl;
10021  xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph;
10022  XXH128_hash_t h128;
10023  h128.low64 = XXH64_avalanche(keyed_lo);
10024  h128.high64 = XXH64_avalanche(keyed_hi);
10025  return h128;
10026  }
10027 }
10028 
10030 XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
10031 {
10032  XXH_ASSERT(input != NULL);
10033  XXH_ASSERT(secret != NULL);
10034  XXH_ASSERT(4 <= len && len <= 8);
10035  seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
10036  { xxh_u32 const input_lo = XXH_readLE32(input);
10037  xxh_u32 const input_hi = XXH_readLE32(input + len - 4);
10038  xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32);
10039  xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed;
10040  xxh_u64 const keyed = input_64 ^ bitflip;
10041 
10042  /* Shift len to the left to ensure it is even, this avoids even multiplies. */
10043  XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2));
10044 
10045  m128.high64 += (m128.low64 << 1);
10046  m128.low64 ^= (m128.high64 >> 3);
10047 
10048  m128.low64 = XXH_xorshift64(m128.low64, 35);
10049  m128.low64 *= 0x9FB21C651E98DF25ULL;
10050  m128.low64 = XXH_xorshift64(m128.low64, 28);
10051  m128.high64 = XXH3_avalanche(m128.high64);
10052  return m128;
10053  }
10054 }
10055 
10057 XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
10058 {
10059  XXH_ASSERT(input != NULL);
10060  XXH_ASSERT(secret != NULL);
10061  XXH_ASSERT(9 <= len && len <= 16);
10062  { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed;
10063  xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed;
10064  xxh_u64 const input_lo = XXH_readLE64(input);
10065  xxh_u64 input_hi = XXH_readLE64(input + len - 8);
10066  XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1);
10067  /*
10068  * Put len in the middle of m128 to ensure that the length gets mixed to
10069  * both the low and high bits in the 128x64 multiply below.
10070  */
10071  m128.low64 += (xxh_u64)(len - 1) << 54;
10072  input_hi ^= bitfliph;
10073  /*
10074  * Add the high 32 bits of input_hi to the high 32 bits of m128, then
10075  * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to
10076  * the high 64 bits of m128.
10077  *
10078  * The best approach to this operation is different on 32-bit and 64-bit.
10079  */
10080  if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */
10081  /*
10082  * 32-bit optimized version, which is more readable.
10083  *
10084  * On 32-bit, it removes an ADC and delays a dependency between the two
10085  * halves of m128.high64, but it generates an extra mask on 64-bit.
10086  */
10087  m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2);
10088  } else {
10089  /*
10090  * 64-bit optimized (albeit more confusing) version.
10091  *
10092  * Uses some properties of addition and multiplication to remove the mask:
10093  *
10094  * Let:
10095  * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
10096  * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
10097  * c = XXH_PRIME32_2
10098  *
10099  * a + (b * c)
10100  * Inverse Property: x + y - x == y
10101  * a + (b * (1 + c - 1))
10102  * Distributive Property: x * (y + z) == (x * y) + (x * z)
10103  * a + (b * 1) + (b * (c - 1))
10104  * Identity Property: x * 1 == x
10105  * a + b + (b * (c - 1))
10106  *
10107  * Substitute a, b, and c:
10108  * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
10109  *
10110  * Since input_hi.hi + input_hi.lo == input_hi, we get this:
10111  * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
10112  */
10113  m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1);
10114  }
10115  /* m128 ^= XXH_swap64(m128 >> 64); */
10116  m128.low64 ^= XXH_swap64(m128.high64);
10117 
10118  { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
10119  XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2);
10120  h128.high64 += m128.high64 * XXH_PRIME64_2;
10121 
10122  h128.low64 = XXH3_avalanche(h128.low64);
10123  h128.high64 = XXH3_avalanche(h128.high64);
10124  return h128;
10125  } }
10126 }
10127 
10128 /*
10129  * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
10130  */
10132 XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
10133 {
10134  XXH_ASSERT(len <= 16);
10135  { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed);
10136  if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed);
10137  if (len) return XXH3_len_1to3_128b(input, len, secret, seed);
10138  { XXH128_hash_t h128;
10139  xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72);
10140  xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88);
10141  h128.low64 = XXH64_avalanche(seed ^ bitflipl);
10142  h128.high64 = XXH64_avalanche( seed ^ bitfliph);
10143  return h128;
10144  } }
10145 }
10146 
10147 /*
10148  * A bit slower than XXH3_mix16B, but handles multiply by zero better.
10149  */
10151 XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
10152  const xxh_u8* secret, XXH64_hash_t seed)
10153 {
10154  acc.low64 += XXH3_mix16B (input_1, secret+0, seed);
10155  acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8);
10156  acc.high64 += XXH3_mix16B (input_2, secret+16, seed);
10157  acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8);
10158  return acc;
10159 }
10160 
10161 
10163 XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
10164  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
10165  XXH64_hash_t seed)
10166 {
10167  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
10168  XXH_ASSERT(16 < len && len <= 128);
10169 
10170  { XXH128_hash_t acc;
10171  acc.low64 = len * XXH_PRIME64_1;
10172  acc.high64 = 0;
10173  if (len > 32) {
10174  if (len > 64) {
10175  if (len > 96) {
10176  acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed);
10177  }
10178  acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed);
10179  }
10180  acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed);
10181  }
10182  acc = XXH128_mix32B(acc, input, input+len-16, secret, seed);
10183  { XXH128_hash_t h128;
10184  h128.low64 = acc.low64 + acc.high64;
10185  h128.high64 = (acc.low64 * XXH_PRIME64_1)
10186  + (acc.high64 * XXH_PRIME64_4)
10187  + ((len - seed) * XXH_PRIME64_2);
10188  h128.low64 = XXH3_avalanche(h128.low64);
10189  h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
10190  return h128;
10191  }
10192  }
10193 }
10194 
10196 XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
10197  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
10198  XXH64_hash_t seed)
10199 {
10200  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
10201  XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
10202 
10203  { XXH128_hash_t acc;
10204  int const nbRounds = (int)len / 32;
10205  int i;
10206  acc.low64 = len * XXH_PRIME64_1;
10207  acc.high64 = 0;
10208  for (i=0; i<4; i++) {
10209  acc = XXH128_mix32B(acc,
10210  input + (32 * i),
10211  input + (32 * i) + 16,
10212  secret + (32 * i),
10213  seed);
10214  }
10215  acc.low64 = XXH3_avalanche(acc.low64);
10216  acc.high64 = XXH3_avalanche(acc.high64);
10217  XXH_ASSERT(nbRounds >= 4);
10218  for (i=4 ; i < nbRounds; i++) {
10219  acc = XXH128_mix32B(acc,
10220  input + (32 * i),
10221  input + (32 * i) + 16,
10222  secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)),
10223  seed);
10224  }
10225  /* last bytes */
10226  acc = XXH128_mix32B(acc,
10227  input + len - 16,
10228  input + len - 32,
10229  secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16,
10230  0ULL - seed);
10231 
10232  { XXH128_hash_t h128;
10233  h128.low64 = acc.low64 + acc.high64;
10234  h128.high64 = (acc.low64 * XXH_PRIME64_1)
10235  + (acc.high64 * XXH_PRIME64_4)
10236  + ((len - seed) * XXH_PRIME64_2);
10237  h128.low64 = XXH3_avalanche(h128.low64);
10238  h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
10239  return h128;
10240  }
10241  }
10242 }
10243 
10245 XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
10246  const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
10247  XXH3_f_accumulate_512 f_acc512,
10248  XXH3_f_scrambleAcc f_scramble)
10249 {
10250  XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
10251 
10252  XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble);
10253 
10254  /* converge into final hash */
10255  XXH_STATIC_ASSERT(sizeof(acc) == 64);
10256  XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
10257  { XXH128_hash_t h128;
10258  h128.low64 = XXH3_mergeAccs(acc,
10259  secret + XXH_SECRET_MERGEACCS_START,
10260  (xxh_u64)len * XXH_PRIME64_1);
10261  h128.high64 = XXH3_mergeAccs(acc,
10262  secret + secretSize
10263  - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
10264  ~((xxh_u64)len * XXH_PRIME64_2));
10265  return h128;
10266  }
10267 }
10268 
10269 /*
10270  * It's important for performance that XXH3_hashLong is not inlined.
10271  */
10273 XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
10274  XXH64_hash_t seed64,
10275  const void* XXH_RESTRICT secret, size_t secretLen)
10276 {
10277  (void)seed64; (void)secret; (void)secretLen;
10278  return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret),
10279  XXH3_accumulate_512, XXH3_scrambleAcc);
10280 }
10281 
10282 /*
10283  * It's important for performance to pass @secretLen (when it's static)
10284  * to the compiler, so that it can properly optimize the vectorized loop.
10285  */
10287 XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len,
10288  XXH64_hash_t seed64,
10289  const void* XXH_RESTRICT secret, size_t secretLen)
10290 {
10291  (void)seed64;
10292  return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen,
10293  XXH3_accumulate_512, XXH3_scrambleAcc);
10294 }
10295 
10297 XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len,
10298  XXH64_hash_t seed64,
10299  XXH3_f_accumulate_512 f_acc512,
10300  XXH3_f_scrambleAcc f_scramble,
10301  XXH3_f_initCustomSecret f_initSec)
10302 {
10303  if (seed64 == 0)
10304  return XXH3_hashLong_128b_internal(input, len,
10305  XXH3_kSecret, sizeof(XXH3_kSecret),
10306  f_acc512, f_scramble);
10307  { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
10308  f_initSec(secret, seed64);
10309  return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret),
10310  f_acc512, f_scramble);
10311  }
10312 }
10313 
10314 /*
10315  * It's important for performance that XXH3_hashLong is not inlined.
10316  */
10318 XXH3_hashLong_128b_withSeed(const void* input, size_t len,
10319  XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen)
10320 {
10321  (void)secret; (void)secretLen;
10322  return XXH3_hashLong_128b_withSeed_internal(input, len, seed64,
10323  XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
10324 }
10325 
10326 typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t,
10327  XXH64_hash_t, const void* XXH_RESTRICT, size_t);
10328 
10330 XXH3_128bits_internal(const void* input, size_t len,
10331  XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
10332  XXH3_hashLong128_f f_hl128)
10333 {
10334  XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
10335  /*
10336  * If an action is to be taken if `secret` conditions are not respected,
10337  * it should be done here.
10338  * For now, it's a contract pre-condition.
10339  * Adding a check and a branch here would cost performance at every hash.
10340  */
10341  if (len <= 16)
10342  return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
10343  if (len <= 128)
10344  return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
10345  if (len <= XXH3_MIDSIZE_MAX)
10346  return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
10347  return f_hl128(input, len, seed64, secret, secretLen);
10348 }
10349 
10350 
10351 /* === Public XXH128 API === */
10352 
10354 XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
10355 {
10356  return XXH3_128bits_internal(input, len, 0,
10357  XXH3_kSecret, sizeof(XXH3_kSecret),
10358  XXH3_hashLong_128b_default);
10359 }
10360 
10363 XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
10364 {
10365  return XXH3_128bits_internal(input, len, 0,
10366  (const xxh_u8*)secret, secretSize,
10367  XXH3_hashLong_128b_withSecret);
10368 }
10369 
10372 XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
10373 {
10374  return XXH3_128bits_internal(input, len, seed,
10375  XXH3_kSecret, sizeof(XXH3_kSecret),
10376  XXH3_hashLong_128b_withSeed);
10377 }
10378 
10381 XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
10382 {
10383  if (len <= XXH3_MIDSIZE_MAX)
10384  return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
10385  return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
10386 }
10387 
10390 XXH128(const void* input, size_t len, XXH64_hash_t seed)
10391 {
10392  return XXH3_128bits_withSeed(input, len, seed);
10393 }
10394 
10395 
10396 /* === XXH3 128-bit streaming === */
10397 
10398 /*
10399  * All initialization and update functions are identical to 64-bit streaming variant.
10400  * The only difference is the finalization routine.
10401  */
10402 
10406 {
10407  return XXH3_64bits_reset(statePtr);
10408 }
10409 
10412 XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
10413 {
10414  return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
10415 }
10416 
10420 {
10421  return XXH3_64bits_reset_withSeed(statePtr, seed);
10422 }
10423 
10426 XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
10427 {
10428  return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
10429 }
10430 
10433 XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
10434 {
10435  return XXH3_update(state, (const xxh_u8*)input, len,
10436  XXH3_accumulate_512, XXH3_scrambleAcc);
10437 }
10438 
10441 {
10442  const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
10443  if (state->totalLen > XXH3_MIDSIZE_MAX) {
10444  XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
10445  XXH3_digest_long(acc, state, secret);
10446  XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
10447  { XXH128_hash_t h128;
10448  h128.low64 = XXH3_mergeAccs(acc,
10449  secret + XXH_SECRET_MERGEACCS_START,
10450  (xxh_u64)state->totalLen * XXH_PRIME64_1);
10451  h128.high64 = XXH3_mergeAccs(acc,
10452  secret + state->secretLimit + XXH_STRIPE_LEN
10453  - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
10454  ~((xxh_u64)state->totalLen * XXH_PRIME64_2));
10455  return h128;
10456  }
10457  }
10458  /* len <= XXH3_MIDSIZE_MAX : short code */
10459  if (state->seed)
10460  return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
10461  return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
10462  secret, state->secretLimit + XXH_STRIPE_LEN);
10463 }
10464 
10465 /* 128-bit utility functions */
10466 
10467 #include <string.h> /* memcmp, memcpy */
10468 
10469 /* return : 1 is equal, 0 if different */
10472 {
10473  /* note : XXH128_hash_t is compact, it has no padding byte */
10474  return !(memcmp(&h1, &h2, sizeof(h1)));
10475 }
10476 
10477 /* This prototype is compatible with stdlib's qsort().
10478  * return : >0 if *h128_1 > *h128_2
10479  * <0 if *h128_1 < *h128_2
10480  * =0 if *h128_1 == *h128_2 */
10482 XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
10483 {
10484  XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
10485  XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2;
10486  int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64);
10487  /* note : bets that, in most cases, hash values are different */
10488  if (hcmp) return hcmp;
10489  return (h1.low64 > h2.low64) - (h2.low64 > h1.low64);
10490 }
10491 
10492 
10493 /*====== Canonical representation ======*/
10495 XXH_PUBLIC_API void
10497 {
10499  if (XXH_CPU_LITTLE_ENDIAN) {
10500  hash.high64 = XXH_swap64(hash.high64);
10501  hash.low64 = XXH_swap64(hash.low64);
10502  }
10503  XXH_memcpy(dst, &hash.high64, sizeof(hash.high64));
10504  XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
10505 }
10506 
10510 {
10511  XXH128_hash_t h;
10512  h.high64 = XXH_readBE64(src);
10513  h.low64 = XXH_readBE64(src->digest + 8);
10514  return h;
10515 }
10516 
10517 
10518 
10519 /* ==========================================
10520  * Secret generators
10521  * ==========================================
10522  */
10523 #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
10524 
10525 XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
10526 {
10527  XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 );
10528  XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
10529 }
10530 
10533 XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
10534 {
10535 #if (XXH_DEBUGLEVEL >= 1)
10536  XXH_ASSERT(secretBuffer != NULL);
10537  XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
10538 #else
10539  /* production mode, assert() are disabled */
10540  if (secretBuffer == NULL) return XXH_ERROR;
10541  if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
10542 #endif
10543 
10544  if (customSeedSize == 0) {
10545  customSeed = XXH3_kSecret;
10546  customSeedSize = XXH_SECRET_DEFAULT_SIZE;
10547  }
10548 #if (XXH_DEBUGLEVEL >= 1)
10549  XXH_ASSERT(customSeed != NULL);
10550 #else
10551  if (customSeed == NULL) return XXH_ERROR;
10552 #endif
10553 
10554  /* Fill secretBuffer with a copy of customSeed - repeat as needed */
10555  { size_t pos = 0;
10556  while (pos < secretSize) {
10557  size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
10558  memcpy((char*)secretBuffer + pos, customSeed, toCopy);
10559  pos += toCopy;
10560  } }
10561 
10562  { size_t const nbSeg16 = secretSize / 16;
10563  size_t n;
10564  XXH128_canonical_t scrambler;
10565  XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
10566  for (n=0; n<nbSeg16; n++) {
10567  XXH128_hash_t const h128 = XXH128(&scrambler, sizeof(scrambler), n);
10568  XXH3_combine16((char*)secretBuffer + n*16, h128);
10569  }
10570  /* last segment */
10571  XXH3_combine16((char*)secretBuffer + secretSize - 16, XXH128_hashFromCanonical(&scrambler));
10572  }
10573  return XXH_OK;
10574 }
10575 
10577 XXH_PUBLIC_API void
10578 XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
10579 {
10580  XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
10581  XXH3_initCustomSecret(secret, seed);
10582  XXH_ASSERT(secretBuffer != NULL);
10583  memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
10584 }
10585 
10586 
10587 
10588 /* Pop our optimization override from above */
10589 #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
10590  && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
10591  && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
10592 # pragma GCC pop_options
10593 #endif
10594 
10595 #endif /* XXH_NO_LONG_LONG */
10596 
10597 #endif /* XXH_NO_XXH3 */
10598 
10602 #endif /* XXH_IMPLEMENTATION */
10603 
10604 
10605 #if defined (__cplusplus)
10606 }
10607 #endif
10608 /**** ended inlining xxhash.h ****/
10609 #ifndef ZSTD_NO_TRACE
10610 /**** start inlining zstd_trace.h ****/
10611 /*
10612  * Copyright (c) Meta Platforms, Inc. and affiliates.
10613  * All rights reserved.
10614  *
10615  * This source code is licensed under both the BSD-style license (found in the
10616  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
10617  * in the COPYING file in the root directory of this source tree).
10618  * You may select, at your option, one of the above-listed licenses.
10619  */
10620 
10621 #ifndef ZSTD_TRACE_H
10622 #define ZSTD_TRACE_H
10623 
10624 #if defined (__cplusplus)
10625 extern "C" {
10626 #endif
10627 
10628 #include <stddef.h>
10629 
10630 /* weak symbol support
10631  * For now, enable conservatively:
10632  * - Only GNUC
10633  * - Only ELF
10634  * - Only x86-64, i386 and aarch64
10635  * Also, explicitly disable on platforms known not to work so they aren't
10636  * forgotten in the future.
10637  */
10638 #if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \
10639  defined(__GNUC__) && defined(__ELF__) && \
10640  (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) || defined(__aarch64__)) && \
10641  !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \
10642  !defined(__CYGWIN__) && !defined(_AIX)
10643 # define ZSTD_HAVE_WEAK_SYMBOLS 1
10644 #else
10645 # define ZSTD_HAVE_WEAK_SYMBOLS 0
10646 #endif
10647 #if ZSTD_HAVE_WEAK_SYMBOLS
10648 # define ZSTD_WEAK_ATTR __attribute__((__weak__))
10649 #else
10650 # define ZSTD_WEAK_ATTR
10651 #endif
10652 
10653 /* Only enable tracing when weak symbols are available. */
10654 #ifndef ZSTD_TRACE
10655 # define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS
10656 #endif
10657 
10658 #if ZSTD_TRACE
10659 
10660 struct ZSTD_CCtx_s;
10661 struct ZSTD_DCtx_s;
10662 struct ZSTD_CCtx_params_s;
10663 
10664 typedef struct {
10673  unsigned version;
10677  unsigned streaming;
10681  unsigned dictionaryID;
10686  unsigned dictionaryIsCold;
10690  size_t dictionarySize;
10694  size_t uncompressedSize;
10698  size_t compressedSize;
10702  struct ZSTD_CCtx_params_s const* params;
10706  struct ZSTD_CCtx_s const* cctx;
10710  struct ZSTD_DCtx_s const* dctx;
10711 } ZSTD_Trace;
10712 
10727 typedef unsigned long long ZSTD_TraceCtx;
10728 
10736 ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin(
10737  struct ZSTD_CCtx_s const* cctx);
10738 
10744 ZSTD_WEAK_ATTR void ZSTD_trace_compress_end(
10745  ZSTD_TraceCtx ctx,
10746  ZSTD_Trace const* trace);
10747 
10755 ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin(
10756  struct ZSTD_DCtx_s const* dctx);
10757 
10763 ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end(
10764  ZSTD_TraceCtx ctx,
10765  ZSTD_Trace const* trace);
10766 
10767 #endif /* ZSTD_TRACE */
10768 
10769 #if defined (__cplusplus)
10770 }
10771 #endif
10772 
10773 #endif /* ZSTD_TRACE_H */
10774 /**** ended inlining zstd_trace.h ****/
10775 #else
10776 # define ZSTD_TRACE 0
10777 #endif
10778 
10779 #if defined (__cplusplus)
10780 extern "C" {
10781 #endif
10782 
10783 /* ---- static assert (debug) --- */
10784 #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
10785 #define ZSTD_isError ERR_isError /* for inlining */
10786 #define FSE_isError ERR_isError
10787 #define HUF_isError ERR_isError
10788 
10789 
10790 /*-*************************************
10791 * shared macros
10792 ***************************************/
10793 #undef MIN
10794 #undef MAX
10795 #define MIN(a,b) ((a)<(b) ? (a) : (b))
10796 #define MAX(a,b) ((a)>(b) ? (a) : (b))
10797 #define BOUNDED(min,val,max) (MAX(min,MIN(val,max)))
10798 
10799 
10800 /*-*************************************
10801 * Common constants
10802 ***************************************/
10803 #define ZSTD_OPT_NUM (1<<12)
10804 
10805 #define ZSTD_REP_NUM 3 /* number of repcodes */
10806 static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
10807 
10808 #define KB *(1 <<10)
10809 #define MB *(1 <<20)
10810 #define GB *(1U<<30)
10811 
10812 #define BIT7 128
10813 #define BIT6 64
10814 #define BIT5 32
10815 #define BIT4 16
10816 #define BIT1 2
10817 #define BIT0 1
10818 
10819 #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
10820 static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
10821 static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
10822 
10823 #define ZSTD_FRAMEIDSIZE 4 /* magic number size */
10824 
10825 #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
10828 
10829 #define ZSTD_FRAMECHECKSUMSIZE 4
10830 
10831 #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
10832 #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */
10833 #define MIN_LITERALS_FOR_4_STREAMS 6
10834 
10836 
10837 #define LONGNBSEQ 0x7F00
10838 
10839 #define MINMATCH 3
10840 
10841 #define Litbits 8
10842 #define LitHufLog 11
10843 #define MaxLit ((1<<Litbits) - 1)
10844 #define MaxML 52
10845 #define MaxLL 35
10846 #define DefaultMaxOff 28
10847 #define MaxOff 31
10848 #define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
10849 #define MLFSELog 9
10850 #define LLFSELog 9
10851 #define OffFSELog 8
10852 #define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
10853 #define MaxMLBits 16
10854 #define MaxLLBits 16
10855 
10856 #define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */
10857 /* Each table cannot take more than #symbols * FSELog bits */
10858 #define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8)
10859 
10860 static UNUSED_ATTR const U8 LL_bits[MaxLL+1] = {
10861  0, 0, 0, 0, 0, 0, 0, 0,
10862  0, 0, 0, 0, 0, 0, 0, 0,
10863  1, 1, 1, 1, 2, 2, 3, 3,
10864  4, 6, 7, 8, 9,10,11,12,
10865  13,14,15,16
10866 };
10868  4, 3, 2, 2, 2, 2, 2, 2,
10869  2, 2, 2, 2, 2, 1, 1, 1,
10870  2, 2, 2, 2, 2, 2, 2, 2,
10871  2, 3, 2, 1, 1, 1, 1, 1,
10872  -1,-1,-1,-1
10873 };
10874 #define LL_DEFAULTNORMLOG 6 /* for static allocation */
10876 
10877 static UNUSED_ATTR const U8 ML_bits[MaxML+1] = {
10878  0, 0, 0, 0, 0, 0, 0, 0,
10879  0, 0, 0, 0, 0, 0, 0, 0,
10880  0, 0, 0, 0, 0, 0, 0, 0,
10881  0, 0, 0, 0, 0, 0, 0, 0,
10882  1, 1, 1, 1, 2, 2, 3, 3,
10883  4, 4, 5, 7, 8, 9,10,11,
10884  12,13,14,15,16
10885 };
10887  1, 4, 3, 2, 2, 2, 2, 2,
10888  2, 1, 1, 1, 1, 1, 1, 1,
10889  1, 1, 1, 1, 1, 1, 1, 1,
10890  1, 1, 1, 1, 1, 1, 1, 1,
10891  1, 1, 1, 1, 1, 1, 1, 1,
10892  1, 1, 1, 1, 1, 1,-1,-1,
10893  -1,-1,-1,-1,-1
10894 };
10895 #define ML_DEFAULTNORMLOG 6 /* for static allocation */
10897 
10899  1, 1, 1, 1, 1, 1, 2, 2,
10900  2, 1, 1, 1, 1, 1, 1, 1,
10901  1, 1, 1, 1, 1, 1, 1, 1,
10902  -1,-1,-1,-1,-1
10903 };
10904 #define OF_DEFAULTNORMLOG 5 /* for static allocation */
10906 
10907 
10908 /*-*******************************************
10909 * Shared functions to include for inlining
10910 *********************************************/
10911 static void ZSTD_copy8(void* dst, const void* src) {
10912 #if defined(ZSTD_ARCH_ARM_NEON)
10913  vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
10914 #else
10915  ZSTD_memcpy(dst, src, 8);
10916 #endif
10917 }
10918 #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
10919 
10920 /* Need to use memmove here since the literal buffer can now be located within
10921  the dst buffer. In circumstances where the op "catches up" to where the
10922  literal buffer is, there can be partial overlaps in this call on the final
10923  copy if the literal is being shifted by less than 16 bytes. */
10924 static void ZSTD_copy16(void* dst, const void* src) {
10925 #if defined(ZSTD_ARCH_ARM_NEON)
10926  vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
10927 #elif defined(ZSTD_ARCH_X86_SSE2)
10928  _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
10929 #elif defined(__clang__)
10930  ZSTD_memmove(dst, src, 16);
10931 #else
10932  /* ZSTD_memmove is not inlined properly by gcc */
10933  BYTE copy16_buf[16];
10934  ZSTD_memcpy(copy16_buf, src, 16);
10935  ZSTD_memcpy(dst, copy16_buf, 16);
10936 #endif
10937 }
10938 #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
10939 
10940 #define WILDCOPY_OVERLENGTH 32
10941 #define WILDCOPY_VECLEN 16
10942 
10943 typedef enum {
10946  /* ZSTD_overlap_dst_before_src, */
10947 } ZSTD_overlap_e;
10948 
10957 void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
10958 {
10959  ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
10960  const BYTE* ip = (const BYTE*)src;
10961  BYTE* op = (BYTE*)dst;
10962  BYTE* const oend = op + length;
10963 
10964  if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
10965  /* Handle short offset copies. */
10966  do {
10967  COPY8(op, ip)
10968  } while (op < oend);
10969  } else {
10970  assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
10971  /* Separate out the first COPY16() call because the copy length is
10972  * almost certain to be short, so the branches have different
10973  * probabilities. Since it is almost certain to be short, only do
10974  * one COPY16() in the first call. Then, do two calls per loop since
10975  * at that point it is more likely to have a high trip count.
10976  */
10977  ZSTD_copy16(op, ip);
10978  if (16 >= length) return;
10979  op += 16;
10980  ip += 16;
10981  do {
10982  COPY16(op, ip);
10983  COPY16(op, ip);
10984  }
10985  while (op < oend);
10986  }
10987 }
10988 
10989 MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
10990 {
10991  size_t const length = MIN(dstCapacity, srcSize);
10992  if (length > 0) {
10993  ZSTD_memcpy(dst, src, length);
10994  }
10995  return length;
10996 }
10997 
10998 /* define "workspace is too large" as this number of times larger than needed */
10999 #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
11000 
11001 /* when workspace is continuously too large
11002  * during at least this number of times,
11003  * context's memory usage is considered wasteful,
11004  * because it's sized to handle a worst case scenario which rarely happens.
11005  * In which case, resize it down to free some memory */
11006 #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
11007 
11008 /* Controls whether the input/output buffer is buffered or stable. */
11009 typedef enum {
11010  ZSTD_bm_buffered = 0, /* Buffer the input/output */
11011  ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */
11013 
11014 
11015 /*-*******************************************
11016 * Private declarations
11017 *********************************************/
11018 typedef struct seqDef_s {
11019  U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
11021  U16 mlBase; /* mlBase == matchLength - MINMATCH */
11022 } seqDef;
11023 
11024 /* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
11025 typedef enum {
11026  ZSTD_llt_none = 0, /* no longLengthType */
11027  ZSTD_llt_literalLength = 1, /* represents a long literal */
11028  ZSTD_llt_matchLength = 2 /* represents a long match */
11030 
11031 typedef struct {
11033  seqDef* sequences; /* ptr to end of sequences */
11035  BYTE* lit; /* ptr to end of literals */
11039  size_t maxNbSeq;
11040  size_t maxNbLit;
11041 
11042  /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
11043  * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
11044  * the existing value of the litLength or matchLength by 0x10000.
11045  */
11047  U32 longLengthPos; /* Index of the sequence to apply long length modification to */
11048 } seqStore_t;
11049 
11050 typedef struct {
11054 
11060 {
11061  ZSTD_sequenceLength seqLen;
11062  seqLen.litLength = seq->litLength;
11063  seqLen.matchLength = seq->mlBase + MINMATCH;
11064  if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
11065  if (seqStore->longLengthType == ZSTD_llt_literalLength) {
11066  seqLen.litLength += 0x10000;
11067  }
11068  if (seqStore->longLengthType == ZSTD_llt_matchLength) {
11069  seqLen.matchLength += 0x10000;
11070  }
11071  }
11072  return seqLen;
11073 }
11074 
11081 typedef struct {
11082  size_t nbBlocks;
11084  unsigned long long decompressedBound;
11085 } ZSTD_frameSizeInfo; /* decompress & legacy */
11086 
11087 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
11088 int ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
11089 
11090 
11091 /* ZSTD_invalidateRepCodes() :
11092  * ensures next compression will not use repcodes from previous block.
11093  * Note : only works with regular variant;
11094  * do not use with extDict variant ! */
11095 void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
11096 
11097 
11098 typedef struct {
11102 } blockProperties_t; /* declared here for decompress and fullbench */
11103 
11106 /* Used by: decompress, fullbench (does not get its definition from here) */
11107 size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
11108  blockProperties_t* bpPtr);
11109 
11112 /* Used by: decompress, fullbench (does not get its definition from here) */
11113 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
11114  const void* src, size_t srcSize);
11115 
11120 {
11121  ZSTD_cpuid_t cpuid = ZSTD_cpuid();
11122  return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);
11123 }
11124 
11125 #if defined (__cplusplus)
11126 }
11127 #endif
11128 
11129 #endif /* ZSTD_CCOMMON_H_MODULE */
11130 /**** ended inlining zstd_internal.h ****/
11131 
11132 
11133 /*-****************************************
11134 * Version
11135 ******************************************/
11136 unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; }
11137 
11138 const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }
11139 
11140 
11141 /*-****************************************
11142 * ZSTD Error Management
11143 ******************************************/
11144 #undef ZSTD_isError /* defined within zstd_internal.h */
11145 
11148 unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
11149 
11152 const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
11153 
11156 ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
11157 
11160 const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); }
11161 /**** ended inlining common/zstd_common.c ****/
11162 
11163 /**** start inlining compress/fse_compress.c ****/
11164 /* ******************************************************************
11165  * FSE : Finite State Entropy encoder
11166  * Copyright (c) Meta Platforms, Inc. and affiliates.
11167  *
11168  * You can contact the author at :
11169  * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
11170  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
11171  *
11172  * This source code is licensed under both the BSD-style license (found in the
11173  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11174  * in the COPYING file in the root directory of this source tree).
11175  * You may select, at your option, one of the above-listed licenses.
11176 ****************************************************************** */
11177 
11178 /* **************************************************************
11179 * Includes
11180 ****************************************************************/
11181 /**** skipping file: ../common/compiler.h ****/
11182 /**** skipping file: ../common/mem.h ****/
11183 /**** skipping file: ../common/debug.h ****/
11184 /**** start inlining hist.h ****/
11185 /* ******************************************************************
11186  * hist : Histogram functions
11187  * part of Finite State Entropy project
11188  * Copyright (c) Meta Platforms, Inc. and affiliates.
11189  *
11190  * You can contact the author at :
11191  * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
11192  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
11193  *
11194  * This source code is licensed under both the BSD-style license (found in the
11195  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11196  * in the COPYING file in the root directory of this source tree).
11197  * You may select, at your option, one of the above-listed licenses.
11198 ****************************************************************** */
11199 
11200 /* --- dependencies --- */
11201 /**** skipping file: ../common/zstd_deps.h ****/
11202 
11203 
11204 /* --- simple histogram functions --- */
11205 
11214 size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
11215  const void* src, size_t srcSize);
11216 
11217 unsigned HIST_isError(size_t code);
11220 /* --- advanced histogram functions --- */
11221 
11222 #define HIST_WKSP_SIZE_U32 1024
11223 #define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
11224 
11230 size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
11231  const void* src, size_t srcSize,
11232  void* workSpace, size_t workSpaceSize);
11233 
11238 size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
11239  const void* src, size_t srcSize);
11240 
11246 size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
11247  const void* src, size_t srcSize,
11248  void* workSpace, size_t workSpaceSize);
11249 
11258 unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
11259  const void* src, size_t srcSize);
11260 /**** ended inlining hist.h ****/
11261 /**** skipping file: ../common/bitstream.h ****/
11262 #define FSE_STATIC_LINKING_ONLY
11263 /**** skipping file: ../common/fse.h ****/
11264 /**** skipping file: ../common/error_private.h ****/
11265 #define ZSTD_DEPS_NEED_MALLOC
11266 #define ZSTD_DEPS_NEED_MATH64
11267 /**** skipping file: ../common/zstd_deps.h ****/
11268 /**** skipping file: ../common/bits.h ****/
11269 
11270 
11271 /* **************************************************************
11272 * Error Management
11273 ****************************************************************/
11274 #define FSE_isError ERR_isError
11275 
11276 
11277 /* **************************************************************
11278 * Templates
11279 ****************************************************************/
11280 /*
11281  designed to be included
11282  for type-specific functions (template emulation in C)
11283  Objective is to write these functions only once, for improved maintenance
11284 */
11285 
11286 /* safety checks */
11287 #ifndef FSE_FUNCTION_EXTENSION
11288 # error "FSE_FUNCTION_EXTENSION must be defined"
11289 #endif
11290 #ifndef FSE_FUNCTION_TYPE
11291 # error "FSE_FUNCTION_TYPE must be defined"
11292 #endif
11293 
11294 /* Function names */
11295 #define FSE_CAT(X,Y) X##Y
11296 #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
11297 #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
11298 
11299 
11300 /* Function templates */
11301 
11302 /* FSE_buildCTable_wksp() :
11303  * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
11304  * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
11305  * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
11306  */
11308  const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
11309  void* workSpace, size_t wkspSize)
11310 {
11311  U32 const tableSize = 1 << tableLog;
11312  U32 const tableMask = tableSize - 1;
11313  void* const ptr = ct;
11314  U16* const tableU16 = ( (U16*) ptr) + 2;
11315  void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
11317  U32 const step = FSE_TABLESTEP(tableSize);
11318  U32 const maxSV1 = maxSymbolValue+1;
11319 
11320  U16* cumul = (U16*)workSpace; /* size = maxSV1 */
11321  FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */
11322 
11323  U32 highThreshold = tableSize-1;
11324 
11325  assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */
11326  if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge);
11327  /* CTable header */
11328  tableU16[-2] = (U16) tableLog;
11329  tableU16[-1] = (U16) maxSymbolValue;
11330  assert(tableLog < 16); /* required for threshold strategy to work */
11331 
11332  /* For explanations on how to distribute symbol values over the table :
11333  * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
11334 
11335  #ifdef __clang_analyzer__
11336  ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
11337  #endif
11338 
11339  /* symbol start positions */
11340  { U32 u;
11341  cumul[0] = 0;
11342  for (u=1; u <= maxSV1; u++) {
11343  if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
11344  cumul[u] = cumul[u-1] + 1;
11345  tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
11346  } else {
11347  assert(normalizedCounter[u-1] >= 0);
11348  cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1];
11349  assert(cumul[u] >= cumul[u-1]); /* no overflow */
11350  } }
11351  cumul[maxSV1] = (U16)(tableSize+1);
11352  }
11353 
11354  /* Spread symbols */
11355  if (highThreshold == tableSize - 1) {
11356  /* Case for no low prob count symbols. Lay down 8 bytes at a time
11357  * to reduce branch misses since we are operating on a small block
11358  */
11359  BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */
11360  { U64 const add = 0x0101010101010101ull;
11361  size_t pos = 0;
11362  U64 sv = 0;
11363  U32 s;
11364  for (s=0; s<maxSV1; ++s, sv += add) {
11365  int i;
11366  int const n = normalizedCounter[s];
11367  MEM_write64(spread + pos, sv);
11368  for (i = 8; i < n; i += 8) {
11369  MEM_write64(spread + pos + i, sv);
11370  }
11371  assert(n>=0);
11372  pos += (size_t)n;
11373  }
11374  }
11375  /* Spread symbols across the table. Lack of lowprob symbols means that
11376  * we don't need variable sized inner loop, so we can unroll the loop and
11377  * reduce branch misses.
11378  */
11379  { size_t position = 0;
11380  size_t s;
11381  size_t const unroll = 2; /* Experimentally determined optimal unroll */
11382  assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
11383  for (s = 0; s < (size_t)tableSize; s += unroll) {
11384  size_t u;
11385  for (u = 0; u < unroll; ++u) {
11386  size_t const uPosition = (position + (u * step)) & tableMask;
11387  tableSymbol[uPosition] = spread[s + u];
11388  }
11389  position = (position + (unroll * step)) & tableMask;
11390  }
11391  assert(position == 0); /* Must have initialized all positions */
11392  }
11393  } else {
11394  U32 position = 0;
11395  U32 symbol;
11396  for (symbol=0; symbol<maxSV1; symbol++) {
11397  int nbOccurrences;
11398  int const freq = normalizedCounter[symbol];
11399  for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
11400  tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
11401  position = (position + step) & tableMask;
11402  while (position > highThreshold)
11403  position = (position + step) & tableMask; /* Low proba area */
11404  } }
11405  assert(position==0); /* Must have initialized all positions */
11406  }
11407 
11408  /* Build table */
11409  { U32 u; for (u=0; u<tableSize; u++) {
11410  FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */
11411  tableU16[cumul[s]++] = (U16) (tableSize+u); /* TableU16 : sorted by symbol order; gives next state value */
11412  } }
11413 
11414  /* Build Symbol Transformation Table */
11415  { unsigned total = 0;
11416  unsigned s;
11417  for (s=0; s<=maxSymbolValue; s++) {
11418  switch (normalizedCounter[s])
11419  {
11420  case 0:
11421  /* filling nonetheless, for compatibility with FSE_getMaxNbBits() */
11422  symbolTT[s].deltaNbBits = ((tableLog+1) << 16) - (1<<tableLog);
11423  break;
11424 
11425  case -1:
11426  case 1:
11427  symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
11428  assert(total <= INT_MAX);
11429  symbolTT[s].deltaFindState = (int)(total - 1);
11430  total ++;
11431  break;
11432  default :
11433  assert(normalizedCounter[s] > 1);
11434  { U32 const maxBitsOut = tableLog - ZSTD_highbit32 ((U32)normalizedCounter[s]-1);
11435  U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut;
11436  symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
11437  symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]);
11438  total += (unsigned)normalizedCounter[s];
11439  } } } }
11440 
11441 #if 0 /* debug : symbol costs */
11442  DEBUGLOG(5, "\n --- table statistics : ");
11443  { U32 symbol;
11444  for (symbol=0; symbol<=maxSymbolValue; symbol++) {
11445  DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f",
11446  symbol, normalizedCounter[symbol],
11447  FSE_getMaxNbBits(symbolTT, symbol),
11448  (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);
11449  } }
11450 #endif
11451 
11452  return 0;
11453 }
11454 
11455 
11456 
11457 #ifndef FSE_COMMONDEFS_ONLY
11458 
11459 /*-**************************************************************
11460 * FSE NCount encoding
11461 ****************************************************************/
11462 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
11463 {
11464  size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog
11465  + 4 /* bitCount initialized at 4 */
11466  + 2 /* first two symbols may use one additional bit each */) / 8)
11467  + 1 /* round up to whole nb bytes */
11468  + 2 /* additional two bytes for bitstream flush */;
11469  return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
11470 }
11471 
11472 static size_t
11473 FSE_writeNCount_generic (void* header, size_t headerBufferSize,
11474  const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
11475  unsigned writeIsSafe)
11476 {
11477  BYTE* const ostart = (BYTE*) header;
11478  BYTE* out = ostart;
11479  BYTE* const oend = ostart + headerBufferSize;
11480  int nbBits;
11481  const int tableSize = 1 << tableLog;
11482  int remaining;
11483  int threshold;
11484  U32 bitStream = 0;
11485  int bitCount = 0;
11486  unsigned symbol = 0;
11487  unsigned const alphabetSize = maxSymbolValue + 1;
11488  int previousIs0 = 0;
11489 
11490  /* Table Size */
11491  bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
11492  bitCount += 4;
11493 
11494  /* Init */
11495  remaining = tableSize+1; /* +1 for extra accuracy */
11496  threshold = tableSize;
11497  nbBits = tableLog+1;
11498 
11499  while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */
11500  if (previousIs0) {
11501  unsigned start = symbol;
11502  while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++;
11503  if (symbol == alphabetSize) break; /* incorrect distribution */
11504  while (symbol >= start+24) {
11505  start+=24;
11506  bitStream += 0xFFFFU << bitCount;
11507  if ((!writeIsSafe) && (out > oend-2))
11508  return ERROR(dstSize_tooSmall); /* Buffer overflow */
11509  out[0] = (BYTE) bitStream;
11510  out[1] = (BYTE)(bitStream>>8);
11511  out+=2;
11512  bitStream>>=16;
11513  }
11514  while (symbol >= start+3) {
11515  start+=3;
11516  bitStream += 3 << bitCount;
11517  bitCount += 2;
11518  }
11519  bitStream += (symbol-start) << bitCount;
11520  bitCount += 2;
11521  if (bitCount>16) {
11522  if ((!writeIsSafe) && (out > oend - 2))
11523  return ERROR(dstSize_tooSmall); /* Buffer overflow */
11524  out[0] = (BYTE)bitStream;
11525  out[1] = (BYTE)(bitStream>>8);
11526  out += 2;
11527  bitStream >>= 16;
11528  bitCount -= 16;
11529  } }
11530  { int count = normalizedCounter[symbol++];
11531  int const max = (2*threshold-1) - remaining;
11532  remaining -= count < 0 ? -count : count;
11533  count++; /* +1 for extra accuracy */
11534  if (count>=threshold)
11535  count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
11536  bitStream += count << bitCount;
11537  bitCount += nbBits;
11538  bitCount -= (count<max);
11539  previousIs0 = (count==1);
11540  if (remaining<1) return ERROR(GENERIC);
11541  while (remaining<threshold) { nbBits--; threshold>>=1; }
11542  }
11543  if (bitCount>16) {
11544  if ((!writeIsSafe) && (out > oend - 2))
11545  return ERROR(dstSize_tooSmall); /* Buffer overflow */
11546  out[0] = (BYTE)bitStream;
11547  out[1] = (BYTE)(bitStream>>8);
11548  out += 2;
11549  bitStream >>= 16;
11550  bitCount -= 16;
11551  } }
11552 
11553  if (remaining != 1)
11554  return ERROR(GENERIC); /* incorrect normalized distribution */
11555  assert(symbol <= alphabetSize);
11556 
11557  /* flush remaining bitStream */
11558  if ((!writeIsSafe) && (out > oend - 2))
11559  return ERROR(dstSize_tooSmall); /* Buffer overflow */
11560  out[0] = (BYTE)bitStream;
11561  out[1] = (BYTE)(bitStream>>8);
11562  out+= (bitCount+7) /8;
11563 
11564  return (out-ostart);
11565 }
11566 
11567 
11568 size_t FSE_writeNCount (void* buffer, size_t bufferSize,
11569  const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
11570 {
11571  if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */
11572  if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
11573 
11574  if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
11575  return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
11576 
11577  return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */);
11578 }
11579 
11580 
11581 /*-**************************************************************
11582 * FSE Compression Code
11583 ****************************************************************/
11584 
11585 /* provides the minimum logSize to safely represent a distribution */
11586 static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
11587 {
11588  U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1;
11589  U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2;
11590  U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
11591  assert(srcSize > 1); /* Not supported, RLE should be used instead */
11592  return minBits;
11593 }
11594 
11595 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
11596 {
11597  U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus;
11598  U32 tableLog = maxTableLog;
11599  U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
11600  assert(srcSize > 1); /* Not supported, RLE should be used instead */
11601  if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
11602  if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
11603  if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
11604  if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
11605  if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
11606  return tableLog;
11607 }
11608 
11609 unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
11610 {
11611  return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
11612 }
11613 
11614 /* Secondary normalization method.
11615  To be used when primary method fails. */
11616 
11617 static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount)
11618 {
11619  short const NOT_YET_ASSIGNED = -2;
11620  U32 s;
11621  U32 distributed = 0;
11622  U32 ToDistribute;
11623 
11624  /* Init */
11625  U32 const lowThreshold = (U32)(total >> tableLog);
11626  U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
11627 
11628  for (s=0; s<=maxSymbolValue; s++) {
11629  if (count[s] == 0) {
11630  norm[s]=0;
11631  continue;
11632  }
11633  if (count[s] <= lowThreshold) {
11634  norm[s] = lowProbCount;
11635  distributed++;
11636  total -= count[s];
11637  continue;
11638  }
11639  if (count[s] <= lowOne) {
11640  norm[s] = 1;
11641  distributed++;
11642  total -= count[s];
11643  continue;
11644  }
11645 
11646  norm[s]=NOT_YET_ASSIGNED;
11647  }
11648  ToDistribute = (1 << tableLog) - distributed;
11649 
11650  if (ToDistribute == 0)
11651  return 0;
11652 
11653  if ((total / ToDistribute) > lowOne) {
11654  /* risk of rounding to zero */
11655  lowOne = (U32)((total * 3) / (ToDistribute * 2));
11656  for (s=0; s<=maxSymbolValue; s++) {
11657  if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
11658  norm[s] = 1;
11659  distributed++;
11660  total -= count[s];
11661  continue;
11662  } }
11663  ToDistribute = (1 << tableLog) - distributed;
11664  }
11665 
11666  if (distributed == maxSymbolValue+1) {
11667  /* all values are pretty poor;
11668  probably incompressible data (should have already been detected);
11669  find max, then give all remaining points to max */
11670  U32 maxV = 0, maxC = 0;
11671  for (s=0; s<=maxSymbolValue; s++)
11672  if (count[s] > maxC) { maxV=s; maxC=count[s]; }
11673  norm[maxV] += (short)ToDistribute;
11674  return 0;
11675  }
11676 
11677  if (total == 0) {
11678  /* all of the symbols were low enough for the lowOne or lowThreshold */
11679  for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
11680  if (norm[s] > 0) { ToDistribute--; norm[s]++; }
11681  return 0;
11682  }
11683 
11684  { U64 const vStepLog = 62 - tableLog;
11685  U64 const mid = (1ULL << (vStepLog-1)) - 1;
11686  U64 const rStep = ZSTD_div64((((U64)1<<vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */
11687  U64 tmpTotal = mid;
11688  for (s=0; s<=maxSymbolValue; s++) {
11689  if (norm[s]==NOT_YET_ASSIGNED) {
11690  U64 const end = tmpTotal + (count[s] * rStep);
11691  U32 const sStart = (U32)(tmpTotal >> vStepLog);
11692  U32 const sEnd = (U32)(end >> vStepLog);
11693  U32 const weight = sEnd - sStart;
11694  if (weight < 1)
11695  return ERROR(GENERIC);
11696  norm[s] = (short)weight;
11697  tmpTotal = end;
11698  } } }
11699 
11700  return 0;
11701 }
11702 
11703 size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
11704  const unsigned* count, size_t total,
11705  unsigned maxSymbolValue, unsigned useLowProbCount)
11706 {
11707  /* Sanity checks */
11708  if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
11709  if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */
11710  if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */
11711  if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
11712 
11713  { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
11714  short const lowProbCount = useLowProbCount ? -1 : 1;
11715  U64 const scale = 62 - tableLog;
11716  U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */
11717  U64 const vStep = 1ULL<<(scale-20);
11718  int stillToDistribute = 1<<tableLog;
11719  unsigned s;
11720  unsigned largest=0;
11721  short largestP=0;
11722  U32 lowThreshold = (U32)(total >> tableLog);
11723 
11724  for (s=0; s<=maxSymbolValue; s++) {
11725  if (count[s] == total) return 0; /* rle special case */
11726  if (count[s] == 0) { normalizedCounter[s]=0; continue; }
11727  if (count[s] <= lowThreshold) {
11728  normalizedCounter[s] = lowProbCount;
11729  stillToDistribute--;
11730  } else {
11731  short proba = (short)((count[s]*step) >> scale);
11732  if (proba<8) {
11733  U64 restToBeat = vStep * rtbTable[proba];
11734  proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
11735  }
11736  if (proba > largestP) { largestP=proba; largest=s; }
11737  normalizedCounter[s] = proba;
11738  stillToDistribute -= proba;
11739  } }
11740  if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
11741  /* corner case, need another normalization method */
11742  size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount);
11743  if (FSE_isError(errorCode)) return errorCode;
11744  }
11745  else normalizedCounter[largest] += (short)stillToDistribute;
11746  }
11747 
11748 #if 0
11749  { /* Print Table (debug) */
11750  U32 s;
11751  U32 nTotal = 0;
11752  for (s=0; s<=maxSymbolValue; s++)
11753  RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]);
11754  for (s=0; s<=maxSymbolValue; s++)
11755  nTotal += abs(normalizedCounter[s]);
11756  if (nTotal != (1U<<tableLog))
11757  RAWLOG(2, "Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
11758  getchar();
11759  }
11760 #endif
11761 
11762  return tableLog;
11763 }
11764 
11765 /* fake FSE_CTable, for rle input (always same symbol) */
11766 size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
11767 {
11768  void* ptr = ct;
11769  U16* tableU16 = ( (U16*) ptr) + 2;
11770  void* FSCTptr = (U32*)ptr + 2;
11772 
11773  /* header */
11774  tableU16[-2] = (U16) 0;
11775  tableU16[-1] = (U16) symbolValue;
11776 
11777  /* Build table */
11778  tableU16[0] = 0;
11779  tableU16[1] = 0; /* just in case */
11780 
11781  /* Build Symbol Transformation Table */
11782  symbolTT[symbolValue].deltaNbBits = 0;
11783  symbolTT[symbolValue].deltaFindState = 0;
11784 
11785  return 0;
11786 }
11787 
11788 
11789 static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
11790  const void* src, size_t srcSize,
11791  const FSE_CTable* ct, const unsigned fast)
11792 {
11793  const BYTE* const istart = (const BYTE*) src;
11794  const BYTE* const iend = istart + srcSize;
11795  const BYTE* ip=iend;
11796 
11797  BIT_CStream_t bitC;
11798  FSE_CState_t CState1, CState2;
11799 
11800  /* init */
11801  if (srcSize <= 2) return 0;
11802  { size_t const initError = BIT_initCStream(&bitC, dst, dstSize);
11803  if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ }
11804 
11805 #define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
11806 
11807  if (srcSize & 1) {
11808  FSE_initCState2(&CState1, ct, *--ip);
11809  FSE_initCState2(&CState2, ct, *--ip);
11810  FSE_encodeSymbol(&bitC, &CState1, *--ip);
11811  FSE_FLUSHBITS(&bitC);
11812  } else {
11813  FSE_initCState2(&CState2, ct, *--ip);
11814  FSE_initCState2(&CState1, ct, *--ip);
11815  }
11816 
11817  /* join to mod 4 */
11818  srcSize -= 2;
11819  if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */
11820  FSE_encodeSymbol(&bitC, &CState2, *--ip);
11821  FSE_encodeSymbol(&bitC, &CState1, *--ip);
11822  FSE_FLUSHBITS(&bitC);
11823  }
11824 
11825  /* 2 or 4 encoding per loop */
11826  while ( ip>istart ) {
11827 
11828  FSE_encodeSymbol(&bitC, &CState2, *--ip);
11829 
11830  if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */
11831  FSE_FLUSHBITS(&bitC);
11832 
11833  FSE_encodeSymbol(&bitC, &CState1, *--ip);
11834 
11835  if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */
11836  FSE_encodeSymbol(&bitC, &CState2, *--ip);
11837  FSE_encodeSymbol(&bitC, &CState1, *--ip);
11838  }
11839 
11840  FSE_FLUSHBITS(&bitC);
11841  }
11842 
11843  FSE_flushCState(&bitC, &CState2);
11844  FSE_flushCState(&bitC, &CState1);
11845  return BIT_closeCStream(&bitC);
11846 }
11847 
11848 size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
11849  const void* src, size_t srcSize,
11850  const FSE_CTable* ct)
11851 {
11852  unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
11853 
11854  if (fast)
11855  return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
11856  else
11857  return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
11858 }
11859 
11860 
11861 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
11862 
11863 #endif /* FSE_COMMONDEFS_ONLY */
11864 /**** ended inlining compress/fse_compress.c ****/
11865 /**** start inlining compress/hist.c ****/
11866 /* ******************************************************************
11867  * hist : Histogram functions
11868  * part of Finite State Entropy project
11869  * Copyright (c) Meta Platforms, Inc. and affiliates.
11870  *
11871  * You can contact the author at :
11872  * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
11873  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
11874  *
11875  * This source code is licensed under both the BSD-style license (found in the
11876  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11877  * in the COPYING file in the root directory of this source tree).
11878  * You may select, at your option, one of the above-listed licenses.
11879 ****************************************************************** */
11880 
11881 /* --- dependencies --- */
11882 /**** skipping file: ../common/mem.h ****/
11883 /**** skipping file: ../common/debug.h ****/
11884 /**** skipping file: ../common/error_private.h ****/
11885 /**** skipping file: hist.h ****/
11886 
11887 
11888 /* --- Error management --- */
11889 unsigned HIST_isError(size_t code) { return ERR_isError(code); }
11890 
11891 /*-**************************************************************
11892  * Histogram functions
11893  ****************************************************************/
11894 unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
11895  const void* src, size_t srcSize)
11896 {
11897  const BYTE* ip = (const BYTE*)src;
11898  const BYTE* const end = ip + srcSize;
11899  unsigned maxSymbolValue = *maxSymbolValuePtr;
11900  unsigned largestCount=0;
11901 
11902  ZSTD_memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
11903  if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
11904 
11905  while (ip<end) {
11906  assert(*ip <= maxSymbolValue);
11907  count[*ip++]++;
11908  }
11909 
11910  while (!count[maxSymbolValue]) maxSymbolValue--;
11911  *maxSymbolValuePtr = maxSymbolValue;
11912 
11913  { U32 s;
11914  for (s=0; s<=maxSymbolValue; s++)
11915  if (count[s] > largestCount) largestCount = count[s];
11916  }
11917 
11918  return largestCount;
11919 }
11920 
11922 
11923 /* HIST_count_parallel_wksp() :
11924  * store histogram into 4 intermediate tables, recombined at the end.
11925  * this design makes better use of OoO cpus,
11926  * and is noticeably faster when some values are heavily repeated.
11927  * But it needs some additional workspace for intermediate tables.
11928  * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32.
11929  * @return : largest histogram frequency,
11930  * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */
11932  unsigned* count, unsigned* maxSymbolValuePtr,
11933  const void* source, size_t sourceSize,
11935  U32* const workSpace)
11936 {
11937  const BYTE* ip = (const BYTE*)source;
11938  const BYTE* const iend = ip+sourceSize;
11939  size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count);
11940  unsigned max=0;
11941  U32* const Counting1 = workSpace;
11942  U32* const Counting2 = Counting1 + 256;
11943  U32* const Counting3 = Counting2 + 256;
11944  U32* const Counting4 = Counting3 + 256;
11945 
11946  /* safety checks */
11947  assert(*maxSymbolValuePtr <= 255);
11948  if (!sourceSize) {
11949  ZSTD_memset(count, 0, countSize);
11950  *maxSymbolValuePtr = 0;
11951  return 0;
11952  }
11953  ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned));
11954 
11955  /* by stripes of 16 bytes */
11956  { U32 cached = MEM_read32(ip); ip += 4;
11957  while (ip < iend-15) {
11958  U32 c = cached; cached = MEM_read32(ip); ip += 4;
11959  Counting1[(BYTE) c ]++;
11960  Counting2[(BYTE)(c>>8) ]++;
11961  Counting3[(BYTE)(c>>16)]++;
11962  Counting4[ c>>24 ]++;
11963  c = cached; cached = MEM_read32(ip); ip += 4;
11964  Counting1[(BYTE) c ]++;
11965  Counting2[(BYTE)(c>>8) ]++;
11966  Counting3[(BYTE)(c>>16)]++;
11967  Counting4[ c>>24 ]++;
11968  c = cached; cached = MEM_read32(ip); ip += 4;
11969  Counting1[(BYTE) c ]++;
11970  Counting2[(BYTE)(c>>8) ]++;
11971  Counting3[(BYTE)(c>>16)]++;
11972  Counting4[ c>>24 ]++;
11973  c = cached; cached = MEM_read32(ip); ip += 4;
11974  Counting1[(BYTE) c ]++;
11975  Counting2[(BYTE)(c>>8) ]++;
11976  Counting3[(BYTE)(c>>16)]++;
11977  Counting4[ c>>24 ]++;
11978  }
11979  ip-=4;
11980  }
11981 
11982  /* finish last symbols */
11983  while (ip<iend) Counting1[*ip++]++;
11984 
11985  { U32 s;
11986  for (s=0; s<256; s++) {
11987  Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
11988  if (Counting1[s] > max) max = Counting1[s];
11989  } }
11990 
11991  { unsigned maxSymbolValue = 255;
11992  while (!Counting1[maxSymbolValue]) maxSymbolValue--;
11993  if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall);
11994  *maxSymbolValuePtr = maxSymbolValue;
11995  ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */
11996  }
11997  return (size_t)max;
11998 }
11999 
12000 /* HIST_countFast_wksp() :
12001  * Same as HIST_countFast(), but using an externally provided scratch buffer.
12002  * `workSpace` is a writable buffer which must be 4-bytes aligned,
12003  * `workSpaceSize` must be >= HIST_WKSP_SIZE
12004  */
12005 size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
12006  const void* source, size_t sourceSize,
12007  void* workSpace, size_t workSpaceSize)
12008 {
12009  if (sourceSize < 1500) /* heuristic threshold */
12010  return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);
12011  if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
12012  if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
12013  return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
12014 }
12015 
12016 /* HIST_count_wksp() :
12017  * Same as HIST_count(), but using an externally provided scratch buffer.
12018  * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
12019 size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
12020  const void* source, size_t sourceSize,
12021  void* workSpace, size_t workSpaceSize)
12022 {
12023  if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
12024  if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
12025  if (*maxSymbolValuePtr < 255)
12026  return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);
12027  *maxSymbolValuePtr = 255;
12028  return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
12029 }
12030 
12031 #ifndef ZSTD_NO_UNUSED_FUNCTIONS
12032 /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
12033 size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
12034  const void* source, size_t sourceSize)
12035 {
12036  unsigned tmpCounters[HIST_WKSP_SIZE_U32];
12037  return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
12038 }
12039 
12040 size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
12041  const void* src, size_t srcSize)
12042 {
12043  unsigned tmpCounters[HIST_WKSP_SIZE_U32];
12044  return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
12045 }
12046 #endif
12047 /**** ended inlining compress/hist.c ****/
12048 /**** start inlining compress/huf_compress.c ****/
12049 /* ******************************************************************
12050  * Huffman encoder, part of New Generation Entropy library
12051  * Copyright (c) Meta Platforms, Inc. and affiliates.
12052  *
12053  * You can contact the author at :
12054  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
12055  * - Public forum : https://groups.google.com/forum/#!forum/lz4c
12056  *
12057  * This source code is licensed under both the BSD-style license (found in the
12058  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
12059  * in the COPYING file in the root directory of this source tree).
12060  * You may select, at your option, one of the above-listed licenses.
12061 ****************************************************************** */
12062 
12063 /* **************************************************************
12064 * Compiler specifics
12065 ****************************************************************/
12066 #ifdef _MSC_VER /* Visual Studio */
12067 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
12068 #endif
12069 
12070 
12071 /* **************************************************************
12072 * Includes
12073 ****************************************************************/
12074 /**** skipping file: ../common/zstd_deps.h ****/
12075 /**** skipping file: ../common/compiler.h ****/
12076 /**** skipping file: ../common/bitstream.h ****/
12077 /**** skipping file: hist.h ****/
12078 #define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
12079 /**** skipping file: ../common/fse.h ****/
12080 /**** skipping file: ../common/huf.h ****/
12081 /**** skipping file: ../common/error_private.h ****/
12082 /**** skipping file: ../common/bits.h ****/
12083 
12084 
12085 /* **************************************************************
12086 * Error Management
12087 ****************************************************************/
12088 #define HUF_isError ERR_isError
12089 #define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
12090 
12091 
12092 /* **************************************************************
12093 * Required declarations
12094 ****************************************************************/
12095 typedef struct nodeElt_s {
12100 } nodeElt;
12101 
12102 
12103 /* **************************************************************
12104 * Debug Traces
12105 ****************************************************************/
12106 
12107 #if DEBUGLEVEL >= 2
12108 
12109 static size_t showU32(const U32* arr, size_t size)
12110 {
12111  size_t u;
12112  for (u=0; u<size; u++) {
12113  RAWLOG(6, " %u", arr[u]); (void)arr;
12114  }
12115  RAWLOG(6, " \n");
12116  return size;
12117 }
12118 
12119 static size_t HUF_getNbBits(HUF_CElt elt);
12120 
12121 static size_t showCTableBits(const HUF_CElt* ctable, size_t size)
12122 {
12123  size_t u;
12124  for (u=0; u<size; u++) {
12125  RAWLOG(6, " %zu", HUF_getNbBits(ctable[u])); (void)ctable;
12126  }
12127  RAWLOG(6, " \n");
12128  return size;
12129 
12130 }
12131 
12132 static size_t showHNodeSymbols(const nodeElt* hnode, size_t size)
12133 {
12134  size_t u;
12135  for (u=0; u<size; u++) {
12136  RAWLOG(6, " %u", hnode[u].byte); (void)hnode;
12137  }
12138  RAWLOG(6, " \n");
12139  return size;
12140 }
12141 
12142 static size_t showHNodeBits(const nodeElt* hnode, size_t size)
12143 {
12144  size_t u;
12145  for (u=0; u<size; u++) {
12146  RAWLOG(6, " %u", hnode[u].nbBits); (void)hnode;
12147  }
12148  RAWLOG(6, " \n");
12149  return size;
12150 }
12151 
12152 #endif
12153 
12154 
12155 /* *******************************************************
12156 * HUF : Huffman block compression
12157 *********************************************************/
12158 #define HUF_WORKSPACE_MAX_ALIGNMENT 8
12159 
12160 static void* HUF_alignUpWorkspace(void* workspace, size_t* workspaceSizePtr, size_t align)
12161 {
12162  size_t const mask = align - 1;
12163  size_t const rem = (size_t)workspace & mask;
12164  size_t const add = (align - rem) & mask;
12165  BYTE* const aligned = (BYTE*)workspace + add;
12166  assert((align & (align - 1)) == 0); /* pow 2 */
12168  if (*workspaceSizePtr >= add) {
12169  assert(add < align);
12170  assert(((size_t)aligned & mask) == 0);
12171  *workspaceSizePtr -= add;
12172  return aligned;
12173  } else {
12174  *workspaceSizePtr = 0;
12175  return NULL;
12176  }
12177 }
12178 
12179 
12180 /* HUF_compressWeights() :
12181  * Same as FSE_compress(), but dedicated to huff0's weights compression.
12182  * The use case needs much less stack memory.
12183  * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
12184  */
12185 #define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
12186 
12187 typedef struct {
12193 
12194 static size_t
12195 HUF_compressWeights(void* dst, size_t dstSize,
12196  const void* weightTable, size_t wtSize,
12197  void* workspace, size_t workspaceSize)
12198 {
12199  BYTE* const ostart = (BYTE*) dst;
12200  BYTE* op = ostart;
12201  BYTE* const oend = ostart + dstSize;
12202 
12203  unsigned maxSymbolValue = HUF_TABLELOG_MAX;
12206 
12207  if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC);
12208 
12209  /* init conditions */
12210  if (wtSize <= 1) return 0; /* Not compressible */
12211 
12212  /* Scan input and build symbol stats */
12213  { unsigned const maxCount = HIST_count_simple(wksp->count, &maxSymbolValue, weightTable, wtSize); /* never fails */
12214  if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
12215  if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
12216  }
12217 
12218  tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
12219  CHECK_F( FSE_normalizeCount(wksp->norm, tableLog, wksp->count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) );
12220 
12221  /* Write table description header */
12222  { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), wksp->norm, maxSymbolValue, tableLog) );
12223  op += hSize;
12224  }
12225 
12226  /* Compress */
12227  CHECK_F( FSE_buildCTable_wksp(wksp->CTable, wksp->norm, maxSymbolValue, tableLog, wksp->scratchBuffer, sizeof(wksp->scratchBuffer)) );
12228  { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, wksp->CTable) );
12229  if (cSize == 0) return 0; /* not enough space for compressed data */
12230  op += cSize;
12231  }
12232 
12233  return (size_t)(op-ostart);
12234 }
12235 
12236 static size_t HUF_getNbBits(HUF_CElt elt)
12237 {
12238  return elt & 0xFF;
12239 }
12240 
12241 static size_t HUF_getNbBitsFast(HUF_CElt elt)
12242 {
12243  return elt;
12244 }
12245 
12246 static size_t HUF_getValue(HUF_CElt elt)
12247 {
12248  return elt & ~(size_t)0xFF;
12249 }
12250 
12251 static size_t HUF_getValueFast(HUF_CElt elt)
12252 {
12253  return elt;
12254 }
12255 
12256 static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits)
12257 {
12258  assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX);
12259  *elt = nbBits;
12260 }
12261 
12262 static void HUF_setValue(HUF_CElt* elt, size_t value)
12263 {
12264  size_t const nbBits = HUF_getNbBits(*elt);
12265  if (nbBits > 0) {
12266  assert((value >> nbBits) == 0);
12267  *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits);
12268  }
12269 }
12270 
12271 typedef struct {
12273  BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
12276 
12277 size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize,
12278  const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog,
12279  void* workspace, size_t workspaceSize)
12280 {
12281  HUF_CElt const* const ct = CTable + 1;
12282  BYTE* op = (BYTE*)dst;
12283  U32 n;
12284  HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32));
12285 
12287 
12288  /* check conditions */
12289  if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC);
12290  if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
12291 
12292  /* convert to weight */
12293  wksp->bitsToWeight[0] = 0;
12294  for (n=1; n<huffLog+1; n++)
12295  wksp->bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
12296  for (n=0; n<maxSymbolValue; n++)
12297  wksp->huffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])];
12298 
12299  /* attempt weights compression by FSE */
12300  if (maxDstSize < 1) return ERROR(dstSize_tooSmall);
12301  { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) );
12302  if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */
12303  op[0] = (BYTE)hSize;
12304  return hSize+1;
12305  } }
12306 
12307  /* write raw values as 4-bits (max : 15) */
12308  if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
12309  if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
12310  op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
12311  wksp->huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
12312  for (n=0; n<maxSymbolValue; n+=2)
12313  op[(n/2)+1] = (BYTE)((wksp->huffWeight[n] << 4) + wksp->huffWeight[n+1]);
12314  return ((maxSymbolValue+1)/2) + 1;
12315 }
12316 
12317 
12318 size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights)
12319 {
12320  BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */
12321  U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
12322  U32 tableLog = 0;
12323  U32 nbSymbols = 0;
12324  HUF_CElt* const ct = CTable + 1;
12325 
12326  /* get symbol weights */
12327  CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
12328  *hasZeroWeights = (rankVal[0] > 0);
12329 
12330  /* check result */
12331  if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
12332  if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall);
12333 
12334  CTable[0] = tableLog;
12335 
12336  /* Prepare base value per rank */
12337  { U32 n, nextRankStart = 0;
12338  for (n=1; n<=tableLog; n++) {
12339  U32 curr = nextRankStart;
12340  nextRankStart += (rankVal[n] << (n-1));
12341  rankVal[n] = curr;
12342  } }
12343 
12344  /* fill nbBits */
12345  { U32 n; for (n=0; n<nbSymbols; n++) {
12346  const U32 w = huffWeight[n];
12347  HUF_setNbBits(ct + n, (BYTE)(tableLog + 1 - w) & -(w != 0));
12348  } }
12349 
12350  /* fill val */
12351  { U16 nbPerRank[HUF_TABLELOG_MAX+2] = {0}; /* support w=0=>n=tableLog+1 */
12352  U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
12353  { U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[HUF_getNbBits(ct[n])]++; }
12354  /* determine stating value per rank */
12355  valPerRank[tableLog+1] = 0; /* for w==0 */
12356  { U16 min = 0;
12357  U32 n; for (n=tableLog; n>0; n--) { /* start at n=tablelog <-> w=1 */
12358  valPerRank[n] = min; /* get starting value within each rank */
12359  min += nbPerRank[n];
12360  min >>= 1;
12361  } }
12362  /* assign value within rank, symbol order */
12363  { U32 n; for (n=0; n<nbSymbols; n++) HUF_setValue(ct + n, valPerRank[HUF_getNbBits(ct[n])]++); }
12364  }
12365 
12366  *maxSymbolValuePtr = nbSymbols - 1;
12367  return readSize;
12368 }
12369 
12370 U32 HUF_getNbBitsFromCTable(HUF_CElt const* CTable, U32 symbolValue)
12371 {
12372  const HUF_CElt* const ct = CTable + 1;
12373  assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
12374  return (U32)HUF_getNbBits(ct[symbolValue]);
12375 }
12376 
12377 
12399 static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits)
12400 {
12401  const U32 largestBits = huffNode[lastNonNull].nbBits;
12402  /* early exit : no elt > targetNbBits, so the tree is already valid. */
12403  if (largestBits <= targetNbBits) return largestBits;
12404 
12405  DEBUGLOG(5, "HUF_setMaxHeight (targetNbBits = %u)", targetNbBits);
12406 
12407  /* there are several too large elements (at least >= 2) */
12408  { int totalCost = 0;
12409  const U32 baseCost = 1 << (largestBits - targetNbBits);
12410  int n = (int)lastNonNull;
12411 
12412  /* Adjust any ranks > targetNbBits to targetNbBits.
12413  * Compute totalCost, which is how far the sum of the ranks is
12414  * we are over 2^largestBits after adjust the offending ranks.
12415  */
12416  while (huffNode[n].nbBits > targetNbBits) {
12417  totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
12418  huffNode[n].nbBits = (BYTE)targetNbBits;
12419  n--;
12420  }
12421  /* n stops at huffNode[n].nbBits <= targetNbBits */
12422  assert(huffNode[n].nbBits <= targetNbBits);
12423  /* n end at index of smallest symbol using < targetNbBits */
12424  while (huffNode[n].nbBits == targetNbBits) --n;
12425 
12426  /* renorm totalCost from 2^largestBits to 2^targetNbBits
12427  * note : totalCost is necessarily a multiple of baseCost */
12428  assert(((U32)totalCost & (baseCost - 1)) == 0);
12429  totalCost >>= (largestBits - targetNbBits);
12430  assert(totalCost > 0);
12431 
12432  /* repay normalized cost */
12433  { U32 const noSymbol = 0xF0F0F0F0;
12434  U32 rankLast[HUF_TABLELOG_MAX+2];
12435 
12436  /* Get pos of last (smallest = lowest cum. count) symbol per rank */
12437  ZSTD_memset(rankLast, 0xF0, sizeof(rankLast));
12438  { U32 currentNbBits = targetNbBits;
12439  int pos;
12440  for (pos=n ; pos >= 0; pos--) {
12441  if (huffNode[pos].nbBits >= currentNbBits) continue;
12442  currentNbBits = huffNode[pos].nbBits; /* < targetNbBits */
12443  rankLast[targetNbBits-currentNbBits] = (U32)pos;
12444  } }
12445 
12446  while (totalCost > 0) {
12447  /* Try to reduce the next power of 2 above totalCost because we
12448  * gain back half the rank.
12449  */
12450  U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1;
12451  for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
12452  U32 const highPos = rankLast[nBitsToDecrease];
12453  U32 const lowPos = rankLast[nBitsToDecrease-1];
12454  if (highPos == noSymbol) continue;
12455  /* Decrease highPos if no symbols of lowPos or if it is
12456  * not cheaper to remove 2 lowPos than highPos.
12457  */
12458  if (lowPos == noSymbol) break;
12459  { U32 const highTotal = huffNode[highPos].count;
12460  U32 const lowTotal = 2 * huffNode[lowPos].count;
12461  if (highTotal <= lowTotal) break;
12462  } }
12463  /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
12464  assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1);
12465  /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
12466  while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
12467  nBitsToDecrease++;
12468  assert(rankLast[nBitsToDecrease] != noSymbol);
12469  /* Increase the number of bits to gain back half the rank cost. */
12470  totalCost -= 1 << (nBitsToDecrease-1);
12471  huffNode[rankLast[nBitsToDecrease]].nbBits++;
12472 
12473  /* Fix up the new rank.
12474  * If the new rank was empty, this symbol is now its smallest.
12475  * Otherwise, this symbol will be the largest in the new rank so no adjustment.
12476  */
12477  if (rankLast[nBitsToDecrease-1] == noSymbol)
12478  rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];
12479  /* Fix up the old rank.
12480  * If the symbol was at position 0, meaning it was the highest weight symbol in the tree,
12481  * it must be the only symbol in its rank, so the old rank now has no symbols.
12482  * Otherwise, since the Huffman nodes are sorted by count, the previous position is now
12483  * the smallest node in the rank. If the previous position belongs to a different rank,
12484  * then the rank is now empty.
12485  */
12486  if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
12487  rankLast[nBitsToDecrease] = noSymbol;
12488  else {
12489  rankLast[nBitsToDecrease]--;
12490  if (huffNode[rankLast[nBitsToDecrease]].nbBits != targetNbBits-nBitsToDecrease)
12491  rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
12492  }
12493  } /* while (totalCost > 0) */
12494 
12495  /* If we've removed too much weight, then we have to add it back.
12496  * To avoid overshooting again, we only adjust the smallest rank.
12497  * We take the largest nodes from the lowest rank 0 and move them
12498  * to rank 1. There's guaranteed to be enough rank 0 symbols because
12499  * TODO.
12500  */
12501  while (totalCost < 0) { /* Sometimes, cost correction overshoot */
12502  /* special case : no rank 1 symbol (using targetNbBits-1);
12503  * let's create one from largest rank 0 (using targetNbBits).
12504  */
12505  if (rankLast[1] == noSymbol) {
12506  while (huffNode[n].nbBits == targetNbBits) n--;
12507  huffNode[n+1].nbBits--;
12508  assert(n >= 0);
12509  rankLast[1] = (U32)(n+1);
12510  totalCost++;
12511  continue;
12512  }
12513  huffNode[ rankLast[1] + 1 ].nbBits--;
12514  rankLast[1]++;
12515  totalCost ++;
12516  }
12517  } /* repay normalized cost */
12518  } /* there are several too large elements (at least >= 2) */
12519 
12520  return targetNbBits;
12521 }
12522 
12523 typedef struct {
12526 } rankPos;
12527 
12529 
12530 /* Number of buckets available for HUF_sort() */
12531 #define RANK_POSITION_TABLE_SIZE 192
12532 
12533 typedef struct {
12537 
12538 /* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing.
12539  * Strategy is to use as many buckets as possible for representing distinct
12540  * counts while using the remainder to represent all "large" counts.
12541  *
12542  * To satisfy this requirement for 192 buckets, we can do the following:
12543  * Let buckets 0-166 represent distinct counts of [0, 166]
12544  * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing.
12545  */
12546 #define RANK_POSITION_MAX_COUNT_LOG 32
12547 #define RANK_POSITION_LOG_BUCKETS_BEGIN ((RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */)
12548 #define RANK_POSITION_DISTINCT_COUNT_CUTOFF (RANK_POSITION_LOG_BUCKETS_BEGIN + ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */)
12549 
12550 /* Return the appropriate bucket index for a given count. See definition of
12551  * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy.
12552  */
12553 static U32 HUF_getIndex(U32 const count) {
12555  ? count
12557 }
12558 
12559 /* Helper swap function for HUF_quickSortPartition() */
12560 static void HUF_swapNodes(nodeElt* a, nodeElt* b) {
12561  nodeElt tmp = *a;
12562  *a = *b;
12563  *b = tmp;
12564 }
12565 
12566 /* Returns 0 if the huffNode array is not sorted by descending count */
12567 MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) {
12568  U32 i;
12569  for (i = 1; i < maxSymbolValue1; ++i) {
12570  if (huffNode[i].count > huffNode[i-1].count) {
12571  return 0;
12572  }
12573  }
12574  return 1;
12575 }
12576 
12577 /* Insertion sort by descending order */
12578 HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) {
12579  int i;
12580  int const size = high-low+1;
12581  huffNode += low;
12582  for (i = 1; i < size; ++i) {
12583  nodeElt const key = huffNode[i];
12584  int j = i - 1;
12585  while (j >= 0 && huffNode[j].count < key.count) {
12586  huffNode[j + 1] = huffNode[j];
12587  j--;
12588  }
12589  huffNode[j + 1] = key;
12590  }
12591 }
12592 
12593 /* Pivot helper function for quicksort. */
12594 static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) {
12595  /* Simply select rightmost element as pivot. "Better" selectors like
12596  * median-of-three don't experimentally appear to have any benefit.
12597  */
12598  U32 const pivot = arr[high].count;
12599  int i = low - 1;
12600  int j = low;
12601  for ( ; j < high; j++) {
12602  if (arr[j].count > pivot) {
12603  i++;
12604  HUF_swapNodes(&arr[i], &arr[j]);
12605  }
12606  }
12607  HUF_swapNodes(&arr[i + 1], &arr[high]);
12608  return i + 1;
12609 }
12610 
12611 /* Classic quicksort by descending with partially iterative calls
12612  * to reduce worst case callstack size.
12613  */
12614 static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) {
12615  int const kInsertionSortThreshold = 8;
12616  if (high - low < kInsertionSortThreshold) {
12617  HUF_insertionSort(arr, low, high);
12618  return;
12619  }
12620  while (low < high) {
12621  int const idx = HUF_quickSortPartition(arr, low, high);
12622  if (idx - low < high - idx) {
12623  HUF_simpleQuickSort(arr, low, idx - 1);
12624  low = idx + 1;
12625  } else {
12626  HUF_simpleQuickSort(arr, idx + 1, high);
12627  high = idx - 1;
12628  }
12629  }
12630 }
12631 
12643 static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) {
12644  U32 n;
12645  U32 const maxSymbolValue1 = maxSymbolValue+1;
12646 
12647  /* Compute base and set curr to base.
12648  * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1.
12649  * See HUF_getIndex to see bucketing strategy.
12650  * We attribute each symbol to lowerRank's base value, because we want to know where
12651  * each rank begins in the output, so for rank R we want to count ranks R+1 and above.
12652  */
12653  ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE);
12654  for (n = 0; n < maxSymbolValue1; ++n) {
12655  U32 lowerRank = HUF_getIndex(count[n]);
12656  assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1);
12657  rankPosition[lowerRank].base++;
12658  }
12659 
12660  assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0);
12661  /* Set up the rankPosition table */
12662  for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) {
12663  rankPosition[n-1].base += rankPosition[n].base;
12664  rankPosition[n-1].curr = rankPosition[n-1].base;
12665  }
12666 
12667  /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */
12668  for (n = 0; n < maxSymbolValue1; ++n) {
12669  U32 const c = count[n];
12670  U32 const r = HUF_getIndex(c) + 1;
12671  U32 const pos = rankPosition[r].curr++;
12672  assert(pos < maxSymbolValue1);
12673  huffNode[pos].count = c;
12674  huffNode[pos].byte = (BYTE)n;
12675  }
12676 
12677  /* Sort each bucket. */
12679  int const bucketSize = rankPosition[n].curr - rankPosition[n].base;
12680  U32 const bucketStartIdx = rankPosition[n].base;
12681  if (bucketSize > 1) {
12682  assert(bucketStartIdx < maxSymbolValue1);
12683  HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1);
12684  }
12685  }
12686 
12687  assert(HUF_isSorted(huffNode, maxSymbolValue1));
12688 }
12689 
12690 
12695 #define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
12696 
12697 /* HUF_buildTree():
12698  * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree.
12699  *
12700  * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array.
12701  * @param maxSymbolValue The maximum symbol value.
12702  * @return The smallest node in the Huffman tree (by count).
12703  */
12704 static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue)
12705 {
12706  nodeElt* const huffNode0 = huffNode - 1;
12707  int nonNullRank;
12708  int lowS, lowN;
12709  int nodeNb = STARTNODE;
12710  int n, nodeRoot;
12711  DEBUGLOG(5, "HUF_buildTree (alphabet size = %u)", maxSymbolValue + 1);
12712  /* init for parents */
12713  nonNullRank = (int)maxSymbolValue;
12714  while(huffNode[nonNullRank].count == 0) nonNullRank--;
12715  lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
12716  huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
12717  huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb;
12718  nodeNb++; lowS-=2;
12719  for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
12720  huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */
12721 
12722  /* create parents */
12723  while (nodeNb <= nodeRoot) {
12724  int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
12725  int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
12726  huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
12727  huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb;
12728  nodeNb++;
12729  }
12730 
12731  /* distribute weights (unlimited tree height) */
12732  huffNode[nodeRoot].nbBits = 0;
12733  for (n=nodeRoot-1; n>=STARTNODE; n--)
12734  huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
12735  for (n=0; n<=nonNullRank; n++)
12736  huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
12737 
12738  DEBUGLOG(6, "Initial distribution of bits completed (%zu sorted symbols)", showHNodeBits(huffNode, maxSymbolValue+1));
12739 
12740  return nonNullRank;
12741 }
12742 
12753 static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits)
12754 {
12755  HUF_CElt* const ct = CTable + 1;
12756  /* fill result into ctable (val, nbBits) */
12757  int n;
12758  U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
12759  U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
12760  int const alphabetSize = (int)(maxSymbolValue + 1);
12761  for (n=0; n<=nonNullRank; n++)
12762  nbPerRank[huffNode[n].nbBits]++;
12763  /* determine starting value per rank */
12764  { U16 min = 0;
12765  for (n=(int)maxNbBits; n>0; n--) {
12766  valPerRank[n] = min; /* get starting value within each rank */
12767  min += nbPerRank[n];
12768  min >>= 1;
12769  } }
12770  for (n=0; n<alphabetSize; n++)
12771  HUF_setNbBits(ct + huffNode[n].byte, huffNode[n].nbBits); /* push nbBits per symbol, symbol order */
12772  for (n=0; n<alphabetSize; n++)
12773  HUF_setValue(ct + n, valPerRank[HUF_getNbBits(ct[n])]++); /* assign value within rank, symbol order */
12774  CTable[0] = maxNbBits;
12775 }
12776 
12777 size_t
12778 HUF_buildCTable_wksp(HUF_CElt* CTable, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
12779  void* workSpace, size_t wkspSize)
12780 {
12781  HUF_buildCTable_wksp_tables* const wksp_tables =
12783  nodeElt* const huffNode0 = wksp_tables->huffNodeTbl;
12784  nodeElt* const huffNode = huffNode0+1;
12785  int nonNullRank;
12786 
12788 
12789  DEBUGLOG(5, "HUF_buildCTable_wksp (alphabet size = %u)", maxSymbolValue+1);
12790 
12791  /* safety checks */
12792  if (wkspSize < sizeof(HUF_buildCTable_wksp_tables))
12793  return ERROR(workSpace_tooSmall);
12794  if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
12795  if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
12796  return ERROR(maxSymbolValue_tooLarge);
12797  ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable));
12798 
12799  /* sort, decreasing order */
12800  HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition);
12801  DEBUGLOG(6, "sorted symbols completed (%zu symbols)", showHNodeSymbols(huffNode, maxSymbolValue+1));
12802 
12803  /* build tree */
12804  nonNullRank = HUF_buildTree(huffNode, maxSymbolValue);
12805 
12806  /* determine and enforce maxTableLog */
12807  maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits);
12808  if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
12809 
12810  HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits);
12811 
12812  return maxNbBits;
12813 }
12814 
12815 size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
12816 {
12817  HUF_CElt const* ct = CTable + 1;
12818  size_t nbBits = 0;
12819  int s;
12820  for (s = 0; s <= (int)maxSymbolValue; ++s) {
12821  nbBits += HUF_getNbBits(ct[s]) * count[s];
12822  }
12823  return nbBits >> 3;
12824 }
12825 
12826 int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
12827  HUF_CElt const* ct = CTable + 1;
12828  int bad = 0;
12829  int s;
12830  for (s = 0; s <= (int)maxSymbolValue; ++s) {
12831  bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0);
12832  }
12833  return !bad;
12834 }
12835 
12836 size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
12837 
12856 #define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8)
12857 
12858 typedef struct {
12859  size_t bitContainer[2];
12860  size_t bitPos[2];
12861 
12865 } HUF_CStream_t;
12866 
12871 static size_t HUF_initCStream(HUF_CStream_t* bitC,
12872  void* startPtr, size_t dstCapacity)
12873 {
12874  ZSTD_memset(bitC, 0, sizeof(*bitC));
12875  bitC->startPtr = (BYTE*)startPtr;
12876  bitC->ptr = bitC->startPtr;
12877  bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]);
12878  if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall);
12879  return 0;
12880 }
12881 
12892 FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast)
12893 {
12894  assert(idx <= 1);
12896  /* This is efficient on x86-64 with BMI2 because shrx
12897  * only reads the low 6 bits of the register. The compiler
12898  * knows this and elides the mask. When fast is set,
12899  * every operation can use the same value loaded from elt.
12900  */
12901  bitC->bitContainer[idx] >>= HUF_getNbBits(elt);
12902  bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt);
12903  /* We only read the low 8 bits of bitC->bitPos[idx] so it
12904  * doesn't matter that the high bits have noise from the value.
12905  */
12906  bitC->bitPos[idx] += HUF_getNbBitsFast(elt);
12907  assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER);
12908  /* The last 4-bits of elt are dirty if fast is set,
12909  * so we must not be overwriting bits that have already been
12910  * inserted into the bit container.
12911  */
12912 #if DEBUGLEVEL >= 1
12913  {
12914  size_t const nbBits = HUF_getNbBits(elt);
12915  size_t const dirtyBits = nbBits == 0 ? 0 : ZSTD_highbit32((U32)nbBits) + 1;
12916  (void)dirtyBits;
12917  /* Middle bits are 0. */
12918  assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0);
12919  /* We didn't overwrite any bits in the bit container. */
12920  assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER);
12921  (void)dirtyBits;
12922  }
12923 #endif
12924 }
12925 
12927 {
12928  bitC->bitContainer[1] = 0;
12929  bitC->bitPos[1] = 0;
12930 }
12931 
12937 {
12938  assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER);
12939  bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF);
12940  bitC->bitContainer[0] |= bitC->bitContainer[1];
12941  bitC->bitPos[0] += bitC->bitPos[1];
12942  assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER);
12943 }
12944 
12953 {
12954  /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */
12955  size_t const nbBits = bitC->bitPos[0] & 0xFF;
12956  size_t const nbBytes = nbBits >> 3;
12957  /* The top nbBits bits of bitContainer are the ones we need. */
12958  size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits);
12959  /* Mask bitPos to account for the bytes we consumed. */
12960  bitC->bitPos[0] &= 7;
12961  assert(nbBits > 0);
12962  assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8);
12963  assert(bitC->ptr <= bitC->endPtr);
12964  MEM_writeLEST(bitC->ptr, bitContainer);
12965  bitC->ptr += nbBytes;
12966  assert(!kFast || bitC->ptr <= bitC->endPtr);
12967  if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
12968  /* bitContainer doesn't need to be modified because the leftover
12969  * bits are already the top bitPos bits. And we don't care about
12970  * noise in the lower values.
12971  */
12972 }
12973 
12977 static HUF_CElt HUF_endMark(void)
12978 {
12979  HUF_CElt endMark;
12980  HUF_setNbBits(&endMark, 1);
12981  HUF_setValue(&endMark, 1);
12982  return endMark;
12983 }
12984 
12988 static size_t HUF_closeCStream(HUF_CStream_t* bitC)
12989 {
12990  HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0);
12991  HUF_flushBits(bitC, /* kFast */ 0);
12992  {
12993  size_t const nbBits = bitC->bitPos[0] & 0xFF;
12994  if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
12995  return (size_t)(bitC->ptr - bitC->startPtr) + (nbBits > 0);
12996  }
12997 }
12998 
13000 HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast)
13001 {
13002  HUF_addBits(bitCPtr, CTable[symbol], idx, fast);
13003 }
13004 
13007  const BYTE* ip, size_t srcSize,
13008  const HUF_CElt* ct,
13009  int kUnroll, int kFastFlush, int kLastFast)
13010 {
13011  /* Join to kUnroll */
13012  int n = (int)srcSize;
13013  int rem = n % kUnroll;
13014  if (rem > 0) {
13015  for (; rem > 0; --rem) {
13016  HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0);
13017  }
13018  HUF_flushBits(bitC, kFastFlush);
13019  }
13020  assert(n % kUnroll == 0);
13021 
13022  /* Join to 2 * kUnroll */
13023  if (n % (2 * kUnroll)) {
13024  int u;
13025  for (u = 1; u < kUnroll; ++u) {
13026  HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1);
13027  }
13028  HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast);
13029  HUF_flushBits(bitC, kFastFlush);
13030  n -= kUnroll;
13031  }
13032  assert(n % (2 * kUnroll) == 0);
13033 
13034  for (; n>0; n-= 2 * kUnroll) {
13035  /* Encode kUnroll symbols into the bitstream @ index 0. */
13036  int u;
13037  for (u = 1; u < kUnroll; ++u) {
13038  HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1);
13039  }
13040  HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast);
13041  HUF_flushBits(bitC, kFastFlush);
13042  /* Encode kUnroll symbols into the bitstream @ index 1.
13043  * This allows us to start filling the bit container
13044  * without any data dependencies.
13045  */
13046  HUF_zeroIndex1(bitC);
13047  for (u = 1; u < kUnroll; ++u) {
13048  HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1);
13049  }
13050  HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast);
13051  /* Merge bitstream @ index 1 into the bitstream @ index 0 */
13052  HUF_mergeIndex1(bitC);
13053  HUF_flushBits(bitC, kFastFlush);
13054  }
13055  assert(n == 0);
13056 
13057 }
13058 
13064 static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog)
13065 {
13066  return ((srcSize * tableLog) >> 3) + 8;
13067 }
13068 
13069 
13070 FORCE_INLINE_TEMPLATE size_t
13072  const void* src, size_t srcSize,
13073  const HUF_CElt* CTable)
13074 {
13075  U32 const tableLog = (U32)CTable[0];
13076  HUF_CElt const* ct = CTable + 1;
13077  const BYTE* ip = (const BYTE*) src;
13078  BYTE* const ostart = (BYTE*)dst;
13079  BYTE* const oend = ostart + dstSize;
13080  BYTE* op = ostart;
13081  HUF_CStream_t bitC;
13082 
13083  /* init */
13084  if (dstSize < 8) return 0; /* not enough space to compress */
13085  { size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op));
13086  if (HUF_isError(initErr)) return 0; }
13087 
13088  if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11)
13089  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0);
13090  else {
13091  if (MEM_32bits()) {
13092  switch (tableLog) {
13093  case 11:
13094  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0);
13095  break;
13096  case 10: ZSTD_FALLTHROUGH;
13097  case 9: ZSTD_FALLTHROUGH;
13098  case 8:
13099  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1);
13100  break;
13101  case 7: ZSTD_FALLTHROUGH;
13102  default:
13103  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1);
13104  break;
13105  }
13106  } else {
13107  switch (tableLog) {
13108  case 11:
13109  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0);
13110  break;
13111  case 10:
13112  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1);
13113  break;
13114  case 9:
13115  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0);
13116  break;
13117  case 8:
13118  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0);
13119  break;
13120  case 7:
13121  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0);
13122  break;
13123  case 6: ZSTD_FALLTHROUGH;
13124  default:
13125  HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1);
13126  break;
13127  }
13128  }
13129  }
13130  assert(bitC.ptr <= bitC.endPtr);
13131 
13132  return HUF_closeCStream(&bitC);
13133 }
13134 
13135 #if DYNAMIC_BMI2
13136 
13137 static BMI2_TARGET_ATTRIBUTE size_t
13138 HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize,
13139  const void* src, size_t srcSize,
13140  const HUF_CElt* CTable)
13141 {
13142  return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
13143 }
13144 
13145 static size_t
13146 HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize,
13147  const void* src, size_t srcSize,
13148  const HUF_CElt* CTable)
13149 {
13150  return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
13151 }
13152 
13153 static size_t
13154 HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
13155  const void* src, size_t srcSize,
13156  const HUF_CElt* CTable, const int flags)
13157 {
13158  if (flags & HUF_flags_bmi2) {
13159  return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);
13160  }
13161  return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable);
13162 }
13163 
13164 #else
13165 
13166 static size_t
13168  const void* src, size_t srcSize,
13169  const HUF_CElt* CTable, const int flags)
13170 {
13171  (void)flags;
13172  return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
13173 }
13174 
13175 #endif
13176 
13177 size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags)
13178 {
13179  return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
13180 }
13181 
13182 static size_t
13184  const void* src, size_t srcSize,
13185  const HUF_CElt* CTable, int flags)
13186 {
13187  size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
13188  const BYTE* ip = (const BYTE*) src;
13189  const BYTE* const iend = ip + srcSize;
13190  BYTE* const ostart = (BYTE*) dst;
13191  BYTE* const oend = ostart + dstSize;
13192  BYTE* op = ostart;
13193 
13194  if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */
13195  if (srcSize < 12) return 0; /* no saving possible : too small input */
13196  op += 6; /* jumpTable */
13197 
13198  assert(op <= oend);
13199  { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
13200  if (cSize == 0 || cSize > 65535) return 0;
13201  MEM_writeLE16(ostart, (U16)cSize);
13202  op += cSize;
13203  }
13204 
13205  ip += segmentSize;
13206  assert(op <= oend);
13207  { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
13208  if (cSize == 0 || cSize > 65535) return 0;
13209  MEM_writeLE16(ostart+2, (U16)cSize);
13210  op += cSize;
13211  }
13212 
13213  ip += segmentSize;
13214  assert(op <= oend);
13215  { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) );
13216  if (cSize == 0 || cSize > 65535) return 0;
13217  MEM_writeLE16(ostart+4, (U16)cSize);
13218  op += cSize;
13219  }
13220 
13221  ip += segmentSize;
13222  assert(op <= oend);
13223  assert(ip <= iend);
13224  { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) );
13225  if (cSize == 0 || cSize > 65535) return 0;
13226  op += cSize;
13227  }
13228 
13229  return (size_t)(op-ostart);
13230 }
13231 
13232 size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags)
13233 {
13234  return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags);
13235 }
13236 
13238 
13240  BYTE* const ostart, BYTE* op, BYTE* const oend,
13241  const void* src, size_t srcSize,
13242  HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags)
13243 {
13244  size_t const cSize = (nbStreams==HUF_singleStream) ?
13245  HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags) :
13246  HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags);
13247  if (HUF_isError(cSize)) { return cSize; }
13248  if (cSize==0) { return 0; } /* uncompressible */
13249  op += cSize;
13250  /* check compressibility */
13251  assert(op >= ostart);
13252  if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
13253  return (size_t)(op-ostart);
13254 }
13255 
13256 typedef struct {
13259  union {
13263  } wksps;
13265 
13266 #define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096
13267 #define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */
13268 
13269 unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue)
13270 {
13271  unsigned cardinality = 0;
13272  unsigned i;
13273 
13274  for (i = 0; i < maxSymbolValue + 1; i++) {
13275  if (count[i] != 0) cardinality += 1;
13276  }
13277 
13278  return cardinality;
13279 }
13280 
13281 unsigned HUF_minTableLog(unsigned symbolCardinality)
13282 {
13283  U32 minBitsSymbols = ZSTD_highbit32(symbolCardinality) + 1;
13284  return minBitsSymbols;
13285 }
13286 
13288  unsigned maxTableLog,
13289  size_t srcSize,
13290  unsigned maxSymbolValue,
13291  void* workSpace, size_t wkspSize,
13292  HUF_CElt* table,
13293  const unsigned* count,
13294  int flags)
13295 {
13296  assert(srcSize > 1); /* Not supported, RLE should be used instead */
13297  assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables));
13298 
13299  if (!(flags & HUF_flags_optimalDepth)) {
13300  /* cheap evaluation, based on FSE */
13301  return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
13302  }
13303 
13304  { BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp);
13305  size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp);
13306  size_t maxBits, hSize, newSize;
13307  const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue);
13308  const unsigned minTableLog = HUF_minTableLog(symbolCardinality);
13309  size_t optSize = ((size_t) ~0) - 1;
13310  unsigned optLog = maxTableLog, optLogGuess;
13311 
13312  DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize);
13313 
13314  /* Search until size increases */
13315  for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) {
13316  DEBUGLOG(7, "checking for huffLog=%u", optLogGuess);
13317  maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize);
13318  if (ERR_isError(maxBits)) continue;
13319 
13320  if (maxBits < optLogGuess && optLogGuess > minTableLog) break;
13321 
13322  hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize);
13323 
13324  if (ERR_isError(hSize)) continue;
13325 
13326  newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize;
13327 
13328  if (newSize > optSize + 1) {
13329  break;
13330  }
13331 
13332  if (newSize < optSize) {
13333  optSize = newSize;
13334  optLog = optLogGuess;
13335  }
13336  }
13337  assert(optLog <= HUF_TABLELOG_MAX);
13338  return optLog;
13339  }
13340 }
13341 
13342 /* HUF_compress_internal() :
13343  * `workSpace_align4` must be aligned on 4-bytes boundaries,
13344  * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */
13345 static size_t
13346 HUF_compress_internal (void* dst, size_t dstSize,
13347  const void* src, size_t srcSize,
13348  unsigned maxSymbolValue, unsigned huffLog,
13349  HUF_nbStreams_e nbStreams,
13350  void* workSpace, size_t wkspSize,
13351  HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags)
13352 {
13353  HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t));
13354  BYTE* const ostart = (BYTE*)dst;
13355  BYTE* const oend = ostart + dstSize;
13356  BYTE* op = ostart;
13357 
13358  DEBUGLOG(5, "HUF_compress_internal (srcSize=%zu)", srcSize);
13360 
13361  /* checks & inits */
13362  if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall);
13363  if (!srcSize) return 0; /* Uncompressed */
13364  if (!dstSize) return 0; /* cannot fit anything within dst budget */
13365  if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
13366  if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
13367  if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
13368  if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
13369  if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
13370 
13371  /* Heuristic : If old table is valid, use it for small inputs */
13372  if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) {
13373  return HUF_compressCTable_internal(ostart, op, oend,
13374  src, srcSize,
13375  nbStreams, oldHufTable, flags);
13376  }
13377 
13378  /* If uncompressible data is suspected, do a smaller sampling first */
13381  size_t largestTotal = 0;
13382  DEBUGLOG(5, "input suspected incompressible : sampling to check");
13383  { unsigned maxSymbolValueBegin = maxSymbolValue;
13384  CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) );
13385  largestTotal += largestBegin;
13386  }
13387  { unsigned maxSymbolValueEnd = maxSymbolValue;
13388  CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) );
13389  largestTotal += largestEnd;
13390  }
13391  if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */
13392  }
13393 
13394  /* Scan input and build symbol stats */
13395  { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) );
13396  if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
13397  if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
13398  }
13399  DEBUGLOG(6, "histogram detail completed (%zu symbols)", showU32(table->count, maxSymbolValue+1));
13400 
13401  /* Check validity of previous table */
13402  if ( repeat
13403  && *repeat == HUF_repeat_check
13404  && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) {
13405  *repeat = HUF_repeat_none;
13406  }
13407  /* Heuristic : use existing table for small inputs */
13408  if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) {
13409  return HUF_compressCTable_internal(ostart, op, oend,
13410  src, srcSize,
13411  nbStreams, oldHufTable, flags);
13412  }
13413 
13414  /* Build Huffman Tree */
13415  huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags);
13416  { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
13417  maxSymbolValue, huffLog,
13418  &table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp));
13419  CHECK_F(maxBits);
13420  huffLog = (U32)maxBits;
13421  DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1));
13422  }
13423  /* Zero unused symbols in CTable, so we can check it for validity */
13424  {
13425  size_t const ctableSize = HUF_CTABLE_SIZE_ST(maxSymbolValue);
13426  size_t const unusedSize = sizeof(table->CTable) - ctableSize * sizeof(HUF_CElt);
13427  ZSTD_memset(table->CTable + ctableSize, 0, unusedSize);
13428  }
13429 
13430  /* Write table description header */
13431  { CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog,
13432  &table->wksps.writeCTable_wksp, sizeof(table->wksps.writeCTable_wksp)) );
13433  /* Check if using previous huffman table is beneficial */
13434  if (repeat && *repeat != HUF_repeat_none) {
13435  size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue);
13436  size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue);
13437  if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
13438  return HUF_compressCTable_internal(ostart, op, oend,
13439  src, srcSize,
13440  nbStreams, oldHufTable, flags);
13441  } }
13442 
13443  /* Use the new huffman table */
13444  if (hSize + 12ul >= srcSize) { return 0; }
13445  op += hSize;
13446  if (repeat) { *repeat = HUF_repeat_none; }
13447  if (oldHufTable)
13448  ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
13449  }
13450  return HUF_compressCTable_internal(ostart, op, oend,
13451  src, srcSize,
13452  nbStreams, table->CTable, flags);
13453 }
13454 
13455 size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
13456  const void* src, size_t srcSize,
13457  unsigned maxSymbolValue, unsigned huffLog,
13458  void* workSpace, size_t wkspSize,
13459  HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
13460 {
13461  DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize);
13462  return HUF_compress_internal(dst, dstSize, src, srcSize,
13463  maxSymbolValue, huffLog, HUF_singleStream,
13464  workSpace, wkspSize, hufTable,
13465  repeat, flags);
13466 }
13467 
13468 /* HUF_compress4X_repeat():
13469  * compress input using 4 streams.
13470  * consider skipping quickly
13471  * re-use an existing huffman compression table */
13472 size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
13473  const void* src, size_t srcSize,
13474  unsigned maxSymbolValue, unsigned huffLog,
13475  void* workSpace, size_t wkspSize,
13476  HUF_CElt* hufTable, HUF_repeat* repeat, int flags)
13477 {
13478  DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize);
13479  return HUF_compress_internal(dst, dstSize, src, srcSize,
13480  maxSymbolValue, huffLog, HUF_fourStreams,
13481  workSpace, wkspSize,
13482  hufTable, repeat, flags);
13483 }
13484 /**** ended inlining compress/huf_compress.c ****/
13485 /**** start inlining compress/zstd_compress_literals.c ****/
13486 /*
13487  * Copyright (c) Meta Platforms, Inc. and affiliates.
13488  * All rights reserved.
13489  *
13490  * This source code is licensed under both the BSD-style license (found in the
13491  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
13492  * in the COPYING file in the root directory of this source tree).
13493  * You may select, at your option, one of the above-listed licenses.
13494  */
13495 
13496  /*-*************************************
13497  * Dependencies
13498  ***************************************/
13499 /**** start inlining zstd_compress_literals.h ****/
13500 /*
13501  * Copyright (c) Meta Platforms, Inc. and affiliates.
13502  * All rights reserved.
13503  *
13504  * This source code is licensed under both the BSD-style license (found in the
13505  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
13506  * in the COPYING file in the root directory of this source tree).
13507  * You may select, at your option, one of the above-listed licenses.
13508  */
13509 
13510 #ifndef ZSTD_COMPRESS_LITERALS_H
13511 #define ZSTD_COMPRESS_LITERALS_H
13512 
13513 /**** start inlining zstd_compress_internal.h ****/
13514 /*
13515  * Copyright (c) Meta Platforms, Inc. and affiliates.
13516  * All rights reserved.
13517  *
13518  * This source code is licensed under both the BSD-style license (found in the
13519  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
13520  * in the COPYING file in the root directory of this source tree).
13521  * You may select, at your option, one of the above-listed licenses.
13522  */
13523 
13524 /* This header contains definitions
13525  * that shall **only** be used by modules within lib/compress.
13526  */
13527 
13528 #ifndef ZSTD_COMPRESS_H
13529 #define ZSTD_COMPRESS_H
13530 
13531 /*-*************************************
13532 * Dependencies
13533 ***************************************/
13534 /**** skipping file: ../common/zstd_internal.h ****/
13535 /**** start inlining zstd_cwksp.h ****/
13536 /*
13537  * Copyright (c) Meta Platforms, Inc. and affiliates.
13538  * All rights reserved.
13539  *
13540  * This source code is licensed under both the BSD-style license (found in the
13541  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
13542  * in the COPYING file in the root directory of this source tree).
13543  * You may select, at your option, one of the above-listed licenses.
13544  */
13545 
13546 #ifndef ZSTD_CWKSP_H
13547 #define ZSTD_CWKSP_H
13548 
13549 /*-*************************************
13550 * Dependencies
13551 ***************************************/
13552 /**** skipping file: ../common/allocations.h ****/
13553 /**** skipping file: ../common/zstd_internal.h ****/
13554 /**** skipping file: ../common/portability_macros.h ****/
13555 
13556 #if defined (__cplusplus)
13557 extern "C" {
13558 #endif
13559 
13560 /*-*************************************
13561 * Constants
13562 ***************************************/
13563 
13564 /* Since the workspace is effectively its own little malloc implementation /
13565  * arena, when we run under ASAN, we should similarly insert redzones between
13566  * each internal element of the workspace, so ASAN will catch overruns that
13567  * reach outside an object but that stay inside the workspace.
13568  *
13569  * This defines the size of that redzone.
13570  */
13571 #ifndef ZSTD_CWKSP_ASAN_REDZONE_SIZE
13572 #define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128
13573 #endif
13574 
13575 
13576 /* Set our tables and aligneds to align by 64 bytes */
13577 #define ZSTD_CWKSP_ALIGNMENT_BYTES 64
13578 
13579 /*-*************************************
13580 * Structures
13581 ***************************************/
13582 typedef enum {
13588 
13594 typedef enum {
13598 
13693 typedef struct {
13694  void* workspace;
13696 
13697  void* objectEnd;
13698  void* tableEnd;
13700  void* allocStart;
13702 
13707 } ZSTD_cwksp;
13708 
13709 /*-*************************************
13710 * Functions
13711 ***************************************/
13712 
13715 
13717  (void)ws;
13718  assert(ws->workspace <= ws->objectEnd);
13719  assert(ws->objectEnd <= ws->tableEnd);
13720  assert(ws->objectEnd <= ws->tableValidEnd);
13721  assert(ws->tableEnd <= ws->allocStart);
13722  assert(ws->tableValidEnd <= ws->allocStart);
13723  assert(ws->allocStart <= ws->workspaceEnd);
13724  assert(ws->initOnceStart <= ZSTD_cwksp_initialAllocStart(ws));
13725  assert(ws->workspace <= ws->initOnceStart);
13726 #if ZSTD_MEMORY_SANITIZER
13727  {
13728  intptr_t const offset = __msan_test_shadow(ws->initOnceStart,
13729  (U8*)ZSTD_cwksp_initialAllocStart(ws) - (U8*)ws->initOnceStart);
13730 #if defined(ZSTD_MSAN_PRINT)
13731  if(offset!=-1) {
13732  __msan_print_shadow((U8*)ws->initOnceStart + offset - 8, 32);
13733  }
13734 #endif
13735  assert(offset==-1);
13736  };
13737 #endif
13738 }
13739 
13743 MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) {
13744  size_t const mask = align - 1;
13745  assert((align & mask) == 0);
13746  return (size + mask) & ~mask;
13747 }
13748 
13762  if (size == 0)
13763  return 0;
13764 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
13765  return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
13766 #else
13767  return size;
13768 #endif
13769 }
13770 
13777 }
13778 
13784  /* For alignment, the wksp will always allocate an additional 2*ZSTD_CWKSP_ALIGNMENT_BYTES
13785  * bytes to align the beginning of tables section and end of buffers;
13786  */
13787  size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES * 2;
13788  return slackSpace;
13789 }
13790 
13791 
13796 MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) {
13797  size_t const alignBytesMask = alignBytes - 1;
13798  size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask;
13799  assert((alignBytes & alignBytesMask) == 0);
13800  assert(bytes < alignBytes);
13801  return bytes;
13802 }
13803 
13809  return (void*)((size_t)ws->workspaceEnd & ~(ZSTD_CWKSP_ALIGNMENT_BYTES-1));
13810 }
13811 
13819 MEM_STATIC void*
13821 {
13822  void* const alloc = (BYTE*)ws->allocStart - bytes;
13823  void* const bottom = ws->tableEnd;
13824  DEBUGLOG(5, "cwksp: reserving %p %zd bytes, %zd bytes remaining",
13827  assert(alloc >= bottom);
13828  if (alloc < bottom) {
13829  DEBUGLOG(4, "cwksp: alloc failed!");
13830  ws->allocFailed = 1;
13831  return NULL;
13832  }
13833  /* the area is reserved from the end of wksp.
13834  * If it overlaps with tableValidEnd, it voids guarantees on values' range */
13835  if (alloc < ws->tableValidEnd) {
13836  ws->tableValidEnd = alloc;
13837  }
13838  ws->allocStart = alloc;
13839  return alloc;
13840 }
13841 
13847 MEM_STATIC size_t
13849 {
13850  assert(phase >= ws->phase);
13851  if (phase > ws->phase) {
13852  /* Going from allocating objects to allocating initOnce / tables */
13853  if (ws->phase < ZSTD_cwksp_alloc_aligned_init_once &&
13855  ws->tableValidEnd = ws->objectEnd;
13856  ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws);
13857 
13858  { /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */
13859  void *const alloc = ws->objectEnd;
13860  size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES);
13861  void *const objectEnd = (BYTE *) alloc + bytesToAlign;
13862  DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign);
13863  RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation,
13864  "table phase - alignment initial allocation failed!");
13865  ws->objectEnd = objectEnd;
13866  ws->tableEnd = objectEnd; /* table area starts being empty */
13867  if (ws->tableValidEnd < ws->tableEnd) {
13868  ws->tableValidEnd = ws->tableEnd;
13869  }
13870  }
13871  }
13872  ws->phase = phase;
13874  }
13875  return 0;
13876 }
13877 
13882 {
13883  return (ptr != NULL) && (ws->workspace <= ptr) && (ptr < ws->workspaceEnd);
13884 }
13885 
13889 MEM_STATIC void*
13891 {
13892  void* alloc;
13893  if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) {
13894  return NULL;
13895  }
13896 
13897 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
13898  /* over-reserve space */
13900 #endif
13901 
13903 
13904 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
13905  /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
13906  * either size. */
13907  if (alloc) {
13908  alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
13909  if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
13910  /* We need to keep the redzone poisoned while unpoisoning the bytes that
13911  * are actually allocated. */
13912  __asan_unpoison_memory_region(alloc, bytes - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE);
13913  }
13914  }
13915 #endif
13916 
13917  return alloc;
13918 }
13919 
13924 {
13926 }
13927 
13938 {
13939  size_t const alignedBytes = ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES);
13941  assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
13942  if(ptr && ptr < ws->initOnceStart) {
13943  /* We assume the memory following the current allocation is either:
13944  * 1. Not usable as initOnce memory (end of workspace)
13945  * 2. Another initOnce buffer that has been allocated before (and so was previously memset)
13946  * 3. An ASAN redzone, in which case we don't want to write on it
13947  * For these reasons it should be fine to not explicitly zero every byte up to ws->initOnceStart.
13948  * Note that we assume here that MSAN and ASAN cannot run in the same time. */
13949  ZSTD_memset(ptr, 0, MIN((size_t)((U8*)ws->initOnceStart - (U8*)ptr), alignedBytes));
13950  ws->initOnceStart = ptr;
13951  }
13952 #if ZSTD_MEMORY_SANITIZER
13953  assert(__msan_test_shadow(ptr, bytes) == -1);
13954 #endif
13955  return ptr;
13956 }
13957 
13962 {
13965  assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
13966  return ptr;
13967 }
13968 
13975 {
13977  void* alloc;
13978  void* end;
13979  void* top;
13980 
13981  /* We can only start allocating tables after we are done reserving space for objects at the
13982  * start of the workspace */
13983  if(ws->phase < phase) {
13985  return NULL;
13986  }
13987  }
13988  alloc = ws->tableEnd;
13989  end = (BYTE *)alloc + bytes;
13990  top = ws->allocStart;
13991 
13992  DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining",
13994  assert((bytes & (sizeof(U32)-1)) == 0);
13996  assert(end <= top);
13997  if (end > top) {
13998  DEBUGLOG(4, "cwksp: table alloc failed!");
13999  ws->allocFailed = 1;
14000  return NULL;
14001  }
14002  ws->tableEnd = end;
14003 
14004 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
14005  if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
14006  __asan_unpoison_memory_region(alloc, bytes);
14007  }
14008 #endif
14009 
14010  assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0);
14011  assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1))== 0);
14012  return alloc;
14013 }
14014 
14020 {
14021  size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*));
14022  void* alloc = ws->objectEnd;
14023  void* end = (BYTE*)alloc + roundedBytes;
14024 
14025 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
14026  /* over-reserve space */
14027  end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;
14028 #endif
14029 
14030  DEBUGLOG(4,
14031  "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining",
14032  alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes);
14033  assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0);
14034  assert(bytes % ZSTD_ALIGNOF(void*) == 0);
14036  /* we must be in the first phase, no advance is possible */
14037  if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) {
14038  DEBUGLOG(3, "cwksp: object alloc failed!");
14039  ws->allocFailed = 1;
14040  return NULL;
14041  }
14042  ws->objectEnd = end;
14043  ws->tableEnd = end;
14044  ws->tableValidEnd = end;
14045 
14046 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
14047  /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on
14048  * either size. */
14049  alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;
14050  if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
14051  __asan_unpoison_memory_region(alloc, bytes);
14052  }
14053 #endif
14054 
14055  return alloc;
14056 }
14057 
14059 {
14060  DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty");
14061 
14062 #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
14063  /* To validate that the table re-use logic is sound, and that we don't
14064  * access table space that we haven't cleaned, we re-"poison" the table
14065  * space every time we mark it dirty.
14066  * Since tableValidEnd space and initOnce space may overlap we don't poison
14067  * the initOnce portion as it break its promise. This means that this poisoning
14068  * check isn't always applied fully. */
14069  {
14070  size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;
14071  assert(__msan_test_shadow(ws->objectEnd, size) == -1);
14072  if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) {
14073  __msan_poison(ws->objectEnd, size);
14074  } else {
14075  assert(ws->initOnceStart >= ws->objectEnd);
14076  __msan_poison(ws->objectEnd, (BYTE*)ws->initOnceStart - (BYTE*)ws->objectEnd);
14077  }
14078  }
14079 #endif
14080 
14081  assert(ws->tableValidEnd >= ws->objectEnd);
14082  assert(ws->tableValidEnd <= ws->allocStart);
14083  ws->tableValidEnd = ws->objectEnd;
14085 }
14086 
14088  DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_clean");
14089  assert(ws->tableValidEnd >= ws->objectEnd);
14090  assert(ws->tableValidEnd <= ws->allocStart);
14091  if (ws->tableValidEnd < ws->tableEnd) {
14092  ws->tableValidEnd = ws->tableEnd;
14093  }
14095 }
14096 
14101  DEBUGLOG(4, "cwksp: ZSTD_cwksp_clean_tables");
14102  assert(ws->tableValidEnd >= ws->objectEnd);
14103  assert(ws->tableValidEnd <= ws->allocStart);
14104  if (ws->tableValidEnd < ws->tableEnd) {
14105  ZSTD_memset(ws->tableValidEnd, 0, (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd));
14106  }
14108 }
14109 
14115  DEBUGLOG(4, "cwksp: clearing tables!");
14116 
14117 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
14118  /* We don't do this when the workspace is statically allocated, because
14119  * when that is the case, we have no capability to hook into the end of the
14120  * workspace's lifecycle to unpoison the memory.
14121  */
14122  if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
14123  size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;
14124  __asan_poison_memory_region(ws->objectEnd, size);
14125  }
14126 #endif
14127 
14128  ws->tableEnd = ws->objectEnd;
14130 }
14131 
14137  DEBUGLOG(4, "cwksp: clearing!");
14138 
14139 #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
14140  /* To validate that the context re-use logic is sound, and that we don't
14141  * access stuff that this compression hasn't initialized, we re-"poison"
14142  * the workspace except for the areas in which we expect memory re-use
14143  * without initialization (objects, valid tables area and init once
14144  * memory). */
14145  {
14146  if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) {
14147  size_t size = (BYTE*)ws->initOnceStart - (BYTE*)ws->tableValidEnd;
14148  __msan_poison(ws->tableValidEnd, size);
14149  }
14150  }
14151 #endif
14152 
14153 #if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)
14154  /* We don't do this when the workspace is statically allocated, because
14155  * when that is the case, we have no capability to hook into the end of the
14156  * workspace's lifecycle to unpoison the memory.
14157  */
14158  if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) {
14159  size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd;
14160  __asan_poison_memory_region(ws->objectEnd, size);
14161  }
14162 #endif
14163 
14164  ws->tableEnd = ws->objectEnd;
14165  ws->allocStart = ZSTD_cwksp_initialAllocStart(ws);
14166  ws->allocFailed = 0;
14167  if (ws->phase > ZSTD_cwksp_alloc_aligned_init_once) {
14169  }
14171 }
14172 
14179  DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size);
14180  assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
14181  ws->workspace = start;
14182  ws->workspaceEnd = (BYTE*)start + size;
14183  ws->objectEnd = ws->workspace;
14184  ws->tableValidEnd = ws->objectEnd;
14185  ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws);
14186  ws->phase = ZSTD_cwksp_alloc_objects;
14187  ws->isStatic = isStatic;
14189  ws->workspaceOversizedDuration = 0;
14191 }
14192 
14193 MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {
14194  void* workspace = ZSTD_customMalloc(size, customMem);
14195  DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size);
14196  RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!");
14198  return 0;
14199 }
14200 
14201 MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {
14202  void *ptr = ws->workspace;
14203  DEBUGLOG(4, "cwksp: freeing workspace");
14204  ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp));
14205  ZSTD_customFree(ptr, customMem);
14206 }
14207 
14213  *dst = *src;
14214  ZSTD_memset(src, 0, sizeof(ZSTD_cwksp));
14215 }
14216 
14218  return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace);
14219 }
14220 
14222  return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace)
14223  + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart);
14224 }
14225 
14227  return ws->allocFailed;
14228 }
14229 
14230 /*-*************************************
14231 * Functions Checking Free Space
14232 ***************************************/
14233 
14234 /* ZSTD_alignmentSpaceWithinBounds() :
14235  * Returns if the estimated space needed for a wksp is within an acceptable limit of the
14236  * actual amount of space used.
14237  */
14238 MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace) {
14239  /* We have an alignment space between objects and tables between tables and buffers, so we can have up to twice
14240  * the alignment bytes difference between estimation and actual usage */
14241  return (estimatedSpace - ZSTD_cwksp_slack_space_required()) <= ZSTD_cwksp_used(ws) &&
14242  ZSTD_cwksp_used(ws) <= estimatedSpace;
14243 }
14244 
14245 
14247  return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd);
14248 }
14249 
14250 MEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp* ws, size_t additionalNeededSpace) {
14251  return ZSTD_cwksp_available_space(ws) >= additionalNeededSpace;
14252 }
14253 
14254 MEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp* ws, size_t additionalNeededSpace) {
14256  ws, additionalNeededSpace * ZSTD_WORKSPACETOOLARGE_FACTOR);
14257 }
14258 
14259 MEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp* ws, size_t additionalNeededSpace) {
14260  return ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)
14261  && ws->workspaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION;
14262 }
14263 
14265  ZSTD_cwksp* ws, size_t additionalNeededSpace) {
14266  if (ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)) {
14267  ws->workspaceOversizedDuration++;
14268  } else {
14269  ws->workspaceOversizedDuration = 0;
14270  }
14271 }
14272 
14273 #if defined (__cplusplus)
14274 }
14275 #endif
14276 
14277 #endif /* ZSTD_CWKSP_H */
14278 /**** ended inlining zstd_cwksp.h ****/
14279 #ifdef ZSTD_MULTITHREAD
14280 /**** start inlining zstdmt_compress.h ****/
14281 /*
14282  * Copyright (c) Meta Platforms, Inc. and affiliates.
14283  * All rights reserved.
14284  *
14285  * This source code is licensed under both the BSD-style license (found in the
14286  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
14287  * in the COPYING file in the root directory of this source tree).
14288  * You may select, at your option, one of the above-listed licenses.
14289  */
14290 
14291  #ifndef ZSTDMT_COMPRESS_H
14292  #define ZSTDMT_COMPRESS_H
14293 
14294  #if defined (__cplusplus)
14295  extern "C" {
14296  #endif
14297 
14298 
14299 /* Note : This is an internal API.
14300  * These APIs used to be exposed with ZSTDLIB_API,
14301  * because it used to be the only way to invoke MT compression.
14302  * Now, you must use ZSTD_compress2 and ZSTD_compressStream2() instead.
14303  *
14304  * This API requires ZSTD_MULTITHREAD to be defined during compilation,
14305  * otherwise ZSTDMT_createCCtx*() will fail.
14306  */
14307 
14308 /* === Dependencies === */
14309 /**** skipping file: ../common/zstd_deps.h ****/
14310 #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
14311 /**** skipping file: ../zstd.h ****/
14312 
14313 
14314 /* === Constants === */
14315 #ifndef ZSTDMT_NBWORKERS_MAX /* a different value can be selected at compile time */
14316 # define ZSTDMT_NBWORKERS_MAX ((sizeof(void*)==4) /*32-bit*/ ? 64 : 256)
14317 #endif
14318 #ifndef ZSTDMT_JOBSIZE_MIN /* a different value can be selected at compile time */
14319 # define ZSTDMT_JOBSIZE_MIN (512 KB)
14320 #endif
14321 #define ZSTDMT_JOBLOG_MAX (MEM_32bits() ? 29 : 30)
14322 #define ZSTDMT_JOBSIZE_MAX (MEM_32bits() ? (512 MB) : (1024 MB))
14323 
14324 
14325 /* ========================================================
14326  * === Private interface, for use by ZSTD_compress.c ===
14327  * === Not exposed in libzstd. Never invoke directly ===
14328  * ======================================================== */
14329 
14330 /* === Memory management === */
14332 /* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */
14333 ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers,
14334  ZSTD_customMem cMem,
14335  ZSTD_threadPool *pool);
14336 size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
14337 
14338 size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
14339 
14340 /* === Streaming functions === */
14341 
14342 size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);
14343 
14353  const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
14354  const ZSTD_CDict* cdict,
14355  ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
14356 
14366  ZSTD_inBuffer* input,
14367  ZSTD_EndDirective endOp);
14368 
14375 size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx);
14376 
14380 void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams);
14381 
14386 ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx);
14387 
14388 
14389 #if defined (__cplusplus)
14390 }
14391 #endif
14392 
14393 #endif /* ZSTDMT_COMPRESS_H */
14394 /**** ended inlining zstdmt_compress.h ****/
14395 #endif
14396 /**** skipping file: ../common/bits.h ****/
14397 
14398 #if defined (__cplusplus)
14399 extern "C" {
14400 #endif
14401 
14402 /*-*************************************
14403 * Constants
14404 ***************************************/
14405 #define kSearchStrength 8
14406 #define HASH_READ_SIZE 8
14407 #define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted".
14408  It could be confused for a real successor at index "1", if sorted as larger than its predecessor.
14409  It's not a big deal though : candidate will just be sorted again.
14410  Additionally, candidate position 1 will be lost.
14411  But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
14412  The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.
14413  This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
14415 
14416 /*-*************************************
14417 * Context memory management
14418 ***************************************/
14420 typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage;
14421 
14422 typedef struct ZSTD_prefixDict_s {
14423  const void* dict;
14424  size_t dictSize;
14425  ZSTD_dictContentType_e dictContentType;
14428 typedef struct {
14429  void* dictBuffer;
14430  void const* dict;
14431  size_t dictSize;
14432  ZSTD_dictContentType_e dictContentType;
14433  ZSTD_CDict* cdict;
14434 } ZSTD_localDict;
14436 typedef struct {
14438  HUF_repeat repeatMode;
14441 typedef struct {
14443  FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
14445  FSE_repeat offcode_repeatMode;
14446  FSE_repeat matchlength_repeatMode;
14447  FSE_repeat litlength_repeatMode;
14449 
14450 typedef struct {
14451  ZSTD_hufCTables_t huf;
14452  ZSTD_fseCTables_t fse;
14454 
14455 /***********************************************
14456 * Entropy buffer statistics structs and funcs *
14457 ***********************************************/
14463 typedef struct {
14464  symbolEncodingType_e hType;
14465  BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
14466  size_t hufDesSize;
14474 typedef struct {
14475  symbolEncodingType_e llType;
14476  symbolEncodingType_e ofType;
14479  size_t fseTablesSize;
14480  size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
14482 
14483 typedef struct {
14484  ZSTD_hufCTablesMetadata_t hufMetadata;
14485  ZSTD_fseCTablesMetadata_t fseMetadata;
14487 
14492  const seqStore_t* seqStorePtr,
14493  const ZSTD_entropyCTables_t* prevEntropy,
14494  ZSTD_entropyCTables_t* nextEntropy,
14495  const ZSTD_CCtx_params* cctxParams,
14496  ZSTD_entropyCTablesMetadata_t* entropyMetadata,
14497  void* workspace, size_t wkspSize);
14498 
14499 /*********************************
14500 * Compression internals structs *
14501 *********************************/
14503 typedef struct {
14504  U32 off; /* Offset sumtype code for the match, using ZSTD_storeSeq() format */
14505  U32 len; /* Raw length of match */
14506 } ZSTD_match_t;
14507 
14508 typedef struct {
14509  U32 offset; /* Offset of sequence */
14510  U32 litLength; /* Length of literals prior to match */
14511  U32 matchLength; /* Raw length of match */
14512 } rawSeq;
14514 typedef struct {
14515  rawSeq* seq; /* The start of the sequences */
14516  size_t pos; /* The index in seq where reading stopped. pos <= size. */
14517  size_t posInSequence; /* The position within the sequence at seq[pos] where reading
14518  stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
14519  size_t size; /* The number of sequences. <= capacity. */
14520  size_t capacity; /* The capacity starting from `seq` pointer */
14521 } rawSeqStore_t;
14522 
14523 typedef struct {
14524  U32 idx; /* Index in array of ZSTD_Sequence */
14525  U32 posInSequence; /* Position within sequence at idx */
14526  size_t posInSrc; /* Number of bytes given by sequences provided so far */
14529 UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
14531 typedef struct {
14532  int price;
14533  U32 off;
14534  U32 mlen;
14535  U32 litlen;
14536  U32 rep[ZSTD_REP_NUM];
14541 typedef struct {
14542  /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */
14543  unsigned* litFreq; /* table of literals statistics, of size 256 */
14544  unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */
14545  unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */
14546  unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */
14547  ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_NUM+1 */
14548  ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */
14550  U32 litSum; /* nb of literals */
14551  U32 litLengthSum; /* nb of litLength codes */
14552  U32 matchLengthSum; /* nb of matchLength codes */
14553  U32 offCodeSum; /* nb of offset codes */
14554  U32 litSumBasePrice; /* to compare to log2(litfreq) */
14555  U32 litLengthSumBasePrice; /* to compare to log2(llfreq) */
14556  U32 matchLengthSumBasePrice;/* to compare to log2(mlfreq) */
14557  U32 offCodeSumBasePrice; /* to compare to log2(offreq) */
14558  ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */
14559  const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */
14560  ZSTD_paramSwitch_e literalCompressionMode;
14561 } optState_t;
14563 typedef struct {
14568 typedef struct {
14569  BYTE const* nextSrc; /* next block here to continue on current prefix */
14570  BYTE const* base; /* All regular indexes relative to this position */
14571  BYTE const* dictBase; /* extDict indexes relative to this position */
14572  U32 dictLimit; /* below that point, need extDict */
14573  U32 lowLimit; /* below that point, no more valid data */
14574  U32 nbOverflowCorrections; /* Number of times overflow correction has run since
14575  * ZSTD_window_init(). Useful for debugging coredumps
14576  * and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY.
14577  */
14579 
14580 #define ZSTD_WINDOW_START_INDEX 2
14583 
14584 #define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
14585 
14586 struct ZSTD_matchState_t {
14587  ZSTD_window_t window; /* State for window round buffer management */
14588  U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
14589  * When loadedDictEnd != 0, a dictionary is in use, and still valid.
14590  * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance.
14591  * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity().
14592  * When dict referential is copied into active context (i.e. not attached),
14593  * loadedDictEnd == dictSize, since referential starts from zero.
14594  */
14595  U32 nextToUpdate; /* index from which to continue table update */
14596  U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
14597 
14598  U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/
14599  BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */
14600  U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */
14601  U64 hashSalt; /* For row-based matchFinder: salts the hash for re-use of tag table */
14602  U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */
14603 
14605  U32* hashTable3;
14606  U32* chainTable;
14608  U32 forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
14610  int dedicatedDictSearch; /* Indicates whether this matchState is using the
14611  * dedicated dictionary search structure.
14612  */
14613  optState_t opt; /* optimal parser state */
14615  ZSTD_compressionParameters cParams;
14616  const rawSeqStore_t* ldmSeqStore;
14617 
14618  /* Controls prefetching in some dictMatchState matchfinders.
14619  * This behavior is controlled from the cctx ms.
14620  * This parameter has no effect in the cdict ms. */
14621  int prefetchCDictTables;
14623  /* When == 0, lazy match finders insert every position.
14624  * When != 0, lazy match finders only insert positions they search.
14625  * This allows them to skip much faster over incompressible data,
14626  * at a small cost to compression ratio.
14627  */
14629 };
14630 
14631 typedef struct {
14634  ZSTD_matchState_t matchState;
14637 typedef struct {
14638  U32 offset;
14641 
14642 typedef struct {
14643  BYTE const* split;
14644  U32 hash;
14645  U32 checksum;
14646  ldmEntry_t* bucket;
14649 #define LDM_BATCH_SIZE 64
14651 typedef struct {
14652  ZSTD_window_t window; /* State for the window round buffer management */
14653  ldmEntry_t* hashTable;
14654  U32 loadedDictEnd;
14655  BYTE* bucketOffsets; /* Next position in bucket to insert entry */
14656  size_t splitIndices[LDM_BATCH_SIZE];
14660 typedef struct {
14661  ZSTD_paramSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */
14662  U32 hashLog; /* Log size of hashTable */
14663  U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
14664  U32 minMatchLength; /* Minimum match length */
14665  U32 hashRateLog; /* Log number of entries to skip */
14666  U32 windowLog; /* Window log for the LDM */
14668 
14669 typedef struct {
14670  int collectSequences;
14671  ZSTD_Sequence* seqStart;
14672  size_t seqIndex;
14673  size_t maxSequences;
14674 } SeqCollector;
14677  ZSTD_format_e format;
14678  ZSTD_compressionParameters cParams;
14679  ZSTD_frameParameters fParams;
14680 
14682  int forceWindow; /* force back-references to respect limit of
14683  * 1<<wLog, even for dictionary */
14684  size_t targetCBlockSize; /* Tries to fit compressed block size to be around targetCBlockSize.
14685  * No target when targetCBlockSize == 0.
14686  * There is no guarantee on compressed block size */
14687  int srcSizeHint; /* User's best guess of source size.
14688  * Hint is not valid when srcSizeHint == 0.
14689  * There is no guarantee that hint is close to actual source size */
14691  ZSTD_dictAttachPref_e attachDictPref;
14692  ZSTD_paramSwitch_e literalCompressionMode;
14693 
14694  /* Multithreading: used to pass parameters to mtctx */
14696  size_t jobSize;
14697  int overlapLog;
14699 
14700  /* Long distance matching parameters */
14703  /* Dedicated dict search algorithm trigger */
14706  /* Input/output buffer modes */
14710  /* Sequence compression API */
14711  ZSTD_sequenceFormat_e blockDelimiters;
14713 
14714  /* Block splitting */
14715  ZSTD_paramSwitch_e useBlockSplitter;
14716 
14717  /* Param for deciding whether to use row-based matchfinder */
14718  ZSTD_paramSwitch_e useRowMatchFinder;
14719 
14720  /* Always load a dictionary in ext-dict mode (not prefix mode)? */
14722 
14723  /* Internal use, for createCCtxParams() and freeCCtxParams() only */
14724  ZSTD_customMem customMem;
14726  /* Controls prefetching in some dictMatchState matchfinders */
14727  ZSTD_paramSwitch_e prefetchCDictTables;
14728 
14729  /* Controls whether zstd will fall back to an internal matchfinder
14730  * if the external matchfinder returns an error code. */
14732 
14733  /* Indicates whether an external matchfinder has been referenced.
14734  * Users can't set this externally.
14735  * It is set internally in ZSTD_registerSequenceProducer(). */
14737 
14738  /* Adjust the max block size*/
14741  /* Controls repcode search in external sequence parsing */
14742  ZSTD_paramSwitch_e searchForExternalRepcodes;
14743 }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
14744 
14745 #define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
14746 #define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
14753 typedef enum {
14762 #define ZSTD_MAX_NB_BLOCK_SPLITS 196
14763 typedef struct {
14764  seqStore_t fullSeqStoreChunk;
14765  seqStore_t firstHalfSeqStore;
14766  seqStore_t secondHalfSeqStore;
14767  seqStore_t currSeqStore;
14768  seqStore_t nextSeqStore;
14774 /* Context for block-level external matchfinder API */
14775 typedef struct {
14776  void* mState;
14777  ZSTD_sequenceProducer_F* mFinder;
14778  ZSTD_Sequence* seqBuffer;
14779  size_t seqBufferCapacity;
14782 struct ZSTD_CCtx_s {
14784  int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
14785  int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
14786  ZSTD_CCtx_params requestedParams;
14787  ZSTD_CCtx_params appliedParams;
14788  ZSTD_CCtx_params simpleApiParams; /* Param storage used by the simple API - not sticky. Must only be used in top-level simple API functions for storage. */
14792  ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */
14793  size_t blockSize;
14794  unsigned long long pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */
14795  unsigned long long consumedSrcSize;
14796  unsigned long long producedCSize;
14798  ZSTD_customMem customMem;
14799  ZSTD_threadPool* pool;
14800  size_t staticSize;
14805  seqStore_t seqStore; /* sequences storage ptrs */
14806  ldmState_t ldmState; /* long distance matching state */
14807  rawSeq* ldmSequences; /* Storage for the ldm output sequences */
14809  rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
14811  U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
14813  /* Whether we are streaming or not */
14816  /* streaming */
14817  char* inBuff;
14818  size_t inBuffSize;
14820  size_t inBuffPos;
14822  char* outBuff;
14823  size_t outBuffSize;
14827  U32 frameEnded;
14828 
14829  /* Stable in/out buffer verification */
14831  size_t stableIn_notConsumed; /* nb bytes within stable input buffer that are said to be consumed but are not */
14832  size_t expectedOutBufferSize;
14833 
14834  /* Dictionary */
14836  const ZSTD_CDict* cdict;
14837  ZSTD_prefixDict prefixDict; /* single-usage dictionary */
14838 
14839  /* Multi-threading */
14840 #ifdef ZSTD_MULTITHREAD
14841  ZSTDMT_CCtx* mtctx;
14842 #endif
14843 
14844  /* Tracing */
14845 #if ZSTD_TRACE
14846  ZSTD_TraceCtx traceCtx;
14847 #endif
14848 
14849  /* Workspace for block splitter */
14852  /* Workspace for external matchfinder */
14854 };
14858 
14859 typedef enum {
14862  ZSTD_dictMatchState = 2,
14864 } ZSTD_dictMode_e;
14866 typedef enum {
14867  ZSTD_cpm_noAttachDict = 0, /* Compression with ZSTD_noDict or ZSTD_extDict.
14868  * In this mode we use both the srcSize and the dictSize
14869  * when selecting and adjusting parameters.
14870  */
14871  ZSTD_cpm_attachDict = 1, /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch.
14872  * In this mode we only take the srcSize into account when selecting
14873  * and adjusting parameters.
14874  */
14875  ZSTD_cpm_createCDict = 2, /* Creating a CDict.
14876  * In this mode we take both the source size and the dictionary size
14877  * into account when selecting and adjusting the parameters.
14878  */
14879  ZSTD_cpm_unknown = 3 /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
14880  * We don't know what these parameters are for. We default to the legacy
14881  * behavior of taking both the source size and the dict size into account
14882  * when selecting and adjusting parameters.
14883  */
14885 
14887  ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
14888  void const* src, size_t srcSize);
14889 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
14890 
14891 
14892 MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
14893 {
14894  static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
14895  8, 9, 10, 11, 12, 13, 14, 15,
14896  16, 16, 17, 17, 18, 18, 19, 19,
14897  20, 20, 20, 20, 21, 21, 21, 21,
14898  22, 22, 22, 22, 22, 22, 22, 22,
14899  23, 23, 23, 23, 23, 23, 23, 23,
14900  24, 24, 24, 24, 24, 24, 24, 24,
14901  24, 24, 24, 24, 24, 24, 24, 24 };
14902  static const U32 LL_deltaCode = 19;
14903  return (litLength > 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
14904 }
14905 
14906 /* ZSTD_MLcode() :
14907  * note : mlBase = matchLength - MINMATCH;
14908  * because it's the format it's stored in seqStore->sequences */
14909 MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
14910 {
14911  static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
14912  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
14913  32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
14914  38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
14915  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
14916  41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
14917  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
14918  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
14919  static const U32 ML_deltaCode = 36;
14920  return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
14921 }
14922 
14923 /* ZSTD_cParam_withinBounds:
14924  * @return 1 if value is within cParam bounds,
14925  * 0 otherwise */
14927 {
14928  ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
14929  if (ZSTD_isError(bounds.error)) return 0;
14930  if (value < bounds.lowerBound) return 0;
14931  if (value > bounds.upperBound) return 0;
14932  return 1;
14934 
14935 /* ZSTD_noCompressBlock() :
14936  * Writes uncompressed block to dst buffer from given src.
14937  * Returns the size of the block */
14938 MEM_STATIC size_t
14939 ZSTD_noCompressBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
14940 {
14941  U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
14942  DEBUGLOG(5, "ZSTD_noCompressBlock (srcSize=%zu, dstCapacity=%zu)", srcSize, dstCapacity);
14944  dstSize_tooSmall, "dst buf too small for uncompressed block");
14945  MEM_writeLE24(dst, cBlockHeader24);
14947  return ZSTD_blockHeaderSize + srcSize;
14948 }
14949 
14950 MEM_STATIC size_t
14951 ZSTD_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock)
14952 {
14953  BYTE* const op = (BYTE*)dst;
14954  U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3);
14955  RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, "");
14956  MEM_writeLE24(op, cBlockHeader);
14957  op[3] = src;
14958  return 4;
14959 }
14961 
14962 /* ZSTD_minGain() :
14963  * minimum compression required
14964  * to generate a compress block or a compressed literals section.
14965  * note : use same formula for both situations */
14966 MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
14967 {
14968  U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
14971  return (srcSize >> minlog) + 2;
14972 }
14973 
14974 MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams)
14975 {
14976  switch (cctxParams->literalCompressionMode) {
14977  case ZSTD_ps_enable:
14978  return 0;
14979  case ZSTD_ps_disable:
14980  return 1;
14981  default:
14982  assert(0 /* impossible: pre-validated */);
14984  case ZSTD_ps_auto:
14985  return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
14986  }
14987 }
14988 
14994 static void
14995 ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w)
14996 {
14997  assert(iend > ilimit_w);
14998  if (ip <= ilimit_w) {
14999  ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap);
15000  op += ilimit_w - ip;
15001  ip = ilimit_w;
15002  }
15003  while (ip < iend) *op++ = *ip++;
15007 #define REPCODE1_TO_OFFBASE REPCODE_TO_OFFBASE(1)
15008 #define REPCODE2_TO_OFFBASE REPCODE_TO_OFFBASE(2)
15009 #define REPCODE3_TO_OFFBASE REPCODE_TO_OFFBASE(3)
15010 #define REPCODE_TO_OFFBASE(r) (assert((r)>=1), assert((r)<=ZSTD_REP_NUM), (r)) /* accepts IDs 1,2,3 */
15011 #define OFFSET_TO_OFFBASE(o) (assert((o)>0), o + ZSTD_REP_NUM)
15012 #define OFFBASE_IS_OFFSET(o) ((o) > ZSTD_REP_NUM)
15013 #define OFFBASE_IS_REPCODE(o) ( 1 <= (o) && (o) <= ZSTD_REP_NUM)
15014 #define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM)
15015 #define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */
15016 
15024 ZSTD_storeSeq(seqStore_t* seqStorePtr,
15025  size_t litLength, const BYTE* literals, const BYTE* litLimit,
15026  U32 offBase,
15027  size_t matchLength)
15028 {
15029  BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH;
15030  BYTE const* const litEnd = literals + litLength;
15031 #if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6)
15032  static const BYTE* g_start = NULL;
15033  if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */
15034  { U32 const pos = (U32)((const BYTE*)literals - g_start);
15035  DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offBase%7u",
15036  pos, (U32)litLength, (U32)matchLength, (U32)offBase);
15037  }
15038 #endif
15039  assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
15040  /* copy Literals */
15041  assert(seqStorePtr->maxNbLit <= 128 KB);
15042  assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
15043  assert(literals + litLength <= litLimit);
15044  if (litEnd <= litLimit_w) {
15045  /* Common case we can use wildcopy.
15046  * First copy 16 bytes, because literals are likely short.
15047  */
15049  ZSTD_copy16(seqStorePtr->lit, literals);
15050  if (litLength > 16) {
15051  ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap);
15052  }
15053  } else {
15054  ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);
15055  }
15056  seqStorePtr->lit += litLength;
15057 
15058  /* literal Length */
15059  if (litLength>0xFFFF) {
15060  assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
15061  seqStorePtr->longLengthType = ZSTD_llt_literalLength;
15062  seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
15063  }
15064  seqStorePtr->sequences[0].litLength = (U16)litLength;
15065 
15066  /* match offset */
15067  seqStorePtr->sequences[0].offBase = offBase;
15068 
15069  /* match Length */
15070  assert(matchLength >= MINMATCH);
15071  { size_t const mlBase = matchLength - MINMATCH;
15072  if (mlBase>0xFFFF) {
15073  assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
15074  seqStorePtr->longLengthType = ZSTD_llt_matchLength;
15075  seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
15076  }
15077  seqStorePtr->sequences[0].mlBase = (U16)mlBase;
15078  }
15079 
15080  seqStorePtr->sequences++;
15081 }
15083 /* ZSTD_updateRep() :
15084  * updates in-place @rep (array of repeat offsets)
15085  * @offBase : sum-type, using numeric representation of ZSTD_storeSeq()
15086  */
15087 MEM_STATIC void
15088 ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
15089 {
15090  if (OFFBASE_IS_OFFSET(offBase)) { /* full offset */
15091  rep[2] = rep[1];
15092  rep[1] = rep[0];
15093  rep[0] = OFFBASE_TO_OFFSET(offBase);
15094  } else { /* repcode */
15095  U32 const repCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0;
15096  if (repCode > 0) { /* note : if repCode==0, no change */
15097  U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
15098  rep[2] = (repCode >= 2) ? rep[1] : rep[2];
15099  rep[1] = rep[0];
15100  rep[0] = currentOffset;
15101  } else { /* repCode == 0 */
15102  /* nothing to do */
15103  }
15104  }
15105 }
15107 typedef struct repcodes_s {
15108  U32 rep[3];
15109 } repcodes_t;
15110 
15112 ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
15113 {
15114  repcodes_t newReps;
15115  ZSTD_memcpy(&newReps, rep, sizeof(newReps));
15116  ZSTD_updateRep(newReps.rep, offBase, ll0);
15117  return newReps;
15119 
15120 
15121 /*-*************************************
15122 * Match length counter
15123 ***************************************/
15124 MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
15125 {
15126  const BYTE* const pStart = pIn;
15127  const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
15128 
15129  if (pIn < pInLoopLimit) {
15130  { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
15131  if (diff) return ZSTD_NbCommonBytes(diff); }
15132  pIn+=sizeof(size_t); pMatch+=sizeof(size_t);
15133  while (pIn < pInLoopLimit) {
15134  size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
15135  if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
15136  pIn += ZSTD_NbCommonBytes(diff);
15137  return (size_t)(pIn - pStart);
15138  } }
15139  if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
15140  if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
15141  if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
15142  return (size_t)(pIn - pStart);
15143 }
15149 MEM_STATIC size_t
15150 ZSTD_count_2segments(const BYTE* ip, const BYTE* match,
15151  const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
15152 {
15153  const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
15154  size_t const matchLength = ZSTD_count(ip, match, vEnd);
15155  if (match + matchLength != mEnd) return matchLength;
15156  DEBUGLOG(7, "ZSTD_count_2segments: found a 2-parts match (current length==%zu)", matchLength);
15157  DEBUGLOG(7, "distance from match beginning to end dictionary = %zi", mEnd - match);
15158  DEBUGLOG(7, "distance from current pos to end buffer = %zi", iEnd - ip);
15159  DEBUGLOG(7, "next byte : ip==%02X, istart==%02X", ip[matchLength], *iStart);
15160  DEBUGLOG(7, "final match length = %zu", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd));
15161  return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
15165 /*-*************************************
15166  * Hashes
15167  ***************************************/
15168 static const U32 prime3bytes = 506832829U;
15169 static U32 ZSTD_hash3(U32 u, U32 h, U32 s) { assert(h <= 32); return (((u << (32-24)) * prime3bytes) ^ s) >> (32-h) ; }
15170 MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */
15171 MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); }
15173 static const U32 prime4bytes = 2654435761U;
15174 static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; }
15175 static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); }
15176 static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); }
15178 static const U64 prime5bytes = 889523592379ULL;
15179 static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; }
15180 static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); }
15181 static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); }
15183 static const U64 prime6bytes = 227718039650203ULL;
15184 static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; }
15185 static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); }
15186 static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); }
15188 static const U64 prime7bytes = 58295818150454627ULL;
15189 static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; }
15190 static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); }
15191 static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); }
15192 
15193 static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
15194 static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; }
15195 static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); }
15196 static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); }
15197 
15198 
15200 size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
15201 {
15202  /* Although some of these hashes do support hBits up to 64, some do not.
15203  * To be on the safe side, always avoid hBits > 32. */
15204  assert(hBits <= 32);
15205 
15206  switch(mls)
15207  {
15208  default:
15209  case 4: return ZSTD_hash4Ptr(p, hBits);
15210  case 5: return ZSTD_hash5Ptr(p, hBits);
15211  case 6: return ZSTD_hash6Ptr(p, hBits);
15212  case 7: return ZSTD_hash7Ptr(p, hBits);
15213  case 8: return ZSTD_hash8Ptr(p, hBits);
15214  }
15215 }
15216 
15218 size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) {
15219  /* Although some of these hashes do support hBits up to 64, some do not.
15220  * To be on the safe side, always avoid hBits > 32. */
15221  assert(hBits <= 32);
15222 
15223  switch(mls)
15224  {
15225  default:
15226  case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt);
15227  case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt);
15228  case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt);
15229  case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt);
15230  case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt);
15231  }
15233 
15234 
15238 static U64 ZSTD_ipow(U64 base, U64 exponent)
15239 {
15240  U64 power = 1;
15241  while (exponent) {
15242  if (exponent & 1) power *= base;
15243  exponent >>= 1;
15244  base *= base;
15245  }
15246  return power;
15247 }
15249 #define ZSTD_ROLL_HASH_CHAR_OFFSET 10
15250 
15254 static U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size)
15255 {
15256  BYTE const* istart = (BYTE const*)buf;
15257  size_t pos;
15258  for (pos = 0; pos < size; ++pos) {
15259  hash *= prime8bytes;
15260  hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET;
15261  }
15262  return hash;
15263 }
15264 
15268 MEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size)
15269 {
15270  return ZSTD_rollingHash_append(0, buf, size);
15272 
15278 {
15279  return ZSTD_ipow(prime8bytes, length - 1);
15280 }
15281 
15285 MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower)
15286 {
15287  hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower;
15288  hash *= prime8bytes;
15289  hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET;
15290  return hash;
15291 }
15292 
15293 /*-*************************************
15294 * Round buffer management
15295 ***************************************/
15296 #if (ZSTD_WINDOWLOG_MAX_64 > 31)
15297 # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
15298 #endif
15299 /* Max current allowed */
15300 #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
15301 /* Maximum chunk size before overflow correction needs to be called again */
15302 #define ZSTD_CHUNKSIZE_MAX \
15303  ( ((U32)-1) /* Maximum ending current index */ \
15304  - ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */
15305 
15311 {
15312  size_t const endT = (size_t)(window->nextSrc - window->base);
15313  U32 const end = (U32)endT;
15314 
15315  window->lowLimit = end;
15316  window->dictLimit = end;
15317 }
15318 
15320 {
15321  return window.dictLimit == ZSTD_WINDOW_START_INDEX &&
15322  window.lowLimit == ZSTD_WINDOW_START_INDEX &&
15323  (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX;
15325 
15331 {
15332  return window.lowLimit < window.dictLimit;
15333 }
15341 {
15342  return ZSTD_window_hasExtDict(ms->window) ?
15343  ZSTD_extDict :
15344  ms->dictMatchState != NULL ?
15346  ZSTD_noDict;
15347 }
15348 
15349 /* Defining this macro to non-zero tells zstd to run the overflow correction
15350  * code much more frequently. This is very inefficient, and should only be
15351  * used for tests and fuzzers.
15352  */
15353 #ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
15354 # ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
15355 # define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1
15356 # else
15357 # define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0
15358 # endif
15359 #endif
15367  U32 cycleLog,
15368  U32 maxDist,
15369  U32 loadedDictEnd,
15370  void const* src)
15371 {
15372  U32 const cycleSize = 1u << cycleLog;
15373  U32 const curr = (U32)((BYTE const*)src - window.base);
15374  U32 const minIndexToOverflowCorrect = cycleSize
15375  + MAX(maxDist, cycleSize)
15377 
15378  /* Adjust the min index to backoff the overflow correction frequency,
15379  * so we don't waste too much CPU in overflow correction. If this
15380  * computation overflows we don't really care, we just need to make
15381  * sure it is at least minIndexToOverflowCorrect.
15382  */
15383  U32 const adjustment = window.nbOverflowCorrections + 1;
15384  U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment,
15385  minIndexToOverflowCorrect);
15386  U32 const indexLargeEnough = curr > adjustedIndex;
15387 
15388  /* Only overflow correct early if the dictionary is invalidated already,
15389  * so we don't hurt compression ratio.
15390  */
15391  U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
15392 
15393  return indexLargeEnough && dictionaryInvalidated;
15394 }
15402  U32 cycleLog,
15403  U32 maxDist,
15404  U32 loadedDictEnd,
15405  void const* src,
15406  void const* srcEnd)
15407 {
15408  U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
15410  if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) {
15411  return 1;
15412  }
15413  }
15414  return curr > ZSTD_CURRENT_MAX;
15415 }
15416 
15427  U32 maxDist, void const* src)
15428 {
15429  /* preemptive overflow correction:
15430  * 1. correction is large enough:
15431  * lowLimit > (3<<29) ==> current > 3<<29 + 1<<windowLog
15432  * 1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog
15433  *
15434  * current - newCurrent
15435  * > (3<<29 + 1<<windowLog) - (1<<windowLog + 1<<chainLog)
15436  * > (3<<29) - (1<<chainLog)
15437  * > (3<<29) - (1<<30) (NOTE: chainLog <= 30)
15438  * > 1<<29
15439  *
15440  * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow:
15441  * After correction, current is less than (1<<chainLog + 1<<windowLog).
15442  * In 64-bit mode we are safe, because we have 64-bit ptrdiff_t.
15443  * In 32-bit mode we are safe, because (chainLog <= 29), so
15444  * ip+ZSTD_CHUNKSIZE_MAX - cctx->base < 1<<32.
15445  * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
15446  * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
15447  */
15448  U32 const cycleSize = 1u << cycleLog;
15449  U32 const cycleMask = cycleSize - 1;
15450  U32 const curr = (U32)((BYTE const*)src - window->base);
15451  U32 const currentCycle = curr & cycleMask;
15452  /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */
15453  U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX
15454  ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX)
15455  : 0;
15456  U32 const newCurrent = currentCycle
15457  + currentCycleCorrection
15458  + MAX(maxDist, cycleSize);
15459  U32 const correction = curr - newCurrent;
15460  /* maxDist must be a power of two so that:
15461  * (newCurrent & cycleMask) == (curr & cycleMask)
15462  * This is required to not corrupt the chains / binary tree.
15463  */
15464  assert((maxDist & (maxDist - 1)) == 0);
15465  assert((curr & cycleMask) == (newCurrent & cycleMask));
15466  assert(curr > newCurrent);
15468  /* Loose bound, should be around 1<<29 (see above) */
15469  assert(correction > 1<<28);
15470  }
15471 
15472  window->base += correction;
15473  window->dictBase += correction;
15474  if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) {
15476  } else {
15477  window->lowLimit -= correction;
15478  }
15479  if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) {
15481  } else {
15482  window->dictLimit -= correction;
15483  }
15484 
15485  /* Ensure we can still reference the full window. */
15486  assert(newCurrent >= maxDist);
15487  assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX);
15488  /* Ensure that lowLimit and dictLimit didn't underflow. */
15489  assert(window->lowLimit <= newCurrent);
15490  assert(window->dictLimit <= newCurrent);
15491 
15492  ++window->nbOverflowCorrections;
15493 
15494  DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
15495  window->lowLimit);
15496  return correction;
15497 }
15498 
15522 MEM_STATIC void
15524  const void* blockEnd,
15525  U32 maxDist,
15526  U32* loadedDictEndPtr,
15527  const ZSTD_matchState_t** dictMatchStatePtr)
15528 {
15529  U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
15530  U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
15531  DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
15532  (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
15533 
15534  /* - When there is no dictionary : loadedDictEnd == 0.
15535  In which case, the test (blockEndIdx > maxDist) is merely to avoid
15536  overflowing next operation `newLowLimit = blockEndIdx - maxDist`.
15537  - When there is a standard dictionary :
15538  Index referential is copied from the dictionary,
15539  which means it starts from 0.
15540  In which case, loadedDictEnd == dictSize,
15541  and it makes sense to compare `blockEndIdx > maxDist + dictSize`
15542  since `blockEndIdx` also starts from zero.
15543  - When there is an attached dictionary :
15544  loadedDictEnd is expressed within the referential of the context,
15545  so it can be directly compared against blockEndIdx.
15546  */
15547  if (blockEndIdx > maxDist + loadedDictEnd) {
15548  U32 const newLowLimit = blockEndIdx - maxDist;
15549  if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
15550  if (window->dictLimit < window->lowLimit) {
15551  DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u",
15552  (unsigned)window->dictLimit, (unsigned)window->lowLimit);
15553  window->dictLimit = window->lowLimit;
15554  }
15555  /* On reaching window size, dictionaries are invalidated */
15556  if (loadedDictEndPtr) *loadedDictEndPtr = 0;
15557  if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
15558  }
15559 }
15560 
15561 /* Similar to ZSTD_window_enforceMaxDist(),
15562  * but only invalidates dictionary
15563  * when input progresses beyond window size.
15564  * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL)
15565  * loadedDictEnd uses same referential as window->base
15566  * maxDist is the window size */
15567 MEM_STATIC void
15569  const void* blockEnd,
15570  U32 maxDist,
15571  U32* loadedDictEndPtr,
15572  const ZSTD_matchState_t** dictMatchStatePtr)
15573 {
15574  assert(loadedDictEndPtr != NULL);
15575  assert(dictMatchStatePtr != NULL);
15576  { U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
15577  U32 const loadedDictEnd = *loadedDictEndPtr;
15578  DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
15579  (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
15580  assert(blockEndIdx >= loadedDictEnd);
15581 
15582  if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) {
15583  /* On reaching window size, dictionaries are invalidated.
15584  * For simplification, if window size is reached anywhere within next block,
15585  * the dictionary is invalidated for the full block.
15586  *
15587  * We also have to invalidate the dictionary if ZSTD_window_update() has detected
15588  * non-contiguous segments, which means that loadedDictEnd != window->dictLimit.
15589  * loadedDictEnd may be 0, if forceWindow is true, but in that case we never use
15590  * dictMatchState, so setting it to NULL is not a problem.
15591  */
15592  DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)");
15593  *loadedDictEndPtr = 0;
15594  *dictMatchStatePtr = NULL;
15595  } else {
15596  if (*loadedDictEndPtr != 0) {
15597  DEBUGLOG(6, "dictionary considered valid for current block");
15598  } } }
15599 }
15600 
15602  ZSTD_memset(window, 0, sizeof(*window));
15603  window->base = (BYTE const*)" ";
15604  window->dictBase = (BYTE const*)" ";
15605  ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */
15606  window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */
15607  window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */
15608  window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */
15609  window->nbOverflowCorrections = 0;
15610 }
15611 
15620  void const* src, size_t srcSize,
15621  int forceNonContiguous)
15622 {
15623  BYTE const* const ip = (BYTE const*)src;
15624  U32 contiguous = 1;
15625  DEBUGLOG(5, "ZSTD_window_update");
15626  if (srcSize == 0)
15627  return contiguous;
15628  assert(window->base != NULL);
15629  assert(window->dictBase != NULL);
15630  /* Check if blocks follow each other */
15631  if (src != window->nextSrc || forceNonContiguous) {
15632  /* not contiguous */
15633  size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);
15634  DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit);
15635  window->lowLimit = window->dictLimit;
15636  assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */
15637  window->dictLimit = (U32)distanceFromBase;
15638  window->dictBase = window->base;
15639  window->base = ip - distanceFromBase;
15640  /* ms->nextToUpdate = window->dictLimit; */
15641  if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */
15642  contiguous = 0;
15643  }
15644  window->nextSrc = ip + srcSize;
15645  /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
15646  if ( (ip+srcSize > window->dictBase + window->lowLimit)
15647  & (ip < window->dictBase + window->dictLimit)) {
15648  ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase;
15649  U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx;
15650  window->lowLimit = lowLimitMax;
15651  DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit);
15652  }
15653  return contiguous;
15654 }
15655 
15659 MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
15660 {
15661  U32 const maxDistance = 1U << windowLog;
15662  U32 const lowestValid = ms->window.lowLimit;
15663  U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
15664  U32 const isDictionary = (ms->loadedDictEnd != 0);
15665  /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
15666  * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
15667  * valid for the entire block. So this check is sufficient to find the lowest valid match index.
15668  */
15669  U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
15670  return matchLowest;
15671 }
15672 
15676 MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
15677 {
15678  U32 const maxDistance = 1U << windowLog;
15679  U32 const lowestValid = ms->window.dictLimit;
15680  U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
15681  U32 const isDictionary = (ms->loadedDictEnd != 0);
15682  /* When computing the lowest prefix index we need to take the dictionary into account to handle
15683  * the edge case where the dictionary and the source are contiguous in memory.
15684  */
15685  U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
15686  return matchLowest;
15687 }
15688 
15689 
15690 
15691 /* debug functions */
15692 #if (DEBUGLEVEL>=2)
15693 
15694 MEM_STATIC double ZSTD_fWeight(U32 rawStat)
15695 {
15696  U32 const fp_accuracy = 8;
15697  U32 const fp_multiplier = (1 << fp_accuracy);
15698  U32 const newStat = rawStat + 1;
15699  U32 const hb = ZSTD_highbit32(newStat);
15700  U32 const BWeight = hb * fp_multiplier;
15701  U32 const FWeight = (newStat << fp_accuracy) >> hb;
15702  U32 const weight = BWeight + FWeight;
15703  assert(hb + fp_accuracy < 31);
15704  return (double)weight / fp_multiplier;
15705 }
15706 
15707 /* display a table content,
15708  * listing each element, its frequency, and its predicted bit cost */
15709 MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
15710 {
15711  unsigned u, sum;
15712  for (u=0, sum=0; u<=max; u++) sum += table[u];
15713  DEBUGLOG(2, "total nb elts: %u", sum);
15714  for (u=0; u<=max; u++) {
15715  DEBUGLOG(2, "%2u: %5u (%.2f)",
15716  u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) );
15717  }
15718 }
15719 
15720 #endif
15721 
15722 /* Short Cache */
15723 
15724 /* Normally, zstd matchfinders follow this flow:
15725  * 1. Compute hash at ip
15726  * 2. Load index from hashTable[hash]
15727  * 3. Check if *ip == *(base + index)
15728  * In dictionary compression, loading *(base + index) is often an L2 or even L3 miss.
15729  *
15730  * Short cache is an optimization which allows us to avoid step 3 most of the time
15731  * when the data doesn't actually match. With short cache, the flow becomes:
15732  * 1. Compute (hash, currentTag) at ip. currentTag is an 8-bit independent hash at ip.
15733  * 2. Load (index, matchTag) from hashTable[hash]. See ZSTD_writeTaggedIndex to understand how this works.
15734  * 3. Only if currentTag == matchTag, check *ip == *(base + index). Otherwise, continue.
15735  *
15736  * Currently, short cache is only implemented in CDict hashtables. Thus, its use is limited to
15737  * dictMatchState matchfinders.
15738  */
15739 #define ZSTD_SHORT_CACHE_TAG_BITS 8
15740 #define ZSTD_SHORT_CACHE_TAG_MASK ((1u << ZSTD_SHORT_CACHE_TAG_BITS) - 1)
15741 
15742 /* Helper function for ZSTD_fillHashTable and ZSTD_fillDoubleHashTable.
15743  * Unpacks hashAndTag into (hash, tag), then packs (index, tag) into hashTable[hash]. */
15744 MEM_STATIC void ZSTD_writeTaggedIndex(U32* const hashTable, size_t hashAndTag, U32 index) {
15745  size_t const hash = hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS;
15746  U32 const tag = (U32)(hashAndTag & ZSTD_SHORT_CACHE_TAG_MASK);
15747  assert(index >> (32 - ZSTD_SHORT_CACHE_TAG_BITS) == 0);
15748  hashTable[hash] = (index << ZSTD_SHORT_CACHE_TAG_BITS) | tag;
15749 }
15750 
15751 /* Helper function for short cache matchfinders.
15752  * Unpacks tag1 and tag2 from lower bits of packedTag1 and packedTag2, then checks if the tags match. */
15753 MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) {
15754  U32 const tag1 = packedTag1 & ZSTD_SHORT_CACHE_TAG_MASK;
15755  U32 const tag2 = packedTag2 & ZSTD_SHORT_CACHE_TAG_MASK;
15756  return tag1 == tag2;
15757 }
15758 
15759 #if defined (__cplusplus)
15760 }
15761 #endif
15762 
15763 /* ===============================================================
15764  * Shared internal declarations
15765  * These prototypes may be called from sources not in lib/compress
15766  * =============================================================== */
15767 
15768 /* ZSTD_loadCEntropy() :
15769  * dict : must point at beginning of a valid zstd dictionary.
15770  * return : size of dictionary header (size of magic number + dict ID + entropy tables)
15771  * assumptions : magic number supposed already checked
15772  * and dictSize >= 8 */
15773 size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
15774  const void* const dict, size_t dictSize);
15775 
15777 
15778 /* ==============================================================
15779  * Private declarations
15780  * These prototypes shall only be called from within lib/compress
15781  * ============================================================== */
15782 
15783 /* ZSTD_getCParamsFromCCtxParams() :
15784  * cParams are built depending on compressionLevel, src size hints,
15785  * LDM and manually set compression parameters.
15786  * Note: srcSizeHint == 0 means 0!
15787  */
15788 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
15789  const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
15790 
15797  const void* dict, size_t dictSize,
15798  const ZSTD_CDict* cdict,
15799  const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize);
15800 
15801 void ZSTD_resetSeqStore(seqStore_t* ssPtr);
15802 
15805 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
15806 
15807 /* ZSTD_compressBegin_advanced_internal() :
15808  * Private use only. To be called from zstdmt_compress.c. */
15810  const void* dict, size_t dictSize,
15811  ZSTD_dictContentType_e dictContentType,
15813  const ZSTD_CDict* cdict,
15814  const ZSTD_CCtx_params* params,
15815  unsigned long long pledgedSrcSize);
15816 
15817 /* ZSTD_compress_advanced_internal() :
15818  * Private use only. To be called from zstdmt_compress.c. */
15820  void* dst, size_t dstCapacity,
15821  const void* src, size_t srcSize,
15822  const void* dict,size_t dictSize,
15823  const ZSTD_CCtx_params* params);
15824 
15825 
15826 /* ZSTD_writeLastEmptyBlock() :
15827  * output an empty Block with end-of-frame mark to complete a frame
15828  * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
15829  * or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)
15830  */
15831 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);
15832 
15833 
15834 /* ZSTD_referenceExternalSequences() :
15835  * Must be called before starting a compression operation.
15836  * seqs must parse a prefix of the source.
15837  * This cannot be used when long range matching is enabled.
15838  * Zstd will use these sequences, and pass the literals to a secondary block
15839  * compressor.
15840  * @return : An error code on failure.
15841  * NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory
15842  * access and data corruption.
15843  */
15844 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);
15845 
15848 U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
15849 
15853 void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
15854 
15855 /* Returns 0 on success, and a ZSTD_error otherwise. This function scans through an array of
15856  * ZSTD_Sequence, storing the sequences it finds, until it reaches a block delimiter.
15857  * Note that the block delimiter must include the last literals of the block.
15858  */
15859 size_t
15861  ZSTD_sequencePosition* seqPos,
15862  const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
15863  const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch);
15864 
15865 /* Returns the number of bytes to move the current read position back by.
15866  * Only non-zero if we ended up splitting a sequence.
15867  * Otherwise, it may return a ZSTD error if something went wrong.
15868  *
15869  * This function will attempt to scan through blockSize bytes
15870  * represented by the sequences in @inSeqs,
15871  * storing any (partial) sequences.
15872  *
15873  * Occasionally, we may want to change the actual number of bytes we consumed from inSeqs to
15874  * avoid splitting a match, or to avoid splitting a match such that it would produce a match
15875  * smaller than MINMATCH. In this case, we return the number of bytes that we didn't read from this block.
15876  */
15877 size_t
15879  const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
15880  const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch);
15881 
15882 
15883 /* ===============================================================
15884  * Deprecated definitions that are still used internally to avoid
15885  * deprecation warnings. These functions are exactly equivalent to
15886  * their public variants, but avoid the deprecation warnings.
15887  * =============================================================== */
15888 
15890 
15892  void* dst, size_t dstCapacity,
15893  const void* src, size_t srcSize);
15894 
15895 size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx,
15896  void* dst, size_t dstCapacity,
15897  const void* src, size_t srcSize);
15898 
15899 size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
15900 
15901 
15902 #endif /* ZSTD_COMPRESS_H */
15903 /**** ended inlining zstd_compress_internal.h ****/
15904 
15905 
15906 size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
15907 
15908 /* ZSTD_compressRleLiteralsBlock() :
15909  * Conditions :
15910  * - All bytes in @src are identical
15911  * - dstCapacity >= 4 */
15912 size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
15913 
15914 /* ZSTD_compressLiterals():
15915  * @entropyWorkspace: must be aligned on 4-bytes boundaries
15916  * @entropyWorkspaceSize : must be >= HUF_WORKSPACE_SIZE
15917  * @suspectUncompressible: sampling checks, to potentially skip huffman coding
15918  */
15919 size_t ZSTD_compressLiterals (void* dst, size_t dstCapacity,
15920  const void* src, size_t srcSize,
15921  void* entropyWorkspace, size_t entropyWorkspaceSize,
15922  const ZSTD_hufCTables_t* prevHuf,
15923  ZSTD_hufCTables_t* nextHuf,
15924  ZSTD_strategy strategy, int disableLiteralCompression,
15925  int suspectUncompressible,
15926  int bmi2);
15927 
15928 #endif /* ZSTD_COMPRESS_LITERALS_H */
15929 /**** ended inlining zstd_compress_literals.h ****/
15930 
15931 
15932 /* **************************************************************
15933 * Debug Traces
15934 ****************************************************************/
15935 #if DEBUGLEVEL >= 2
15936 
15937 static size_t showHexa(const void* src, size_t srcSize)
15938 {
15939  const BYTE* const ip = (const BYTE*)src;
15940  size_t u;
15941  for (u=0; u<srcSize; u++) {
15942  RAWLOG(5, " %02X", ip[u]); (void)ip;
15943  }
15944  RAWLOG(5, " \n");
15945  return srcSize;
15946 }
15947 
15948 #endif
15949 
15950 
15951 /* **************************************************************
15952 * Literals compression - special cases
15953 ****************************************************************/
15954 size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
15955 {
15956  BYTE* const ostart = (BYTE*)dst;
15957  U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
15958 
15959  DEBUGLOG(5, "ZSTD_noCompressLiterals: srcSize=%zu, dstCapacity=%zu", srcSize, dstCapacity);
15960 
15961  RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, "");
15962 
15963  switch(flSize)
15964  {
15965  case 1: /* 2 - 1 - 5 */
15966  ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
15967  break;
15968  case 2: /* 2 - 2 - 12 */
15969  MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
15970  break;
15971  case 3: /* 2 - 2 - 20 */
15972  MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
15973  break;
15974  default: /* not necessary : flSize is {1,2,3} */
15975  assert(0);
15976  }
15978  ZSTD_memcpy(ostart + flSize, src, srcSize);
15979  DEBUGLOG(5, "Raw (uncompressed) literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
15980  return srcSize + flSize;
15981 }
15982 
15983 static int allBytesIdentical(const void* src, size_t srcSize)
15984 {
15985  assert(srcSize >= 1);
15986  assert(src != NULL);
15987  { const BYTE b = ((const BYTE*)src)[0];
15988  size_t p;
15989  for (p=1; p<srcSize; p++) {
15990  if (((const BYTE*)src)[p] != b) return 0;
15991  }
15992  return 1;
15993  }
15994 }
15995 
15996 size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
15997 {
15998  BYTE* const ostart = (BYTE*)dst;
15999  U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
16000 
16001  assert(dstCapacity >= 4); (void)dstCapacity;
16003 
16004  switch(flSize)
16005  {
16006  case 1: /* 2 - 1 - 5 */
16007  ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
16008  break;
16009  case 2: /* 2 - 2 - 12 */
16010  MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
16011  break;
16012  case 3: /* 2 - 2 - 20 */
16013  MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
16014  break;
16015  default: /* not necessary : flSize is {1,2,3} */
16016  assert(0);
16017  }
16018 
16019  ostart[flSize] = *(const BYTE*)src;
16020  DEBUGLOG(5, "RLE : Repeated Literal (%02X: %u times) -> %u bytes encoded", ((const BYTE*)src)[0], (U32)srcSize, (U32)flSize + 1);
16021  return flSize+1;
16022 }
16023 
16024 /* ZSTD_minLiteralsToCompress() :
16025  * returns minimal amount of literals
16026  * for literal compression to even be attempted.
16027  * Minimum is made tighter as compression strategy increases.
16028  */
16029 static size_t
16031 {
16032  assert((int)strategy >= 0);
16033  assert((int)strategy <= 9);
16034  /* btultra2 : min 8 bytes;
16035  * then 2x larger for each successive compression strategy
16036  * max threshold 64 bytes */
16037  { int const shift = MIN(9-(int)strategy, 3);
16038  size_t const mintc = (huf_repeat == HUF_repeat_valid) ? 6 : (size_t)8 << shift;
16039  DEBUGLOG(7, "minLiteralsToCompress = %zu", mintc);
16040  return mintc;
16041  }
16042 }
16043 
16044 size_t ZSTD_compressLiterals (
16045  void* dst, size_t dstCapacity,
16046  const void* src, size_t srcSize,
16047  void* entropyWorkspace, size_t entropyWorkspaceSize,
16048  const ZSTD_hufCTables_t* prevHuf,
16049  ZSTD_hufCTables_t* nextHuf,
16050  ZSTD_strategy strategy,
16051  int disableLiteralCompression,
16052  int suspectUncompressible,
16053  int bmi2)
16054 {
16055  size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
16056  BYTE* const ostart = (BYTE*)dst;
16057  U32 singleStream = srcSize < 256;
16059  size_t cLitSize;
16060 
16061  DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)",
16062  disableLiteralCompression, (U32)srcSize, dstCapacity);
16063 
16064  DEBUGLOG(6, "Completed literals listing (%zu bytes)", showHexa(src, srcSize));
16065 
16066  /* Prepare nextEntropy assuming reusing the existing table */
16067  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
16068 
16069  if (disableLiteralCompression)
16070  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
16071 
16072  /* if too small, don't even attempt compression (speed opt) */
16073  if (srcSize < ZSTD_minLiteralsToCompress(strategy, prevHuf->repeatMode))
16074  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
16075 
16076  RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
16077  { HUF_repeat repeat = prevHuf->repeatMode;
16078  int const flags = 0
16079  | (bmi2 ? HUF_flags_bmi2 : 0)
16080  | (strategy < ZSTD_lazy && srcSize <= 1024 ? HUF_flags_preferRepeat : 0)
16082  | (suspectUncompressible ? HUF_flags_suspectUncompressible : 0);
16083 
16084  typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int);
16085  huf_compress_f huf_compress;
16086  if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
16087  huf_compress = singleStream ? HUF_compress1X_repeat : HUF_compress4X_repeat;
16088  cLitSize = huf_compress(ostart+lhSize, dstCapacity-lhSize,
16089  src, srcSize,
16091  entropyWorkspace, entropyWorkspaceSize,
16092  (HUF_CElt*)nextHuf->CTable,
16093  &repeat, flags);
16094  DEBUGLOG(5, "%zu literals compressed into %zu bytes (before header)", srcSize, cLitSize);
16095  if (repeat != HUF_repeat_none) {
16096  /* reused the existing table */
16097  DEBUGLOG(5, "reusing statistics from previous huffman block");
16098  hType = set_repeat;
16099  }
16100  }
16101 
16102  { size_t const minGain = ZSTD_minGain(srcSize, strategy);
16103  if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) {
16104  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
16105  return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
16106  } }
16107  if (cLitSize==1) {
16108  /* A return value of 1 signals that the alphabet consists of a single symbol.
16109  * However, in some rare circumstances, it could be the compressed size (a single byte).
16110  * For that outcome to have a chance to happen, it's necessary that `srcSize < 8`.
16111  * (it's also necessary to not generate statistics).
16112  * Therefore, in such a case, actively check that all bytes are identical. */
16113  if ((srcSize >= 8) || allBytesIdentical(src, srcSize)) {
16114  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
16115  return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
16116  } }
16117 
16118  if (hType == set_compressed) {
16119  /* using a newly constructed table */
16120  nextHuf->repeatMode = HUF_repeat_check;
16121  }
16122 
16123  /* Build header */
16124  switch(lhSize)
16125  {
16126  case 3: /* 2 - 2 - 10 - 10 */
16127  if (!singleStream) assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS);
16128  { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
16129  MEM_writeLE24(ostart, lhc);
16130  break;
16131  }
16132  case 4: /* 2 - 2 - 14 - 14 */
16134  { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
16135  MEM_writeLE32(ostart, lhc);
16136  break;
16137  }
16138  case 5: /* 2 - 2 - 18 - 18 */
16140  { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
16141  MEM_writeLE32(ostart, lhc);
16142  ostart[4] = (BYTE)(cLitSize >> 10);
16143  break;
16144  }
16145  default: /* not possible : lhSize is {3,4,5} */
16146  assert(0);
16147  }
16148  DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize));
16149  return lhSize+cLitSize;
16150 }
16151 /**** ended inlining compress/zstd_compress_literals.c ****/
16152 /**** start inlining compress/zstd_compress_sequences.c ****/
16153 /*
16154  * Copyright (c) Meta Platforms, Inc. and affiliates.
16155  * All rights reserved.
16156  *
16157  * This source code is licensed under both the BSD-style license (found in the
16158  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
16159  * in the COPYING file in the root directory of this source tree).
16160  * You may select, at your option, one of the above-listed licenses.
16161  */
16162 
16163  /*-*************************************
16164  * Dependencies
16165  ***************************************/
16166 /**** start inlining zstd_compress_sequences.h ****/
16167 /*
16168  * Copyright (c) Meta Platforms, Inc. and affiliates.
16169  * All rights reserved.
16170  *
16171  * This source code is licensed under both the BSD-style license (found in the
16172  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
16173  * in the COPYING file in the root directory of this source tree).
16174  * You may select, at your option, one of the above-listed licenses.
16175  */
16176 
16177 #ifndef ZSTD_COMPRESS_SEQUENCES_H
16178 #define ZSTD_COMPRESS_SEQUENCES_H
16180 /**** skipping file: ../common/fse.h ****/
16181 /**** skipping file: ../common/zstd_internal.h ****/
16182 
16183 typedef enum {
16187 
16190  FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
16191  size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
16192  FSE_CTable const* prevCTable,
16193  short const* defaultNorm, U32 defaultNormLog,
16194  ZSTD_defaultPolicy_e const isDefaultAllowed,
16195  ZSTD_strategy const strategy);
16196 
16197 size_t
16198 ZSTD_buildCTable(void* dst, size_t dstCapacity,
16199  FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
16200  unsigned* count, U32 max,
16201  const BYTE* codeTable, size_t nbSeq,
16202  const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
16203  const FSE_CTable* prevCTable, size_t prevCTableSize,
16204  void* entropyWorkspace, size_t entropyWorkspaceSize);
16205 
16206 size_t ZSTD_encodeSequences(
16207  void* dst, size_t dstCapacity,
16208  FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
16209  FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
16210  FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
16211  seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2);
16212 
16213 size_t ZSTD_fseBitCost(
16214  FSE_CTable const* ctable,
16215  unsigned const* count,
16216  unsigned const max);
16217 
16218 size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
16219  unsigned const* count, unsigned const max);
16220 #endif /* ZSTD_COMPRESS_SEQUENCES_H */
16221 /**** ended inlining zstd_compress_sequences.h ****/
16228 static unsigned const kInverseProbabilityLog256[256] = {
16229  0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
16230  1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
16231  874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
16232  724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
16233  618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
16234  535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
16235  468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
16236  411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
16237  362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
16238  318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
16239  279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
16240  244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
16241  212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
16242  182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
16243  155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
16244  130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
16245  106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
16246  83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
16247  62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
16248  42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
16249  23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
16250  5, 4, 2, 1,
16251 };
16252 
16253 static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
16254  void const* ptr = ctable;
16255  U16 const* u16ptr = (U16 const*)ptr;
16256  U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
16257  return maxSymbolValue;
16259 
16264 static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
16265 {
16266  /* Heuristic: This should cover most blocks <= 16K and
16267  * start to fade out after 16K to about 32K depending on
16268  * compressibility.
16269  */
16270  return nbSeq >= 2048;
16272 
16277 static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
16278  size_t const nbSeq, unsigned const FSELog)
16279 {
16280  BYTE wksp[FSE_NCOUNTBOUND];
16281  S16 norm[MaxSeq + 1];
16282  const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
16283  FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
16284  return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
16286 
16291 static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
16292 {
16293  unsigned cost = 0;
16294  unsigned s;
16295 
16296  assert(total > 0);
16297  for (s = 0; s <= max; ++s) {
16298  unsigned norm = (unsigned)((256 * count[s]) / total);
16299  if (count[s] != 0 && norm == 0)
16300  norm = 1;
16301  assert(count[s] < total);
16302  cost += count[s] * kInverseProbabilityLog256[norm];
16303  }
16304  return cost >> 8;
16306 
16311 size_t ZSTD_fseBitCost(
16312  FSE_CTable const* ctable,
16313  unsigned const* count,
16314  unsigned const max)
16315 {
16316  unsigned const kAccuracyLog = 8;
16317  size_t cost = 0;
16318  unsigned s;
16319  FSE_CState_t cstate;
16320  FSE_initCState(&cstate, ctable);
16321  if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
16322  DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
16323  ZSTD_getFSEMaxSymbolValue(ctable), max);
16324  return ERROR(GENERIC);
16325  }
16326  for (s = 0; s <= max; ++s) {
16327  unsigned const tableLog = cstate.stateLog;
16328  unsigned const badCost = (tableLog + 1) << kAccuracyLog;
16329  unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
16330  if (count[s] == 0)
16331  continue;
16332  if (bitCost >= badCost) {
16333  DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
16334  return ERROR(GENERIC);
16335  }
16336  cost += (size_t)count[s] * bitCost;
16337  }
16338  return cost >> kAccuracyLog;
16339 }
16346 size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
16347  unsigned const* count, unsigned const max)
16348 {
16349  unsigned const shift = 8 - accuracyLog;
16350  size_t cost = 0;
16351  unsigned s;
16352  assert(accuracyLog <= 8);
16353  for (s = 0; s <= max; ++s) {
16354  unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1;
16355  unsigned const norm256 = normAcc << shift;
16356  assert(norm256 > 0);
16357  assert(norm256 < 256);
16358  cost += count[s] * kInverseProbabilityLog256[norm256];
16359  }
16360  return cost >> 8;
16361 }
16362 
16365  FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
16366  size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
16367  FSE_CTable const* prevCTable,
16368  short const* defaultNorm, U32 defaultNormLog,
16369  ZSTD_defaultPolicy_e const isDefaultAllowed,
16370  ZSTD_strategy const strategy)
16371 {
16373  if (mostFrequent == nbSeq) {
16374  *repeatMode = FSE_repeat_none;
16375  if (isDefaultAllowed && nbSeq <= 2) {
16376  /* Prefer set_basic over set_rle when there are 2 or fewer symbols,
16377  * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
16378  * If basic encoding isn't possible, always choose RLE.
16379  */
16380  DEBUGLOG(5, "Selected set_basic");
16381  return set_basic;
16382  }
16383  DEBUGLOG(5, "Selected set_rle");
16384  return set_rle;
16385  }
16386  if (strategy < ZSTD_lazy) {
16387  if (isDefaultAllowed) {
16388  size_t const staticFse_nbSeq_max = 1000;
16389  size_t const mult = 10 - strategy;
16390  size_t const baseLog = 3;
16391  size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
16392  assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
16393  assert(mult <= 9 && mult >= 7);
16394  if ( (*repeatMode == FSE_repeat_valid)
16395  && (nbSeq < staticFse_nbSeq_max) ) {
16396  DEBUGLOG(5, "Selected set_repeat");
16397  return set_repeat;
16398  }
16399  if ( (nbSeq < dynamicFse_nbSeq_min)
16400  || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
16401  DEBUGLOG(5, "Selected set_basic");
16402  /* The format allows default tables to be repeated, but it isn't useful.
16403  * When using simple heuristics to select encoding type, we don't want
16404  * to confuse these tables with dictionaries. When running more careful
16405  * analysis, we don't need to waste time checking both repeating tables
16406  * and default tables.
16407  */
16408  *repeatMode = FSE_repeat_none;
16409  return set_basic;
16410  }
16411  }
16412  } else {
16413  size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
16414  size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
16415  size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
16416  size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
16417 
16418  if (isDefaultAllowed) {
16419  assert(!ZSTD_isError(basicCost));
16420  assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
16421  }
16422  assert(!ZSTD_isError(NCountCost));
16423  assert(compressedCost < ERROR(maxCode));
16424  DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
16425  (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
16426  if (basicCost <= repeatCost && basicCost <= compressedCost) {
16427  DEBUGLOG(5, "Selected set_basic");
16428  assert(isDefaultAllowed);
16429  *repeatMode = FSE_repeat_none;
16430  return set_basic;
16431  }
16432  if (repeatCost <= compressedCost) {
16433  DEBUGLOG(5, "Selected set_repeat");
16434  assert(!ZSTD_isError(repeatCost));
16435  return set_repeat;
16436  }
16437  assert(compressedCost < basicCost && compressedCost < repeatCost);
16438  }
16439  DEBUGLOG(5, "Selected set_compressed");
16440  *repeatMode = FSE_repeat_check;
16441  return set_compressed;
16442 }
16443 
16444 typedef struct {
16445  S16 norm[MaxSeq + 1];
16448 
16449 size_t
16450 ZSTD_buildCTable(void* dst, size_t dstCapacity,
16451  FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
16452  unsigned* count, U32 max,
16453  const BYTE* codeTable, size_t nbSeq,
16454  const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
16455  const FSE_CTable* prevCTable, size_t prevCTableSize,
16456  void* entropyWorkspace, size_t entropyWorkspaceSize)
16457 {
16458  BYTE* op = (BYTE*)dst;
16459  const BYTE* const oend = op + dstCapacity;
16460  DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
16461 
16462  switch (type) {
16463  case set_rle:
16464  FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), "");
16465  RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space");
16466  *op = codeTable[0];
16467  return 1;
16468  case set_repeat:
16469  ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize);
16470  return 0;
16471  case set_basic:
16472  FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
16473  return 0;
16474  case set_compressed: {
16475  ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace;
16476  size_t nbSeq_1 = nbSeq;
16477  const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
16478  if (count[codeTable[nbSeq-1]] > 1) {
16479  count[codeTable[nbSeq-1]]--;
16480  nbSeq_1--;
16481  }
16482  assert(nbSeq_1 > 1);
16483  assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp));
16484  (void)entropyWorkspaceSize;
16485  FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed");
16486  assert(oend >= op);
16487  { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */
16488  FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
16489  FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed");
16490  return NCountSize;
16491  }
16492  }
16493  default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach");
16494  }
16495 }
16496 
16497 FORCE_INLINE_TEMPLATE size_t
16499  void* dst, size_t dstCapacity,
16500  FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
16501  FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
16502  FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
16503  seqDef const* sequences, size_t nbSeq, int longOffsets)
16504 {
16505  BIT_CStream_t blockStream;
16506  FSE_CState_t stateMatchLength;
16507  FSE_CState_t stateOffsetBits;
16508  FSE_CState_t stateLitLength;
16509 
16511  ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),
16512  dstSize_tooSmall, "not enough space remaining");
16513  DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)",
16514  (int)(blockStream.endPtr - blockStream.startPtr),
16515  (unsigned)dstCapacity);
16516 
16517  /* first symbols */
16518  FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
16519  FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
16520  FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
16521  BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
16522  if (MEM_32bits()) BIT_flushBits(&blockStream);
16523  BIT_addBits(&blockStream, sequences[nbSeq-1].mlBase, ML_bits[mlCodeTable[nbSeq-1]]);
16524  if (MEM_32bits()) BIT_flushBits(&blockStream);
16525  if (longOffsets) {
16526  U32 const ofBits = ofCodeTable[nbSeq-1];
16527  unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
16528  if (extraBits) {
16529  BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, extraBits);
16530  BIT_flushBits(&blockStream);
16531  }
16532  BIT_addBits(&blockStream, sequences[nbSeq-1].offBase >> extraBits,
16533  ofBits - extraBits);
16534  } else {
16535  BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, ofCodeTable[nbSeq-1]);
16536  }
16537  BIT_flushBits(&blockStream);
16538 
16539  { size_t n;
16540  for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
16541  BYTE const llCode = llCodeTable[n];
16542  BYTE const ofCode = ofCodeTable[n];
16543  BYTE const mlCode = mlCodeTable[n];
16544  U32 const llBits = LL_bits[llCode];
16545  U32 const ofBits = ofCode;
16546  U32 const mlBits = ML_bits[mlCode];
16547  DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
16548  (unsigned)sequences[n].litLength,
16549  (unsigned)sequences[n].mlBase + MINMATCH,
16550  (unsigned)sequences[n].offBase);
16551  /* 32b*/ /* 64b*/
16552  /* (7)*/ /* (7)*/
16553  FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
16554  FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
16555  if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
16556  FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
16557  if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
16558  BIT_flushBits(&blockStream); /* (7)*/
16559  BIT_addBits(&blockStream, sequences[n].litLength, llBits);
16560  if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
16561  BIT_addBits(&blockStream, sequences[n].mlBase, mlBits);
16562  if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
16563  if (longOffsets) {
16564  unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
16565  if (extraBits) {
16566  BIT_addBits(&blockStream, sequences[n].offBase, extraBits);
16567  BIT_flushBits(&blockStream); /* (7)*/
16568  }
16569  BIT_addBits(&blockStream, sequences[n].offBase >> extraBits,
16570  ofBits - extraBits); /* 31 */
16571  } else {
16572  BIT_addBits(&blockStream, sequences[n].offBase, ofBits); /* 31 */
16573  }
16574  BIT_flushBits(&blockStream); /* (7)*/
16575  DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
16576  } }
16577 
16578  DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
16579  FSE_flushCState(&blockStream, &stateMatchLength);
16580  DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
16581  FSE_flushCState(&blockStream, &stateOffsetBits);
16582  DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
16583  FSE_flushCState(&blockStream, &stateLitLength);
16584 
16585  { size_t const streamSize = BIT_closeCStream(&blockStream);
16586  RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space");
16587  return streamSize;
16588  }
16589 }
16590 
16591 static size_t
16593  void* dst, size_t dstCapacity,
16594  FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
16595  FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
16596  FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
16597  seqDef const* sequences, size_t nbSeq, int longOffsets)
16598 {
16599  return ZSTD_encodeSequences_body(dst, dstCapacity,
16600  CTable_MatchLength, mlCodeTable,
16601  CTable_OffsetBits, ofCodeTable,
16602  CTable_LitLength, llCodeTable,
16603  sequences, nbSeq, longOffsets);
16604 }
16605 
16606 
16607 #if DYNAMIC_BMI2
16608 
16609 static BMI2_TARGET_ATTRIBUTE size_t
16610 ZSTD_encodeSequences_bmi2(
16611  void* dst, size_t dstCapacity,
16612  FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
16613  FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
16614  FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
16615  seqDef const* sequences, size_t nbSeq, int longOffsets)
16616 {
16617  return ZSTD_encodeSequences_body(dst, dstCapacity,
16618  CTable_MatchLength, mlCodeTable,
16619  CTable_OffsetBits, ofCodeTable,
16620  CTable_LitLength, llCodeTable,
16621  sequences, nbSeq, longOffsets);
16622 }
16623 
16624 #endif
16625 
16626 size_t ZSTD_encodeSequences(
16627  void* dst, size_t dstCapacity,
16628  FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
16629  FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
16630  FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
16631  seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
16632 {
16633  DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
16634 #if DYNAMIC_BMI2
16635  if (bmi2) {
16636  return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
16637  CTable_MatchLength, mlCodeTable,
16638  CTable_OffsetBits, ofCodeTable,
16639  CTable_LitLength, llCodeTable,
16640  sequences, nbSeq, longOffsets);
16641  }
16642 #endif
16643  (void)bmi2;
16644  return ZSTD_encodeSequences_default(dst, dstCapacity,
16645  CTable_MatchLength, mlCodeTable,
16646  CTable_OffsetBits, ofCodeTable,
16647  CTable_LitLength, llCodeTable,
16648  sequences, nbSeq, longOffsets);
16649 }
16650 /**** ended inlining compress/zstd_compress_sequences.c ****/
16651 /**** start inlining compress/zstd_compress_superblock.c ****/
16652 /*
16653  * Copyright (c) Meta Platforms, Inc. and affiliates.
16654  * All rights reserved.
16655  *
16656  * This source code is licensed under both the BSD-style license (found in the
16657  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
16658  * in the COPYING file in the root directory of this source tree).
16659  * You may select, at your option, one of the above-listed licenses.
16660  */
16661 
16662  /*-*************************************
16663  * Dependencies
16664  ***************************************/
16665 /**** start inlining zstd_compress_superblock.h ****/
16666 /*
16667  * Copyright (c) Meta Platforms, Inc. and affiliates.
16668  * All rights reserved.
16669  *
16670  * This source code is licensed under both the BSD-style license (found in the
16671  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
16672  * in the COPYING file in the root directory of this source tree).
16673  * You may select, at your option, one of the above-listed licenses.
16674  */
16675 
16676 #ifndef ZSTD_COMPRESS_ADVANCED_H
16677 #define ZSTD_COMPRESS_ADVANCED_H
16678 
16679 /*-*************************************
16680 * Dependencies
16681 ***************************************/
16682 
16683 /**** skipping file: ../zstd.h ****/
16684 
16685 /*-*************************************
16686 * Target Compressed Block Size
16687 ***************************************/
16688 
16689 /* ZSTD_compressSuperBlock() :
16690  * Used to compress a super block when targetCBlockSize is being used.
16691  * The given block will be compressed into multiple sub blocks that are around targetCBlockSize. */
16693  void* dst, size_t dstCapacity,
16694  void const* src, size_t srcSize,
16695  unsigned lastBlock);
16696 
16697 #endif /* ZSTD_COMPRESS_ADVANCED_H */
16698 /**** ended inlining zstd_compress_superblock.h ****/
16699 
16700 /**** skipping file: ../common/zstd_internal.h ****/
16701 /**** skipping file: hist.h ****/
16702 /**** skipping file: zstd_compress_internal.h ****/
16703 /**** skipping file: zstd_compress_sequences.h ****/
16704 /**** skipping file: zstd_compress_literals.h ****/
16705 
16725 static size_t
16726 ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
16727  const ZSTD_hufCTablesMetadata_t* hufMetadata,
16728  const BYTE* literals, size_t litSize,
16729  void* dst, size_t dstSize,
16730  const int bmi2, int writeEntropy, int* entropyWritten)
16731 {
16732  size_t const header = writeEntropy ? 200 : 0;
16733  size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header));
16734  BYTE* const ostart = (BYTE*)dst;
16735  BYTE* const oend = ostart + dstSize;
16736  BYTE* op = ostart + lhSize;
16737  U32 const singleStream = lhSize == 3;
16738  symbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat;
16739  size_t cLitSize = 0;
16740 
16741  DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy);
16742 
16743  *entropyWritten = 0;
16744  if (litSize == 0 || hufMetadata->hType == set_basic) {
16745  DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal");
16746  return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
16747  } else if (hufMetadata->hType == set_rle) {
16748  DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal");
16749  return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize);
16750  }
16751 
16752  assert(litSize > 0);
16753  assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
16754 
16755  if (writeEntropy && hufMetadata->hType == set_compressed) {
16756  ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
16757  op += hufMetadata->hufDesSize;
16758  cLitSize += hufMetadata->hufDesSize;
16759  DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
16760  }
16761 
16762  { int const flags = bmi2 ? HUF_flags_bmi2 : 0;
16763  const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, oend-op, literals, litSize, hufTable, flags)
16764  : HUF_compress4X_usingCTable(op, oend-op, literals, litSize, hufTable, flags);
16765  op += cSize;
16766  cLitSize += cSize;
16767  if (cSize == 0 || ERR_isError(cSize)) {
16768  DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize));
16769  return 0;
16770  }
16771  /* If we expand and we aren't writing a header then emit uncompressed */
16772  if (!writeEntropy && cLitSize >= litSize) {
16773  DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible");
16774  return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
16775  }
16776  /* If we are writing headers then allow expansion that doesn't change our header size. */
16777  if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) {
16778  assert(cLitSize > litSize);
16779  DEBUGLOG(5, "Literals expanded beyond allowed header size");
16780  return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
16781  }
16782  DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize);
16783  }
16784 
16785  /* Build header */
16786  switch(lhSize)
16787  {
16788  case 3: /* 2 - 2 - 10 - 10 */
16789  { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14);
16790  MEM_writeLE24(ostart, lhc);
16791  break;
16792  }
16793  case 4: /* 2 - 2 - 14 - 14 */
16794  { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18);
16795  MEM_writeLE32(ostart, lhc);
16796  break;
16797  }
16798  case 5: /* 2 - 2 - 18 - 18 */
16799  { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22);
16800  MEM_writeLE32(ostart, lhc);
16801  ostart[4] = (BYTE)(cLitSize >> 10);
16802  break;
16803  }
16804  default: /* not possible : lhSize is {3,4,5} */
16805  assert(0);
16806  }
16807  *entropyWritten = 1;
16808  DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart));
16809  return op-ostart;
16810 }
16811 
16812 static size_t
16813 ZSTD_seqDecompressedSize(seqStore_t const* seqStore,
16814  const seqDef* sequences, size_t nbSeq,
16815  size_t litSize, int lastSequence)
16816 {
16817  const seqDef* const sstart = sequences;
16818  const seqDef* const send = sequences + nbSeq;
16819  const seqDef* sp = sstart;
16820  size_t matchLengthSum = 0;
16821  size_t litLengthSum = 0;
16822  (void)(litLengthSum); /* suppress unused variable warning on some environments */
16823  while (send-sp > 0) {
16824  ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
16825  litLengthSum += seqLen.litLength;
16826  matchLengthSum += seqLen.matchLength;
16827  sp++;
16828  }
16829  assert(litLengthSum <= litSize);
16830  if (!lastSequence) {
16831  assert(litLengthSum == litSize);
16832  }
16833  return matchLengthSum + litSize;
16834 }
16835 
16846 static size_t
16848  const ZSTD_fseCTablesMetadata_t* fseMetadata,
16849  const seqDef* sequences, size_t nbSeq,
16850  const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
16851  const ZSTD_CCtx_params* cctxParams,
16852  void* dst, size_t dstCapacity,
16853  const int bmi2, int writeEntropy, int* entropyWritten)
16854 {
16855  const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
16856  BYTE* const ostart = (BYTE*)dst;
16857  BYTE* const oend = ostart + dstCapacity;
16858  BYTE* op = ostart;
16859  BYTE* seqHead;
16860 
16861  DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets);
16862 
16863  *entropyWritten = 0;
16864  /* Sequences Header */
16865  RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
16866  dstSize_tooSmall, "");
16867  if (nbSeq < 0x7F)
16868  *op++ = (BYTE)nbSeq;
16869  else if (nbSeq < LONGNBSEQ)
16870  op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
16871  else
16872  op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
16873  if (nbSeq==0) {
16874  return op - ostart;
16875  }
16876 
16877  /* seqHead : flags for FSE encoding type */
16878  seqHead = op++;
16879 
16880  DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart));
16881 
16882  if (writeEntropy) {
16883  const U32 LLtype = fseMetadata->llType;
16884  const U32 Offtype = fseMetadata->ofType;
16885  const U32 MLtype = fseMetadata->mlType;
16886  DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
16887  *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
16888  ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
16889  op += fseMetadata->fseTablesSize;
16890  } else {
16891  const U32 repeat = set_repeat;
16892  *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2));
16893  }
16894 
16895  { size_t const bitstreamSize = ZSTD_encodeSequences(
16896  op, oend - op,
16897  fseTables->matchlengthCTable, mlCode,
16898  fseTables->offcodeCTable, ofCode,
16899  fseTables->litlengthCTable, llCode,
16900  sequences, nbSeq,
16901  longOffsets, bmi2);
16902  FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
16903  op += bitstreamSize;
16904  /* zstd versions <= 1.3.4 mistakenly report corruption when
16905  * FSE_readNCount() receives a buffer < 4 bytes.
16906  * Fixed by https://github.com/facebook/zstd/pull/1146.
16907  * This can happen when the last set_compressed table present is 2
16908  * bytes and the bitstream is only one byte.
16909  * In this exceedingly rare case, we will simply emit an uncompressed
16910  * block, since it isn't worth optimizing.
16911  */
16912 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
16913  if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) {
16914  /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
16915  assert(fseMetadata->lastCountSize + bitstreamSize == 3);
16916  DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
16917  "emitting an uncompressed block.");
16918  return 0;
16919  }
16920 #endif
16921  DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize);
16922  }
16923 
16924  /* zstd versions <= 1.4.0 mistakenly report error when
16925  * sequences section body size is less than 3 bytes.
16926  * Fixed by https://github.com/facebook/zstd/pull/1664.
16927  * This can happen when the previous sequences section block is compressed
16928  * with rle mode and the current block's sequences section is compressed
16929  * with repeat mode where sequences section body size can be 1 byte.
16930  */
16931 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
16932  if (op-seqHead < 4) {
16933  DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting "
16934  "an uncompressed block when sequences are < 4 bytes");
16935  return 0;
16936  }
16937 #endif
16938 
16939  *entropyWritten = 1;
16940  return op - ostart;
16942 
16947 static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy,
16948  const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
16949  const seqDef* sequences, size_t nbSeq,
16950  const BYTE* literals, size_t litSize,
16951  const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
16952  const ZSTD_CCtx_params* cctxParams,
16953  void* dst, size_t dstCapacity,
16954  const int bmi2,
16955  int writeLitEntropy, int writeSeqEntropy,
16956  int* litEntropyWritten, int* seqEntropyWritten,
16957  U32 lastBlock)
16958 {
16959  BYTE* const ostart = (BYTE*)dst;
16960  BYTE* const oend = ostart + dstCapacity;
16961  BYTE* op = ostart + ZSTD_blockHeaderSize;
16962  DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)",
16963  litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock);
16964  { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable,
16965  &entropyMetadata->hufMetadata, literals, litSize,
16966  op, oend-op, bmi2, writeLitEntropy, litEntropyWritten);
16967  FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed");
16968  if (cLitSize == 0) return 0;
16969  op += cLitSize;
16970  }
16971  { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse,
16972  &entropyMetadata->fseMetadata,
16973  sequences, nbSeq,
16974  llCode, mlCode, ofCode,
16975  cctxParams,
16976  op, oend-op,
16977  bmi2, writeSeqEntropy, seqEntropyWritten);
16978  FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed");
16979  if (cSeqSize == 0) return 0;
16980  op += cSeqSize;
16981  }
16982  /* Write block header */
16983  { size_t cSize = (op-ostart)-ZSTD_blockHeaderSize;
16984  U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
16985  MEM_writeLE24(ostart, cBlockHeader24);
16986  }
16987  return op-ostart;
16988 }
16989 
16990 static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize,
16991  const ZSTD_hufCTables_t* huf,
16992  const ZSTD_hufCTablesMetadata_t* hufMetadata,
16993  void* workspace, size_t wkspSize,
16994  int writeEntropy)
16995 {
16996  unsigned* const countWksp = (unsigned*)workspace;
16997  unsigned maxSymbolValue = 255;
16998  size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
16999 
17000  if (hufMetadata->hType == set_basic) return litSize;
17001  else if (hufMetadata->hType == set_rle) return 1;
17002  else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) {
17003  size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize);
17004  if (ZSTD_isError(largest)) return litSize;
17005  { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue);
17006  if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize;
17007  return cLitSizeEstimate + literalSectionHeaderSize;
17008  } }
17009  assert(0); /* impossible */
17010  return 0;
17011 }
17012 
17014  const BYTE* codeTable, unsigned maxCode,
17015  size_t nbSeq, const FSE_CTable* fseCTable,
17016  const U8* additionalBits,
17017  short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
17018  void* workspace, size_t wkspSize)
17019 {
17020  unsigned* const countWksp = (unsigned*)workspace;
17021  const BYTE* ctp = codeTable;
17022  const BYTE* const ctStart = ctp;
17023  const BYTE* const ctEnd = ctStart + nbSeq;
17024  size_t cSymbolTypeSizeEstimateInBits = 0;
17025  unsigned max = maxCode;
17026 
17027  HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
17028  if (type == set_basic) {
17029  /* We selected this encoding type, so it must be valid. */
17030  assert(max <= defaultMax);
17031  cSymbolTypeSizeEstimateInBits = max <= defaultMax
17032  ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max)
17033  : ERROR(GENERIC);
17034  } else if (type == set_rle) {
17035  cSymbolTypeSizeEstimateInBits = 0;
17036  } else if (type == set_compressed || type == set_repeat) {
17037  cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max);
17038  }
17039  if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10;
17040  while (ctp < ctEnd) {
17041  if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp];
17042  else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */
17043  ctp++;
17044  }
17045  return cSymbolTypeSizeEstimateInBits / 8;
17046 }
17047 
17048 static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
17049  const BYTE* llCodeTable,
17050  const BYTE* mlCodeTable,
17051  size_t nbSeq,
17052  const ZSTD_fseCTables_t* fseTables,
17053  const ZSTD_fseCTablesMetadata_t* fseMetadata,
17054  void* workspace, size_t wkspSize,
17055  int writeEntropy)
17056 {
17057  size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
17058  size_t cSeqSizeEstimate = 0;
17059  if (nbSeq == 0) return sequencesSectionHeaderSize;
17060  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
17061  nbSeq, fseTables->offcodeCTable, NULL,
17063  workspace, wkspSize);
17064  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
17065  nbSeq, fseTables->litlengthCTable, LL_bits,
17067  workspace, wkspSize);
17068  cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
17069  nbSeq, fseTables->matchlengthCTable, ML_bits,
17071  workspace, wkspSize);
17072  if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
17073  return cSeqSizeEstimate + sequencesSectionHeaderSize;
17074 }
17075 
17076 static size_t ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize,
17077  const BYTE* ofCodeTable,
17078  const BYTE* llCodeTable,
17079  const BYTE* mlCodeTable,
17080  size_t nbSeq,
17081  const ZSTD_entropyCTables_t* entropy,
17082  const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
17083  void* workspace, size_t wkspSize,
17084  int writeLitEntropy, int writeSeqEntropy) {
17085  size_t cSizeEstimate = 0;
17086  cSizeEstimate += ZSTD_estimateSubBlockSize_literal(literals, litSize,
17087  &entropy->huf, &entropyMetadata->hufMetadata,
17088  workspace, wkspSize, writeLitEntropy);
17089  cSizeEstimate += ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
17090  nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
17091  workspace, wkspSize, writeSeqEntropy);
17092  return cSizeEstimate + ZSTD_blockHeaderSize;
17093 }
17094 
17095 static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata)
17096 {
17097  if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle)
17098  return 1;
17099  if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle)
17100  return 1;
17101  if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle)
17102  return 1;
17103  return 0;
17104 }
17105 
17113 static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
17114  const ZSTD_compressedBlockState_t* prevCBlock,
17115  ZSTD_compressedBlockState_t* nextCBlock,
17116  const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
17117  const ZSTD_CCtx_params* cctxParams,
17118  void* dst, size_t dstCapacity,
17119  const void* src, size_t srcSize,
17120  const int bmi2, U32 lastBlock,
17121  void* workspace, size_t wkspSize)
17122 {
17123  const seqDef* const sstart = seqStorePtr->sequencesStart;
17124  const seqDef* const send = seqStorePtr->sequences;
17125  const seqDef* sp = sstart;
17126  const BYTE* const lstart = seqStorePtr->litStart;
17127  const BYTE* const lend = seqStorePtr->lit;
17128  const BYTE* lp = lstart;
17129  BYTE const* ip = (BYTE const*)src;
17130  BYTE const* const iend = ip + srcSize;
17131  BYTE* const ostart = (BYTE*)dst;
17132  BYTE* const oend = ostart + dstCapacity;
17133  BYTE* op = ostart;
17134  const BYTE* llCodePtr = seqStorePtr->llCode;
17135  const BYTE* mlCodePtr = seqStorePtr->mlCode;
17136  const BYTE* ofCodePtr = seqStorePtr->ofCode;
17137  size_t targetCBlockSize = cctxParams->targetCBlockSize;
17138  size_t litSize, seqCount;
17139  int writeLitEntropy = entropyMetadata->hufMetadata.hType == set_compressed;
17140  int writeSeqEntropy = 1;
17141  int lastSequence = 0;
17142 
17143  DEBUGLOG(5, "ZSTD_compressSubBlock_multi (litSize=%u, nbSeq=%u)",
17144  (unsigned)(lend-lp), (unsigned)(send-sstart));
17145 
17146  litSize = 0;
17147  seqCount = 0;
17148  do {
17149  size_t cBlockSizeEstimate = 0;
17150  if (sstart == send) {
17151  lastSequence = 1;
17152  } else {
17153  const seqDef* const sequence = sp + seqCount;
17154  lastSequence = sequence == send - 1;
17155  litSize += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength;
17156  seqCount++;
17157  }
17158  if (lastSequence) {
17159  assert(lp <= lend);
17160  assert(litSize <= (size_t)(lend - lp));
17161  litSize = (size_t)(lend - lp);
17162  }
17163  /* I think there is an optimization opportunity here.
17164  * Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful
17165  * since it recalculates estimate from scratch.
17166  * For example, it would recount literal distribution and symbol codes every time.
17167  */
17168  cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount,
17169  &nextCBlock->entropy, entropyMetadata,
17170  workspace, wkspSize, writeLitEntropy, writeSeqEntropy);
17171  if (cBlockSizeEstimate > targetCBlockSize || lastSequence) {
17172  int litEntropyWritten = 0;
17173  int seqEntropyWritten = 0;
17174  const size_t decompressedSize = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence);
17175  const size_t cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata,
17176  sp, seqCount,
17177  lp, litSize,
17178  llCodePtr, mlCodePtr, ofCodePtr,
17179  cctxParams,
17180  op, oend-op,
17181  bmi2, writeLitEntropy, writeSeqEntropy,
17182  &litEntropyWritten, &seqEntropyWritten,
17183  lastBlock && lastSequence);
17184  FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed");
17185  if (cSize > 0 && cSize < decompressedSize) {
17186  DEBUGLOG(5, "Committed the sub-block");
17187  assert(ip + decompressedSize <= iend);
17188  ip += decompressedSize;
17189  sp += seqCount;
17190  lp += litSize;
17191  op += cSize;
17192  llCodePtr += seqCount;
17193  mlCodePtr += seqCount;
17194  ofCodePtr += seqCount;
17195  litSize = 0;
17196  seqCount = 0;
17197  /* Entropy only needs to be written once */
17198  if (litEntropyWritten) {
17199  writeLitEntropy = 0;
17200  }
17201  if (seqEntropyWritten) {
17202  writeSeqEntropy = 0;
17203  }
17204  }
17205  }
17206  } while (!lastSequence);
17207  if (writeLitEntropy) {
17208  DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
17209  ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
17210  }
17211  if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
17212  /* If we haven't written our entropy tables, then we've violated our contract and
17213  * must emit an uncompressed block.
17214  */
17215  DEBUGLOG(5, "ZSTD_compressSubBlock_multi has sequence entropy tables unwritten");
17216  return 0;
17217  }
17218  if (ip < iend) {
17219  size_t const cSize = ZSTD_noCompressBlock(op, oend - op, ip, iend - ip, lastBlock);
17220  DEBUGLOG(5, "ZSTD_compressSubBlock_multi last sub-block uncompressed, %zu bytes", (size_t)(iend - ip));
17221  FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
17222  assert(cSize != 0);
17223  op += cSize;
17224  /* We have to regenerate the repcodes because we've skipped some sequences */
17225  if (sp < send) {
17226  seqDef const* seq;
17227  repcodes_t rep;
17228  ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
17229  for (seq = sstart; seq < sp; ++seq) {
17230  ZSTD_updateRep(rep.rep, seq->offBase, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
17231  }
17232  ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
17233  }
17234  }
17235  DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
17236  return op-ostart;
17237 }
17238 
17240  void* dst, size_t dstCapacity,
17241  void const* src, size_t srcSize,
17242  unsigned lastBlock) {
17243  ZSTD_entropyCTablesMetadata_t entropyMetadata;
17244 
17248  &zc->appliedParams,
17249  &entropyMetadata,
17250  zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
17251 
17253  zc->blockState.prevCBlock,
17254  zc->blockState.nextCBlock,
17255  &entropyMetadata,
17256  &zc->appliedParams,
17257  dst, dstCapacity,
17258  src, srcSize,
17259  zc->bmi2, lastBlock,
17260  zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
17261 }
17262 /**** ended inlining compress/zstd_compress_superblock.c ****/
17263 /**** start inlining compress/zstd_compress.c ****/
17264 /*
17265  * Copyright (c) Meta Platforms, Inc. and affiliates.
17266  * All rights reserved.
17267  *
17268  * This source code is licensed under both the BSD-style license (found in the
17269  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17270  * in the COPYING file in the root directory of this source tree).
17271  * You may select, at your option, one of the above-listed licenses.
17272  */
17273 
17274 /*-*************************************
17275 * Dependencies
17276 ***************************************/
17277 /**** skipping file: ../common/allocations.h ****/
17278 /**** skipping file: ../common/zstd_deps.h ****/
17279 /**** skipping file: ../common/mem.h ****/
17280 /**** skipping file: hist.h ****/
17281 #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
17282 /**** skipping file: ../common/fse.h ****/
17283 /**** skipping file: ../common/huf.h ****/
17284 /**** skipping file: zstd_compress_internal.h ****/
17285 /**** skipping file: zstd_compress_sequences.h ****/
17286 /**** skipping file: zstd_compress_literals.h ****/
17287 /**** start inlining zstd_fast.h ****/
17288 /*
17289  * Copyright (c) Meta Platforms, Inc. and affiliates.
17290  * All rights reserved.
17291  *
17292  * This source code is licensed under both the BSD-style license (found in the
17293  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17294  * in the COPYING file in the root directory of this source tree).
17295  * You may select, at your option, one of the above-listed licenses.
17296  */
17297 
17298 #ifndef ZSTD_FAST_H
17299 #define ZSTD_FAST_H
17300 
17301 #if defined (__cplusplus)
17302 extern "C" {
17303 #endif
17304 
17305 /**** skipping file: ../common/mem.h ****/
17306 /**** skipping file: zstd_compress_internal.h ****/
17307 
17309  void const* end, ZSTD_dictTableLoadMethod_e dtlm,
17312  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17313  void const* src, size_t srcSize);
17315  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17316  void const* src, size_t srcSize);
17318  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17319  void const* src, size_t srcSize);
17320 
17321 #if defined (__cplusplus)
17322 }
17323 #endif
17324 
17325 #endif /* ZSTD_FAST_H */
17326 /**** ended inlining zstd_fast.h ****/
17327 /**** start inlining zstd_double_fast.h ****/
17328 /*
17329  * Copyright (c) Meta Platforms, Inc. and affiliates.
17330  * All rights reserved.
17331  *
17332  * This source code is licensed under both the BSD-style license (found in the
17333  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17334  * in the COPYING file in the root directory of this source tree).
17335  * You may select, at your option, one of the above-listed licenses.
17336  */
17337 
17338 #ifndef ZSTD_DOUBLE_FAST_H
17339 #define ZSTD_DOUBLE_FAST_H
17340 
17341 #if defined (__cplusplus)
17342 extern "C" {
17343 #endif
17344 
17345 /**** skipping file: ../common/mem.h ****/
17346 /**** skipping file: zstd_compress_internal.h ****/
17347 
17349  void const* end, ZSTD_dictTableLoadMethod_e dtlm,
17352  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17353  void const* src, size_t srcSize);
17355  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17356  void const* src, size_t srcSize);
17358  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17359  void const* src, size_t srcSize);
17360 
17361 
17362 #if defined (__cplusplus)
17363 }
17364 #endif
17365 
17366 #endif /* ZSTD_DOUBLE_FAST_H */
17367 /**** ended inlining zstd_double_fast.h ****/
17368 /**** start inlining zstd_lazy.h ****/
17369 /*
17370  * Copyright (c) Meta Platforms, Inc. and affiliates.
17371  * All rights reserved.
17372  *
17373  * This source code is licensed under both the BSD-style license (found in the
17374  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17375  * in the COPYING file in the root directory of this source tree).
17376  * You may select, at your option, one of the above-listed licenses.
17377  */
17378 
17379 #ifndef ZSTD_LAZY_H
17380 #define ZSTD_LAZY_H
17381 
17382 #if defined (__cplusplus)
17383 extern "C" {
17384 #endif
17385 
17386 /**** skipping file: zstd_compress_internal.h ****/
17387 
17394 #define ZSTD_LAZY_DDSS_BUCKET_LOG 2
17395 
17396 #define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */
17397 
17399 void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip);
17400 
17402 
17403 void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue);
17406  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17407  void const* src, size_t srcSize);
17409  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17410  void const* src, size_t srcSize);
17412  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17413  void const* src, size_t srcSize);
17415  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17416  void const* src, size_t srcSize);
17418  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17419  void const* src, size_t srcSize);
17421  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17422  void const* src, size_t srcSize);
17424  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17425  void const* src, size_t srcSize);
17426 
17428  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17429  void const* src, size_t srcSize);
17431  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17432  void const* src, size_t srcSize);
17434  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17435  void const* src, size_t srcSize);
17437  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17438  void const* src, size_t srcSize);
17440  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17441  void const* src, size_t srcSize);
17443  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17444  void const* src, size_t srcSize);
17446  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17447  void const* src, size_t srcSize);
17448 
17450  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17451  void const* src, size_t srcSize);
17453  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17454  void const* src, size_t srcSize);
17456  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17457  void const* src, size_t srcSize);
17459  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17460  void const* src, size_t srcSize);
17462  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17463  void const* src, size_t srcSize);
17465  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17466  void const* src, size_t srcSize);
17467 
17469  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17470  void const* src, size_t srcSize);
17472  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17473  void const* src, size_t srcSize);
17475  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17476  void const* src, size_t srcSize);
17478  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17479  void const* src, size_t srcSize);
17481  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17482  void const* src, size_t srcSize);
17484  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17485  void const* src, size_t srcSize);
17487  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17488  void const* src, size_t srcSize);
17489 
17490 
17491 #if defined (__cplusplus)
17492 }
17493 #endif
17494 
17495 #endif /* ZSTD_LAZY_H */
17496 /**** ended inlining zstd_lazy.h ****/
17497 /**** start inlining zstd_opt.h ****/
17498 /*
17499  * Copyright (c) Meta Platforms, Inc. and affiliates.
17500  * All rights reserved.
17501  *
17502  * This source code is licensed under both the BSD-style license (found in the
17503  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17504  * in the COPYING file in the root directory of this source tree).
17505  * You may select, at your option, one of the above-listed licenses.
17506  */
17507 
17508 #ifndef ZSTD_OPT_H
17509 #define ZSTD_OPT_H
17510 
17511 #if defined (__cplusplus)
17512 extern "C" {
17513 #endif
17514 
17515 /**** skipping file: zstd_compress_internal.h ****/
17516 
17517 /* used in ZSTD_loadDictionaryContent() */
17518 void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend);
17519 
17521  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17522  void const* src, size_t srcSize);
17524  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17525  void const* src, size_t srcSize);
17527  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17528  void const* src, size_t srcSize);
17529 
17530 
17532  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17533  void const* src, size_t srcSize);
17535  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17536  void const* src, size_t srcSize);
17537 
17539  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17540  void const* src, size_t srcSize);
17542  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17543  void const* src, size_t srcSize);
17544 
17545  /* note : no btultra2 variant for extDict nor dictMatchState,
17546  * because btultra2 is not meant to work with dictionaries
17547  * and is only specific for the first block (no prefix) */
17548 
17549 #if defined (__cplusplus)
17550 }
17551 #endif
17552 
17553 #endif /* ZSTD_OPT_H */
17554 /**** ended inlining zstd_opt.h ****/
17555 /**** start inlining zstd_ldm.h ****/
17556 /*
17557  * Copyright (c) Meta Platforms, Inc. and affiliates.
17558  * All rights reserved.
17559  *
17560  * This source code is licensed under both the BSD-style license (found in the
17561  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
17562  * in the COPYING file in the root directory of this source tree).
17563  * You may select, at your option, one of the above-listed licenses.
17564  */
17565 
17566 #ifndef ZSTD_LDM_H
17567 #define ZSTD_LDM_H
17568 
17569 #if defined (__cplusplus)
17570 extern "C" {
17571 #endif
17572 
17573 /**** skipping file: zstd_compress_internal.h ****/
17574 /**** skipping file: ../zstd.h ****/
17575 
17576 /*-*************************************
17577 * Long distance matching
17578 ***************************************/
17579 
17580 #define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT
17581 
17583  ldmState_t* state, const BYTE* ip,
17584  const BYTE* iend, ldmParams_t const* params);
17585 
17601  ldmState_t* ldms, rawSeqStore_t* sequences,
17602  ldmParams_t const* params, void const* src, size_t srcSize);
17603 
17622 size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
17623  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
17624  ZSTD_paramSwitch_e useRowMatchFinder,
17625  void const* src, size_t srcSize);
17626 
17634 void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,
17635  U32 const minMatch);
17636 
17637 /* ZSTD_ldm_skipRawSeqStoreBytes():
17638  * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
17639  * Not to be used in conjunction with ZSTD_ldm_skipSequences().
17640  * Must be called for data with is not passed to ZSTD_ldm_blockCompress().
17641  */
17642 void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes);
17643 
17648 size_t ZSTD_ldm_getTableSize(ldmParams_t params);
17649 
17654 size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize);
17655 
17666  ZSTD_compressionParameters const* cParams);
17667 
17668 #if defined (__cplusplus)
17669 }
17670 #endif
17671 
17672 #endif /* ZSTD_FAST_H */
17673 /**** ended inlining zstd_ldm.h ****/
17674 /**** skipping file: zstd_compress_superblock.h ****/
17675 /**** skipping file: ../common/bits.h ****/
17676 
17677 /* ***************************************************************
17678 * Tuning parameters
17679 *****************************************************************/
17686 #ifndef ZSTD_COMPRESS_HEAPMODE
17687 # define ZSTD_COMPRESS_HEAPMODE 0
17688 #endif
17689 
17699 #ifndef ZSTD_HASHLOG3_MAX
17700 # define ZSTD_HASHLOG3_MAX 17
17701 #endif
17702 
17703 /*-*************************************
17704 * Helper functions
17705 ***************************************/
17706 /* ZSTD_compressBound()
17707  * Note that the result from this function is only valid for
17708  * the one-pass compression functions.
17709  * When employing the streaming mode,
17710  * if flushes are frequently altering the size of blocks,
17711  * the overhead from block headers can make the compressed data larger
17712  * than the return value of ZSTD_compressBound().
17713  */
17714 size_t ZSTD_compressBound(size_t srcSize) {
17715  size_t const r = ZSTD_COMPRESSBOUND(srcSize);
17716  if (r==0) return ERROR(srcSize_wrong);
17717  return r;
17721 /*-*************************************
17722 * Context memory management
17723 ***************************************/
17725  const void* dictContent;
17727  ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
17728  U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
17732  ZSTD_customMem customMem;
17733  U32 dictID;
17734  int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
17735  ZSTD_paramSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
17736  * row-based matchfinder. Unless the cdict is reloaded, we will use
17737  * the same greedy/lazy matchfinder at compression time.
17738  */
17739 }; /* typedef'd to ZSTD_CDict within "zstd.h" */
17742 {
17743  return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
17744 }
17745 
17746 static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
17747 {
17748  assert(cctx != NULL);
17749  ZSTD_memset(cctx, 0, sizeof(*cctx));
17750  cctx->customMem = memManager;
17751  cctx->bmi2 = ZSTD_cpuSupportsBmi2();
17752  { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);
17753  assert(!ZSTD_isError(err));
17754  (void)err;
17755  }
17756 }
17757 
17758 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
17759 {
17762  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
17763  { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem);
17764  if (!cctx) return NULL;
17765  ZSTD_initCCtx(cctx, customMem);
17766  return cctx;
17767  }
17768 }
17769 
17770 ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
17771 {
17772  ZSTD_cwksp ws;
17773  ZSTD_CCtx* cctx;
17774  if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */
17775  if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */
17776  ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
17777 
17778  cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
17779  if (cctx == NULL) return NULL;
17780 
17781  ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx));
17782  ZSTD_cwksp_move(&cctx->workspace, &ws);
17783  cctx->staticSize = workspaceSize;
17784 
17785  /* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
17790  cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
17791  return cctx;
17792 }
17793 
17797 static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
17798 {
17801  ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict));
17802  ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
17803  cctx->cdict = NULL;
17804 }
17805 
17806 static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict)
17808  size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0;
17809  size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict);
17810  return bufferSize + cdictSize;
17811 }
17812 
17813 static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
17814 {
17815  assert(cctx != NULL);
17816  assert(cctx->staticSize == 0);
17817  ZSTD_clearAllDicts(cctx);
17818 #ifdef ZSTD_MULTITHREAD
17819  ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
17820 #endif
17821  ZSTD_cwksp_free(&cctx->workspace, cctx->customMem);
17822 }
17823 
17824 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
17825 {
17826  if (cctx==NULL) return 0; /* support free on NULL */
17827  RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
17828  "not compatible with static CCtx");
17829  { int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx);
17830  ZSTD_freeCCtxContent(cctx);
17831  if (!cctxInWorkspace) ZSTD_customFree(cctx, cctx->customMem);
17832  }
17833  return 0;
17834 }
17835 
17836 
17837 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
17838 {
17839 #ifdef ZSTD_MULTITHREAD
17840  return ZSTDMT_sizeof_CCtx(cctx->mtctx);
17841 #else
17842  (void)cctx;
17843  return 0;
17844 #endif
17845 }
17846 
17847 
17848 size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
17849 {
17850  if (cctx==NULL) return 0; /* support sizeof on NULL */
17851  /* cctx may be in the workspace */
17852  return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx))
17853  + ZSTD_cwksp_sizeof(&cctx->workspace)
17855  + ZSTD_sizeof_mtctx(cctx);
17856 }
17857 
17859 {
17860  return ZSTD_sizeof_CCtx(zcs); /* same object */
17862 
17863 /* private API call, for dictBuilder only */
17864 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
17865 
17866 /* Returns true if the strategy supports using a row based matchfinder */
17867 static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
17868  return (strategy >= ZSTD_greedy && strategy <= ZSTD_lazy2);
17869 }
17870 
17871 /* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
17872  * for this compression.
17873  */
17874 static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e mode) {
17875  assert(mode != ZSTD_ps_auto);
17876  return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable);
17877 }
17878 
17879 /* Returns row matchfinder usage given an initial mode and cParams */
17880 static ZSTD_paramSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_paramSwitch_e mode,
17881  const ZSTD_compressionParameters* const cParams) {
17882 #if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON)
17883  int const kHasSIMD128 = 1;
17884 #else
17885  int const kHasSIMD128 = 0;
17886 #endif
17887  if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
17888  mode = ZSTD_ps_disable;
17889  if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
17890  if (kHasSIMD128) {
17891  if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
17892  } else {
17893  if (cParams->windowLog > 17) mode = ZSTD_ps_enable;
17894  }
17895  return mode;
17896 }
17897 
17898 /* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */
17899 static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode,
17900  const ZSTD_compressionParameters* const cParams) {
17901  if (mode != ZSTD_ps_auto) return mode;
17902  return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable;
17903 }
17904 
17905 /* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
17906 static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
17907  const ZSTD_paramSwitch_e useRowMatchFinder,
17908  const U32 forDDSDict) {
17909  assert(useRowMatchFinder != ZSTD_ps_auto);
17910  /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
17911  * We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder.
17912  */
17913  return forDDSDict || ((strategy != ZSTD_fast) && !ZSTD_rowMatchFinderUsed(strategy, useRowMatchFinder));
17915 
17916 /* Returns ZSTD_ps_enable if compression parameters are such that we should
17917  * enable long distance matching (wlog >= 27, strategy >= btopt).
17918  * Returns ZSTD_ps_disable otherwise.
17919  */
17920 static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode,
17921  const ZSTD_compressionParameters* const cParams) {
17922  if (mode != ZSTD_ps_auto) return mode;
17923  return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
17924 }
17926 static int ZSTD_resolveExternalSequenceValidation(int mode) {
17927  return mode;
17928 }
17929 
17930 /* Resolves maxBlockSize to the default if no value is present. */
17931 static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) {
17932  if (maxBlockSize == 0) {
17934  } else {
17935  return maxBlockSize;
17936  }
17937 }
17938 
17939 static ZSTD_paramSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_paramSwitch_e value, int cLevel) {
17940  if (value != ZSTD_ps_auto) return value;
17941  if (cLevel < 10) {
17942  return ZSTD_ps_disable;
17943  } else {
17944  return ZSTD_ps_enable;
17945  }
17946 }
17947 
17948 /* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged.
17949  * If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */
17950 static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) {
17951  return cParams->strategy == ZSTD_fast || cParams->strategy == ZSTD_dfast;
17952 }
17953 
17954 static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
17955  ZSTD_compressionParameters cParams)
17956 {
17957  ZSTD_CCtx_params cctxParams;
17958  /* should not matter, as all cParams are presumed properly defined */
17960  cctxParams.cParams = cParams;
17961 
17962  /* Adjust advanced params according to cParams */
17963  cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams);
17964  if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) {
17965  ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams);
17966  assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
17967  assert(cctxParams.ldmParams.hashRateLog < 32);
17968  }
17969  cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams);
17970  cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
17971  cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences);
17972  cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize);
17973  cctxParams.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams.searchForExternalRepcodes,
17974  cctxParams.compressionLevel);
17975  assert(!ZSTD_checkCParams(cParams));
17976  return cctxParams;
17977 }
17978 
17979 static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced(
17980  ZSTD_customMem customMem)
17981 {
17982  ZSTD_CCtx_params* params;
17983  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
17984  params = (ZSTD_CCtx_params*)ZSTD_customCalloc(
17985  sizeof(ZSTD_CCtx_params), customMem);
17986  if (!params) { return NULL; }
17988  params->customMem = customMem;
17989  return params;
17990 }
17992 ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
17993 {
17994  return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem);
17995 }
17996 
17997 size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
17999  if (params == NULL) { return 0; }
18000  ZSTD_customFree(params, params->customMem);
18001  return 0;
18002 }
18004 size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
18005 {
18006  return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
18007 }
18008 
18009 size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
18010  RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
18011  ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
18012  cctxParams->compressionLevel = compressionLevel;
18013  cctxParams->fParams.contentSizeFlag = 1;
18014  return 0;
18015 }
18016 
18017 #define ZSTD_NO_CLEVEL 0
18023 static void
18024 ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams,
18025  const ZSTD_parameters* params,
18026  int compressionLevel)
18027 {
18028  assert(!ZSTD_checkCParams(params->cParams));
18029  ZSTD_memset(cctxParams, 0, sizeof(*cctxParams));
18030  cctxParams->cParams = params->cParams;
18031  cctxParams->fParams = params->fParams;
18032  /* Should not matter, as all cParams are presumed properly defined.
18033  * But, set it for tracing anyway.
18034  */
18035  cctxParams->compressionLevel = compressionLevel;
18036  cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, &params->cParams);
18037  cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, &params->cParams);
18038  cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, &params->cParams);
18039  cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences);
18040  cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize);
18041  cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel);
18042  DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
18043  cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm);
18044 }
18045 
18046 size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
18047 {
18048  RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!");
18049  FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
18050  ZSTD_CCtxParams_init_internal(cctxParams, &params, ZSTD_NO_CLEVEL);
18051  return 0;
18053 
18058 static void ZSTD_CCtxParams_setZstdParams(
18059  ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params)
18060 {
18061  assert(!ZSTD_checkCParams(params->cParams));
18062  cctxParams->cParams = params->cParams;
18063  cctxParams->fParams = params->fParams;
18064  /* Should not matter, as all cParams are presumed properly defined.
18065  * But, set it for tracing anyway.
18066  */
18067  cctxParams->compressionLevel = ZSTD_NO_CLEVEL;
18068 }
18069 
18071 {
18072  ZSTD_bounds bounds = { 0, 0, 0 };
18073 
18074  switch(param)
18075  {
18077  bounds.lowerBound = ZSTD_minCLevel();
18078  bounds.upperBound = ZSTD_maxCLevel();
18079  return bounds;
18080 
18081  case ZSTD_c_windowLog:
18082  bounds.lowerBound = ZSTD_WINDOWLOG_MIN;
18083  bounds.upperBound = ZSTD_WINDOWLOG_MAX;
18084  return bounds;
18085 
18086  case ZSTD_c_hashLog:
18087  bounds.lowerBound = ZSTD_HASHLOG_MIN;
18088  bounds.upperBound = ZSTD_HASHLOG_MAX;
18089  return bounds;
18090 
18091  case ZSTD_c_chainLog:
18092  bounds.lowerBound = ZSTD_CHAINLOG_MIN;
18093  bounds.upperBound = ZSTD_CHAINLOG_MAX;
18094  return bounds;
18095 
18096  case ZSTD_c_searchLog:
18097  bounds.lowerBound = ZSTD_SEARCHLOG_MIN;
18098  bounds.upperBound = ZSTD_SEARCHLOG_MAX;
18099  return bounds;
18100 
18101  case ZSTD_c_minMatch:
18102  bounds.lowerBound = ZSTD_MINMATCH_MIN;
18103  bounds.upperBound = ZSTD_MINMATCH_MAX;
18104  return bounds;
18105 
18106  case ZSTD_c_targetLength:
18107  bounds.lowerBound = ZSTD_TARGETLENGTH_MIN;
18108  bounds.upperBound = ZSTD_TARGETLENGTH_MAX;
18109  return bounds;
18110 
18111  case ZSTD_c_strategy:
18112  bounds.lowerBound = ZSTD_STRATEGY_MIN;
18113  bounds.upperBound = ZSTD_STRATEGY_MAX;
18114  return bounds;
18115 
18117  bounds.lowerBound = 0;
18118  bounds.upperBound = 1;
18119  return bounds;
18120 
18121  case ZSTD_c_checksumFlag:
18122  bounds.lowerBound = 0;
18123  bounds.upperBound = 1;
18124  return bounds;
18125 
18126  case ZSTD_c_dictIDFlag:
18127  bounds.lowerBound = 0;
18128  bounds.upperBound = 1;
18129  return bounds;
18130 
18131  case ZSTD_c_nbWorkers:
18132  bounds.lowerBound = 0;
18133 #ifdef ZSTD_MULTITHREAD
18135 #else
18136  bounds.upperBound = 0;
18137 #endif
18138  return bounds;
18139 
18140  case ZSTD_c_jobSize:
18141  bounds.lowerBound = 0;
18142 #ifdef ZSTD_MULTITHREAD
18143  bounds.upperBound = ZSTDMT_JOBSIZE_MAX;
18144 #else
18145  bounds.upperBound = 0;
18146 #endif
18147  return bounds;
18148 
18149  case ZSTD_c_overlapLog:
18150 #ifdef ZSTD_MULTITHREAD
18151  bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;
18152  bounds.upperBound = ZSTD_OVERLAPLOG_MAX;
18153 #else
18154  bounds.lowerBound = 0;
18155  bounds.upperBound = 0;
18156 #endif
18157  return bounds;
18158 
18159  case ZSTD_c_enableDedicatedDictSearch:
18160  bounds.lowerBound = 0;
18161  bounds.upperBound = 1;
18162  return bounds;
18163 
18165  bounds.lowerBound = (int)ZSTD_ps_auto;
18166  bounds.upperBound = (int)ZSTD_ps_disable;
18167  return bounds;
18168 
18169  case ZSTD_c_ldmHashLog:
18170  bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN;
18171  bounds.upperBound = ZSTD_LDM_HASHLOG_MAX;
18172  return bounds;
18173 
18174  case ZSTD_c_ldmMinMatch:
18175  bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN;
18176  bounds.upperBound = ZSTD_LDM_MINMATCH_MAX;
18177  return bounds;
18178 
18180  bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN;
18181  bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX;
18182  return bounds;
18183 
18184  case ZSTD_c_ldmHashRateLog:
18185  bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN;
18186  bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX;
18187  return bounds;
18188 
18189  /* experimental parameters */
18190  case ZSTD_c_rsyncable:
18191  bounds.lowerBound = 0;
18192  bounds.upperBound = 1;
18193  return bounds;
18194 
18195  case ZSTD_c_forceMaxWindow :
18196  bounds.lowerBound = 0;
18197  bounds.upperBound = 1;
18198  return bounds;
18199 
18200  case ZSTD_c_format:
18201  ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
18202  bounds.lowerBound = ZSTD_f_zstd1;
18203  bounds.upperBound = ZSTD_f_zstd1_magicless; /* note : how to ensure at compile time that this is the highest value enum ? */
18204  return bounds;
18205 
18206  case ZSTD_c_forceAttachDict:
18207  ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad);
18208  bounds.lowerBound = ZSTD_dictDefaultAttach;
18209  bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */
18210  return bounds;
18211 
18212  case ZSTD_c_literalCompressionMode:
18213  ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable);
18214  bounds.lowerBound = (int)ZSTD_ps_auto;
18215  bounds.upperBound = (int)ZSTD_ps_disable;
18216  return bounds;
18217 
18218  case ZSTD_c_targetCBlockSize:
18219  bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN;
18220  bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;
18221  return bounds;
18222 
18223  case ZSTD_c_srcSizeHint:
18224  bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN;
18225  bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
18226  return bounds;
18227 
18228  case ZSTD_c_stableInBuffer:
18229  case ZSTD_c_stableOutBuffer:
18230  bounds.lowerBound = (int)ZSTD_bm_buffered;
18231  bounds.upperBound = (int)ZSTD_bm_stable;
18232  return bounds;
18233 
18234  case ZSTD_c_blockDelimiters:
18235  bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters;
18236  bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters;
18237  return bounds;
18238 
18239  case ZSTD_c_validateSequences:
18240  bounds.lowerBound = 0;
18241  bounds.upperBound = 1;
18242  return bounds;
18243 
18244  case ZSTD_c_useBlockSplitter:
18245  bounds.lowerBound = (int)ZSTD_ps_auto;
18246  bounds.upperBound = (int)ZSTD_ps_disable;
18247  return bounds;
18248 
18249  case ZSTD_c_useRowMatchFinder:
18250  bounds.lowerBound = (int)ZSTD_ps_auto;
18251  bounds.upperBound = (int)ZSTD_ps_disable;
18252  return bounds;
18253 
18254  case ZSTD_c_deterministicRefPrefix:
18255  bounds.lowerBound = 0;
18256  bounds.upperBound = 1;
18257  return bounds;
18258 
18259  case ZSTD_c_prefetchCDictTables:
18260  bounds.lowerBound = (int)ZSTD_ps_auto;
18261  bounds.upperBound = (int)ZSTD_ps_disable;
18262  return bounds;
18263 
18264  case ZSTD_c_enableSeqProducerFallback:
18265  bounds.lowerBound = 0;
18266  bounds.upperBound = 1;
18267  return bounds;
18268 
18269  case ZSTD_c_maxBlockSize:
18270  bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
18271  bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
18272  return bounds;
18273 
18274  case ZSTD_c_searchForExternalRepcodes:
18275  bounds.lowerBound = (int)ZSTD_ps_auto;
18276  bounds.upperBound = (int)ZSTD_ps_disable;
18277  return bounds;
18278 
18279  default:
18280  bounds.error = ERROR(parameter_unsupported);
18281  return bounds;
18282  }
18283 }
18284 
18285 /* ZSTD_cParam_clampBounds:
18286  * Clamps the value into the bounded range.
18287  */
18288 static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
18289 {
18290  ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
18291  if (ZSTD_isError(bounds.error)) return bounds.error;
18292  if (*value < bounds.lowerBound) *value = bounds.lowerBound;
18293  if (*value > bounds.upperBound) *value = bounds.upperBound;
18294  return 0;
18295 }
18296 
18297 #define BOUNDCHECK(cParam, val) { \
18298  RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
18299  parameter_outOfBound, "Param out of bounds"); \
18300 }
18301 
18302 
18303 static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
18304 {
18305  switch(param)
18306  {
18308  case ZSTD_c_hashLog:
18309  case ZSTD_c_chainLog:
18310  case ZSTD_c_searchLog:
18311  case ZSTD_c_minMatch:
18312  case ZSTD_c_targetLength:
18313  case ZSTD_c_strategy:
18314  return 1;
18315 
18316  case ZSTD_c_format:
18317  case ZSTD_c_windowLog:
18319  case ZSTD_c_checksumFlag:
18320  case ZSTD_c_dictIDFlag:
18321  case ZSTD_c_forceMaxWindow :
18322  case ZSTD_c_nbWorkers:
18323  case ZSTD_c_jobSize:
18324  case ZSTD_c_overlapLog:
18325  case ZSTD_c_rsyncable:
18326  case ZSTD_c_enableDedicatedDictSearch:
18328  case ZSTD_c_ldmHashLog:
18329  case ZSTD_c_ldmMinMatch:
18331  case ZSTD_c_ldmHashRateLog:
18332  case ZSTD_c_forceAttachDict:
18333  case ZSTD_c_literalCompressionMode:
18334  case ZSTD_c_targetCBlockSize:
18335  case ZSTD_c_srcSizeHint:
18336  case ZSTD_c_stableInBuffer:
18337  case ZSTD_c_stableOutBuffer:
18338  case ZSTD_c_blockDelimiters:
18339  case ZSTD_c_validateSequences:
18340  case ZSTD_c_useBlockSplitter:
18341  case ZSTD_c_useRowMatchFinder:
18342  case ZSTD_c_deterministicRefPrefix:
18343  case ZSTD_c_prefetchCDictTables:
18344  case ZSTD_c_enableSeqProducerFallback:
18345  case ZSTD_c_maxBlockSize:
18346  case ZSTD_c_searchForExternalRepcodes:
18347  default:
18348  return 0;
18349  }
18350 }
18351 
18352 size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
18353 {
18354  DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value);
18355  if (cctx->streamStage != zcss_init) {
18357  cctx->cParamsChanged = 1;
18358  } else {
18359  RETURN_ERROR(stage_wrong, "can only set params in cctx init stage");
18360  } }
18361 
18362  switch(param)
18363  {
18364  case ZSTD_c_nbWorkers:
18365  RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported,
18366  "MT not compatible with static alloc");
18367  break;
18368 
18370  case ZSTD_c_windowLog:
18371  case ZSTD_c_hashLog:
18372  case ZSTD_c_chainLog:
18373  case ZSTD_c_searchLog:
18374  case ZSTD_c_minMatch:
18375  case ZSTD_c_targetLength:
18376  case ZSTD_c_strategy:
18377  case ZSTD_c_ldmHashRateLog:
18378  case ZSTD_c_format:
18380  case ZSTD_c_checksumFlag:
18381  case ZSTD_c_dictIDFlag:
18382  case ZSTD_c_forceMaxWindow:
18383  case ZSTD_c_forceAttachDict:
18384  case ZSTD_c_literalCompressionMode:
18385  case ZSTD_c_jobSize:
18386  case ZSTD_c_overlapLog:
18387  case ZSTD_c_rsyncable:
18388  case ZSTD_c_enableDedicatedDictSearch:
18390  case ZSTD_c_ldmHashLog:
18391  case ZSTD_c_ldmMinMatch:
18393  case ZSTD_c_targetCBlockSize:
18394  case ZSTD_c_srcSizeHint:
18395  case ZSTD_c_stableInBuffer:
18396  case ZSTD_c_stableOutBuffer:
18397  case ZSTD_c_blockDelimiters:
18398  case ZSTD_c_validateSequences:
18399  case ZSTD_c_useBlockSplitter:
18400  case ZSTD_c_useRowMatchFinder:
18401  case ZSTD_c_deterministicRefPrefix:
18402  case ZSTD_c_prefetchCDictTables:
18403  case ZSTD_c_enableSeqProducerFallback:
18404  case ZSTD_c_maxBlockSize:
18405  case ZSTD_c_searchForExternalRepcodes:
18406  break;
18408  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
18409  }
18410  return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);
18411 }
18412 
18413 size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
18414  ZSTD_cParameter param, int value)
18415 {
18416  DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value);
18417  switch(param)
18418  {
18419  case ZSTD_c_format :
18420  BOUNDCHECK(ZSTD_c_format, value);
18421  CCtxParams->format = (ZSTD_format_e)value;
18422  return (size_t)CCtxParams->format;
18423 
18424  case ZSTD_c_compressionLevel : {
18425  FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
18426  if (value == 0)
18427  CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
18428  else
18429  CCtxParams->compressionLevel = value;
18430  if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;
18431  return 0; /* return type (size_t) cannot represent negative values */
18432  }
18433 
18434  case ZSTD_c_windowLog :
18435  if (value!=0) /* 0 => use default */
18436  BOUNDCHECK(ZSTD_c_windowLog, value);
18437  CCtxParams->cParams.windowLog = (U32)value;
18438  return CCtxParams->cParams.windowLog;
18439 
18440  case ZSTD_c_hashLog :
18441  if (value!=0) /* 0 => use default */
18442  BOUNDCHECK(ZSTD_c_hashLog, value);
18443  CCtxParams->cParams.hashLog = (U32)value;
18444  return CCtxParams->cParams.hashLog;
18445 
18446  case ZSTD_c_chainLog :
18447  if (value!=0) /* 0 => use default */
18448  BOUNDCHECK(ZSTD_c_chainLog, value);
18449  CCtxParams->cParams.chainLog = (U32)value;
18450  return CCtxParams->cParams.chainLog;
18451 
18452  case ZSTD_c_searchLog :
18453  if (value!=0) /* 0 => use default */
18454  BOUNDCHECK(ZSTD_c_searchLog, value);
18455  CCtxParams->cParams.searchLog = (U32)value;
18456  return (size_t)value;
18457 
18458  case ZSTD_c_minMatch :
18459  if (value!=0) /* 0 => use default */
18460  BOUNDCHECK(ZSTD_c_minMatch, value);
18461  CCtxParams->cParams.minMatch = (U32)value;
18462  return CCtxParams->cParams.minMatch;
18463 
18464  case ZSTD_c_targetLength :
18466  CCtxParams->cParams.targetLength = (U32)value;
18467  return CCtxParams->cParams.targetLength;
18468 
18469  case ZSTD_c_strategy :
18470  if (value!=0) /* 0 => use default */
18471  BOUNDCHECK(ZSTD_c_strategy, value);
18472  CCtxParams->cParams.strategy = (ZSTD_strategy)value;
18473  return (size_t)CCtxParams->cParams.strategy;
18474 
18475  case ZSTD_c_contentSizeFlag :
18476  /* Content size written in frame header _when known_ (default:1) */
18477  DEBUGLOG(4, "set content size flag = %u", (value!=0));
18478  CCtxParams->fParams.contentSizeFlag = value != 0;
18479  return (size_t)CCtxParams->fParams.contentSizeFlag;
18480 
18481  case ZSTD_c_checksumFlag :
18482  /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
18483  CCtxParams->fParams.checksumFlag = value != 0;
18484  return (size_t)CCtxParams->fParams.checksumFlag;
18485 
18486  case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
18487  DEBUGLOG(4, "set dictIDFlag = %u", (value!=0));
18488  CCtxParams->fParams.noDictIDFlag = !value;
18489  return !CCtxParams->fParams.noDictIDFlag;
18490 
18491  case ZSTD_c_forceMaxWindow :
18492  CCtxParams->forceWindow = (value != 0);
18493  return (size_t)CCtxParams->forceWindow;
18494 
18495  case ZSTD_c_forceAttachDict : {
18496  const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value;
18497  BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref);
18498  CCtxParams->attachDictPref = pref;
18499  return CCtxParams->attachDictPref;
18500  }
18501 
18502  case ZSTD_c_literalCompressionMode : {
18503  const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value;
18504  BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
18505  CCtxParams->literalCompressionMode = lcm;
18506  return CCtxParams->literalCompressionMode;
18507  }
18508 
18509  case ZSTD_c_nbWorkers :
18510 #ifndef ZSTD_MULTITHREAD
18511  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
18512  return 0;
18513 #else
18514  FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
18515  CCtxParams->nbWorkers = value;
18516  return CCtxParams->nbWorkers;
18517 #endif
18518 
18519  case ZSTD_c_jobSize :
18520 #ifndef ZSTD_MULTITHREAD
18521  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
18522  return 0;
18523 #else
18524  /* Adjust to the minimum non-default value. */
18525  if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)
18527  FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
18528  assert(value >= 0);
18529  CCtxParams->jobSize = value;
18530  return CCtxParams->jobSize;
18531 #endif
18532 
18533  case ZSTD_c_overlapLog :
18534 #ifndef ZSTD_MULTITHREAD
18535  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
18536  return 0;
18537 #else
18539  CCtxParams->overlapLog = value;
18540  return CCtxParams->overlapLog;
18541 #endif
18542 
18543  case ZSTD_c_rsyncable :
18544 #ifndef ZSTD_MULTITHREAD
18545  RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading");
18546  return 0;
18547 #else
18549  CCtxParams->rsyncable = value;
18550  return CCtxParams->rsyncable;
18551 #endif
18552 
18553  case ZSTD_c_enableDedicatedDictSearch :
18554  CCtxParams->enableDedicatedDictSearch = (value!=0);
18555  return (size_t)CCtxParams->enableDedicatedDictSearch;
18556 
18559  CCtxParams->ldmParams.enableLdm = (ZSTD_paramSwitch_e)value;
18560  return CCtxParams->ldmParams.enableLdm;
18561 
18562  case ZSTD_c_ldmHashLog :
18563  if (value!=0) /* 0 ==> auto */
18564  BOUNDCHECK(ZSTD_c_ldmHashLog, value);
18565  CCtxParams->ldmParams.hashLog = (U32)value;
18566  return CCtxParams->ldmParams.hashLog;
18567 
18568  case ZSTD_c_ldmMinMatch :
18569  if (value!=0) /* 0 ==> default */
18571  CCtxParams->ldmParams.minMatchLength = (U32)value;
18572  return CCtxParams->ldmParams.minMatchLength;
18573 
18575  if (value!=0) /* 0 ==> default */
18577  CCtxParams->ldmParams.bucketSizeLog = (U32)value;
18578  return CCtxParams->ldmParams.bucketSizeLog;
18579 
18580  case ZSTD_c_ldmHashRateLog :
18581  if (value!=0) /* 0 ==> default */
18583  CCtxParams->ldmParams.hashRateLog = (U32)value;
18584  return CCtxParams->ldmParams.hashRateLog;
18585 
18586  case ZSTD_c_targetCBlockSize :
18587  if (value!=0) /* 0 ==> default */
18588  BOUNDCHECK(ZSTD_c_targetCBlockSize, value);
18589  CCtxParams->targetCBlockSize = (U32)value;
18590  return CCtxParams->targetCBlockSize;
18591 
18592  case ZSTD_c_srcSizeHint :
18593  if (value!=0) /* 0 ==> default */
18594  BOUNDCHECK(ZSTD_c_srcSizeHint, value);
18595  CCtxParams->srcSizeHint = value;
18596  return (size_t)CCtxParams->srcSizeHint;
18597 
18598  case ZSTD_c_stableInBuffer:
18599  BOUNDCHECK(ZSTD_c_stableInBuffer, value);
18600  CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value;
18601  return CCtxParams->inBufferMode;
18602 
18603  case ZSTD_c_stableOutBuffer:
18604  BOUNDCHECK(ZSTD_c_stableOutBuffer, value);
18605  CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value;
18606  return CCtxParams->outBufferMode;
18607 
18608  case ZSTD_c_blockDelimiters:
18609  BOUNDCHECK(ZSTD_c_blockDelimiters, value);
18610  CCtxParams->blockDelimiters = (ZSTD_sequenceFormat_e)value;
18611  return CCtxParams->blockDelimiters;
18612 
18613  case ZSTD_c_validateSequences:
18614  BOUNDCHECK(ZSTD_c_validateSequences, value);
18615  CCtxParams->validateSequences = value;
18616  return CCtxParams->validateSequences;
18617 
18618  case ZSTD_c_useBlockSplitter:
18619  BOUNDCHECK(ZSTD_c_useBlockSplitter, value);
18620  CCtxParams->useBlockSplitter = (ZSTD_paramSwitch_e)value;
18621  return CCtxParams->useBlockSplitter;
18622 
18623  case ZSTD_c_useRowMatchFinder:
18624  BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
18625  CCtxParams->useRowMatchFinder = (ZSTD_paramSwitch_e)value;
18626  return CCtxParams->useRowMatchFinder;
18627 
18628  case ZSTD_c_deterministicRefPrefix:
18629  BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value);
18630  CCtxParams->deterministicRefPrefix = !!value;
18631  return CCtxParams->deterministicRefPrefix;
18632 
18633  case ZSTD_c_prefetchCDictTables:
18634  BOUNDCHECK(ZSTD_c_prefetchCDictTables, value);
18635  CCtxParams->prefetchCDictTables = (ZSTD_paramSwitch_e)value;
18636  return CCtxParams->prefetchCDictTables;
18637 
18638  case ZSTD_c_enableSeqProducerFallback:
18639  BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value);
18640  CCtxParams->enableMatchFinderFallback = value;
18641  return CCtxParams->enableMatchFinderFallback;
18642 
18643  case ZSTD_c_maxBlockSize:
18644  if (value!=0) /* 0 ==> default */
18645  BOUNDCHECK(ZSTD_c_maxBlockSize, value);
18646  CCtxParams->maxBlockSize = value;
18647  return CCtxParams->maxBlockSize;
18648 
18649  case ZSTD_c_searchForExternalRepcodes:
18650  BOUNDCHECK(ZSTD_c_searchForExternalRepcodes, value);
18651  CCtxParams->searchForExternalRepcodes = (ZSTD_paramSwitch_e)value;
18652  return CCtxParams->searchForExternalRepcodes;
18653 
18654  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
18655  }
18656 }
18658 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value)
18659 {
18660  return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);
18661 }
18662 
18664  ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value)
18665 {
18666  switch(param)
18667  {
18668  case ZSTD_c_format :
18669  *value = CCtxParams->format;
18670  break;
18672  *value = CCtxParams->compressionLevel;
18673  break;
18674  case ZSTD_c_windowLog :
18675  *value = (int)CCtxParams->cParams.windowLog;
18676  break;
18677  case ZSTD_c_hashLog :
18678  *value = (int)CCtxParams->cParams.hashLog;
18679  break;
18680  case ZSTD_c_chainLog :
18681  *value = (int)CCtxParams->cParams.chainLog;
18682  break;
18683  case ZSTD_c_searchLog :
18684  *value = CCtxParams->cParams.searchLog;
18685  break;
18686  case ZSTD_c_minMatch :
18687  *value = CCtxParams->cParams.minMatch;
18688  break;
18689  case ZSTD_c_targetLength :
18690  *value = CCtxParams->cParams.targetLength;
18691  break;
18692  case ZSTD_c_strategy :
18693  *value = (unsigned)CCtxParams->cParams.strategy;
18694  break;
18695  case ZSTD_c_contentSizeFlag :
18696  *value = CCtxParams->fParams.contentSizeFlag;
18697  break;
18698  case ZSTD_c_checksumFlag :
18699  *value = CCtxParams->fParams.checksumFlag;
18700  break;
18701  case ZSTD_c_dictIDFlag :
18702  *value = !CCtxParams->fParams.noDictIDFlag;
18703  break;
18704  case ZSTD_c_forceMaxWindow :
18705  *value = CCtxParams->forceWindow;
18706  break;
18707  case ZSTD_c_forceAttachDict :
18708  *value = CCtxParams->attachDictPref;
18709  break;
18710  case ZSTD_c_literalCompressionMode :
18711  *value = CCtxParams->literalCompressionMode;
18712  break;
18713  case ZSTD_c_nbWorkers :
18714 #ifndef ZSTD_MULTITHREAD
18715  assert(CCtxParams->nbWorkers == 0);
18716 #endif
18717  *value = CCtxParams->nbWorkers;
18718  break;
18719  case ZSTD_c_jobSize :
18720 #ifndef ZSTD_MULTITHREAD
18721  RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
18722 #else
18723  assert(CCtxParams->jobSize <= INT_MAX);
18724  *value = (int)CCtxParams->jobSize;
18725  break;
18726 #endif
18727  case ZSTD_c_overlapLog :
18728 #ifndef ZSTD_MULTITHREAD
18729  RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
18730 #else
18731  *value = CCtxParams->overlapLog;
18732  break;
18733 #endif
18734  case ZSTD_c_rsyncable :
18735 #ifndef ZSTD_MULTITHREAD
18736  RETURN_ERROR(parameter_unsupported, "not compiled with multithreading");
18737 #else
18738  *value = CCtxParams->rsyncable;
18739  break;
18740 #endif
18741  case ZSTD_c_enableDedicatedDictSearch :
18742  *value = CCtxParams->enableDedicatedDictSearch;
18743  break;
18745  *value = CCtxParams->ldmParams.enableLdm;
18746  break;
18747  case ZSTD_c_ldmHashLog :
18748  *value = CCtxParams->ldmParams.hashLog;
18749  break;
18750  case ZSTD_c_ldmMinMatch :
18751  *value = CCtxParams->ldmParams.minMatchLength;
18752  break;
18754  *value = CCtxParams->ldmParams.bucketSizeLog;
18755  break;
18756  case ZSTD_c_ldmHashRateLog :
18757  *value = CCtxParams->ldmParams.hashRateLog;
18758  break;
18759  case ZSTD_c_targetCBlockSize :
18760  *value = (int)CCtxParams->targetCBlockSize;
18761  break;
18762  case ZSTD_c_srcSizeHint :
18763  *value = (int)CCtxParams->srcSizeHint;
18764  break;
18765  case ZSTD_c_stableInBuffer :
18766  *value = (int)CCtxParams->inBufferMode;
18767  break;
18768  case ZSTD_c_stableOutBuffer :
18769  *value = (int)CCtxParams->outBufferMode;
18770  break;
18771  case ZSTD_c_blockDelimiters :
18772  *value = (int)CCtxParams->blockDelimiters;
18773  break;
18774  case ZSTD_c_validateSequences :
18775  *value = (int)CCtxParams->validateSequences;
18776  break;
18777  case ZSTD_c_useBlockSplitter :
18778  *value = (int)CCtxParams->useBlockSplitter;
18779  break;
18780  case ZSTD_c_useRowMatchFinder :
18781  *value = (int)CCtxParams->useRowMatchFinder;
18782  break;
18783  case ZSTD_c_deterministicRefPrefix:
18784  *value = (int)CCtxParams->deterministicRefPrefix;
18785  break;
18786  case ZSTD_c_prefetchCDictTables:
18787  *value = (int)CCtxParams->prefetchCDictTables;
18788  break;
18789  case ZSTD_c_enableSeqProducerFallback:
18790  *value = CCtxParams->enableMatchFinderFallback;
18791  break;
18792  case ZSTD_c_maxBlockSize:
18793  *value = (int)CCtxParams->maxBlockSize;
18794  break;
18795  case ZSTD_c_searchForExternalRepcodes:
18796  *value = (int)CCtxParams->searchForExternalRepcodes;
18797  break;
18798  default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
18799  }
18800  return 0;
18801 }
18802 
18811  ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
18812 {
18813  DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
18814  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18815  "The context is in the wrong stage!");
18816  RETURN_ERROR_IF(cctx->cdict, stage_wrong,
18817  "Can't override parameters with cdict attached (some must "
18818  "be inherited from the cdict).");
18819 
18820  cctx->requestedParams = *params;
18821  return 0;
18822 }
18823 
18824 size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams)
18825 {
18826  ZSTD_STATIC_ASSERT(sizeof(cparams) == 7 * 4 /* all params are listed below */);
18827  DEBUGLOG(4, "ZSTD_CCtx_setCParams");
18828  /* only update if all parameters are valid */
18829  FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), "");
18830  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, cparams.windowLog), "");
18831  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, cparams.chainLog), "");
18832  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, cparams.hashLog), "");
18833  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, cparams.searchLog), "");
18835  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, cparams.targetLength), "");
18836  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, cparams.strategy), "");
18837  return 0;
18838 }
18839 
18840 size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams)
18841 {
18842  ZSTD_STATIC_ASSERT(sizeof(fparams) == 3 * 4 /* all params are listed below */);
18843  DEBUGLOG(4, "ZSTD_CCtx_setFParams");
18844  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, fparams.contentSizeFlag != 0), "");
18845  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, fparams.checksumFlag != 0), "");
18846  FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, fparams.noDictIDFlag == 0), "");
18847  return 0;
18848 }
18849 
18850 size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params)
18851 {
18852  DEBUGLOG(4, "ZSTD_CCtx_setParams");
18853  /* First check cParams, because we want to update all or none. */
18854  FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
18855  /* Next set fParams, because this could fail if the cctx isn't in init stage. */
18856  FORWARD_IF_ERROR(ZSTD_CCtx_setFParams(cctx, params.fParams), "");
18857  /* Finally set cParams, which should succeed. */
18858  FORWARD_IF_ERROR(ZSTD_CCtx_setCParams(cctx, params.cParams), "");
18859  return 0;
18860 }
18861 
18862 size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
18863 {
18864  DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize);
18865  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18866  "Can't set pledgedSrcSize when not in init stage.");
18867  cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
18868  return 0;
18869 }
18870 
18871 static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(
18872  int const compressionLevel,
18873  size_t const dictSize);
18875  const ZSTD_compressionParameters* cParams);
18877  ZSTD_compressionParameters* cParams);
18884 static size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)
18885 {
18886  ZSTD_localDict* const dl = &cctx->localDict;
18887  if (dl->dict == NULL) {
18888  /* No local dictionary. */
18889  assert(dl->dictBuffer == NULL);
18890  assert(dl->cdict == NULL);
18891  assert(dl->dictSize == 0);
18892  return 0;
18893  }
18894  if (dl->cdict != NULL) {
18895  /* Local dictionary already initialized. */
18896  assert(cctx->cdict == dl->cdict);
18897  return 0;
18898  }
18899  assert(dl->dictSize > 0);
18900  assert(cctx->cdict == NULL);
18901  assert(cctx->prefixDict.dict == NULL);
18902 
18904  dl->dict,
18905  dl->dictSize,
18906  ZSTD_dlm_byRef,
18907  dl->dictContentType,
18908  &cctx->requestedParams,
18909  cctx->customMem);
18910  RETURN_ERROR_IF(!dl->cdict, memory_allocation, "ZSTD_createCDict_advanced failed");
18911  cctx->cdict = dl->cdict;
18912  return 0;
18913 }
18914 
18916  ZSTD_CCtx* cctx,
18917  const void* dict, size_t dictSize,
18918  ZSTD_dictLoadMethod_e dictLoadMethod,
18919  ZSTD_dictContentType_e dictContentType)
18920 {
18921  DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize);
18922  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18923  "Can't load a dictionary when cctx is not in init stage.");
18924  ZSTD_clearAllDicts(cctx); /* erase any previously set dictionary */
18925  if (dict == NULL || dictSize == 0) /* no dictionary */
18926  return 0;
18927  if (dictLoadMethod == ZSTD_dlm_byRef) {
18928  cctx->localDict.dict = dict;
18929  } else {
18930  /* copy dictionary content inside CCtx to own its lifetime */
18931  void* dictBuffer;
18932  RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
18933  "static CCtx can't allocate for an internal copy of dictionary");
18934  dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem);
18935  RETURN_ERROR_IF(dictBuffer==NULL, memory_allocation,
18936  "allocation failed for dictionary content");
18937  ZSTD_memcpy(dictBuffer, dict, dictSize);
18938  cctx->localDict.dictBuffer = dictBuffer; /* owned ptr to free */
18939  cctx->localDict.dict = dictBuffer; /* read-only reference */
18940  }
18941  cctx->localDict.dictSize = dictSize;
18942  cctx->localDict.dictContentType = dictContentType;
18943  return 0;
18944 }
18945 
18947  ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
18948 {
18950  cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
18951 }
18952 
18953 size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
18956  cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
18957 }
18958 
18959 
18960 size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
18961 {
18962  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18963  "Can't ref a dict when ctx not in init stage.");
18964  /* Free the existing local cdict (if any) to save memory. */
18965  ZSTD_clearAllDicts(cctx);
18966  cctx->cdict = cdict;
18967  return 0;
18968 }
18969 
18970 size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool)
18971 {
18972  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18973  "Can't ref a pool when ctx not in init stage.");
18974  cctx->pool = pool;
18975  return 0;
18976 }
18978 size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
18979 {
18980  return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent);
18981 }
18982 
18984  ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
18985 {
18986  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
18987  "Can't ref a prefix when ctx not in init stage.");
18988  ZSTD_clearAllDicts(cctx);
18989  if (prefix != NULL && prefixSize > 0) {
18990  cctx->prefixDict.dict = prefix;
18991  cctx->prefixDict.dictSize = prefixSize;
18992  cctx->prefixDict.dictContentType = dictContentType;
18993  }
18994  return 0;
18995 }
18996 
19000 {
19001  if ( (reset == ZSTD_reset_session_only)
19003  cctx->streamStage = zcss_init;
19004  cctx->pledgedSrcSizePlusOne = 0;
19005  }
19006  if ( (reset == ZSTD_reset_parameters)
19008  RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong,
19009  "Reset parameters is only possible during init stage.");
19010  ZSTD_clearAllDicts(cctx);
19011  ZSTD_memset(&cctx->externalMatchCtx, 0, sizeof(cctx->externalMatchCtx));
19012  return ZSTD_CCtxParams_reset(&cctx->requestedParams);
19013  }
19014  return 0;
19016 
19017 
19021 size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
19022 {
19023  BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog);
19024  BOUNDCHECK(ZSTD_c_chainLog, (int)cParams.chainLog);
19025  BOUNDCHECK(ZSTD_c_hashLog, (int)cParams.hashLog);
19026  BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
19027  BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch);
19028  BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
19029  BOUNDCHECK(ZSTD_c_strategy, cParams.strategy);
19030  return 0;
19032 
19036 static ZSTD_compressionParameters
19037 ZSTD_clampCParams(ZSTD_compressionParameters cParams)
19038 {
19039 # define CLAMP_TYPE(cParam, val, type) { \
19040  ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \
19041  if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound; \
19042  else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \
19043  }
19044 # define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned)
19045  CLAMP(ZSTD_c_windowLog, cParams.windowLog);
19046  CLAMP(ZSTD_c_chainLog, cParams.chainLog);
19047  CLAMP(ZSTD_c_hashLog, cParams.hashLog);
19048  CLAMP(ZSTD_c_searchLog, cParams.searchLog);
19049  CLAMP(ZSTD_c_minMatch, cParams.minMatch);
19050  CLAMP(ZSTD_c_targetLength,cParams.targetLength);
19052  return cParams;
19053 }
19054 
19057 U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
19058 {
19059  U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
19060  return hashLog - btScale;
19061 }
19062 
19071 static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
19072 {
19073  const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX;
19074  /* No dictionary ==> No change */
19075  if (dictSize == 0) {
19076  return windowLog;
19077  }
19078  assert(windowLog <= ZSTD_WINDOWLOG_MAX);
19079  assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */
19080  {
19081  U64 const windowSize = 1ULL << windowLog;
19082  U64 const dictAndWindowSize = dictSize + windowSize;
19083  /* If the window size is already large enough to fit both the source and the dictionary
19084  * then just use the window size. Otherwise adjust so that it fits the dictionary and
19085  * the window.
19086  */
19087  if (windowSize >= dictSize + srcSize) {
19088  return windowLog; /* Window size large enough already */
19089  } else if (dictAndWindowSize >= maxWindowSize) {
19090  return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */
19091  } else {
19092  return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1;
19093  }
19094  }
19095 }
19096 
19104 static ZSTD_compressionParameters
19105 ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
19106  unsigned long long srcSize,
19107  size_t dictSize,
19108  ZSTD_cParamMode_e mode,
19109  ZSTD_paramSwitch_e useRowMatchFinder)
19110 {
19111  const U64 minSrcSize = 513; /* (1<<9) + 1 */
19112  const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
19113  assert(ZSTD_checkCParams(cPar)==0);
19114 
19115  switch (mode) {
19116  case ZSTD_cpm_unknown:
19117  case ZSTD_cpm_noAttachDict:
19118  /* If we don't know the source size, don't make any
19119  * assumptions about it. We will already have selected
19120  * smaller parameters if a dictionary is in use.
19121  */
19122  break;
19123  case ZSTD_cpm_createCDict:
19124  /* Assume a small source size when creating a dictionary
19125  * with an unknown source size.
19126  */
19127  if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN)
19128  srcSize = minSrcSize;
19129  break;
19130  case ZSTD_cpm_attachDict:
19131  /* Dictionary has its own dedicated parameters which have
19132  * already been selected. We are selecting parameters
19133  * for only the source.
19134  */
19135  dictSize = 0;
19136  break;
19137  default:
19138  assert(0);
19139  break;
19140  }
19141 
19142  /* resize windowLog if input is small enough, to use less memory */
19143  if ( (srcSize <= maxWindowResize)
19144  && (dictSize <= maxWindowResize) ) {
19145  U32 const tSize = (U32)(srcSize + dictSize);
19146  static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN;
19147  U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN :
19148  ZSTD_highbit32(tSize-1) + 1;
19149  if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
19150  }
19152  U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize);
19153  U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
19154  if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1;
19155  if (cycleLog > dictAndWindowLog)
19156  cPar.chainLog -= (cycleLog - dictAndWindowLog);
19157  }
19158 
19159  if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
19160  cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* minimum wlog required for valid frame header */
19161 
19162  /* We can't use more than 32 bits of hash in total, so that means that we require:
19163  * (hashLog + 8) <= 32 && (chainLog + 8) <= 32
19164  */
19165  if (mode == ZSTD_cpm_createCDict && ZSTD_CDictIndicesAreTagged(&cPar)) {
19166  U32 const maxShortCacheHashLog = 32 - ZSTD_SHORT_CACHE_TAG_BITS;
19167  if (cPar.hashLog > maxShortCacheHashLog) {
19168  cPar.hashLog = maxShortCacheHashLog;
19169  }
19170  if (cPar.chainLog > maxShortCacheHashLog) {
19171  cPar.chainLog = maxShortCacheHashLog;
19172  }
19173  }
19174 
19175 
19176  /* At this point, we aren't 100% sure if we are using the row match finder.
19177  * Unless it is explicitly disabled, conservatively assume that it is enabled.
19178  * In this case it will only be disabled for small sources, so shrinking the
19179  * hash log a little bit shouldn't result in any ratio loss.
19180  */
19181  if (useRowMatchFinder == ZSTD_ps_auto)
19182  useRowMatchFinder = ZSTD_ps_enable;
19183 
19184  /* We can't hash more than 32-bits in total. So that means that we require:
19185  * (hashLog - rowLog + 8) <= 32
19186  */
19187  if (ZSTD_rowMatchFinderUsed(cPar.strategy, useRowMatchFinder)) {
19188  /* Switch to 32-entry rows if searchLog is 5 (or more) */
19189  U32 const rowLog = BOUNDED(4, cPar.searchLog, 6);
19190  U32 const maxRowHashLog = 32 - ZSTD_ROW_HASH_TAG_BITS;
19191  U32 const maxHashLog = maxRowHashLog + rowLog;
19192  assert(cPar.hashLog >= rowLog);
19193  if (cPar.hashLog > maxHashLog) {
19194  cPar.hashLog = maxHashLog;
19195  }
19196  }
19197 
19198  return cPar;
19199 }
19200 
19201 ZSTD_compressionParameters
19202 ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
19203  unsigned long long srcSize,
19204  size_t dictSize)
19205 {
19206  cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */
19208  return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto);
19209 }
19210 
19211 static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
19212 static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
19213 
19214 static void ZSTD_overrideCParams(
19215  ZSTD_compressionParameters* cParams,
19216  const ZSTD_compressionParameters* overrides)
19217 {
19218  if (overrides->windowLog) cParams->windowLog = overrides->windowLog;
19219  if (overrides->hashLog) cParams->hashLog = overrides->hashLog;
19220  if (overrides->chainLog) cParams->chainLog = overrides->chainLog;
19221  if (overrides->searchLog) cParams->searchLog = overrides->searchLog;
19222  if (overrides->minMatch) cParams->minMatch = overrides->minMatch;
19223  if (overrides->targetLength) cParams->targetLength = overrides->targetLength;
19224  if (overrides->strategy) cParams->strategy = overrides->strategy;
19225 }
19226 
19227 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
19228  const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
19229 {
19230  ZSTD_compressionParameters cParams;
19231  if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
19232  srcSizeHint = CCtxParams->srcSizeHint;
19233  }
19234  cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
19235  if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
19236  ZSTD_overrideCParams(&cParams, &CCtxParams->cParams);
19238  /* srcSizeHint == 0 means 0 */
19239  return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode, CCtxParams->useRowMatchFinder);
19240 }
19241 
19242 static size_t
19243 ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
19244  const ZSTD_paramSwitch_e useRowMatchFinder,
19245  const U32 enableDedicatedDictSearch,
19246  const U32 forCCtx)
19247 {
19248  /* chain table size should be 0 for fast or row-hash strategies */
19249  size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, enableDedicatedDictSearch && !forCCtx)
19250  ? ((size_t)1 << cParams->chainLog)
19251  : 0;
19252  size_t const hSize = ((size_t)1) << cParams->hashLog;
19253  U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
19254  size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
19255  /* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't
19256  * surrounded by redzones in ASAN. */
19257  size_t const tableSpace = chainSize * sizeof(U32)
19258  + hSize * sizeof(U32)
19259  + h3Size * sizeof(U32);
19260  size_t const optPotentialSpace =
19261  ZSTD_cwksp_aligned_alloc_size((MaxML+1) * sizeof(U32))
19262  + ZSTD_cwksp_aligned_alloc_size((MaxLL+1) * sizeof(U32))
19263  + ZSTD_cwksp_aligned_alloc_size((MaxOff+1) * sizeof(U32))
19264  + ZSTD_cwksp_aligned_alloc_size((1<<Litbits) * sizeof(U32))
19267  size_t const lazyAdditionalSpace = ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)
19269  : 0;
19270  size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
19271  ? optPotentialSpace
19272  : 0;
19273  size_t const slackSpace = ZSTD_cwksp_slack_space_required();
19274 
19275  /* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */
19276  ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4);
19277  assert(useRowMatchFinder != ZSTD_ps_auto);
19278 
19279  DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
19280  (U32)chainSize, (U32)hSize, (U32)h3Size);
19281  return tableSpace + optSpace + slackSpace + lazyAdditionalSpace;
19282 }
19283 
19284 /* Helper function for calculating memory requirements.
19285  * Gives a tighter bound than ZSTD_sequenceBound() by taking minMatch into account. */
19286 static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useSequenceProducer) {
19287  U32 const divider = (minMatch==3 || useSequenceProducer) ? 3 : 4;
19288  return blockSize / divider;
19289 }
19290 
19292  const ZSTD_compressionParameters* cParams,
19293  const ldmParams_t* ldmParams,
19294  const int isStatic,
19295  const ZSTD_paramSwitch_e useRowMatchFinder,
19296  const size_t buffInSize,
19297  const size_t buffOutSize,
19298  const U64 pledgedSrcSize,
19299  int useSequenceProducer,
19300  size_t maxBlockSize)
19301 {
19302  size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize);
19303  size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize);
19304  size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer);
19305  size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
19306  + ZSTD_cwksp_aligned_alloc_size(maxNbSeq * sizeof(seqDef))
19307  + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
19308  size_t const entropySpace = ZSTD_cwksp_alloc_size(ENTROPY_WORKSPACE_SIZE);
19309  size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
19310  size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1);
19311 
19312  size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
19313  size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
19314  size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ?
19315  ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
19316 
19317 
19318  size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
19319  + ZSTD_cwksp_alloc_size(buffOutSize);
19320 
19321  size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
19322 
19323  size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
19324  size_t const externalSeqSpace = useSequenceProducer
19325  ? ZSTD_cwksp_aligned_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
19326  : 0;
19327 
19328  size_t const neededSpace =
19329  cctxSpace +
19330  entropySpace +
19331  blockStateSpace +
19332  ldmSpace +
19333  ldmSeqSpace +
19334  matchStateSize +
19335  tokenSpace +
19336  bufferSpace +
19337  externalSeqSpace;
19338 
19339  DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
19340  return neededSpace;
19341 }
19342 
19343 size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
19344 {
19345  ZSTD_compressionParameters const cParams =
19347  ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
19348  &cParams);
19349 
19350  RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
19351  /* estimateCCtxSize is for one-shot compression. So no buffers should
19352  * be needed. However, we still allocate two 0-sized buffers, which can
19353  * take space under ASAN. */
19355  &cParams, &params->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, params->useSequenceProducer, params->maxBlockSize);
19356 }
19357 
19358 size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
19359 {
19360  ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams);
19361  if (ZSTD_rowMatchFinderSupported(cParams.strategy)) {
19362  /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
19363  size_t noRowCCtxSize;
19364  size_t rowCCtxSize;
19365  initialParams.useRowMatchFinder = ZSTD_ps_disable;
19366  noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
19367  initialParams.useRowMatchFinder = ZSTD_ps_enable;
19368  rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
19369  return MAX(noRowCCtxSize, rowCCtxSize);
19370  } else {
19371  return ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams);
19372  }
19373 }
19374 
19376 {
19377  int tier = 0;
19378  size_t largestSize = 0;
19379  static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN};
19380  for (; tier < 4; ++tier) {
19381  /* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */
19382  ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict);
19383  largestSize = MAX(ZSTD_estimateCCtxSize_usingCParams(cParams), largestSize);
19384  }
19385  return largestSize;
19386 }
19387 
19389 {
19390  int level;
19391  size_t memBudget = 0;
19392  for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {
19393  /* Ensure monotonically increasing memory usage as compression level increases */
19394  size_t const newMB = ZSTD_estimateCCtxSize_internal(level);
19395  if (newMB > memBudget) memBudget = newMB;
19396  }
19397  return memBudget;
19398 }
19399 
19400 size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
19401 {
19402  RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
19403  { ZSTD_compressionParameters const cParams =
19405  size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(params->maxBlockSize), (size_t)1 << cParams.windowLog);
19406  size_t const inBuffSize = (params->inBufferMode == ZSTD_bm_buffered)
19407  ? ((size_t)1 << cParams.windowLog) + blockSize
19408  : 0;
19409  size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
19410  ? ZSTD_compressBound(blockSize) + 1
19411  : 0;
19412  ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &params->cParams);
19413 
19415  &cParams, &params->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
19416  ZSTD_CONTENTSIZE_UNKNOWN, params->useSequenceProducer, params->maxBlockSize);
19417  }
19418 }
19419 
19420 size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
19421 {
19422  ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams);
19423  if (ZSTD_rowMatchFinderSupported(cParams.strategy)) {
19424  /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */
19425  size_t noRowCCtxSize;
19426  size_t rowCCtxSize;
19427  initialParams.useRowMatchFinder = ZSTD_ps_disable;
19428  noRowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
19429  initialParams.useRowMatchFinder = ZSTD_ps_enable;
19430  rowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
19431  return MAX(noRowCCtxSize, rowCCtxSize);
19432  } else {
19433  return ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams);
19434  }
19435 }
19436 
19438 {
19439  ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
19440  return ZSTD_estimateCStreamSize_usingCParams(cParams);
19441 }
19442 
19444 {
19445  int level;
19446  size_t memBudget = 0;
19447  for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {
19448  size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
19449  if (newMB > memBudget) memBudget = newMB;
19450  }
19451  return memBudget;
19453 
19454 /* ZSTD_getFrameProgression():
19455  * tells how much data has been consumed (input) and produced (output) for current frame.
19456  * able to count progression inside worker threads (non-blocking mode).
19457  */
19458 ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx)
19459 {
19460 #ifdef ZSTD_MULTITHREAD
19461  if (cctx->appliedParams.nbWorkers > 0) {
19462  return ZSTDMT_getFrameProgression(cctx->mtctx);
19463  }
19464 #endif
19465  { ZSTD_frameProgression fp;
19466  size_t const buffered = (cctx->inBuff == NULL) ? 0 :
19467  cctx->inBuffPos - cctx->inToCompress;
19468  if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);
19469  assert(buffered <= ZSTD_BLOCKSIZE_MAX);
19470  fp.ingested = cctx->consumedSrcSize + buffered;
19471  fp.consumed = cctx->consumedSrcSize;
19472  fp.produced = cctx->producedCSize;
19473  fp.flushed = cctx->producedCSize; /* simplified; some data might still be left within streaming output buffer */
19474  fp.currentJobID = 0;
19475  fp.nbActiveWorkers = 0;
19476  return fp;
19477 } }
19478 
19482 size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)
19483 {
19484 #ifdef ZSTD_MULTITHREAD
19485  if (cctx->appliedParams.nbWorkers > 0) {
19486  return ZSTDMT_toFlushNow(cctx->mtctx);
19487  }
19488 #endif
19489  (void)cctx;
19490  return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */
19491 }
19492 
19493 static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
19494  ZSTD_compressionParameters cParams2)
19495 {
19496  (void)cParams1;
19497  (void)cParams2;
19498  assert(cParams1.windowLog == cParams2.windowLog);
19499  assert(cParams1.chainLog == cParams2.chainLog);
19500  assert(cParams1.hashLog == cParams2.hashLog);
19501  assert(cParams1.searchLog == cParams2.searchLog);
19502  assert(cParams1.minMatch == cParams2.minMatch);
19503  assert(cParams1.targetLength == cParams2.targetLength);
19504  assert(cParams1.strategy == cParams2.strategy);
19505 }
19506 
19508 {
19509  int i;
19510  for (i = 0; i < ZSTD_REP_NUM; ++i)
19511  bs->rep[i] = repStartValue[i];
19517 
19523 {
19524  ZSTD_window_clear(&ms->window);
19525 
19526  ms->nextToUpdate = ms->window.dictLimit;
19527  ms->loadedDictEnd = 0;
19528  ms->opt.litLengthSum = 0; /* force reset of btopt stats */
19529  ms->dictMatchState = NULL;
19530 }
19531 
19539 typedef enum {
19549 typedef enum {
19553 
19554 typedef enum {
19558 
19559 /* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */
19560 static U64 ZSTD_bitmix(U64 val, U64 len) {
19561  val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24);
19562  val *= 0x9FB21C651E98DF25ULL;
19563  val ^= (val >> 35) + len ;
19564  val *= 0x9FB21C651E98DF25ULL;
19565  return val ^ (val >> 28);
19566 }
19567 
19568 /* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */
19569 static void ZSTD_advanceHashSalt(ZSTD_matchState_t* ms) {
19570  ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4);
19571 }
19572 
19573 static size_t
19575  ZSTD_cwksp* ws,
19576  const ZSTD_compressionParameters* cParams,
19577  const ZSTD_paramSwitch_e useRowMatchFinder,
19578  const ZSTD_compResetPolicy_e crp,
19579  const ZSTD_indexResetPolicy_e forceResetIndex,
19580  const ZSTD_resetTarget_e forWho)
19581 {
19582  /* disable chain table allocation for fast or row-based strategies */
19583  size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder,
19584  ms->dedicatedDictSearch && (forWho == ZSTD_resetTarget_CDict))
19585  ? ((size_t)1 << cParams->chainLog)
19586  : 0;
19587  size_t const hSize = ((size_t)1) << cParams->hashLog;
19588  U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
19589  size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
19590 
19591  DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
19592  assert(useRowMatchFinder != ZSTD_ps_auto);
19593  if (forceResetIndex == ZSTDirp_reset) {
19594  ZSTD_window_init(&ms->window);
19596  }
19597 
19598  ms->hashLog3 = hashLog3;
19599  ms->lazySkipping = 0;
19600 
19602 
19603  assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */
19604 
19606 
19607  DEBUGLOG(5, "reserving table space");
19608  /* table Space */
19609  ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32));
19610  ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32));
19611  ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32));
19612  RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
19613  "failed a workspace allocation in ZSTD_reset_matchState");
19614 
19615  DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty);
19616  if (crp!=ZSTDcrp_leaveDirty) {
19617  /* reset tables only */
19619  }
19620 
19621  if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) {
19622  /* Row match finder needs an additional table of hashes ("tags") */
19623  size_t const tagTableSize = hSize;
19624  /* We want to generate a new salt in case we reset a Cctx, but we always want to use
19625  * 0 when we reset a Cdict */
19626  if(forWho == ZSTD_resetTarget_CCtx) {
19627  ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize);
19629  } else {
19630  /* When we are not salting we want to always memset the memory */
19631  ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned(ws, tagTableSize);
19632  ZSTD_memset(ms->tagTable, 0, tagTableSize);
19633  ms->hashSalt = 0;
19634  }
19635  { /* Switch to 32-entry rows if searchLog is 5 (or more) */
19636  U32 const rowLog = BOUNDED(4, cParams->searchLog, 6);
19637  assert(cParams->hashLog >= rowLog);
19638  ms->rowHashLog = cParams->hashLog - rowLog;
19639  }
19640  }
19641 
19642  /* opt parser space */
19643  if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
19644  DEBUGLOG(4, "reserving optimal parser space");
19645  ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (1<<Litbits) * sizeof(unsigned));
19646  ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned));
19647  ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned));
19648  ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned));
19651  }
19652 
19653  ms->cParams = *cParams;
19654 
19655  RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
19656  "failed a workspace allocation in ZSTD_reset_matchState");
19657  return 0;
19658 }
19659 
19660 /* ZSTD_indexTooCloseToMax() :
19661  * minor optimization : prefer memset() rather than reduceIndex()
19662  * which is measurably slow in some circumstances (reported for Visual Studio).
19663  * Works when re-using a context for a lot of smallish inputs :
19664  * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN,
19665  * memset() will be triggered before reduceIndex().
19666  */
19667 #define ZSTD_INDEXOVERFLOW_MARGIN (16 MB)
19669 {
19670  return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
19671 }
19678 static int ZSTD_dictTooBig(size_t const loadedDictSize)
19679 {
19680  return loadedDictSize > ZSTD_CHUNKSIZE_MAX;
19681 }
19682 
19689 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
19690  ZSTD_CCtx_params const* params,
19691  U64 const pledgedSrcSize,
19692  size_t const loadedDictSize,
19693  ZSTD_compResetPolicy_e const crp,
19694  ZSTD_buffered_policy_e const zbuff)
19695 {
19696  ZSTD_cwksp* const ws = &zc->workspace;
19697  DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d",
19698  (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->useBlockSplitter);
19699  assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
19700 
19701  zc->isFirstBlock = 1;
19702 
19703  /* Set applied params early so we can modify them for LDM,
19704  * and point params at the applied params.
19705  */
19706  zc->appliedParams = *params;
19707  params = &zc->appliedParams;
19708 
19709  assert(params->useRowMatchFinder != ZSTD_ps_auto);
19710  assert(params->useBlockSplitter != ZSTD_ps_auto);
19711  assert(params->ldmParams.enableLdm != ZSTD_ps_auto);
19712  assert(params->maxBlockSize != 0);
19713  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
19714  /* Adjust long distance matching parameters */
19715  ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, &params->cParams);
19716  assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog);
19717  assert(params->ldmParams.hashRateLog < 32);
19718  }
19719 
19720  { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize));
19721  size_t const blockSize = MIN(params->maxBlockSize, windowSize);
19722  size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, params->useSequenceProducer);
19723  size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered)
19724  ? ZSTD_compressBound(blockSize) + 1
19725  : 0;
19726  size_t const buffInSize = (zbuff == ZSTDb_buffered && params->inBufferMode == ZSTD_bm_buffered)
19727  ? windowSize + blockSize
19728  : 0;
19729  size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize);
19730 
19731  int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window);
19732  int const dictTooBig = ZSTD_dictTooBig(loadedDictSize);
19733  ZSTD_indexResetPolicy_e needsIndexReset =
19734  (indexTooClose || dictTooBig || !zc->initialized) ? ZSTDirp_reset : ZSTDirp_continue;
19735 
19736  size_t const neededSpace =
19738  &params->cParams, &params->ldmParams, zc->staticSize != 0, params->useRowMatchFinder,
19739  buffInSize, buffOutSize, pledgedSrcSize, params->useSequenceProducer, params->maxBlockSize);
19740  int resizeWorkspace;
19741 
19742  FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!");
19743 
19745 
19746  { /* Check if workspace is large enough, alloc a new one if needed */
19747  int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
19748  int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
19749  resizeWorkspace = workspaceTooSmall || workspaceWasteful;
19750  DEBUGLOG(4, "Need %zu B workspace", neededSpace);
19751  DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
19752 
19753  if (resizeWorkspace) {
19754  DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB",
19755  ZSTD_cwksp_sizeof(ws) >> 10,
19756  neededSpace >> 10);
19757 
19758  RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize");
19759 
19760  needsIndexReset = ZSTDirp_reset;
19761 
19763  FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), "");
19764 
19765  DEBUGLOG(5, "reserving object space");
19766  /* Statically sized space.
19767  * entropyWorkspace never moves,
19768  * though prev/next block swap places */
19771  RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
19773  RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
19775  RETURN_ERROR_IF(zc->entropyWorkspace == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
19776  } }
19777 
19779 
19780  /* init params */
19781  zc->blockState.matchState.cParams = params->cParams;
19782  zc->blockState.matchState.prefetchCDictTables = params->prefetchCDictTables == ZSTD_ps_enable;
19783  zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
19784  zc->consumedSrcSize = 0;
19785  zc->producedCSize = 0;
19786  if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
19787  zc->appliedParams.fParams.contentSizeFlag = 0;
19788  DEBUGLOG(4, "pledged content size : %u ; flag : %u",
19789  (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
19790  zc->blockSize = blockSize;
19791 
19792  XXH64_reset(&zc->xxhState, 0);
19793  zc->stage = ZSTDcs_init;
19794  zc->dictID = 0;
19795  zc->dictContentSize = 0;
19796 
19798 
19800  &zc->blockState.matchState,
19801  ws,
19802  &params->cParams,
19803  params->useRowMatchFinder,
19804  crp,
19805  needsIndexReset,
19806  ZSTD_resetTarget_CCtx), "");
19807 
19808  zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));
19809 
19810  /* ldm hash table */
19811  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
19812  /* TODO: avoid memset? */
19813  size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
19815  ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
19816  zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
19817  zc->maxNbLdmSequences = maxNbLdmSeq;
19818 
19820  zc->ldmState.loadedDictEnd = 0;
19821  }
19822 
19823  /* reserve space for block-level external sequences */
19824  if (params->useSequenceProducer) {
19825  size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
19826  zc->externalMatchCtx.seqBufferCapacity = maxNbExternalSeq;
19828  (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
19829  }
19830 
19831  /* buffers */
19832 
19833  /* ZSTD_wildcopy() is used to copy into the literals buffer,
19834  * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
19835  */
19837  zc->seqStore.maxNbLit = blockSize;
19838 
19839  zc->bufferedPolicy = zbuff;
19840  zc->inBuffSize = buffInSize;
19841  zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
19842  zc->outBuffSize = buffOutSize;
19843  zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
19844 
19845  /* ldm bucketOffsets table */
19846  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
19847  /* TODO: avoid memset? */
19848  size_t const numBuckets =
19849  ((size_t)1) << (params->ldmParams.hashLog -
19850  params->ldmParams.bucketSizeLog);
19852  ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets);
19853  }
19854 
19855  /* sequences storage */
19856  ZSTD_referenceExternalSequences(zc, NULL, 0);
19857  zc->seqStore.maxNbSeq = maxNbSeq;
19858  zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
19859  zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
19860  zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
19861 
19862  DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
19864 
19865  zc->initialized = 1;
19866 
19867  return 0;
19868  }
19870 
19871 /* ZSTD_invalidateRepCodes() :
19872  * ensures next compression will not use repcodes from previous block.
19873  * Note : only works with regular variant;
19874  * do not use with extDict variant ! */
19875 void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
19876  int i;
19877  for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0;
19880 
19881 /* These are the approximate sizes for each strategy past which copying the
19882  * dictionary tables into the working context is faster than using them
19883  * in-place.
19884  */
19885 static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = {
19886  8 KB, /* unused */
19887  8 KB, /* ZSTD_fast */
19888  16 KB, /* ZSTD_dfast */
19889  32 KB, /* ZSTD_greedy */
19890  32 KB, /* ZSTD_lazy */
19891  32 KB, /* ZSTD_lazy2 */
19892  32 KB, /* ZSTD_btlazy2 */
19893  32 KB, /* ZSTD_btopt */
19894  8 KB, /* ZSTD_btultra */
19895  8 KB /* ZSTD_btultra2 */
19896 };
19897 
19898 static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
19899  const ZSTD_CCtx_params* params,
19900  U64 pledgedSrcSize)
19901 {
19902  size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
19903  int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch;
19904  return dedicatedDictSearch
19905  || ( ( pledgedSrcSize <= cutoff
19906  || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
19907  || params->attachDictPref == ZSTD_dictForceAttach )
19908  && params->attachDictPref != ZSTD_dictForceCopy
19909  && !params->forceWindow ); /* dictMatchState isn't correctly
19910  * handled in _enforceMaxDist */
19911 }
19912 
19913 static size_t
19915  const ZSTD_CDict* cdict,
19916  ZSTD_CCtx_params params,
19917  U64 pledgedSrcSize,
19918  ZSTD_buffered_policy_e zbuff)
19919 {
19920  DEBUGLOG(4, "ZSTD_resetCCtx_byAttachingCDict() pledgedSrcSize=%llu",
19921  (unsigned long long)pledgedSrcSize);
19922  {
19923  ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams;
19924  unsigned const windowLog = params.cParams.windowLog;
19925  assert(windowLog != 0);
19926  /* Resize working context table params for input only, since the dict
19927  * has its own tables. */
19928  /* pledgedSrcSize == 0 means 0! */
19929 
19930  if (cdict->matchState.dedicatedDictSearch) {
19931  ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams);
19932  }
19933 
19934  params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize,
19936  params.useRowMatchFinder);
19937  params.cParams.windowLog = windowLog;
19938  params.useRowMatchFinder = cdict->useRowMatchFinder; /* cdict overrides */
19939  FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, &params, pledgedSrcSize,
19940  /* loadedDictSize */ 0,
19941  ZSTDcrp_makeClean, zbuff), "");
19942  assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy);
19943  }
19944 
19945  { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc
19946  - cdict->matchState.window.base);
19947  const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;
19948  if (cdictLen == 0) {
19949  /* don't even attach dictionaries with no contents */
19950  DEBUGLOG(4, "skipping attaching empty dictionary");
19951  } else {
19952  DEBUGLOG(4, "attaching dictionary into context");
19954 
19955  /* prep working match state so dict matches never have negative indices
19956  * when they are translated to the working context's index space. */
19957  if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
19959  cctx->blockState.matchState.window.base + cdictEnd;
19961  }
19962  /* loadedDictEnd is expressed within the referential of the active context */
19964  } }
19965 
19966  cctx->dictID = cdict->dictID;
19967  cctx->dictContentSize = cdict->dictContentSize;
19968 
19969  /* copy block state */
19970  ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
19971 
19972  return 0;
19973 }
19974 
19975 static void ZSTD_copyCDictTableIntoCCtx(U32* dst, U32 const* src, size_t tableSize,
19976  ZSTD_compressionParameters const* cParams) {
19977  if (ZSTD_CDictIndicesAreTagged(cParams)){
19978  /* Remove tags from the CDict table if they are present.
19979  * See docs on "short cache" in zstd_compress_internal.h for context. */
19980  size_t i;
19981  for (i = 0; i < tableSize; i++) {
19982  U32 const taggedIndex = src[i];
19983  U32 const index = taggedIndex >> ZSTD_SHORT_CACHE_TAG_BITS;
19984  dst[i] = index;
19985  }
19986  } else {
19987  ZSTD_memcpy(dst, src, tableSize * sizeof(U32));
19988  }
19989 }
19990 
19991 static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
19992  const ZSTD_CDict* cdict,
19993  ZSTD_CCtx_params params,
19994  U64 pledgedSrcSize,
19995  ZSTD_buffered_policy_e zbuff)
19996 {
19997  const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;
19998 
20000  DEBUGLOG(4, "ZSTD_resetCCtx_byCopyingCDict() pledgedSrcSize=%llu",
20001  (unsigned long long)pledgedSrcSize);
20002 
20003  { unsigned const windowLog = params.cParams.windowLog;
20004  assert(windowLog != 0);
20005  /* Copy only compression parameters related to tables. */
20006  params.cParams = *cdict_cParams;
20007  params.cParams.windowLog = windowLog;
20008  params.useRowMatchFinder = cdict->useRowMatchFinder;
20009  FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, &params, pledgedSrcSize,
20010  /* loadedDictSize */ 0,
20011  ZSTDcrp_leaveDirty, zbuff), "");
20012  assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
20013  assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
20014  assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
20015  }
20016 
20018  assert(params.useRowMatchFinder != ZSTD_ps_auto);
20019 
20020  /* copy tables */
20021  { size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */)
20022  ? ((size_t)1 << cdict_cParams->chainLog)
20023  : 0;
20024  size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
20025 
20027  cdict->matchState.hashTable,
20028  hSize, cdict_cParams);
20029 
20030  /* Do not copy cdict's chainTable if cctx has parameters such that it would not use chainTable */
20031  if (ZSTD_allocateChainTable(cctx->appliedParams.cParams.strategy, cctx->appliedParams.useRowMatchFinder, 0 /* forDDSDict */)) {
20033  cdict->matchState.chainTable,
20034  chainSize, cdict_cParams);
20035  }
20036  /* copy tag table */
20037  if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) {
20038  size_t const tagTableSize = hSize;
20040  cdict->matchState.tagTable,
20041  tagTableSize);
20043  }
20044  }
20045 
20046  /* Zero the hashTable3, since the cdict never fills it */
20047  { int const h3log = cctx->blockState.matchState.hashLog3;
20048  size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
20049  assert(cdict->matchState.hashLog3 == 0);
20050  ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
20051  }
20052 
20054 
20055  /* copy dictionary offsets */
20056  { ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
20057  ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
20058  dstMatchState->window = srcMatchState->window;
20059  dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
20060  dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
20061  }
20062 
20063  cctx->dictID = cdict->dictID;
20064  cctx->dictContentSize = cdict->dictContentSize;
20065 
20066  /* copy block state */
20067  ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
20068 
20069  return 0;
20070 }
20071 
20072 /* We have a choice between copying the dictionary context into the working
20073  * context, or referencing the dictionary context from the working context
20074  * in-place. We decide here which strategy to use. */
20075 static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
20076  const ZSTD_CDict* cdict,
20077  const ZSTD_CCtx_params* params,
20078  U64 pledgedSrcSize,
20079  ZSTD_buffered_policy_e zbuff)
20080 {
20081 
20082  DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)",
20083  (unsigned)pledgedSrcSize);
20084 
20085  if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
20087  cctx, cdict, *params, pledgedSrcSize, zbuff);
20088  } else {
20090  cctx, cdict, *params, pledgedSrcSize, zbuff);
20091  }
20092 }
20093 
20101 static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
20102  const ZSTD_CCtx* srcCCtx,
20103  ZSTD_frameParameters fParams,
20104  U64 pledgedSrcSize,
20105  ZSTD_buffered_policy_e zbuff)
20106 {
20107  RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong,
20108  "Can't copy a ctx that's not in init stage.");
20109  DEBUGLOG(5, "ZSTD_copyCCtx_internal");
20110  ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
20111  { ZSTD_CCtx_params params = dstCCtx->requestedParams;
20112  /* Copy only compression parameters related to tables. */
20113  params.cParams = srcCCtx->appliedParams.cParams;
20114  assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto);
20115  assert(srcCCtx->appliedParams.useBlockSplitter != ZSTD_ps_auto);
20116  assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto);
20117  params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
20118  params.useBlockSplitter = srcCCtx->appliedParams.useBlockSplitter;
20119  params.ldmParams = srcCCtx->appliedParams.ldmParams;
20120  params.fParams = fParams;
20121  params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize;
20122  ZSTD_resetCCtx_internal(dstCCtx, &params, pledgedSrcSize,
20123  /* loadedDictSize */ 0,
20124  ZSTDcrp_leaveDirty, zbuff);
20125  assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);
20126  assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);
20127  assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog);
20128  assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog);
20130  }
20131 
20133 
20134  /* copy tables */
20135  { size_t const chainSize = ZSTD_allocateChainTable(srcCCtx->appliedParams.cParams.strategy,
20136  srcCCtx->appliedParams.useRowMatchFinder,
20137  0 /* forDDSDict */)
20138  ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog)
20139  : 0;
20140  size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
20141  int const h3log = srcCCtx->blockState.matchState.hashLog3;
20142  size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
20143 
20145  srcCCtx->blockState.matchState.hashTable,
20146  hSize * sizeof(U32));
20148  srcCCtx->blockState.matchState.chainTable,
20149  chainSize * sizeof(U32));
20151  srcCCtx->blockState.matchState.hashTable3,
20152  h3Size * sizeof(U32));
20153  }
20154 
20156 
20157  /* copy dictionary offsets */
20158  {
20159  const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
20160  ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
20161  dstMatchState->window = srcMatchState->window;
20162  dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
20163  dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
20164  }
20165  dstCCtx->dictID = srcCCtx->dictID;
20166  dstCCtx->dictContentSize = srcCCtx->dictContentSize;
20167 
20168  /* copy block state */
20169  ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
20170 
20171  return 0;
20172 }
20179 size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
20180 {
20181  ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
20182  ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy;
20184  if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
20185  fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);
20186 
20187  return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx,
20188  fParams, pledgedSrcSize,
20189  zbuff);
20190 }
20191 
20192 
20193 #define ZSTD_ROWSIZE 16
20194 
20201 ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark)
20202 {
20203  int const nbRows = (int)size / ZSTD_ROWSIZE;
20204  int cellNb = 0;
20205  int rowNb;
20206  /* Protect special index values < ZSTD_WINDOW_START_INDEX. */
20207  U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
20208  assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
20209  assert(size < (1U<<31)); /* can be casted to int */
20210 
20211 #if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
20212  /* To validate that the table re-use logic is sound, and that we don't
20213  * access table space that we haven't cleaned, we re-"poison" the table
20214  * space every time we mark it dirty.
20215  *
20216  * This function however is intended to operate on those dirty tables and
20217  * re-clean them. So when this function is used correctly, we can unpoison
20218  * the memory it operated on. This introduces a blind spot though, since
20219  * if we now try to operate on __actually__ poisoned memory, we will not
20220  * detect that. */
20221  __msan_unpoison(table, size * sizeof(U32));
20222 #endif
20223 
20224  for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
20225  int column;
20226  for (column=0; column<ZSTD_ROWSIZE; column++) {
20227  U32 newVal;
20228  if (preserveMark && table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) {
20229  /* This write is pointless, but is required(?) for the compiler
20230  * to auto-vectorize the loop. */
20231  newVal = ZSTD_DUBT_UNSORTED_MARK;
20232  } else if (table[cellNb] < reducerThreshold) {
20233  newVal = 0;
20234  } else {
20235  newVal = table[cellNb] - reducerValue;
20236  }
20237  table[cellNb] = newVal;
20238  cellNb++;
20239  } }
20240 }
20242 static void ZSTD_reduceTable(U32* const table, U32 const size, U32 const reducerValue)
20243 {
20244  ZSTD_reduceTable_internal(table, size, reducerValue, 0);
20245 }
20246 
20247 static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const reducerValue)
20249  ZSTD_reduceTable_internal(table, size, reducerValue, 1);
20250 }
20251 
20254 static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
20255 {
20256  { U32 const hSize = (U32)1 << params->cParams.hashLog;
20257  ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
20258  }
20259 
20260  if (ZSTD_allocateChainTable(params->cParams.strategy, params->useRowMatchFinder, (U32)ms->dedicatedDictSearch)) {
20261  U32 const chainSize = (U32)1 << params->cParams.chainLog;
20262  if (params->cParams.strategy == ZSTD_btlazy2)
20263  ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
20264  else
20265  ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);
20266  }
20267 
20268  if (ms->hashLog3) {
20269  U32 const h3Size = (U32)1 << ms->hashLog3;
20270  ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue);
20271  }
20272 }
20273 
20274 
20275 /*-*******************************************************
20276 * Block entropic compression
20277 *********************************************************/
20278 
20279 /* See doc/zstd_compression_format.md for detailed format description */
20280 
20281 int ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
20282 {
20283  const seqDef* const sequences = seqStorePtr->sequencesStart;
20284  BYTE* const llCodeTable = seqStorePtr->llCode;
20285  BYTE* const ofCodeTable = seqStorePtr->ofCode;
20286  BYTE* const mlCodeTable = seqStorePtr->mlCode;
20287  U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
20288  U32 u;
20289  int longOffsets = 0;
20290  assert(nbSeq <= seqStorePtr->maxNbSeq);
20291  for (u=0; u<nbSeq; u++) {
20292  U32 const llv = sequences[u].litLength;
20293  U32 const ofCode = ZSTD_highbit32(sequences[u].offBase);
20294  U32 const mlv = sequences[u].mlBase;
20295  llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);
20296  ofCodeTable[u] = (BYTE)ofCode;
20297  mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);
20298  assert(!(MEM_64bits() && ofCode >= STREAM_ACCUMULATOR_MIN));
20299  if (MEM_32bits() && ofCode >= STREAM_ACCUMULATOR_MIN)
20300  longOffsets = 1;
20301  }
20302  if (seqStorePtr->longLengthType==ZSTD_llt_literalLength)
20303  llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
20304  if (seqStorePtr->longLengthType==ZSTD_llt_matchLength)
20305  mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
20306  return longOffsets;
20308 
20309 /* ZSTD_useTargetCBlockSize():
20310  * Returns if target compressed block size param is being used.
20311  * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize.
20312  * Returns 1 if true, 0 otherwise. */
20313 static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
20314 {
20315  DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize);
20316  return (cctxParams->targetCBlockSize != 0);
20317 }
20319 /* ZSTD_blockSplitterEnabled():
20320  * Returns if block splitting param is being used
20321  * If used, compression will do best effort to split a block in order to improve compression ratio.
20322  * At the time this function is called, the parameter must be finalized.
20323  * Returns 1 if true, 0 otherwise. */
20324 static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
20325 {
20326  DEBUGLOG(5, "ZSTD_blockSplitterEnabled (useBlockSplitter=%d)", cctxParams->useBlockSplitter);
20327  assert(cctxParams->useBlockSplitter != ZSTD_ps_auto);
20328  return (cctxParams->useBlockSplitter == ZSTD_ps_enable);
20331 /* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
20332  * and size of the sequences statistics
20333  */
20334 typedef struct {
20335  U32 LLtype;
20336  U32 Offtype;
20337  U32 MLtype;
20338  size_t size;
20339  size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
20340  int longOffsets;
20342 
20343 /* ZSTD_buildSequencesStatistics():
20344  * Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field.
20345  * Modifies `nextEntropy` to have the appropriate values as a side effect.
20346  * nbSeq must be greater than 0.
20347  *
20348  * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32)
20349  */
20352  const seqStore_t* seqStorePtr, size_t nbSeq,
20353  const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
20354  BYTE* dst, const BYTE* const dstEnd,
20355  ZSTD_strategy strategy, unsigned* countWorkspace,
20356  void* entropyWorkspace, size_t entropyWkspSize)
20357 {
20358  BYTE* const ostart = dst;
20359  const BYTE* const oend = dstEnd;
20360  BYTE* op = ostart;
20361  FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
20362  FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
20363  FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
20364  const BYTE* const ofCodeTable = seqStorePtr->ofCode;
20365  const BYTE* const llCodeTable = seqStorePtr->llCode;
20366  const BYTE* const mlCodeTable = seqStorePtr->mlCode;
20368 
20369  stats.lastCountSize = 0;
20370  /* convert length/distances into codes */
20371  stats.longOffsets = ZSTD_seqToCodes(seqStorePtr);
20372  assert(op <= oend);
20373  assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */
20374  /* build CTable for Literal Lengths */
20375  { unsigned max = MaxLL;
20376  size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
20377  DEBUGLOG(5, "Building LL table");
20378  nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
20379  stats.LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
20380  countWorkspace, max, mostFrequent, nbSeq,
20381  LLFSELog, prevEntropy->litlengthCTable,
20383  ZSTD_defaultAllowed, strategy);
20385  assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
20386  { size_t const countSize = ZSTD_buildCTable(
20387  op, (size_t)(oend - op),
20388  CTable_LitLength, LLFSELog, (symbolEncodingType_e)stats.LLtype,
20389  countWorkspace, max, llCodeTable, nbSeq,
20391  prevEntropy->litlengthCTable,
20392  sizeof(prevEntropy->litlengthCTable),
20393  entropyWorkspace, entropyWkspSize);
20394  if (ZSTD_isError(countSize)) {
20395  DEBUGLOG(3, "ZSTD_buildCTable for LitLens failed");
20396  stats.size = countSize;
20397  return stats;
20398  }
20399  if (stats.LLtype == set_compressed)
20400  stats.lastCountSize = countSize;
20401  op += countSize;
20402  assert(op <= oend);
20403  } }
20404  /* build CTable for Offsets */
20405  { unsigned max = MaxOff;
20406  size_t const mostFrequent = HIST_countFast_wksp(
20407  countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
20408  /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
20410  DEBUGLOG(5, "Building OF table");
20411  nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
20412  stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
20413  countWorkspace, max, mostFrequent, nbSeq,
20414  OffFSELog, prevEntropy->offcodeCTable,
20416  defaultPolicy, strategy);
20417  assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
20418  { size_t const countSize = ZSTD_buildCTable(
20419  op, (size_t)(oend - op),
20420  CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)stats.Offtype,
20421  countWorkspace, max, ofCodeTable, nbSeq,
20423  prevEntropy->offcodeCTable,
20424  sizeof(prevEntropy->offcodeCTable),
20425  entropyWorkspace, entropyWkspSize);
20426  if (ZSTD_isError(countSize)) {
20427  DEBUGLOG(3, "ZSTD_buildCTable for Offsets failed");
20428  stats.size = countSize;
20429  return stats;
20430  }
20431  if (stats.Offtype == set_compressed)
20432  stats.lastCountSize = countSize;
20433  op += countSize;
20434  assert(op <= oend);
20435  } }
20436  /* build CTable for MatchLengths */
20437  { unsigned max = MaxML;
20438  size_t const mostFrequent = HIST_countFast_wksp(
20439  countWorkspace, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
20440  DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
20441  nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
20443  countWorkspace, max, mostFrequent, nbSeq,
20444  MLFSELog, prevEntropy->matchlengthCTable,
20446  ZSTD_defaultAllowed, strategy);
20447  assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
20448  { size_t const countSize = ZSTD_buildCTable(
20449  op, (size_t)(oend - op),
20450  CTable_MatchLength, MLFSELog, (symbolEncodingType_e)stats.MLtype,
20451  countWorkspace, max, mlCodeTable, nbSeq,
20453  prevEntropy->matchlengthCTable,
20454  sizeof(prevEntropy->matchlengthCTable),
20455  entropyWorkspace, entropyWkspSize);
20456  if (ZSTD_isError(countSize)) {
20457  DEBUGLOG(3, "ZSTD_buildCTable for MatchLengths failed");
20458  stats.size = countSize;
20459  return stats;
20460  }
20461  if (stats.MLtype == set_compressed)
20462  stats.lastCountSize = countSize;
20463  op += countSize;
20464  assert(op <= oend);
20465  } }
20466  stats.size = (size_t)(op-ostart);
20467  return stats;
20469 
20470 /* ZSTD_entropyCompressSeqStore_internal():
20471  * compresses both literals and sequences
20472  * Returns compressed size of block, or a zstd error.
20473  */
20474 #define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
20475 MEM_STATIC size_t
20477  const seqStore_t* seqStorePtr,
20478  const ZSTD_entropyCTables_t* prevEntropy,
20479  ZSTD_entropyCTables_t* nextEntropy,
20480  const ZSTD_CCtx_params* cctxParams,
20481  void* dst, size_t dstCapacity,
20482  void* entropyWorkspace, size_t entropyWkspSize,
20483  const int bmi2)
20484 {
20485  ZSTD_strategy const strategy = cctxParams->cParams.strategy;
20486  unsigned* count = (unsigned*)entropyWorkspace;
20487  FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
20488  FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
20489  FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
20490  const seqDef* const sequences = seqStorePtr->sequencesStart;
20491  const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
20492  const BYTE* const ofCodeTable = seqStorePtr->ofCode;
20493  const BYTE* const llCodeTable = seqStorePtr->llCode;
20494  const BYTE* const mlCodeTable = seqStorePtr->mlCode;
20495  BYTE* const ostart = (BYTE*)dst;
20496  BYTE* const oend = ostart + dstCapacity;
20497  BYTE* op = ostart;
20498  size_t lastCountSize;
20499  int longOffsets = 0;
20500 
20501  entropyWorkspace = count + (MaxSeq + 1);
20502  entropyWkspSize -= (MaxSeq + 1) * sizeof(*count);
20503 
20504  DEBUGLOG(5, "ZSTD_entropyCompressSeqStore_internal (nbSeq=%zu, dstCapacity=%zu)", nbSeq, dstCapacity);
20506  assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
20507 
20508  /* Compress literals */
20509  { const BYTE* const literals = seqStorePtr->litStart;
20510  size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
20511  size_t const numLiterals = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
20512  /* Base suspicion of uncompressibility on ratio of literals to sequences */
20513  unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
20514  size_t const litSize = (size_t)(seqStorePtr->lit - literals);
20515 
20516  size_t const cSize = ZSTD_compressLiterals(
20517  op, dstCapacity,
20518  literals, litSize,
20519  entropyWorkspace, entropyWkspSize,
20520  &prevEntropy->huf, &nextEntropy->huf,
20521  cctxParams->cParams.strategy,
20523  suspectUncompressible, bmi2);
20524  FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed");
20525  assert(cSize <= dstCapacity);
20526  op += cSize;
20527  }
20528 
20529  /* Sequences Header */
20530  RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
20531  dstSize_tooSmall, "Can't fit seq hdr in output buf!");
20532  if (nbSeq < 128) {
20533  *op++ = (BYTE)nbSeq;
20534  } else if (nbSeq < LONGNBSEQ) {
20535  op[0] = (BYTE)((nbSeq>>8) + 0x80);
20536  op[1] = (BYTE)nbSeq;
20537  op+=2;
20538  } else {
20539  op[0]=0xFF;
20540  MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ));
20541  op+=3;
20542  }
20543  assert(op <= oend);
20544  if (nbSeq==0) {
20545  /* Copy the old tables over as if we repeated them */
20546  ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
20547  return (size_t)(op - ostart);
20548  }
20549  { BYTE* const seqHead = op++;
20550  /* build stats for sequences */
20551  const ZSTD_symbolEncodingTypeStats_t stats =
20552  ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq,
20553  &prevEntropy->fse, &nextEntropy->fse,
20554  op, oend,
20555  strategy, count,
20556  entropyWorkspace, entropyWkspSize);
20557  FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
20558  *seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2));
20559  lastCountSize = stats.lastCountSize;
20560  op += stats.size;
20561  longOffsets = stats.longOffsets;
20562  }
20563 
20564  { size_t const bitstreamSize = ZSTD_encodeSequences(
20565  op, (size_t)(oend - op),
20566  CTable_MatchLength, mlCodeTable,
20567  CTable_OffsetBits, ofCodeTable,
20568  CTable_LitLength, llCodeTable,
20569  sequences, nbSeq,
20570  longOffsets, bmi2);
20571  FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
20572  op += bitstreamSize;
20573  assert(op <= oend);
20574  /* zstd versions <= 1.3.4 mistakenly report corruption when
20575  * FSE_readNCount() receives a buffer < 4 bytes.
20576  * Fixed by https://github.com/facebook/zstd/pull/1146.
20577  * This can happen when the last set_compressed table present is 2
20578  * bytes and the bitstream is only one byte.
20579  * In this exceedingly rare case, we will simply emit an uncompressed
20580  * block, since it isn't worth optimizing.
20581  */
20582  if (lastCountSize && (lastCountSize + bitstreamSize) < 4) {
20583  /* lastCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
20584  assert(lastCountSize + bitstreamSize == 3);
20585  DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
20586  "emitting an uncompressed block.");
20587  return 0;
20588  }
20589  }
20591  DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
20592  return (size_t)(op - ostart);
20593 }
20594 
20595 MEM_STATIC size_t
20597  const seqStore_t* seqStorePtr,
20598  const ZSTD_entropyCTables_t* prevEntropy,
20599  ZSTD_entropyCTables_t* nextEntropy,
20600  const ZSTD_CCtx_params* cctxParams,
20601  void* dst, size_t dstCapacity,
20602  size_t srcSize,
20603  void* entropyWorkspace, size_t entropyWkspSize,
20604  int bmi2)
20605 {
20606  size_t const cSize = ZSTD_entropyCompressSeqStore_internal(
20607  seqStorePtr, prevEntropy, nextEntropy, cctxParams,
20608  dst, dstCapacity,
20609  entropyWorkspace, entropyWkspSize, bmi2);
20610  if (cSize == 0) return 0;
20611  /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
20612  * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
20613  */
20614  if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) {
20615  DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity);
20616  return 0; /* block not compressed */
20617  }
20618  FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed");
20619 
20620  /* Check compressibility */
20621  { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
20622  if (cSize >= maxCSize) return 0; /* block not compressed */
20623  }
20624  DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize);
20625  /* libzstd decoder before > v1.5.4 is not compatible with compressed blocks of size ZSTD_BLOCKSIZE_MAX exactly.
20626  * This restriction is indirectly already fulfilled by respecting ZSTD_minGain() condition above.
20627  */
20628  assert(cSize < ZSTD_BLOCKSIZE_MAX);
20629  return cSize;
20630 }
20631 
20632 /* ZSTD_selectBlockCompressor() :
20633  * Not static, but internal use only (used by long distance matcher)
20634  * assumption : strat is a valid strategy */
20635 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
20636 {
20637  static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
20638  { ZSTD_compressBlock_fast /* default for 0 */,
20648  { ZSTD_compressBlock_fast_extDict /* default for 0 */,
20658  { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */,
20668  { NULL /* default for 0 */,
20669  NULL,
20670  NULL,
20674  NULL,
20675  NULL,
20676  NULL,
20677  NULL }
20678  };
20679  ZSTD_blockCompressor selectedCompressor;
20680  ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
20681 
20683  DEBUGLOG(4, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
20684  if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) {
20685  static const ZSTD_blockCompressor rowBasedBlockCompressors[4][3] = {
20698  };
20699  DEBUGLOG(4, "Selecting a row-based matchfinder");
20700  assert(useRowMatchFinder != ZSTD_ps_auto);
20701  selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
20702  } else {
20703  selectedCompressor = blockCompressor[(int)dictMode][(int)strat];
20704  }
20705  assert(selectedCompressor != NULL);
20706  return selectedCompressor;
20707 }
20708 
20709 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
20710  const BYTE* anchor, size_t lastLLSize)
20711 {
20712  ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
20713  seqStorePtr->lit += lastLLSize;
20714 }
20715 
20716 void ZSTD_resetSeqStore(seqStore_t* ssPtr)
20717 {
20718  ssPtr->lit = ssPtr->litStart;
20719  ssPtr->sequences = ssPtr->sequencesStart;
20720  ssPtr->longLengthType = ZSTD_llt_none;
20721 }
20722 
20723 /* ZSTD_postProcessSequenceProducerResult() :
20724  * Validates and post-processes sequences obtained through the external matchfinder API:
20725  * - Checks whether nbExternalSeqs represents an error condition.
20726  * - Appends a block delimiter to outSeqs if one is not already present.
20727  * See zstd.h for context regarding block delimiters.
20728  * Returns the number of sequences after post-processing, or an error code. */
20730  ZSTD_Sequence* outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize
20731 ) {
20733  nbExternalSeqs > outSeqsCapacity,
20734  sequenceProducer_failed,
20735  "External sequence producer returned error code %lu",
20736  (unsigned long)nbExternalSeqs
20737  );
20738 
20740  nbExternalSeqs == 0 && srcSize > 0,
20741  sequenceProducer_failed,
20742  "Got zero sequences from external sequence producer for a non-empty src buffer!"
20743  );
20744 
20745  if (srcSize == 0) {
20746  ZSTD_memset(&outSeqs[0], 0, sizeof(ZSTD_Sequence));
20747  return 1;
20748  }
20749 
20750  {
20751  ZSTD_Sequence const lastSeq = outSeqs[nbExternalSeqs - 1];
20752 
20753  /* We can return early if lastSeq is already a block delimiter. */
20754  if (lastSeq.offset == 0 && lastSeq.matchLength == 0) {
20755  return nbExternalSeqs;
20756  }
20757 
20758  /* This error condition is only possible if the external matchfinder
20759  * produced an invalid parse, by definition of ZSTD_sequenceBound(). */
20761  nbExternalSeqs == outSeqsCapacity,
20762  sequenceProducer_failed,
20763  "nbExternalSeqs == outSeqsCapacity but lastSeq is not a block delimiter!"
20764  );
20765 
20766  /* lastSeq is not a block delimiter, so we need to append one. */
20767  ZSTD_memset(&outSeqs[nbExternalSeqs], 0, sizeof(ZSTD_Sequence));
20768  return nbExternalSeqs + 1;
20769  }
20770 }
20771 
20772 /* ZSTD_fastSequenceLengthSum() :
20773  * Returns sum(litLen) + sum(matchLen) + lastLits for *seqBuf*.
20774  * Similar to another function in zstd_compress.c (determine_blockSize),
20775  * except it doesn't check for a block delimiter to end summation.
20776  * Removing the early exit allows the compiler to auto-vectorize (https://godbolt.org/z/cY1cajz9P).
20777  * This function can be deleted and replaced by determine_blockSize after we resolve issue #3456. */
20778 static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seqBufSize) {
20779  size_t matchLenSum, litLenSum, i;
20780  matchLenSum = 0;
20781  litLenSum = 0;
20782  for (i = 0; i < seqBufSize; i++) {
20783  litLenSum += seqBuf[i].litLength;
20784  matchLenSum += seqBuf[i].matchLength;
20785  }
20786  return litLenSum + matchLenSum;
20787 }
20788 
20790 
20791 static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
20792 {
20793  ZSTD_matchState_t* const ms = &zc->blockState.matchState;
20794  DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
20796  /* Assert that we have correctly flushed the ctx params into the ms's copy */
20797  ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);
20798  /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
20799  * additional 1. We need to revisit and change this logic to be more consistent */
20801  if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) {
20803  } else {
20804  ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);
20805  }
20806  return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */
20807  }
20808  ZSTD_resetSeqStore(&(zc->seqStore));
20809  /* required for optimal parser to read stats from dictionary */
20811  /* tell the optimal parser how we expect to compress literals */
20812  ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode;
20813  /* a gap between an attached dict and the current window is not safe,
20814  * they must remain adjacent,
20815  * and when that stops being the case, the dict must be unset */
20816  assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
20817 
20818  /* limited update after a very long match */
20819  { const BYTE* const base = ms->window.base;
20820  const BYTE* const istart = (const BYTE*)src;
20821  const U32 curr = (U32)(istart-base);
20822  if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */
20823  if (curr > ms->nextToUpdate + 384)
20824  ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384));
20825  }
20826 
20827  /* select and store sequences */
20828  { ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms);
20829  size_t lastLLSize;
20830  { int i;
20831  for (i = 0; i < ZSTD_REP_NUM; ++i)
20832  zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];
20833  }
20834  if (zc->externSeqStore.pos < zc->externSeqStore.size) {
20835  assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable);
20836 
20837  /* External matchfinder + LDM is technically possible, just not implemented yet.
20838  * We need to revisit soon and implement it. */
20840  zc->appliedParams.useSequenceProducer,
20841  parameter_combination_unsupported,
20842  "Long-distance matching with external sequence producer enabled is not currently supported."
20843  );
20844 
20845  /* Updates ldmSeqStore.pos */
20846  lastLLSize =
20848  ms, &zc->seqStore,
20849  zc->blockState.nextCBlock->rep,
20850  zc->appliedParams.useRowMatchFinder,
20851  src, srcSize);
20853  } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
20854  rawSeqStore_t ldmSeqStore = kNullRawSeqStore;
20855 
20856  /* External matchfinder + LDM is technically possible, just not implemented yet.
20857  * We need to revisit soon and implement it. */
20859  zc->appliedParams.useSequenceProducer,
20860  parameter_combination_unsupported,
20861  "Long-distance matching with external sequence producer enabled is not currently supported."
20862  );
20863 
20864  ldmSeqStore.seq = zc->ldmSequences;
20865  ldmSeqStore.capacity = zc->maxNbLdmSequences;
20866  /* Updates ldmSeqStore.size */
20868  &zc->appliedParams.ldmParams,
20869  src, srcSize), "");
20870  /* Updates ldmSeqStore.pos */
20871  lastLLSize =
20872  ZSTD_ldm_blockCompress(&ldmSeqStore,
20873  ms, &zc->seqStore,
20874  zc->blockState.nextCBlock->rep,
20875  zc->appliedParams.useRowMatchFinder,
20876  src, srcSize);
20877  assert(ldmSeqStore.pos == ldmSeqStore.size);
20878  } else if (zc->appliedParams.useSequenceProducer) {
20879  assert(
20881  );
20882  assert(zc->externalMatchCtx.mFinder != NULL);
20883 
20884  { U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog;
20885 
20886  size_t const nbExternalSeqs = (zc->externalMatchCtx.mFinder)(
20890  src, srcSize,
20891  NULL, 0, /* dict and dictSize, currently not supported */
20892  zc->appliedParams.compressionLevel,
20893  windowSize
20894  );
20895 
20896  size_t const nbPostProcessedSeqs = ZSTD_postProcessSequenceProducerResult(
20898  nbExternalSeqs,
20900  srcSize
20901  );
20902 
20903  /* Return early if there is no error, since we don't need to worry about last literals */
20904  if (!ZSTD_isError(nbPostProcessedSeqs)) {
20905  ZSTD_sequencePosition seqPos = {0,0,0};
20906  size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->externalMatchCtx.seqBuffer, nbPostProcessedSeqs);
20907  RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!");
20910  zc, &seqPos,
20911  zc->externalMatchCtx.seqBuffer, nbPostProcessedSeqs,
20912  src, srcSize,
20913  zc->appliedParams.searchForExternalRepcodes
20914  ),
20915  "Failed to copy external sequences to seqStore!"
20916  );
20917  ms->ldmSeqStore = NULL;
20918  DEBUGLOG(5, "Copied %lu sequences from external sequence producer to internal seqStore.", (unsigned long)nbExternalSeqs);
20919  return ZSTDbss_compress;
20920  }
20921 
20922  /* Propagate the error if fallback is disabled */
20923  if (!zc->appliedParams.enableMatchFinderFallback) {
20924  return nbPostProcessedSeqs;
20925  }
20926 
20927  /* Fallback to software matchfinder */
20928  { ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
20929  zc->appliedParams.useRowMatchFinder,
20930  dictMode);
20931  ms->ldmSeqStore = NULL;
20932  DEBUGLOG(
20933  5,
20934  "External sequence producer returned error code %lu. Falling back to internal parser.",
20935  (unsigned long)nbExternalSeqs
20936  );
20937  lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
20938  } }
20939  } else { /* not long range mode and no external matchfinder */
20940  ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
20941  zc->appliedParams.useRowMatchFinder,
20942  dictMode);
20943  ms->ldmSeqStore = NULL;
20944  lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
20945  }
20946  { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
20947  ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
20948  } }
20949  return ZSTDbss_compress;
20950 }
20951 
20952 static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
20953 {
20954  const seqStore_t* seqStore = ZSTD_getSeqStore(zc);
20955  const seqDef* seqStoreSeqs = seqStore->sequencesStart;
20956  size_t seqStoreSeqSize = seqStore->sequences - seqStoreSeqs;
20957  size_t seqStoreLiteralsSize = (size_t)(seqStore->lit - seqStore->litStart);
20958  size_t literalsRead = 0;
20959  size_t lastLLSize;
20960 
20961  ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];
20962  size_t i;
20963  repcodes_t updatedRepcodes;
20964 
20966  /* Ensure we have enough space for last literals "sequence" */
20967  assert(zc->seqCollector.maxSequences >= seqStoreSeqSize + 1);
20968  ZSTD_memcpy(updatedRepcodes.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
20969  for (i = 0; i < seqStoreSeqSize; ++i) {
20970  U32 rawOffset = seqStoreSeqs[i].offBase - ZSTD_REP_NUM;
20971  outSeqs[i].litLength = seqStoreSeqs[i].litLength;
20972  outSeqs[i].matchLength = seqStoreSeqs[i].mlBase + MINMATCH;
20973  outSeqs[i].rep = 0;
20974 
20975  if (i == seqStore->longLengthPos) {
20976  if (seqStore->longLengthType == ZSTD_llt_literalLength) {
20977  outSeqs[i].litLength += 0x10000;
20978  } else if (seqStore->longLengthType == ZSTD_llt_matchLength) {
20979  outSeqs[i].matchLength += 0x10000;
20980  }
20981  }
20982 
20983  if (seqStoreSeqs[i].offBase <= ZSTD_REP_NUM) {
20984  /* Derive the correct offset corresponding to a repcode */
20985  outSeqs[i].rep = seqStoreSeqs[i].offBase;
20986  if (outSeqs[i].litLength != 0) {
20987  rawOffset = updatedRepcodes.rep[outSeqs[i].rep - 1];
20988  } else {
20989  if (outSeqs[i].rep == 3) {
20990  rawOffset = updatedRepcodes.rep[0] - 1;
20991  } else {
20992  rawOffset = updatedRepcodes.rep[outSeqs[i].rep];
20993  }
20994  }
20995  }
20996  outSeqs[i].offset = rawOffset;
20997  /* seqStoreSeqs[i].offset == offCode+1, and ZSTD_updateRep() expects offCode
20998  so we provide seqStoreSeqs[i].offset - 1 */
20999  ZSTD_updateRep(updatedRepcodes.rep,
21000  seqStoreSeqs[i].offBase,
21001  seqStoreSeqs[i].litLength == 0);
21002  literalsRead += outSeqs[i].litLength;
21003  }
21004  /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0.
21005  * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker
21006  * for the block boundary, according to the API.
21007  */
21008  assert(seqStoreLiteralsSize >= literalsRead);
21009  lastLLSize = seqStoreLiteralsSize - literalsRead;
21010  outSeqs[i].litLength = (U32)lastLLSize;
21011  outSeqs[i].matchLength = outSeqs[i].offset = outSeqs[i].rep = 0;
21012  seqStoreSeqSize++;
21013  zc->seqCollector.seqIndex += seqStoreSeqSize;
21015 
21016 size_t ZSTD_sequenceBound(size_t srcSize) {
21017  return (srcSize / ZSTD_MINMATCH_MIN) + 1;
21018 }
21019 
21020 size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
21021  size_t outSeqsSize, const void* src, size_t srcSize)
21022 {
21023  const size_t dstCapacity = ZSTD_compressBound(srcSize);
21024  void* dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
21025  SeqCollector seqCollector;
21026 
21027  RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
21028 
21029  seqCollector.collectSequences = 1;
21030  seqCollector.seqStart = outSeqs;
21031  seqCollector.seqIndex = 0;
21032  seqCollector.maxSequences = outSeqsSize;
21033  zc->seqCollector = seqCollector;
21035  ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
21036  ZSTD_customFree(dst, ZSTD_defaultCMem);
21037  return zc->seqCollector.seqIndex;
21038 }
21039 
21040 size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) {
21041  size_t in = 0;
21042  size_t out = 0;
21043  for (; in < seqsSize; ++in) {
21044  if (sequences[in].offset == 0 && sequences[in].matchLength == 0) {
21045  if (in != seqsSize - 1) {
21046  sequences[in+1].litLength += sequences[in].litLength;
21047  }
21048  } else {
21049  sequences[out] = sequences[in];
21050  ++out;
21051  }
21052  }
21053  return out;
21054 }
21055 
21056 /* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */
21057 static int ZSTD_isRLE(const BYTE* src, size_t length) {
21058  const BYTE* ip = src;
21059  const BYTE value = ip[0];
21060  const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL);
21061  const size_t unrollSize = sizeof(size_t) * 4;
21062  const size_t unrollMask = unrollSize - 1;
21063  const size_t prefixLength = length & unrollMask;
21064  size_t i;
21065  if (length == 1) return 1;
21066  /* Check if prefix is RLE first before using unrolled loop */
21067  if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) {
21068  return 0;
21069  }
21070  for (i = prefixLength; i != length; i += unrollSize) {
21071  size_t u;
21072  for (u = 0; u < unrollSize; u += sizeof(size_t)) {
21073  if (MEM_readST(ip + i + u) != valueST) {
21074  return 0;
21075  } } }
21076  return 1;
21078 
21079 /* Returns true if the given block may be RLE.
21080  * This is just a heuristic based on the compressibility.
21081  * It may return both false positives and false negatives.
21082  */
21083 static int ZSTD_maybeRLE(seqStore_t const* seqStore)
21084 {
21085  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
21086  size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
21087 
21088  return nbSeqs < 4 && nbLits < 10;
21089 }
21090 
21091 static void
21093 {
21094  ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock;
21096  bs->nextCBlock = tmp;
21097 }
21098 
21099 /* Writes the block header */
21100 static void
21101 writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock)
21102 {
21103  U32 const cBlockHeader = cSize == 1 ?
21104  lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
21105  lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
21106  MEM_writeLE24(op, cBlockHeader);
21107  DEBUGLOG(3, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
21108 }
21109 
21117 static size_t
21118 ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize,
21119  const ZSTD_hufCTables_t* prevHuf,
21120  ZSTD_hufCTables_t* nextHuf,
21121  ZSTD_hufCTablesMetadata_t* hufMetadata,
21122  const int literalsCompressionIsDisabled,
21123  void* workspace, size_t wkspSize,
21124  int hufFlags)
21125 {
21126  BYTE* const wkspStart = (BYTE*)workspace;
21127  BYTE* const wkspEnd = wkspStart + wkspSize;
21128  BYTE* const countWkspStart = wkspStart;
21129  unsigned* const countWksp = (unsigned*)workspace;
21130  const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
21131  BYTE* const nodeWksp = countWkspStart + countWkspSize;
21132  const size_t nodeWkspSize = (size_t)(wkspEnd - nodeWksp);
21133  unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX;
21134  unsigned huffLog = LitHufLog;
21135  HUF_repeat repeat = prevHuf->repeatMode;
21136  DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_literals (srcSize=%zu)", srcSize);
21137 
21138  /* Prepare nextEntropy assuming reusing the existing table */
21139  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
21140 
21141  if (literalsCompressionIsDisabled) {
21142  DEBUGLOG(5, "set_basic - disabled");
21143  hufMetadata->hType = set_basic;
21144  return 0;
21145  }
21146 
21147  /* small ? don't even attempt compression (speed opt) */
21148 #ifndef COMPRESS_LITERALS_SIZE_MIN
21149 # define COMPRESS_LITERALS_SIZE_MIN 63 /* heuristic */
21150 #endif
21151  { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
21152  if (srcSize <= minLitSize) {
21153  DEBUGLOG(5, "set_basic - too small");
21154  hufMetadata->hType = set_basic;
21155  return 0;
21156  } }
21157 
21158  /* Scan input and build symbol stats */
21159  { size_t const largest =
21160  HIST_count_wksp (countWksp, &maxSymbolValue,
21161  (const BYTE*)src, srcSize,
21162  workspace, wkspSize);
21163  FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
21164  if (largest == srcSize) {
21165  /* only one literal symbol */
21166  DEBUGLOG(5, "set_rle");
21167  hufMetadata->hType = set_rle;
21168  return 0;
21169  }
21170  if (largest <= (srcSize >> 7)+4) {
21171  /* heuristic: likely not compressible */
21172  DEBUGLOG(5, "set_basic - no gain");
21173  hufMetadata->hType = set_basic;
21174  return 0;
21175  } }
21176 
21177  /* Validate the previous Huffman table */
21178  if (repeat == HUF_repeat_check
21179  && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
21180  repeat = HUF_repeat_none;
21181  }
21182 
21183  /* Build Huffman Tree */
21184  ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
21185  huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, nodeWksp, nodeWkspSize, nextHuf->CTable, countWksp, hufFlags);
21186  assert(huffLog <= LitHufLog);
21187  { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
21188  maxSymbolValue, huffLog,
21189  nodeWksp, nodeWkspSize);
21190  FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
21191  huffLog = (U32)maxBits;
21192  }
21193  { /* Build and write the CTable */
21194  size_t const newCSize = HUF_estimateCompressedSize(
21195  (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
21196  size_t const hSize = HUF_writeCTable_wksp(
21197  hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
21198  (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog,
21199  nodeWksp, nodeWkspSize);
21200  /* Check against repeating the previous CTable */
21201  if (repeat != HUF_repeat_none) {
21202  size_t const oldCSize = HUF_estimateCompressedSize(
21203  (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
21204  if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
21205  DEBUGLOG(5, "set_repeat - smaller");
21206  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
21207  hufMetadata->hType = set_repeat;
21208  return 0;
21209  } }
21210  if (newCSize + hSize >= srcSize) {
21211  DEBUGLOG(5, "set_basic - no gains");
21212  ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
21213  hufMetadata->hType = set_basic;
21214  return 0;
21215  }
21216  DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
21217  hufMetadata->hType = set_compressed;
21218  nextHuf->repeatMode = HUF_repeat_check;
21219  return hSize;
21220  }
21221 }
21222 
21224 /* ZSTD_buildDummySequencesStatistics():
21225  * Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic,
21226  * and updates nextEntropy to the appropriate repeatMode.
21227  */
21230 {
21232  nextEntropy->litlength_repeatMode = FSE_repeat_none;
21233  nextEntropy->offcode_repeatMode = FSE_repeat_none;
21234  nextEntropy->matchlength_repeatMode = FSE_repeat_none;
21235  return stats;
21236 }
21237 
21243 static size_t
21245  const seqStore_t* seqStorePtr,
21246  const ZSTD_fseCTables_t* prevEntropy,
21247  ZSTD_fseCTables_t* nextEntropy,
21248  const ZSTD_CCtx_params* cctxParams,
21249  ZSTD_fseCTablesMetadata_t* fseMetadata,
21250  void* workspace, size_t wkspSize)
21251 {
21252  ZSTD_strategy const strategy = cctxParams->cParams.strategy;
21253  size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
21254  BYTE* const ostart = fseMetadata->fseTablesBuffer;
21255  BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
21256  BYTE* op = ostart;
21257  unsigned* countWorkspace = (unsigned*)workspace;
21258  unsigned* entropyWorkspace = countWorkspace + (MaxSeq + 1);
21259  size_t entropyWorkspaceSize = wkspSize - (MaxSeq + 1) * sizeof(*countWorkspace);
21261 
21262  DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq);
21263  stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq,
21264  prevEntropy, nextEntropy, op, oend,
21265  strategy, countWorkspace,
21266  entropyWorkspace, entropyWorkspaceSize)
21267  : ZSTD_buildDummySequencesStatistics(nextEntropy);
21268  FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
21269  fseMetadata->llType = (symbolEncodingType_e) stats.LLtype;
21270  fseMetadata->ofType = (symbolEncodingType_e) stats.Offtype;
21271  fseMetadata->mlType = (symbolEncodingType_e) stats.MLtype;
21272  fseMetadata->lastCountSize = stats.lastCountSize;
21273  return stats.size;
21274 }
21275 
21276 
21284  const seqStore_t* seqStorePtr,
21285  const ZSTD_entropyCTables_t* prevEntropy,
21286  ZSTD_entropyCTables_t* nextEntropy,
21287  const ZSTD_CCtx_params* cctxParams,
21288  ZSTD_entropyCTablesMetadata_t* entropyMetadata,
21289  void* workspace, size_t wkspSize)
21290 {
21291  size_t const litSize = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
21292  int const huf_useOptDepth = (cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD);
21293  int const hufFlags = huf_useOptDepth ? HUF_flags_optimalDepth : 0;
21294 
21295  entropyMetadata->hufMetadata.hufDesSize =
21296  ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize,
21297  &prevEntropy->huf, &nextEntropy->huf,
21298  &entropyMetadata->hufMetadata,
21300  workspace, wkspSize, hufFlags);
21301 
21302  FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed");
21303  entropyMetadata->fseMetadata.fseTablesSize =
21305  &prevEntropy->fse, &nextEntropy->fse,
21306  cctxParams,
21307  &entropyMetadata->fseMetadata,
21308  workspace, wkspSize);
21309  FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildBlockEntropyStats_sequences failed");
21310  return 0;
21311 }
21312 
21313 /* Returns the size estimate for the literals section (header + content) of a block */
21314 static size_t
21315 ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize,
21316  const ZSTD_hufCTables_t* huf,
21317  const ZSTD_hufCTablesMetadata_t* hufMetadata,
21318  void* workspace, size_t wkspSize,
21319  int writeEntropy)
21320 {
21321  unsigned* const countWksp = (unsigned*)workspace;
21322  unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX;
21323  size_t literalSectionHeaderSize = 3 + (litSize >= 1 KB) + (litSize >= 16 KB);
21324  U32 singleStream = litSize < 256;
21325 
21326  if (hufMetadata->hType == set_basic) return litSize;
21327  else if (hufMetadata->hType == set_rle) return 1;
21328  else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) {
21329  size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize);
21330  if (ZSTD_isError(largest)) return litSize;
21331  { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue);
21332  if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize;
21333  if (!singleStream) cLitSizeEstimate += 6; /* multi-stream huffman uses 6-byte jump table */
21334  return cLitSizeEstimate + literalSectionHeaderSize;
21335  } }
21336  assert(0); /* impossible */
21337  return 0;
21338 }
21339 
21340 /* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
21341 static size_t
21343  const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
21344  const FSE_CTable* fseCTable,
21345  const U8* additionalBits,
21346  short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
21347  void* workspace, size_t wkspSize)
21348 {
21349  unsigned* const countWksp = (unsigned*)workspace;
21350  const BYTE* ctp = codeTable;
21351  const BYTE* const ctStart = ctp;
21352  const BYTE* const ctEnd = ctStart + nbSeq;
21353  size_t cSymbolTypeSizeEstimateInBits = 0;
21354  unsigned max = maxCode;
21355 
21356  HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
21357  if (type == set_basic) {
21358  /* We selected this encoding type, so it must be valid. */
21359  assert(max <= defaultMax);
21360  (void)defaultMax;
21361  cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max);
21362  } else if (type == set_rle) {
21363  cSymbolTypeSizeEstimateInBits = 0;
21364  } else if (type == set_compressed || type == set_repeat) {
21365  cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max);
21366  }
21367  if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) {
21368  return nbSeq * 10;
21369  }
21370  while (ctp < ctEnd) {
21371  if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp];
21372  else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */
21373  ctp++;
21374  }
21375  return cSymbolTypeSizeEstimateInBits >> 3;
21376 }
21377 
21378 /* Returns the size estimate for the sequences section (header + content) of a block */
21379 static size_t
21380 ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable,
21381  const BYTE* llCodeTable,
21382  const BYTE* mlCodeTable,
21383  size_t nbSeq,
21384  const ZSTD_fseCTables_t* fseTables,
21385  const ZSTD_fseCTablesMetadata_t* fseMetadata,
21386  void* workspace, size_t wkspSize,
21387  int writeEntropy)
21388 {
21389  size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ);
21390  size_t cSeqSizeEstimate = 0;
21391  cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff,
21392  fseTables->offcodeCTable, NULL,
21394  workspace, wkspSize);
21395  cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL,
21396  fseTables->litlengthCTable, LL_bits,
21398  workspace, wkspSize);
21399  cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML,
21400  fseTables->matchlengthCTable, ML_bits,
21402  workspace, wkspSize);
21403  if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
21404  return cSeqSizeEstimate + sequencesSectionHeaderSize;
21405 }
21406 
21407 /* Returns the size estimate for a given stream of literals, of, ll, ml */
21408 static size_t
21409 ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
21410  const BYTE* ofCodeTable,
21411  const BYTE* llCodeTable,
21412  const BYTE* mlCodeTable,
21413  size_t nbSeq,
21414  const ZSTD_entropyCTables_t* entropy,
21415  const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
21416  void* workspace, size_t wkspSize,
21417  int writeLitEntropy, int writeSeqEntropy)
21418 {
21419  size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize,
21420  &entropy->huf, &entropyMetadata->hufMetadata,
21421  workspace, wkspSize, writeLitEntropy);
21422  size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
21423  nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
21424  workspace, wkspSize, writeSeqEntropy);
21425  return seqSize + literalsSize + ZSTD_blockHeaderSize;
21426 }
21428 /* Builds entropy statistics and uses them for blocksize estimation.
21429  *
21430  * @return: estimated compressed size of the seqStore, or a zstd error.
21431  */
21432 static size_t
21434 {
21435  ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
21436  DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
21440  &zc->appliedParams,
21441  entropyMetadata,
21443  return ZSTD_estimateBlockSize(
21444  seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
21445  seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
21446  (size_t)(seqStore->sequences - seqStore->sequencesStart),
21448  entropyMetadata,
21450  (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
21451 }
21452 
21453 /* Returns literals bytes represented in a seqStore */
21454 static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore)
21455 {
21456  size_t literalsBytes = 0;
21457  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
21458  size_t i;
21459  for (i = 0; i < nbSeqs; ++i) {
21460  seqDef const seq = seqStore->sequencesStart[i];
21461  literalsBytes += seq.litLength;
21462  if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
21463  literalsBytes += 0x10000;
21464  } }
21465  return literalsBytes;
21466 }
21467 
21468 /* Returns match bytes represented in a seqStore */
21469 static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore)
21470 {
21471  size_t matchBytes = 0;
21472  size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
21473  size_t i;
21474  for (i = 0; i < nbSeqs; ++i) {
21475  seqDef seq = seqStore->sequencesStart[i];
21476  matchBytes += seq.mlBase + MINMATCH;
21477  if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
21478  matchBytes += 0x10000;
21479  } }
21480  return matchBytes;
21481 }
21482 
21483 /* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx).
21484  * Stores the result in resultSeqStore.
21485  */
21486 static void ZSTD_deriveSeqStoreChunk(seqStore_t* resultSeqStore,
21487  const seqStore_t* originalSeqStore,
21488  size_t startIdx, size_t endIdx)
21489 {
21490  *resultSeqStore = *originalSeqStore;
21491  if (startIdx > 0) {
21492  resultSeqStore->sequences = originalSeqStore->sequencesStart + startIdx;
21493  resultSeqStore->litStart += ZSTD_countSeqStoreLiteralsBytes(resultSeqStore);
21494  }
21495 
21496  /* Move longLengthPos into the correct position if necessary */
21497  if (originalSeqStore->longLengthType != ZSTD_llt_none) {
21498  if (originalSeqStore->longLengthPos < startIdx || originalSeqStore->longLengthPos > endIdx) {
21499  resultSeqStore->longLengthType = ZSTD_llt_none;
21500  } else {
21501  resultSeqStore->longLengthPos -= (U32)startIdx;
21502  }
21503  }
21504  resultSeqStore->sequencesStart = originalSeqStore->sequencesStart + startIdx;
21505  resultSeqStore->sequences = originalSeqStore->sequencesStart + endIdx;
21506  if (endIdx == (size_t)(originalSeqStore->sequences - originalSeqStore->sequencesStart)) {
21507  /* This accounts for possible last literals if the derived chunk reaches the end of the block */
21508  assert(resultSeqStore->lit == originalSeqStore->lit);
21509  } else {
21510  size_t const literalsBytes = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore);
21511  resultSeqStore->lit = resultSeqStore->litStart + literalsBytes;
21512  }
21513  resultSeqStore->llCode += startIdx;
21514  resultSeqStore->mlCode += startIdx;
21515  resultSeqStore->ofCode += startIdx;
21516 }
21522 static U32
21523 ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, const U32 ll0)
21524 {
21525  U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */
21526  assert(OFFBASE_IS_REPCODE(offBase));
21527  if (adjustedRepCode == ZSTD_REP_NUM) {
21528  assert(ll0);
21529  /* litlength == 0 and offCode == 2 implies selection of first repcode - 1
21530  * This is only valid if it results in a valid offset value, aka > 0.
21531  * Note : it may happen that `rep[0]==1` in exceptional circumstances.
21532  * In which case this function will return 0, which is an invalid offset.
21533  * It's not an issue though, since this value will be
21534  * compared and discarded within ZSTD_seqStore_resolveOffCodes().
21535  */
21536  return rep[0] - 1;
21537  }
21538  return rep[adjustedRepCode];
21539 }
21540 
21554 static void
21555 ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRepcodes,
21556  const seqStore_t* const seqStore, U32 const nbSeq)
21557 {
21558  U32 idx = 0;
21559  U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq;
21560  for (; idx < nbSeq; ++idx) {
21561  seqDef* const seq = seqStore->sequencesStart + idx;
21562  U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx);
21563  U32 const offBase = seq->offBase;
21564  assert(offBase > 0);
21565  if (OFFBASE_IS_REPCODE(offBase)) {
21566  U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0);
21567  U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0);
21568  /* Adjust simulated decompression repcode history if we come across a mismatch. Replace
21569  * the repcode with the offset it actually references, determined by the compression
21570  * repcode history.
21571  */
21572  if (dRawOffset != cRawOffset) {
21573  seq->offBase = OFFSET_TO_OFFBASE(cRawOffset);
21574  }
21575  }
21576  /* Compression repcode history is always updated with values directly from the unmodified seqStore.
21577  * Decompression repcode history may use modified seq->offset value taken from compression repcode history.
21578  */
21579  ZSTD_updateRep(dRepcodes->rep, seq->offBase, ll0);
21580  ZSTD_updateRep(cRepcodes->rep, offBase, ll0);
21581  }
21582 }
21583 
21584 /* ZSTD_compressSeqStore_singleBlock():
21585  * Compresses a seqStore into a block with a block header, into the buffer dst.
21586  *
21587  * Returns the total size of that block (including header) or a ZSTD error code.
21588  */
21589 static size_t
21591  const seqStore_t* const seqStore,
21592  repcodes_t* const dRep, repcodes_t* const cRep,
21593  void* dst, size_t dstCapacity,
21594  const void* src, size_t srcSize,
21595  U32 lastBlock, U32 isPartition)
21596 {
21597  const U32 rleMaxLength = 25;
21598  BYTE* op = (BYTE*)dst;
21599  const BYTE* ip = (const BYTE*)src;
21600  size_t cSize;
21601  size_t cSeqsSize;
21602 
21603  /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
21604  repcodes_t const dRepOriginal = *dRep;
21605  DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock");
21606  if (isPartition)
21607  ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
21608 
21609  RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit");
21610  cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore,
21612  &zc->appliedParams,
21613  op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize,
21614  srcSize,
21615  zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
21616  zc->bmi2);
21617  FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!");
21618 
21619  if (!zc->isFirstBlock &&
21620  cSeqsSize < rleMaxLength &&
21621  ZSTD_isRLE((BYTE const*)src, srcSize)) {
21622  /* We don't want to emit our first block as a RLE even if it qualifies because
21623  * doing so will cause the decoder (cli only) to throw a "should consume all input error."
21624  * This is only an issue for zstd <= v1.4.3
21625  */
21626  cSeqsSize = 1;
21627  }
21628 
21629  if (zc->seqCollector.collectSequences) {
21632  return 0;
21633  }
21634 
21635  if (cSeqsSize == 0) {
21636  cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
21637  FORWARD_IF_ERROR(cSize, "Nocompress block failed");
21638  DEBUGLOG(4, "Writing out nocompress block, size: %zu", cSize);
21639  *dRep = dRepOriginal; /* reset simulated decompression repcode history */
21640  } else if (cSeqsSize == 1) {
21641  cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock);
21642  FORWARD_IF_ERROR(cSize, "RLE compress block failed");
21643  DEBUGLOG(4, "Writing out RLE block, size: %zu", cSize);
21644  *dRep = dRepOriginal; /* reset simulated decompression repcode history */
21645  } else {
21647  writeBlockHeader(op, cSeqsSize, srcSize, lastBlock);
21648  cSize = ZSTD_blockHeaderSize + cSeqsSize;
21649  DEBUGLOG(4, "Writing out compressed block, size: %zu", cSize);
21650  }
21651 
21655  return cSize;
21656 }
21657 
21658 /* Struct to keep track of where we are in our recursive calls. */
21659 typedef struct {
21660  U32* splitLocations; /* Array of split indices */
21661  size_t idx; /* The current index within splitLocations being worked on */
21662 } seqStoreSplits;
21663 
21664 #define MIN_SEQUENCES_BLOCK_SPLITTING 300
21665 
21666 /* Helper function to perform the recursive search for block splits.
21667  * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half.
21668  * If advantageous to split, then we recurse down the two sub-blocks.
21669  * If not, or if an error occurred in estimation, then we do not recurse.
21670  *
21671  * Note: The recursion depth is capped by a heuristic minimum number of sequences,
21672  * defined by MIN_SEQUENCES_BLOCK_SPLITTING.
21673  * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING).
21674  * In practice, recursion depth usually doesn't go beyond 4.
21675  *
21676  * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS.
21677  * At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize
21678  * maximum of 128 KB, this value is actually impossible to reach.
21679  */
21680 static void
21681 ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
21682  ZSTD_CCtx* zc, const seqStore_t* origSeqStore)
21683 {
21684  seqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
21685  seqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
21686  seqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
21687  size_t estimatedOriginalSize;
21688  size_t estimatedFirstHalfSize;
21689  size_t estimatedSecondHalfSize;
21690  size_t midIdx = (startIdx + endIdx)/2;
21691 
21692  DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx);
21693  assert(endIdx >= startIdx);
21694  if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) {
21695  DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences (%zu)", endIdx - startIdx);
21696  return;
21697  }
21698  ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx);
21699  ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx);
21700  ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx);
21701  estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc);
21702  estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc);
21703  estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc);
21704  DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu",
21705  estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize);
21706  if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) {
21707  return;
21708  }
21709  if (estimatedFirstHalfSize + estimatedSecondHalfSize < estimatedOriginalSize) {
21710  DEBUGLOG(5, "split decided at seqNb:%zu", midIdx);
21711  ZSTD_deriveBlockSplitsHelper(splits, startIdx, midIdx, zc, origSeqStore);
21712  splits->splitLocations[splits->idx] = (U32)midIdx;
21713  splits->idx++;
21714  ZSTD_deriveBlockSplitsHelper(splits, midIdx, endIdx, zc, origSeqStore);
21715  }
21716 }
21718 /* Base recursive function.
21719  * Populates a table with intra-block partition indices that can improve compression ratio.
21720  *
21721  * @return: number of splits made (which equals the size of the partition table - 1).
21722  */
21723 static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq)
21724 {
21725  seqStoreSplits splits;
21726  splits.splitLocations = partitions;
21727  splits.idx = 0;
21728  if (nbSeq <= 4) {
21729  DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split (%u <= 4)", nbSeq);
21730  /* Refuse to try and split anything with less than 4 sequences */
21731  return 0;
21732  }
21733  ZSTD_deriveBlockSplitsHelper(&splits, 0, nbSeq, zc, &zc->seqStore);
21734  splits.splitLocations[splits.idx] = nbSeq;
21735  DEBUGLOG(5, "ZSTD_deriveBlockSplits: final nb partitions: %zu", splits.idx+1);
21736  return splits.idx;
21737 }
21738 
21739 /* ZSTD_compressBlock_splitBlock():
21740  * Attempts to split a given block into multiple blocks to improve compression ratio.
21741  *
21742  * Returns combined size of all blocks (which includes headers), or a ZSTD error code.
21743  */
21744 static size_t
21746  void* dst, size_t dstCapacity,
21747  const void* src, size_t blockSize,
21748  U32 lastBlock, U32 nbSeq)
21749 {
21750  size_t cSize = 0;
21751  const BYTE* ip = (const BYTE*)src;
21752  BYTE* op = (BYTE*)dst;
21753  size_t i = 0;
21754  size_t srcBytesTotal = 0;
21755  U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
21756  seqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
21757  seqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
21758  size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
21759 
21760  /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
21761  * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two
21762  * separate repcode histories that simulate repcode history on compression and decompression side,
21763  * and use the histories to determine whether we must replace a particular repcode with its raw offset.
21764  *
21765  * 1) cRep gets updated for each partition, regardless of whether the block was emitted as uncompressed
21766  * or RLE. This allows us to retrieve the offset value that an invalid repcode references within
21767  * a nocompress/RLE block.
21768  * 2) dRep gets updated only for compressed partitions, and when a repcode gets replaced, will use
21769  * the replacement offset value rather than the original repcode to update the repcode history.
21770  * dRep also will be the final repcode history sent to the next block.
21771  *
21772  * See ZSTD_seqStore_resolveOffCodes() for more details.
21773  */
21774  repcodes_t dRep;
21775  repcodes_t cRep;
21776  ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
21777  ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t));
21778  ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t));
21779 
21780  DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
21781  (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
21782  (unsigned)zc->blockState.matchState.nextToUpdate);
21783 
21784  if (numSplits == 0) {
21785  size_t cSizeSingleBlock =
21787  &dRep, &cRep,
21788  op, dstCapacity,
21789  ip, blockSize,
21790  lastBlock, 0 /* isPartition */);
21791  FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
21792  DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
21794  assert(cSizeSingleBlock <= zc->blockSize + ZSTD_blockHeaderSize);
21795  return cSizeSingleBlock;
21796  }
21797 
21798  ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]);
21799  for (i = 0; i <= numSplits; ++i) {
21800  size_t cSizeChunk;
21801  U32 const lastPartition = (i == numSplits);
21802  U32 lastBlockEntireSrc = 0;
21803 
21804  size_t srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore);
21805  srcBytesTotal += srcBytes;
21806  if (lastPartition) {
21807  /* This is the final partition, need to account for possible last literals */
21808  srcBytes += blockSize - srcBytesTotal;
21809  lastBlockEntireSrc = lastBlock;
21810  } else {
21811  ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]);
21812  }
21813 
21814  cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore,
21815  &dRep, &cRep,
21816  op, dstCapacity,
21817  ip, srcBytes,
21818  lastBlockEntireSrc, 1 /* isPartition */);
21819  DEBUGLOG(5, "Estimated size: %zu vs %zu : actual size",
21820  ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk);
21821  FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!");
21822 
21823  ip += srcBytes;
21824  op += cSizeChunk;
21825  dstCapacity -= cSizeChunk;
21826  cSize += cSizeChunk;
21827  *currSeqStore = *nextSeqStore;
21828  assert(cSizeChunk <= zc->blockSize + ZSTD_blockHeaderSize);
21829  }
21830  /* cRep and dRep may have diverged during the compression.
21831  * If so, we use the dRep repcodes for the next block.
21832  */
21833  ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(repcodes_t));
21834  return cSize;
21835 }
21836 
21837 static size_t
21839  void* dst, size_t dstCapacity,
21840  const void* src, size_t srcSize, U32 lastBlock)
21841 {
21842  U32 nbSeq;
21843  size_t cSize;
21844  DEBUGLOG(4, "ZSTD_compressBlock_splitBlock");
21845  assert(zc->appliedParams.useBlockSplitter == ZSTD_ps_enable);
21846 
21847  { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
21848  FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
21849  if (bss == ZSTDbss_noCompress) {
21852  cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
21853  FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
21854  DEBUGLOG(4, "ZSTD_compressBlock_splitBlock: Nocompress block");
21855  return cSize;
21856  }
21857  nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
21858  }
21859 
21860  cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq);
21861  FORWARD_IF_ERROR(cSize, "Splitting blocks failed!");
21862  return cSize;
21863 }
21864 
21865 static size_t
21867  void* dst, size_t dstCapacity,
21868  const void* src, size_t srcSize, U32 frame)
21869 {
21870  /* This is an estimated upper bound for the length of an rle block.
21871  * This isn't the actual upper bound.
21872  * Finding the real threshold needs further investigation.
21873  */
21874  const U32 rleMaxLength = 25;
21875  size_t cSize;
21876  const BYTE* ip = (const BYTE*)src;
21877  BYTE* op = (BYTE*)dst;
21878  DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
21879  (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
21880  (unsigned)zc->blockState.matchState.nextToUpdate);
21881 
21882  { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
21883  FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
21884  if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
21885  }
21886 
21887  if (zc->seqCollector.collectSequences) {
21890  return 0;
21891  }
21892 
21893  /* encode sequences and literals */
21896  &zc->appliedParams,
21897  dst, dstCapacity,
21898  srcSize,
21899  zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
21900  zc->bmi2);
21901 
21902  if (frame &&
21903  /* We don't want to emit our first block as a RLE even if it qualifies because
21904  * doing so will cause the decoder (cli only) to throw a "should consume all input error."
21905  * This is only an issue for zstd <= v1.4.3
21906  */
21907  !zc->isFirstBlock &&
21908  cSize < rleMaxLength &&
21909  ZSTD_isRLE(ip, srcSize))
21910  {
21911  cSize = 1;
21912  op[0] = ip[0];
21913  }
21914 
21915 out:
21916  if (!ZSTD_isError(cSize) && cSize > 1) {
21918  }
21919  /* We check that dictionaries have offset codes available for the first
21920  * block. After the first block, the offcode table might not have large
21921  * enough codes to represent the offsets in the data.
21922  */
21925 
21926  return cSize;
21927 }
21928 
21930  void* dst, size_t dstCapacity,
21931  const void* src, size_t srcSize,
21932  const size_t bss, U32 lastBlock)
21933 {
21934  DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()");
21935  if (bss == ZSTDbss_compress) {
21936  if (/* We don't want to emit our first block as a RLE even if it qualifies because
21937  * doing so will cause the decoder (cli only) to throw a "should consume all input error."
21938  * This is only an issue for zstd <= v1.4.3
21939  */
21940  !zc->isFirstBlock &&
21941  ZSTD_maybeRLE(&zc->seqStore) &&
21942  ZSTD_isRLE((BYTE const*)src, srcSize))
21943  {
21944  return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock);
21945  }
21946  /* Attempt superblock compression.
21947  *
21948  * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the
21949  * standard ZSTD_compressBound(). This is a problem, because even if we have
21950  * space now, taking an extra byte now could cause us to run out of space later
21951  * and violate ZSTD_compressBound().
21952  *
21953  * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize.
21954  *
21955  * In order to respect ZSTD_compressBound() we must attempt to emit a raw
21956  * uncompressed block in these cases:
21957  * * cSize == 0: Return code for an uncompressed block.
21958  * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize).
21959  * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of
21960  * output space.
21961  * * cSize >= blockBound(srcSize): We have expanded the block too much so
21962  * emit an uncompressed block.
21963  */
21964  { size_t const cSize =
21965  ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock);
21966  if (cSize != ERROR(dstSize_tooSmall)) {
21967  size_t const maxCSize =
21968  srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy);
21969  FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed");
21970  if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) {
21972  return cSize;
21973  }
21974  }
21975  }
21976  } /* if (bss == ZSTDbss_compress)*/
21977 
21978  DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()");
21979  /* Superblock compression failed, attempt to emit a single no compress block.
21980  * The decoder will be able to stream this block since it is uncompressed.
21981  */
21982  return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
21983 }
21984 
21986  void* dst, size_t dstCapacity,
21987  const void* src, size_t srcSize,
21988  U32 lastBlock)
21989 {
21990  size_t cSize = 0;
21991  const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
21992  DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)",
21993  (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize);
21994  FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
21995 
21996  cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock);
21997  FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed");
21998 
22001 
22002  return cSize;
22003 }
22004 
22006  ZSTD_cwksp* ws,
22007  ZSTD_CCtx_params const* params,
22008  void const* ip,
22009  void const* iend)
22010 {
22011  U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy);
22012  U32 const maxDist = (U32)1 << params->cParams.windowLog;
22013  if (ZSTD_window_needOverflowCorrection(ms->window, cycleLog, maxDist, ms->loadedDictEnd, ip, iend)) {
22014  U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
22015  ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
22016  ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
22017  ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
22019  ZSTD_reduceIndex(ms, params, correction);
22021  if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
22022  else ms->nextToUpdate -= correction;
22023  /* invalidate dictionaries on overflow correction */
22024  ms->loadedDictEnd = 0;
22025  ms->dictMatchState = NULL;
22026  }
22027 }
22028 
22036 static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
22037  void* dst, size_t dstCapacity,
22038  const void* src, size_t srcSize,
22039  U32 lastFrameChunk)
22040 {
22041  size_t blockSize = cctx->blockSize;
22042  size_t remaining = srcSize;
22043  const BYTE* ip = (const BYTE*)src;
22044  BYTE* const ostart = (BYTE*)dst;
22045  BYTE* op = ostart;
22046  U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
22047 
22048  assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
22049 
22050  DEBUGLOG(4, "ZSTD_compress_frameChunk (blockSize=%u)", (unsigned)blockSize);
22051  if (cctx->appliedParams.fParams.checksumFlag && srcSize)
22052  XXH64_update(&cctx->xxhState, src, srcSize);
22053 
22054  while (remaining) {
22055  ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
22056  U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
22057 
22058  /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
22059  * additional 1. We need to revisit and change this logic to be more consistent */
22061  dstSize_tooSmall,
22062  "not enough space to store compressed block");
22063  if (remaining < blockSize) blockSize = remaining;
22064 
22066  ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
22067  ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
22068  ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
22069 
22070  /* Ensure hash/chain table insertion resumes no sooner than lowlimit */
22071  if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
22072 
22073  { size_t cSize;
22075  cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock);
22076  FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed");
22077  assert(cSize > 0);
22078  assert(cSize <= blockSize + ZSTD_blockHeaderSize);
22079  } else if (ZSTD_blockSplitterEnabled(&cctx->appliedParams)) {
22080  cSize = ZSTD_compressBlock_splitBlock(cctx, op, dstCapacity, ip, blockSize, lastBlock);
22081  FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_splitBlock failed");
22082  assert(cSize > 0 || cctx->seqCollector.collectSequences == 1);
22083  } else {
22084  cSize = ZSTD_compressBlock_internal(cctx,
22086  ip, blockSize, 1 /* frame */);
22087  FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed");
22088 
22089  if (cSize == 0) { /* block is not compressible */
22090  cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
22091  FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
22092  } else {
22093  U32 const cBlockHeader = cSize == 1 ?
22094  lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
22095  lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
22096  MEM_writeLE24(op, cBlockHeader);
22097  cSize += ZSTD_blockHeaderSize;
22098  }
22099  } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/
22100 
22101 
22102  ip += blockSize;
22103  assert(remaining >= blockSize);
22104  remaining -= blockSize;
22105  op += cSize;
22106  assert(dstCapacity >= cSize);
22107  dstCapacity -= cSize;
22108  cctx->isFirstBlock = 0;
22109  DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
22110  (unsigned)cSize);
22111  } }
22113  if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
22114  return (size_t)(op-ostart);
22115 }
22116 
22117 
22118 static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
22119  const ZSTD_CCtx_params* params, U64 pledgedSrcSize, U32 dictID)
22120 { BYTE* const op = (BYTE*)dst;
22121  U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
22122  U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
22123  U32 const checksumFlag = params->fParams.checksumFlag>0;
22124  U32 const windowSize = (U32)1 << params->cParams.windowLog;
22125  U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
22126  BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
22127  U32 const fcsCode = params->fParams.contentSizeFlag ?
22128  (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */
22129  BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
22130  size_t pos=0;
22131 
22132  assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
22133  RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall,
22134  "dst buf is too small to fit worst-case frame header size.");
22135  DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
22136  !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
22137  if (params->format == ZSTD_f_zstd1) {
22139  pos = 4;
22140  }
22141  op[pos++] = frameHeaderDescriptionByte;
22142  if (!singleSegment) op[pos++] = windowLogByte;
22143  switch(dictIDSizeCode)
22144  {
22145  default:
22146  assert(0); /* impossible */
22148  case 0 : break;
22149  case 1 : op[pos] = (BYTE)(dictID); pos++; break;
22150  case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
22151  case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
22152  }
22153  switch(fcsCode)
22154  {
22155  default:
22156  assert(0); /* impossible */
22158  case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
22159  case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
22160  case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
22161  case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
22162  }
22163  return pos;
22164 }
22165 
22166 /* ZSTD_writeSkippableFrame_advanced() :
22167  * Writes out a skippable frame with the specified magic number variant (16 are supported),
22168  * from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15, and the desired source data.
22169  *
22170  * Returns the total number of bytes written, or a ZSTD error code.
22171  */
22172 size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
22173  const void* src, size_t srcSize, unsigned magicVariant) {
22174  BYTE* op = (BYTE*)dst;
22175  RETURN_ERROR_IF(dstCapacity < srcSize + ZSTD_SKIPPABLEHEADERSIZE /* Skippable frame overhead */,
22176  dstSize_tooSmall, "Not enough room for skippable frame");
22177  RETURN_ERROR_IF(srcSize > (unsigned)0xFFFFFFFF, srcSize_wrong, "Src size too large for skippable frame");
22178  RETURN_ERROR_IF(magicVariant > 15, parameter_outOfBound, "Skippable frame magic number variant not supported");
22179 
22180  MEM_writeLE32(op, (U32)(ZSTD_MAGIC_SKIPPABLE_START + magicVariant));
22181  MEM_writeLE32(op+4, (U32)srcSize);
22182  ZSTD_memcpy(op+8, src, srcSize);
22183  return srcSize + ZSTD_SKIPPABLEHEADERSIZE;
22184 }
22186 /* ZSTD_writeLastEmptyBlock() :
22187  * output an empty Block with end-of-frame mark to complete a frame
22188  * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
22189  * or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)
22190  */
22191 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
22192 {
22193  RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall,
22194  "dst buf is too small to write frame trailer empty block.");
22195  { U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1); /* 0 size */
22196  MEM_writeLE24(dst, cBlockHeader24);
22197  return ZSTD_blockHeaderSize;
22198  }
22199 }
22200 
22201 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
22202 {
22203  RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong,
22204  "wrong cctx stage");
22205  RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable,
22206  parameter_unsupported,
22207  "incompatible with ldm");
22208  cctx->externSeqStore.seq = seq;
22209  cctx->externSeqStore.size = nbSeq;
22210  cctx->externSeqStore.capacity = nbSeq;
22211  cctx->externSeqStore.pos = 0;
22212  cctx->externSeqStore.posInSequence = 0;
22213  return 0;
22214 }
22215 
22216 
22217 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
22218  void* dst, size_t dstCapacity,
22219  const void* src, size_t srcSize,
22220  U32 frame, U32 lastFrameChunk)
22221 {
22222  ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
22223  size_t fhSize = 0;
22224 
22225  DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
22226  cctx->stage, (unsigned)srcSize);
22227  RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong,
22228  "missing init (ZSTD_compressBegin)");
22229 
22230  if (frame && (cctx->stage==ZSTDcs_init)) {
22231  fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
22232  cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
22233  FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
22234  assert(fhSize <= dstCapacity);
22235  dstCapacity -= fhSize;
22236  dst = (char*)dst + fhSize;
22237  cctx->stage = ZSTDcs_ongoing;
22238  }
22239 
22240  if (!srcSize) return fhSize; /* do not generate an empty block if no input */
22241 
22242  if (!ZSTD_window_update(&ms->window, src, srcSize, ms->forceNonContiguous)) {
22243  ms->forceNonContiguous = 0;
22244  ms->nextToUpdate = ms->window.dictLimit;
22245  }
22246  if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
22247  ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0);
22248  }
22249 
22250  if (!frame) {
22251  /* overflow check and correction for block mode */
22253  ms, &cctx->workspace, &cctx->appliedParams,
22254  src, (BYTE const*)src + srcSize);
22255  }
22256 
22257  DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
22258  { size_t const cSize = frame ?
22259  ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
22260  ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
22261  FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed");
22262  cctx->consumedSrcSize += srcSize;
22263  cctx->producedCSize += (cSize + fhSize);
22264  assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
22265  if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
22266  ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
22268  cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne,
22269  srcSize_wrong,
22270  "error : pledgedSrcSize = %u, while realSrcSize >= %u",
22271  (unsigned)cctx->pledgedSrcSizePlusOne-1,
22272  (unsigned)cctx->consumedSrcSize);
22273  }
22274  return cSize + fhSize;
22275  }
22276 }
22277 
22279  void* dst, size_t dstCapacity,
22280  const void* src, size_t srcSize)
22282  DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize);
22283  return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
22284 }
22285 
22286 /* NOTE: Must just wrap ZSTD_compressContinue_public() */
22287 size_t ZSTD_compressContinue(ZSTD_CCtx* cctx,
22288  void* dst, size_t dstCapacity,
22289  const void* src, size_t srcSize)
22290 {
22291  return ZSTD_compressContinue_public(cctx, dst, dstCapacity, src, srcSize);
22292 }
22293 
22294 static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx)
22295 {
22296  ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams;
22297  assert(!ZSTD_checkCParams(cParams));
22298  return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog);
22299 }
22300 
22301 /* NOTE: Must just wrap ZSTD_getBlockSize_deprecated() */
22302 size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
22303 {
22304  return ZSTD_getBlockSize_deprecated(cctx);
22305 }
22306 
22307 /* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */
22308 size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
22309 {
22310  DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
22311  { size_t const blockSizeMax = ZSTD_getBlockSize_deprecated(cctx);
22312  RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); }
22313 
22314  return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
22315 }
22316 
22317 /* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */
22318 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
22319 {
22320  return ZSTD_compressBlock_deprecated(cctx, dst, dstCapacity, src, srcSize);
22321 }
22322 
22327  ldmState_t* ls,
22328  ZSTD_cwksp* ws,
22329  ZSTD_CCtx_params const* params,
22330  const void* src, size_t srcSize,
22333 {
22334  const BYTE* ip = (const BYTE*) src;
22335  const BYTE* const iend = ip + srcSize;
22336  int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL;
22337 
22338  /* Assert that the ms params match the params we're being given */
22339  ZSTD_assertEqualCParams(params->cParams, ms->cParams);
22340 
22341  { /* Ensure large dictionaries can't cause index overflow */
22342 
22343  /* Allow the dictionary to set indices up to exactly ZSTD_CURRENT_MAX.
22344  * Dictionaries right at the edge will immediately trigger overflow
22345  * correction, but I don't want to insert extra constraints here.
22346  */
22348 
22349  int const CDictTaggedIndices = ZSTD_CDictIndicesAreTagged(&params->cParams);
22350  if (CDictTaggedIndices && tfp == ZSTD_tfp_forCDict) {
22351  /* Some dictionary matchfinders in zstd use "short cache",
22352  * which treats the lower ZSTD_SHORT_CACHE_TAG_BITS of each
22353  * CDict hashtable entry as a tag rather than as part of an index.
22354  * When short cache is used, we need to truncate the dictionary
22355  * so that its indices don't overlap with the tag. */
22356  U32 const shortCacheMaxDictSize = (1u << (32 - ZSTD_SHORT_CACHE_TAG_BITS)) - ZSTD_WINDOW_START_INDEX;
22357  maxDictSize = MIN(maxDictSize, shortCacheMaxDictSize);
22358  assert(!loadLdmDict);
22359  }
22360 
22361  /* If the dictionary is too large, only load the suffix of the dictionary. */
22362  if (srcSize > maxDictSize) {
22363  ip = iend - maxDictSize;
22364  src = ip;
22365  srcSize = maxDictSize;
22366  }
22367  }
22368 
22369  if (srcSize > ZSTD_CHUNKSIZE_MAX) {
22370  /* We must have cleared our windows when our source is this large. */
22372  if (loadLdmDict) assert(ZSTD_window_isEmpty(ls->window));
22373  }
22374  ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0);
22375 
22376  DEBUGLOG(4, "ZSTD_loadDictionaryContent(): useRowMatchFinder=%d", (int)params->useRowMatchFinder);
22377 
22378  if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */
22379  ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0);
22380  ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
22381  ZSTD_ldm_fillHashTable(ls, ip, iend, &params->ldmParams);
22382  }
22383 
22384  /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */
22385  if (params->cParams.strategy < ZSTD_btultra) {
22386  U32 maxDictSize = 8U << MIN(MAX(params->cParams.hashLog, params->cParams.chainLog), 28);
22387  if (srcSize > maxDictSize) {
22388  ip = iend - maxDictSize;
22389  src = ip;
22390  srcSize = maxDictSize;
22391  }
22392  }
22393 
22394  ms->nextToUpdate = (U32)(ip - ms->window.base);
22395  ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
22396  ms->forceNonContiguous = params->deterministicRefPrefix;
22397 
22398  if (srcSize <= HASH_READ_SIZE) return 0;
22399 
22400  ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend);
22401 
22402  switch(params->cParams.strategy)
22403  {
22404  case ZSTD_fast:
22405  ZSTD_fillHashTable(ms, iend, dtlm, tfp);
22406  break;
22407  case ZSTD_dfast:
22408  ZSTD_fillDoubleHashTable(ms, iend, dtlm, tfp);
22409  break;
22410 
22411  case ZSTD_greedy:
22412  case ZSTD_lazy:
22413  case ZSTD_lazy2:
22415  if (ms->dedicatedDictSearch) {
22416  assert(ms->chainTable != NULL);
22418  } else {
22419  assert(params->useRowMatchFinder != ZSTD_ps_auto);
22420  if (params->useRowMatchFinder == ZSTD_ps_enable) {
22421  size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog);
22422  ZSTD_memset(ms->tagTable, 0, tagTableSize);
22423  ZSTD_row_update(ms, iend-HASH_READ_SIZE);
22424  DEBUGLOG(4, "Using row-based hash table for lazy dict");
22425  } else {
22427  DEBUGLOG(4, "Using chain-based hash table for lazy dict");
22428  }
22429  }
22430  break;
22431 
22432  case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
22433  case ZSTD_btopt:
22434  case ZSTD_btultra:
22435  case ZSTD_btultra2:
22437  ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
22438  break;
22439 
22440  default:
22441  assert(0); /* not possible : not a valid strategy id */
22442  }
22443 
22444  ms->nextToUpdate = (U32)(iend - ms->window.base);
22445  return 0;
22446 }
22448 
22449 /* Dictionaries that assign zero probability to symbols that show up causes problems
22450  * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check
22451  * and only dictionaries with 100% valid symbols can be assumed valid.
22452  */
22453 static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue)
22454 {
22455  U32 s;
22456  if (dictMaxSymbolValue < maxSymbolValue) {
22457  return FSE_repeat_check;
22458  }
22459  for (s = 0; s <= maxSymbolValue; ++s) {
22460  if (normalizedCounter[s] == 0) {
22462  }
22463  }
22464  return FSE_repeat_valid;
22465 }
22466 
22467 size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
22468  const void* const dict, size_t dictSize)
22469 {
22470  short offcodeNCount[MaxOff+1];
22471  unsigned offcodeMaxValue = MaxOff;
22472  const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */
22473  const BYTE* const dictEnd = dictPtr + dictSize;
22474  dictPtr += 8;
22476 
22477  { unsigned maxSymbolValue = 255;
22478  unsigned hasZeroWeights = 1;
22479  size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
22480  dictEnd-dictPtr, &hasZeroWeights);
22481 
22482  /* We only set the loaded table as valid if it contains all non-zero
22483  * weights. Otherwise, we set it to check */
22484  if (!hasZeroWeights)
22486 
22487  RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, "");
22488  RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted, "");
22489  dictPtr += hufHeaderSize;
22490  }
22491 
22492  { unsigned offcodeLog;
22493  size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
22494  RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
22495  RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
22496  /* fill all offset symbols to avoid garbage at end of table */
22499  offcodeNCount, MaxOff, offcodeLog,
22500  workspace, HUF_WORKSPACE_SIZE)),
22501  dictionary_corrupted, "");
22502  /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
22503  dictPtr += offcodeHeaderSize;
22504  }
22505 
22506  { short matchlengthNCount[MaxML+1];
22507  unsigned matchlengthMaxValue = MaxML, matchlengthLog;
22508  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
22509  RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
22510  RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
22513  matchlengthNCount, matchlengthMaxValue, matchlengthLog,
22514  workspace, HUF_WORKSPACE_SIZE)),
22515  dictionary_corrupted, "");
22516  bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML);
22517  dictPtr += matchlengthHeaderSize;
22518  }
22519 
22520  { short litlengthNCount[MaxLL+1];
22521  unsigned litlengthMaxValue = MaxLL, litlengthLog;
22522  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
22523  RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
22524  RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
22527  litlengthNCount, litlengthMaxValue, litlengthLog,
22528  workspace, HUF_WORKSPACE_SIZE)),
22529  dictionary_corrupted, "");
22530  bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL);
22531  dictPtr += litlengthHeaderSize;
22532  }
22533 
22534  RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
22535  bs->rep[0] = MEM_readLE32(dictPtr+0);
22536  bs->rep[1] = MEM_readLE32(dictPtr+4);
22537  bs->rep[2] = MEM_readLE32(dictPtr+8);
22538  dictPtr += 12;
22539 
22540  { size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
22541  U32 offcodeMax = MaxOff;
22542  if (dictContentSize <= ((U32)-1) - 128 KB) {
22543  U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
22544  offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
22545  }
22546  /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */
22547  bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff));
22548 
22549  /* All repCodes must be <= dictContentSize and != 0 */
22550  { U32 u;
22551  for (u=0; u<3; u++) {
22552  RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, "");
22553  RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
22554  } } }
22555 
22556  return dictPtr - (const BYTE*)dict;
22557 }
22558 
22559 /* Dictionary format :
22560  * See :
22561  * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format
22562  */
22569  ZSTD_matchState_t* ms,
22570  ZSTD_cwksp* ws,
22571  ZSTD_CCtx_params const* params,
22572  const void* dict, size_t dictSize,
22575  void* workspace)
22576 {
22577  const BYTE* dictPtr = (const BYTE*)dict;
22578  const BYTE* const dictEnd = dictPtr + dictSize;
22579  size_t dictID;
22580  size_t eSize;
22582  assert(dictSize >= 8);
22584 
22585  dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ );
22586  eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize);
22587  FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed");
22588  dictPtr += eSize;
22589 
22590  {
22591  size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
22593  ms, NULL, ws, params, dictPtr, dictContentSize, dtlm, tfp), "");
22594  }
22595  return dictID;
22596 }
22597 
22600 static size_t
22602  ZSTD_matchState_t* ms,
22603  ldmState_t* ls,
22604  ZSTD_cwksp* ws,
22605  const ZSTD_CCtx_params* params,
22606  const void* dict, size_t dictSize,
22607  ZSTD_dictContentType_e dictContentType,
22610  void* workspace)
22611 {
22612  DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
22613  if ((dict==NULL) || (dictSize<8)) {
22614  RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
22615  return 0;
22616  }
22617 
22619 
22620  /* dict restricted modes */
22621  if (dictContentType == ZSTD_dct_rawContent)
22622  return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm, tfp);
22623 
22624  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
22625  if (dictContentType == ZSTD_dct_auto) {
22626  DEBUGLOG(4, "raw content dictionary detected");
22628  ms, ls, ws, params, dict, dictSize, dtlm, tfp);
22629  }
22630  RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, "");
22631  assert(0); /* impossible */
22632  }
22634  /* dict as full zstd dictionary */
22635  return ZSTD_loadZstdDictionary(
22636  bs, ms, ws, params, dict, dictSize, dtlm, tfp, workspace);
22637 }
22638 
22639 #define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB)
22640 #define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL)
22641 
22645 static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
22646  const void* dict, size_t dictSize,
22647  ZSTD_dictContentType_e dictContentType,
22649  const ZSTD_CDict* cdict,
22650  const ZSTD_CCtx_params* params, U64 pledgedSrcSize,
22651  ZSTD_buffered_policy_e zbuff)
22652 {
22653  size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize;
22654 #if ZSTD_TRACE
22655  cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0;
22656 #endif
22657  DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog);
22658  /* params are supposed to be fully validated at this point */
22659  assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
22660  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
22661  if ( (cdict)
22662  && (cdict->dictContentSize > 0)
22663  && ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
22664  || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
22665  || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
22666  || cdict->compressionLevel == 0)
22667  && (params->attachDictPref != ZSTD_dictForceLoad) ) {
22668  return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
22669  }
22670 
22671  FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
22672  dictContentSize,
22673  ZSTDcrp_makeClean, zbuff) , "");
22674  { size_t const dictID = cdict ?
22677  &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
22678  cdict->dictContentSize, cdict->dictContentType, dtlm,
22682  &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
22683  dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->entropyWorkspace);
22684  FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
22685  assert(dictID <= UINT_MAX);
22686  cctx->dictID = (U32)dictID;
22687  cctx->dictContentSize = dictContentSize;
22688  }
22689  return 0;
22690 }
22691 
22693  const void* dict, size_t dictSize,
22694  ZSTD_dictContentType_e dictContentType,
22696  const ZSTD_CDict* cdict,
22697  const ZSTD_CCtx_params* params,
22698  unsigned long long pledgedSrcSize)
22699 {
22700  DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog);
22701  /* compression parameters verification and optimization */
22702  FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , "");
22703  return ZSTD_compressBegin_internal(cctx,
22704  dict, dictSize, dictContentType, dtlm,
22705  cdict,
22706  params, pledgedSrcSize,
22708 }
22709 
22713  const void* dict, size_t dictSize,
22714  ZSTD_parameters params, unsigned long long pledgedSrcSize)
22715 {
22716  ZSTD_CCtx_params cctxParams;
22717  ZSTD_CCtxParams_init_internal(&cctxParams, &params, ZSTD_NO_CLEVEL);
22719  dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
22720  NULL /*cdict*/,
22721  &cctxParams, pledgedSrcSize);
22722 }
22723 
22724 static size_t
22725 ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
22726 {
22727  ZSTD_CCtx_params cctxParams;
22728  { ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict);
22730  }
22731  DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
22732  return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
22734 }
22735 
22736 size_t
22737 ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
22738 {
22739  return ZSTD_compressBegin_usingDict_deprecated(cctx, dict, dictSize, compressionLevel);
22740 }
22741 
22743 {
22746 
22747 
22751 static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
22752 {
22753  BYTE* const ostart = (BYTE*)dst;
22754  BYTE* op = ostart;
22755  size_t fhSize = 0;
22756 
22757  DEBUGLOG(4, "ZSTD_writeEpilogue");
22758  RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing");
22759 
22760  /* special case : empty frame */
22761  if (cctx->stage == ZSTDcs_init) {
22762  fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
22763  FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed");
22764  dstCapacity -= fhSize;
22765  op += fhSize;
22766  cctx->stage = ZSTDcs_ongoing;
22767  }
22768 
22769  if (cctx->stage != ZSTDcs_ending) {
22770  /* write one last empty block, make it the "last" block */
22771  U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
22772  RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for epilogue");
22773  MEM_writeLE32(op, cBlockHeader24);
22775  dstCapacity -= ZSTD_blockHeaderSize;
22776  }
22777 
22778  if (cctx->appliedParams.fParams.checksumFlag) {
22779  U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
22780  RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
22781  DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum);
22782  MEM_writeLE32(op, checksum);
22783  op += 4;
22784  }
22785 
22786  cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
22787  return op-ostart;
22788 }
22789 
22790 void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
22791 {
22792 #if ZSTD_TRACE
22793  if (cctx->traceCtx && ZSTD_trace_compress_end != NULL) {
22794  int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0;
22795  ZSTD_Trace trace;
22796  ZSTD_memset(&trace, 0, sizeof(trace));
22797  trace.version = ZSTD_VERSION_NUMBER;
22798  trace.streaming = streaming;
22799  trace.dictionaryID = cctx->dictID;
22800  trace.dictionarySize = cctx->dictContentSize;
22801  trace.uncompressedSize = cctx->consumedSrcSize;
22802  trace.compressedSize = cctx->producedCSize + extraCSize;
22803  trace.params = &cctx->appliedParams;
22804  trace.cctx = cctx;
22805  ZSTD_trace_compress_end(cctx->traceCtx, &trace);
22806  }
22807  cctx->traceCtx = 0;
22808 #else
22809  (void)cctx;
22810  (void)extraCSize;
22811 #endif
22812 }
22813 
22814 size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx,
22815  void* dst, size_t dstCapacity,
22816  const void* src, size_t srcSize)
22817 {
22818  size_t endResult;
22819  size_t const cSize = ZSTD_compressContinue_internal(cctx,
22820  dst, dstCapacity, src, srcSize,
22821  1 /* frame mode */, 1 /* last chunk */);
22822  FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed");
22823  endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
22824  FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed");
22825  assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
22826  if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
22827  ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
22828  DEBUGLOG(4, "end of frame : controlling src size");
22830  cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1,
22831  srcSize_wrong,
22832  "error : pledgedSrcSize = %u, while realSrcSize = %u",
22833  (unsigned)cctx->pledgedSrcSizePlusOne-1,
22834  (unsigned)cctx->consumedSrcSize);
22835  }
22836  ZSTD_CCtx_trace(cctx, endResult);
22837  return cSize + endResult;
22838 }
22839 
22840 /* NOTE: Must just wrap ZSTD_compressEnd_public() */
22841 size_t ZSTD_compressEnd(ZSTD_CCtx* cctx,
22842  void* dst, size_t dstCapacity,
22843  const void* src, size_t srcSize)
22844 {
22845  return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize);
22846 }
22847 
22848 size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
22849  void* dst, size_t dstCapacity,
22850  const void* src, size_t srcSize,
22851  const void* dict,size_t dictSize,
22852  ZSTD_parameters params)
22853 {
22854  DEBUGLOG(4, "ZSTD_compress_advanced");
22855  FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), "");
22857  return ZSTD_compress_advanced_internal(cctx,
22858  dst, dstCapacity,
22859  src, srcSize,
22860  dict, dictSize,
22861  &cctx->simpleApiParams);
22862 }
22863 
22864 /* Internal */
22866  ZSTD_CCtx* cctx,
22867  void* dst, size_t dstCapacity,
22868  const void* src, size_t srcSize,
22869  const void* dict,size_t dictSize,
22870  const ZSTD_CCtx_params* params)
22871 {
22872  DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
22874  dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
22875  params, srcSize, ZSTDb_not_buffered) , "");
22876  return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize);
22877 }
22878 
22879 size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
22880  void* dst, size_t dstCapacity,
22881  const void* src, size_t srcSize,
22882  const void* dict, size_t dictSize,
22883  int compressionLevel)
22884 {
22885  {
22886  ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict);
22887  assert(params.fParams.contentSizeFlag == 1);
22889  }
22890  DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize);
22891  return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctx->simpleApiParams);
22892 }
22893 
22894 size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
22895  void* dst, size_t dstCapacity,
22896  const void* src, size_t srcSize,
22897  int compressionLevel)
22899  DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (unsigned)srcSize);
22900  assert(cctx != NULL);
22901  return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
22902 }
22903 
22904 size_t ZSTD_compress(void* dst, size_t dstCapacity,
22905  const void* src, size_t srcSize,
22906  int compressionLevel)
22907 {
22908  size_t result;
22909 #if ZSTD_COMPRESS_HEAPMODE
22910  ZSTD_CCtx* cctx = ZSTD_createCCtx();
22911  RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed");
22912  result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel);
22913  ZSTD_freeCCtx(cctx);
22914 #else
22915  ZSTD_CCtx ctxBody;
22916  ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
22917  result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
22918  ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */
22919 #endif
22920  return result;
22921 }
22923 
22924 /* ===== Dictionary API ===== */
22925 
22929  size_t dictSize, ZSTD_compressionParameters cParams,
22930  ZSTD_dictLoadMethod_e dictLoadMethod)
22931 {
22932  DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict));
22933  return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
22935  /* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small
22936  * in case we are using DDS with row-hash. */
22937  + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams),
22938  /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0)
22939  + (dictLoadMethod == ZSTD_dlm_byRef ? 0
22940  : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *))));
22941 }
22942 
22943 size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
22944 {
22945  ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
22946  return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
22947 }
22948 
22949 size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
22950 {
22951  if (cdict==NULL) return 0; /* support sizeof on NULL */
22952  DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict));
22953  /* cdict may be in the workspace */
22954  return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict))
22955  + ZSTD_cwksp_sizeof(&cdict->workspace);
22956 }
22957 
22958 static size_t ZSTD_initCDict_internal(
22959  ZSTD_CDict* cdict,
22960  const void* dictBuffer, size_t dictSize,
22961  ZSTD_dictLoadMethod_e dictLoadMethod,
22962  ZSTD_dictContentType_e dictContentType,
22963  ZSTD_CCtx_params params)
22964 {
22965  DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType);
22966  assert(!ZSTD_checkCParams(params.cParams));
22967  cdict->matchState.cParams = params.cParams;
22968  cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch;
22969  if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
22970  cdict->dictContent = dictBuffer;
22971  } else {
22972  void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
22973  RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!");
22974  cdict->dictContent = internalBuffer;
22975  ZSTD_memcpy(internalBuffer, dictBuffer, dictSize);
22976  }
22977  cdict->dictContentSize = dictSize;
22978  cdict->dictContentType = dictContentType;
22979 
22981 
22982 
22983  /* Reset the state to no dictionary */
22986  &cdict->matchState,
22987  &cdict->workspace,
22988  &params.cParams,
22989  params.useRowMatchFinder,
22991  ZSTDirp_reset,
22992  ZSTD_resetTarget_CDict), "");
22993  /* (Maybe) load the dictionary
22994  * Skips loading the dictionary if it is < 8 bytes.
22995  */
22996  { params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
22997  params.fParams.contentSizeFlag = 1;
22998  { size_t const dictID = ZSTD_compress_insertDictionary(
22999  &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace,
23000  &params, cdict->dictContent, cdict->dictContentSize,
23001  dictContentType, ZSTD_dtlm_full, ZSTD_tfp_forCDict, cdict->entropyWorkspace);
23002  FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
23003  assert(dictID <= (size_t)(U32)-1);
23004  cdict->dictID = (U32)dictID;
23005  }
23006  }
23007 
23008  return 0;
23009 }
23010 
23011 static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize,
23012  ZSTD_dictLoadMethod_e dictLoadMethod,
23013  ZSTD_compressionParameters cParams,
23014  ZSTD_paramSwitch_e useRowMatchFinder,
23015  U32 enableDedicatedDictSearch,
23016  ZSTD_customMem customMem)
23017 {
23018  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
23019 
23020  { size_t const workspaceSize =
23023  ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, enableDedicatedDictSearch, /* forCCtx */ 0) +
23024  (dictLoadMethod == ZSTD_dlm_byRef ? 0
23025  : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));
23026  void* const workspace = ZSTD_customMalloc(workspaceSize, customMem);
23027  ZSTD_cwksp ws;
23028  ZSTD_CDict* cdict;
23029 
23030  if (!workspace) {
23031  ZSTD_customFree(workspace, customMem);
23032  return NULL;
23033  }
23034 
23035  ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc);
23036 
23037  cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
23038  assert(cdict != NULL);
23039  ZSTD_cwksp_move(&cdict->workspace, &ws);
23040  cdict->customMem = customMem;
23041  cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */
23042  cdict->useRowMatchFinder = useRowMatchFinder;
23043  return cdict;
23044  }
23045 }
23046 
23047 ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
23048  ZSTD_dictLoadMethod_e dictLoadMethod,
23049  ZSTD_dictContentType_e dictContentType,
23050  ZSTD_compressionParameters cParams,
23051  ZSTD_customMem customMem)
23052 {
23053  ZSTD_CCtx_params cctxParams;
23054  ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
23055  ZSTD_CCtxParams_init(&cctxParams, 0);
23056  cctxParams.cParams = cParams;
23057  cctxParams.customMem = customMem;
23059  dictBuffer, dictSize,
23060  dictLoadMethod, dictContentType,
23061  &cctxParams, customMem);
23062 }
23063 
23065  const void* dict, size_t dictSize,
23066  ZSTD_dictLoadMethod_e dictLoadMethod,
23067  ZSTD_dictContentType_e dictContentType,
23068  const ZSTD_CCtx_params* originalCctxParams,
23069  ZSTD_customMem customMem)
23070 {
23071  ZSTD_CCtx_params cctxParams = *originalCctxParams;
23072  ZSTD_compressionParameters cParams;
23073  ZSTD_CDict* cdict;
23074 
23075  DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode %u", (unsigned)dictContentType);
23076  if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
23077 
23078  if (cctxParams.enableDedicatedDictSearch) {
23080  cctxParams.compressionLevel, dictSize);
23081  ZSTD_overrideCParams(&cParams, &cctxParams.cParams);
23082  } else {
23084  &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
23085  }
23086 
23087  if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) {
23088  /* Fall back to non-DDSS params */
23089  cctxParams.enableDedicatedDictSearch = 0;
23091  &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
23092  }
23093 
23094  DEBUGLOG(3, "ZSTD_createCDict_advanced2: DDS: %u", cctxParams.enableDedicatedDictSearch);
23095  cctxParams.cParams = cParams;
23096  cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
23097 
23098  cdict = ZSTD_createCDict_advanced_internal(dictSize,
23099  dictLoadMethod, cctxParams.cParams,
23100  cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch,
23101  customMem);
23102 
23104  dict, dictSize,
23105  dictLoadMethod, dictContentType,
23106  cctxParams) )) {
23107  ZSTD_freeCDict(cdict);
23108  return NULL;
23109  }
23110 
23111  return cdict;
23112 }
23113 
23114 ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
23115 {
23116  ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
23117  ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
23118  ZSTD_dlm_byCopy, ZSTD_dct_auto,
23119  cParams, ZSTD_defaultCMem);
23120  if (cdict)
23122  return cdict;
23123 }
23124 
23125 ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
23126 {
23127  ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
23128  ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize,
23129  ZSTD_dlm_byRef, ZSTD_dct_auto,
23130  cParams, ZSTD_defaultCMem);
23131  if (cdict)
23133  return cdict;
23134 }
23135 
23136 size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
23137 {
23138  if (cdict==NULL) return 0; /* support free on NULL */
23139  { ZSTD_customMem const cMem = cdict->customMem;
23140  int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict);
23141  ZSTD_cwksp_free(&cdict->workspace, cMem);
23142  if (!cdictInWorkspace) {
23143  ZSTD_customFree(cdict, cMem);
23144  }
23145  return 0;
23146  }
23147 }
23148 
23163  void* workspace, size_t workspaceSize,
23164  const void* dict, size_t dictSize,
23165  ZSTD_dictLoadMethod_e dictLoadMethod,
23166  ZSTD_dictContentType_e dictContentType,
23167  ZSTD_compressionParameters cParams)
23168 {
23169  ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
23170  /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
23171  size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
23172  size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
23173  + (dictLoadMethod == ZSTD_dlm_byRef ? 0
23174  : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))))
23176  + matchStateSize;
23177  ZSTD_CDict* cdict;
23178  ZSTD_CCtx_params params;
23179 
23180  if ((size_t)workspace & 7) return NULL; /* 8-aligned */
23181 
23182  {
23183  ZSTD_cwksp ws;
23184  ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc);
23185  cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
23186  if (cdict == NULL) return NULL;
23187  ZSTD_cwksp_move(&cdict->workspace, &ws);
23188  }
23189 
23190  DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
23191  (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
23192  if (workspaceSize < neededSize) return NULL;
23193 
23194  ZSTD_CCtxParams_init(&params, 0);
23195  params.cParams = cParams;
23196  params.useRowMatchFinder = useRowMatchFinder;
23197  cdict->useRowMatchFinder = useRowMatchFinder;
23199 
23201  dict, dictSize,
23202  dictLoadMethod, dictContentType,
23203  params) ))
23204  return NULL;
23205 
23206  return cdict;
23207 }
23208 
23209 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
23210 {
23211  assert(cdict != NULL);
23212  return cdict->matchState.cParams;
23214 
23219 unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict)
23220 {
23221  if (cdict==NULL) return 0;
23222  return cdict->dictID;
23223 }
23224 
23225 /* ZSTD_compressBegin_usingCDict_internal() :
23226  * Implementation of various ZSTD_compressBegin_usingCDict* functions.
23227  */
23229  ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
23230  ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
23231 {
23232  ZSTD_CCtx_params cctxParams;
23233  DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_internal");
23234  RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!");
23235  /* Initialize the cctxParams from the cdict */
23236  {
23237  ZSTD_parameters params;
23238  params.fParams = fParams;
23239  params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
23240  || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
23241  || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
23242  || cdict->compressionLevel == 0 ) ?
23245  pledgedSrcSize,
23246  cdict->dictContentSize);
23247  ZSTD_CCtxParams_init_internal(&cctxParams, &params, cdict->compressionLevel);
23248  }
23249  /* Increase window log to fit the entire dictionary and source if the
23250  * source size is known. Limit the increase to 19, which is the
23251  * window log for compression level 1 with the largest source size.
23252  */
23253  if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) {
23254  U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19);
23255  U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
23256  cctxParams.cParams.windowLog = MAX(cctxParams.cParams.windowLog, limitedSrcLog);
23257  }
23258  return ZSTD_compressBegin_internal(cctx,
23259  NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
23260  cdict,
23261  &cctxParams, pledgedSrcSize,
23264 
23265 
23266 /* ZSTD_compressBegin_usingCDict_advanced() :
23267  * This function is DEPRECATED.
23268  * cdict must be != NULL */
23270  ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
23271  ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
23273  return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, pledgedSrcSize);
23274 }
23275 
23276 /* ZSTD_compressBegin_usingCDict() :
23277  * cdict must be != NULL */
23279 {
23280  ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
23282 }
23283 
23284 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
23285 {
23287 }
23288 
23292 static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx,
23293  void* dst, size_t dstCapacity,
23294  const void* src, size_t srcSize,
23295  const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
23296 {
23297  FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */
23298  return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize);
23299 }
23300 
23305  void* dst, size_t dstCapacity,
23306  const void* src, size_t srcSize,
23307  const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
23308 {
23309  return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);
23310 }
23317 size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
23318  void* dst, size_t dstCapacity,
23319  const void* src, size_t srcSize,
23320  const ZSTD_CDict* cdict)
23321 {
23322  ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
23323  return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);
23324 }
23325 
23327 
23328 /* ******************************************************************
23329 * Streaming
23330 ********************************************************************/
23331 
23333 {
23334  DEBUGLOG(3, "ZSTD_createCStream");
23335  return ZSTD_createCStream_advanced(ZSTD_defaultCMem);
23336 }
23338 ZSTD_CStream* ZSTD_initStaticCStream(void *workspace, size_t workspaceSize)
23339 {
23340  return ZSTD_initStaticCCtx(workspace, workspaceSize);
23341 }
23343 ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
23344 { /* CStream and CCtx are now same object */
23345  return ZSTD_createCCtx_advanced(customMem);
23346 }
23347 
23348 size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
23349 {
23350  return ZSTD_freeCCtx(zcs); /* same object */
23352 
23354 
23355 /*====== Initialization ======*/
23356 
23357 size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX; }
23359 size_t ZSTD_CStreamOutSize(void)
23360 {
23361  return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
23362 }
23363 
23364 static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
23365 {
23366  if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
23367  return ZSTD_cpm_attachDict;
23368  else
23369  return ZSTD_cpm_noAttachDict;
23370 }
23371 
23372 /* ZSTD_resetCStream():
23373  * pledgedSrcSize == 0 means "unknown" */
23374 size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
23375 {
23376  /* temporary : 0 interpreted as "unknown" during transition period.
23377  * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN.
23378  * 0 will be interpreted as "empty" in the future.
23379  */
23380  U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
23381  DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (unsigned)pledgedSrcSize);
23383  FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
23384  return 0;
23386 
23392  const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
23393  const ZSTD_CCtx_params* params,
23394  unsigned long long pledgedSrcSize)
23395 {
23396  DEBUGLOG(4, "ZSTD_initCStream_internal");
23398  FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
23399  assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
23400  zcs->requestedParams = *params;
23401  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
23402  if (dict) {
23403  FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
23404  } else {
23405  /* Dictionary is cleared if !cdict */
23406  FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
23407  }
23408  return 0;
23409 }
23410 
23411 /* ZSTD_initCStream_usingCDict_advanced() :
23412  * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
23414  const ZSTD_CDict* cdict,
23415  ZSTD_frameParameters fParams,
23416  unsigned long long pledgedSrcSize)
23417 {
23418  DEBUGLOG(4, "ZSTD_initCStream_usingCDict_advanced");
23420  FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
23421  zcs->requestedParams.fParams = fParams;
23422  FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
23423  return 0;
23424 }
23425 
23426 /* note : cdict must outlive compression session */
23427 size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
23428 {
23429  DEBUGLOG(4, "ZSTD_initCStream_usingCDict");
23431  FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) , "");
23432  return 0;
23433 }
23435 
23436 /* ZSTD_initCStream_advanced() :
23437  * pledgedSrcSize must be exact.
23438  * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
23439  * dict is loaded with default parameters ZSTD_dct_auto and ZSTD_dlm_byCopy. */
23441  const void* dict, size_t dictSize,
23442  ZSTD_parameters params, unsigned long long pss)
23443 {
23444  /* for compatibility with older programs relying on this behavior.
23445  * Users should now specify ZSTD_CONTENTSIZE_UNKNOWN.
23446  * This line will be removed in the future.
23447  */
23448  U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
23449  DEBUGLOG(4, "ZSTD_initCStream_advanced");
23451  FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
23452  FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , "");
23454  FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
23455  return 0;
23456 }
23457 
23458 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
23459 {
23460  DEBUGLOG(4, "ZSTD_initCStream_usingDict");
23463  FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) , "");
23464  return 0;
23465 }
23466 
23467 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)
23468 {
23469  /* temporary : 0 interpreted as "unknown" during transition period.
23470  * Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN.
23471  * 0 will be interpreted as "empty" in the future.
23472  */
23473  U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;
23474  DEBUGLOG(4, "ZSTD_initCStream_srcSize");
23478  FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) , "");
23479  return 0;
23480 }
23481 
23483 {
23484  DEBUGLOG(4, "ZSTD_initCStream");
23486  FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) , "");
23488  return 0;
23489 }
23490 
23491 /*====== Compression ======*/
23492 
23493 static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
23494 {
23495  if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
23496  return cctx->blockSize - cctx->stableIn_notConsumed;
23497  }
23498  assert(cctx->appliedParams.inBufferMode == ZSTD_bm_buffered);
23499  { size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;
23500  if (hintInSize==0) hintInSize = cctx->blockSize;
23501  return hintInSize;
23502  }
23503 }
23504 
23508 static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
23510  ZSTD_inBuffer* input,
23511  ZSTD_EndDirective const flushMode)
23512 {
23513  const char* const istart = (assert(input != NULL), (const char*)input->src);
23514  const char* const iend = (istart != NULL) ? istart + input->size : istart;
23515  const char* ip = (istart != NULL) ? istart + input->pos : istart;
23516  char* const ostart = (assert(output != NULL), (char*)output->dst);
23517  char* const oend = (ostart != NULL) ? ostart + output->size : ostart;
23518  char* op = (ostart != NULL) ? ostart + output->pos : ostart;
23519  U32 someMoreWork = 1;
23520 
23521  /* check expectations */
23522  DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%i, srcSize = %zu", (int)flushMode, input->size - input->pos);
23523  assert(zcs != NULL);
23524  if (zcs->appliedParams.inBufferMode == ZSTD_bm_stable) {
23525  assert(input->pos >= zcs->stableIn_notConsumed);
23526  input->pos -= zcs->stableIn_notConsumed;
23527  ip -= zcs->stableIn_notConsumed;
23528  zcs->stableIn_notConsumed = 0;
23529  }
23530  if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
23531  assert(zcs->inBuff != NULL);
23532  assert(zcs->inBuffSize > 0);
23533  }
23534  if (zcs->appliedParams.outBufferMode == ZSTD_bm_buffered) {
23535  assert(zcs->outBuff != NULL);
23536  assert(zcs->outBuffSize > 0);
23537  }
23538  if (input->src == NULL) assert(input->size == 0);
23539  assert(input->pos <= input->size);
23540  if (output->dst == NULL) assert(output->size == 0);
23541  assert(output->pos <= output->size);
23542  assert((U32)flushMode <= (U32)ZSTD_e_end);
23543 
23544  while (someMoreWork) {
23545  switch(zcs->streamStage)
23546  {
23547  case zcss_init:
23548  RETURN_ERROR(init_missing, "call ZSTD_initCStream() first!");
23549 
23550  case zcss_load:
23551  if ( (flushMode == ZSTD_e_end)
23552  && ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip) /* Enough output space */
23553  || zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */
23554  && (zcs->inBuffPos == 0) ) {
23555  /* shortcut to compression pass directly into output buffer */
23556  size_t const cSize = ZSTD_compressEnd_public(zcs,
23557  op, oend-op, ip, iend-ip);
23558  DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
23559  FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
23560  ip = iend;
23561  op += cSize;
23562  zcs->frameEnded = 1;
23564  someMoreWork = 0; break;
23565  }
23566  /* complete loading into inBuffer in buffered mode */
23567  if (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered) {
23568  size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
23569  size_t const loaded = ZSTD_limitCopy(
23570  zcs->inBuff + zcs->inBuffPos, toLoad,
23571  ip, iend-ip);
23572  zcs->inBuffPos += loaded;
23573  if (ip) ip += loaded;
23574  if ( (flushMode == ZSTD_e_continue)
23575  && (zcs->inBuffPos < zcs->inBuffTarget) ) {
23576  /* not enough input to fill full block : stop here */
23577  someMoreWork = 0; break;
23578  }
23579  if ( (flushMode == ZSTD_e_flush)
23580  && (zcs->inBuffPos == zcs->inToCompress) ) {
23581  /* empty */
23582  someMoreWork = 0; break;
23583  }
23584  } else {
23585  assert(zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
23586  if ( (flushMode == ZSTD_e_continue)
23587  && ( (size_t)(iend - ip) < zcs->blockSize) ) {
23588  /* can't compress a full block : stop here */
23589  zcs->stableIn_notConsumed = (size_t)(iend - ip);
23590  ip = iend; /* pretend to have consumed input */
23591  someMoreWork = 0; break;
23592  }
23593  if ( (flushMode == ZSTD_e_flush)
23594  && (ip == iend) ) {
23595  /* empty */
23596  someMoreWork = 0; break;
23597  }
23598  }
23599  /* compress current block (note : this stage cannot be stopped in the middle) */
23600  DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode);
23601  { int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
23602  void* cDst;
23603  size_t cSize;
23604  size_t oSize = oend-op;
23605  size_t const iSize = inputBuffered ? zcs->inBuffPos - zcs->inToCompress
23606  : MIN((size_t)(iend - ip), zcs->blockSize);
23607  if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
23608  cDst = op; /* compress into output buffer, to skip flush stage */
23609  else
23610  cDst = zcs->outBuff, oSize = zcs->outBuffSize;
23611  if (inputBuffered) {
23612  unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);
23613  cSize = lastBlock ?
23614  ZSTD_compressEnd_public(zcs, cDst, oSize,
23615  zcs->inBuff + zcs->inToCompress, iSize) :
23616  ZSTD_compressContinue_public(zcs, cDst, oSize,
23617  zcs->inBuff + zcs->inToCompress, iSize);
23618  FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
23619  zcs->frameEnded = lastBlock;
23620  /* prepare next block */
23621  zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
23622  if (zcs->inBuffTarget > zcs->inBuffSize)
23623  zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
23624  DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
23625  (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
23626  if (!lastBlock)
23627  assert(zcs->inBuffTarget <= zcs->inBuffSize);
23628  zcs->inToCompress = zcs->inBuffPos;
23629  } else { /* !inputBuffered, hence ZSTD_bm_stable */
23630  unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip + iSize == iend);
23631  cSize = lastBlock ?
23632  ZSTD_compressEnd_public(zcs, cDst, oSize, ip, iSize) :
23633  ZSTD_compressContinue_public(zcs, cDst, oSize, ip, iSize);
23634  /* Consume the input prior to error checking to mirror buffered mode. */
23635  if (ip) ip += iSize;
23636  FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
23637  zcs->frameEnded = lastBlock;
23638  if (lastBlock) assert(ip == iend);
23639  }
23640  if (cDst == op) { /* no need to flush */
23641  op += cSize;
23642  if (zcs->frameEnded) {
23643  DEBUGLOG(5, "Frame completed directly in outBuffer");
23644  someMoreWork = 0;
23646  }
23647  break;
23648  }
23649  zcs->outBuffContentSize = cSize;
23650  zcs->outBuffFlushedSize = 0;
23651  zcs->streamStage = zcss_flush; /* pass-through to flush stage */
23652  }
23654  case zcss_flush:
23655  DEBUGLOG(5, "flush stage");
23656  assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
23657  { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
23658  size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),
23659  zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
23660  DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u",
23661  (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);
23662  if (flushed)
23663  op += flushed;
23664  zcs->outBuffFlushedSize += flushed;
23665  if (toFlush!=flushed) {
23666  /* flush not fully completed, presumably because dst is too small */
23667  assert(op==oend);
23668  someMoreWork = 0;
23669  break;
23670  }
23671  zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
23672  if (zcs->frameEnded) {
23673  DEBUGLOG(5, "Frame completed on flush");
23674  someMoreWork = 0;
23676  break;
23677  }
23678  zcs->streamStage = zcss_load;
23679  break;
23680  }
23681 
23682  default: /* impossible */
23683  assert(0);
23684  }
23685  }
23686 
23687  input->pos = ip - istart;
23688  output->pos = op - ostart;
23689  if (zcs->frameEnded) return 0;
23690  return ZSTD_nextInputSizeHint(zcs);
23691 }
23692 
23693 static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx)
23694 {
23695 #ifdef ZSTD_MULTITHREAD
23696  if (cctx->appliedParams.nbWorkers >= 1) {
23697  assert(cctx->mtctx != NULL);
23698  return ZSTDMT_nextInputSizeHint(cctx->mtctx);
23699  }
23700 #endif
23701  return ZSTD_nextInputSizeHint(cctx);
23702 
23703 }
23704 
23706 {
23708  return ZSTD_nextInputSizeHint_MTorST(zcs);
23710 
23711 /* After a compression call set the expected input/output buffer.
23712  * This is validated at the start of the next compression call.
23713  */
23714 static void
23716 {
23717  DEBUGLOG(5, "ZSTD_setBufferExpectations (for advanced stable in/out modes)");
23718  if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
23719  cctx->expectedInBuffer = *input;
23720  }
23721  if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
23722  cctx->expectedOutBufferSize = output->size - output->pos;
23723  }
23724 }
23725 
23726 /* Validate that the input/output buffers match the expectations set by
23727  * ZSTD_setBufferExpectations.
23728  */
23729 static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
23730  ZSTD_outBuffer const* output,
23731  ZSTD_inBuffer const* input,
23732  ZSTD_EndDirective endOp)
23733 {
23734  if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
23735  ZSTD_inBuffer const expect = cctx->expectedInBuffer;
23736  if (expect.src != input->src || expect.pos != input->pos)
23737  RETURN_ERROR(stabilityCondition_notRespected, "ZSTD_c_stableInBuffer enabled but input differs!");
23738  }
23739  (void)endOp;
23740  if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
23741  size_t const outBufferSize = output->size - output->pos;
23742  if (cctx->expectedOutBufferSize != outBufferSize)
23743  RETURN_ERROR(stabilityCondition_notRespected, "ZSTD_c_stableOutBuffer enabled but output size differs!");
23744  }
23745  return 0;
23746 }
23747 
23748 static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
23749  ZSTD_EndDirective endOp,
23750  size_t inSize)
23751 {
23752  ZSTD_CCtx_params params = cctx->requestedParams;
23753  ZSTD_prefixDict const prefixDict = cctx->prefixDict;
23754  FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) , ""); /* Init the local dict if present. */
23755  ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
23756  assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
23757  if (cctx->cdict && !cctx->localDict.cdict) {
23758  /* Let the cdict's compression level take priority over the requested params.
23759  * But do not take the cdict's compression level if the "cdict" is actually a localDict
23760  * generated from ZSTD_initLocalDict().
23761  */
23762  params.compressionLevel = cctx->cdict->compressionLevel;
23763  }
23764  DEBUGLOG(4, "ZSTD_compressStream2 : transparent init stage");
23765  if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-determine pledgedSrcSize */
23766 
23767  { size_t const dictSize = prefixDict.dict
23768  ? prefixDict.dictSize
23769  : (cctx->cdict ? cctx->cdict->dictContentSize : 0);
23770  ZSTD_cParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, &params, cctx->pledgedSrcSizePlusOne - 1);
23771  params.cParams = ZSTD_getCParamsFromCCtxParams(
23772  &params, cctx->pledgedSrcSizePlusOne-1,
23773  dictSize, mode);
23774  }
23775 
23776  params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, &params.cParams);
23777  params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, &params.cParams);
23778  params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, &params.cParams);
23779  params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences);
23780  params.maxBlockSize = ZSTD_resolveMaxBlockSize(params.maxBlockSize);
23781  params.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(params.searchForExternalRepcodes, params.compressionLevel);
23782 
23783 #ifdef ZSTD_MULTITHREAD
23784  /* If external matchfinder is enabled, make sure to fail before checking job size (for consistency) */
23786  params.useSequenceProducer == 1 && params.nbWorkers >= 1,
23787  parameter_combination_unsupported,
23788  "External sequence producer isn't supported with nbWorkers >= 1"
23789  );
23790 
23791  if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
23792  params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
23793  }
23794  if (params.nbWorkers > 0) {
23795 #if ZSTD_TRACE
23796  cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0;
23797 #endif
23798  /* mt context creation */
23799  if (cctx->mtctx == NULL) {
23800  DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
23801  params.nbWorkers);
23802  cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem, cctx->pool);
23803  RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation, "NULL pointer!");
23804  }
23805  /* mt compression */
23806  DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
23808  cctx->mtctx,
23809  prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
23810  cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) , "");
23811  cctx->dictID = cctx->cdict ? cctx->cdict->dictID : 0;
23812  cctx->dictContentSize = cctx->cdict ? cctx->cdict->dictContentSize : prefixDict.dictSize;
23813  cctx->consumedSrcSize = 0;
23814  cctx->producedCSize = 0;
23815  cctx->streamStage = zcss_load;
23816  cctx->appliedParams = params;
23817  } else
23818 #endif /* ZSTD_MULTITHREAD */
23819  { U64 const pledgedSrcSize = cctx->pledgedSrcSizePlusOne - 1;
23820  assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
23822  prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType, ZSTD_dtlm_fast,
23823  cctx->cdict,
23824  &params, pledgedSrcSize,
23825  ZSTDb_buffered) , "");
23826  assert(cctx->appliedParams.nbWorkers == 0);
23827  cctx->inToCompress = 0;
23828  cctx->inBuffPos = 0;
23829  if (cctx->appliedParams.inBufferMode == ZSTD_bm_buffered) {
23830  /* for small input: avoid automatic flush on reaching end of block, since
23831  * it would require to add a 3-bytes null block to end frame
23832  */
23833  cctx->inBuffTarget = cctx->blockSize + (cctx->blockSize == pledgedSrcSize);
23834  } else {
23835  cctx->inBuffTarget = 0;
23836  }
23837  cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
23838  cctx->streamStage = zcss_load;
23839  cctx->frameEnded = 0;
23840  }
23841  return 0;
23842 }
23843 
23844 /* @return provides a minimum amount of data remaining to be flushed from internal buffers
23845  */
23846 size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
23848  ZSTD_inBuffer* input,
23849  ZSTD_EndDirective endOp)
23850 {
23851  DEBUGLOG(5, "ZSTD_compressStream2, endOp=%u ", (unsigned)endOp);
23852  /* check conditions */
23853  RETURN_ERROR_IF(output->pos > output->size, dstSize_tooSmall, "invalid output buffer");
23854  RETURN_ERROR_IF(input->pos > input->size, srcSize_wrong, "invalid input buffer");
23855  RETURN_ERROR_IF((U32)endOp > (U32)ZSTD_e_end, parameter_outOfBound, "invalid endDirective");
23856  assert(cctx != NULL);
23857 
23858  /* transparent initialization stage */
23859  if (cctx->streamStage == zcss_init) {
23860  size_t const inputSize = input->size - input->pos; /* no obligation to start from pos==0 */
23861  size_t const totalInputSize = inputSize + cctx->stableIn_notConsumed;
23862  if ( (cctx->requestedParams.inBufferMode == ZSTD_bm_stable) /* input is presumed stable, across invocations */
23863  && (endOp == ZSTD_e_continue) /* no flush requested, more input to come */
23864  && (totalInputSize < ZSTD_BLOCKSIZE_MAX) ) { /* not even reached one block yet */
23865  if (cctx->stableIn_notConsumed) { /* not the first time */
23866  /* check stable source guarantees */
23867  RETURN_ERROR_IF(input->src != cctx->expectedInBuffer.src, stabilityCondition_notRespected, "stableInBuffer condition not respected: wrong src pointer");
23868  RETURN_ERROR_IF(input->pos != cctx->expectedInBuffer.size, stabilityCondition_notRespected, "stableInBuffer condition not respected: externally modified pos");
23869  }
23870  /* pretend input was consumed, to give a sense forward progress */
23871  input->pos = input->size;
23872  /* save stable inBuffer, for later control, and flush/end */
23873  cctx->expectedInBuffer = *input;
23874  /* but actually input wasn't consumed, so keep track of position from where compression shall resume */
23876  /* don't initialize yet, wait for the first block of flush() order, for better parameters adaptation */
23877  return ZSTD_FRAMEHEADERSIZE_MIN(cctx->requestedParams.format); /* at least some header to produce */
23878  }
23879  FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, endOp, totalInputSize), "compressStream2 initialization failed");
23880  ZSTD_setBufferExpectations(cctx, output, input); /* Set initial buffer expectations now that we've initialized */
23881  }
23882  /* end of transparent initialization stage */
23883 
23884  FORWARD_IF_ERROR(ZSTD_checkBufferStability(cctx, output, input, endOp), "invalid buffers");
23885  /* compression stage */
23886 #ifdef ZSTD_MULTITHREAD
23887  if (cctx->appliedParams.nbWorkers > 0) {
23888  size_t flushMin;
23889  if (cctx->cParamsChanged) {
23891  cctx->cParamsChanged = 0;
23892  }
23893  if (cctx->stableIn_notConsumed) {
23894  assert(cctx->appliedParams.inBufferMode == ZSTD_bm_stable);
23895  /* some early data was skipped - make it available for consumption */
23896  assert(input->pos >= cctx->stableIn_notConsumed);
23897  input->pos -= cctx->stableIn_notConsumed;
23898  cctx->stableIn_notConsumed = 0;
23899  }
23900  for (;;) {
23901  size_t const ipos = input->pos;
23902  size_t const opos = output->pos;
23903  flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
23904  cctx->consumedSrcSize += (U64)(input->pos - ipos);
23905  cctx->producedCSize += (U64)(output->pos - opos);
23906  if ( ZSTD_isError(flushMin)
23907  || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
23908  if (flushMin == 0)
23909  ZSTD_CCtx_trace(cctx, 0);
23911  }
23912  FORWARD_IF_ERROR(flushMin, "ZSTDMT_compressStream_generic failed");
23913 
23914  if (endOp == ZSTD_e_continue) {
23915  /* We only require some progress with ZSTD_e_continue, not maximal progress.
23916  * We're done if we've consumed or produced any bytes, or either buffer is
23917  * full.
23918  */
23919  if (input->pos != ipos || output->pos != opos || input->pos == input->size || output->pos == output->size)
23920  break;
23921  } else {
23922  assert(endOp == ZSTD_e_flush || endOp == ZSTD_e_end);
23923  /* We require maximal progress. We're done when the flush is complete or the
23924  * output buffer is full.
23925  */
23926  if (flushMin == 0 || output->pos == output->size)
23927  break;
23928  }
23929  }
23930  DEBUGLOG(5, "completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic");
23931  /* Either we don't require maximum forward progress, we've finished the
23932  * flush, or we are out of output space.
23933  */
23934  assert(endOp == ZSTD_e_continue || flushMin == 0 || output->pos == output->size);
23935  ZSTD_setBufferExpectations(cctx, output, input);
23936  return flushMin;
23937  }
23938 #endif /* ZSTD_MULTITHREAD */
23940  DEBUGLOG(5, "completed ZSTD_compressStream2");
23941  ZSTD_setBufferExpectations(cctx, output, input);
23942  return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
23943 }
23944 
23946  ZSTD_CCtx* cctx,
23947  void* dst, size_t dstCapacity, size_t* dstPos,
23948  const void* src, size_t srcSize, size_t* srcPos,
23949  ZSTD_EndDirective endOp)
23950 {
23952  ZSTD_inBuffer input;
23953  output.dst = dst;
23954  output.size = dstCapacity;
23955  output.pos = *dstPos;
23956  input.src = src;
23957  input.size = srcSize;
23958  input.pos = *srcPos;
23959  /* ZSTD_compressStream2() will check validity of dstPos and srcPos */
23960  { size_t const cErr = ZSTD_compressStream2(cctx, &output, &input, endOp);
23961  *dstPos = output.pos;
23962  *srcPos = input.pos;
23963  return cErr;
23964  }
23965 }
23966 
23967 size_t ZSTD_compress2(ZSTD_CCtx* cctx,
23968  void* dst, size_t dstCapacity,
23969  const void* src, size_t srcSize)
23970 {
23971  ZSTD_bufferMode_e const originalInBufferMode = cctx->requestedParams.inBufferMode;
23972  ZSTD_bufferMode_e const originalOutBufferMode = cctx->requestedParams.outBufferMode;
23973  DEBUGLOG(4, "ZSTD_compress2 (srcSize=%u)", (unsigned)srcSize);
23975  /* Enable stable input/output buffers. */
23976  cctx->requestedParams.inBufferMode = ZSTD_bm_stable;
23977  cctx->requestedParams.outBufferMode = ZSTD_bm_stable;
23978  { size_t oPos = 0;
23979  size_t iPos = 0;
23980  size_t const result = ZSTD_compressStream2_simpleArgs(cctx,
23981  dst, dstCapacity, &oPos,
23982  src, srcSize, &iPos,
23983  ZSTD_e_end);
23984  /* Reset to the original values. */
23985  cctx->requestedParams.inBufferMode = originalInBufferMode;
23986  cctx->requestedParams.outBufferMode = originalOutBufferMode;
23987 
23988  FORWARD_IF_ERROR(result, "ZSTD_compressStream2_simpleArgs failed");
23989  if (result != 0) { /* compression not completed, due to lack of output space */
23990  assert(oPos == dstCapacity);
23991  RETURN_ERROR(dstSize_tooSmall, "");
23992  }
23993  assert(iPos == srcSize); /* all input is expected consumed */
23994  return oPos;
23995  }
23996 }
23998 /* ZSTD_validateSequence() :
23999  * @offCode : is presumed to follow format required by ZSTD_storeSeq()
24000  * @returns a ZSTD error code if sequence is not valid
24001  */
24002 static size_t
24003 ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch,
24004  size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
24005 {
24006  U32 const windowSize = 1u << windowLog;
24007  /* posInSrc represents the amount of data the decoder would decode up to this point.
24008  * As long as the amount of data decoded is less than or equal to window size, offsets may be
24009  * larger than the total length of output decoded in order to reference the dict, even larger than
24010  * window size. After output surpasses windowSize, we're limited to windowSize offsets again.
24011  */
24012  size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
24013  size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4;
24014  RETURN_ERROR_IF(offCode > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
24015  /* Validate maxNbSeq is large enough for the given matchLength and minMatch */
24016  RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch");
24017  return 0;
24018 }
24019 
24020 /* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */
24021 static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0)
24022 {
24023  U32 offBase = OFFSET_TO_OFFBASE(rawOffset);
24024 
24025  if (!ll0 && rawOffset == rep[0]) {
24026  offBase = REPCODE1_TO_OFFBASE;
24027  } else if (rawOffset == rep[1]) {
24028  offBase = REPCODE_TO_OFFBASE(2 - ll0);
24029  } else if (rawOffset == rep[2]) {
24030  offBase = REPCODE_TO_OFFBASE(3 - ll0);
24031  } else if (ll0 && rawOffset == rep[0] - 1) {
24033  }
24034  return offBase;
24035 }
24036 
24037 size_t
24039  ZSTD_sequencePosition* seqPos,
24040  const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
24041  const void* src, size_t blockSize,
24042  ZSTD_paramSwitch_e externalRepSearch)
24043 {
24044  U32 idx = seqPos->idx;
24045  U32 const startIdx = idx;
24046  BYTE const* ip = (BYTE const*)(src);
24047  const BYTE* const iend = ip + blockSize;
24048  repcodes_t updatedRepcodes;
24049  U32 dictSize;
24050 
24051  DEBUGLOG(5, "ZSTD_copySequencesToSeqStoreExplicitBlockDelim (blockSize = %zu)", blockSize);
24052 
24053  if (cctx->cdict) {
24054  dictSize = (U32)cctx->cdict->dictContentSize;
24055  } else if (cctx->prefixDict.dict) {
24056  dictSize = (U32)cctx->prefixDict.dictSize;
24057  } else {
24058  dictSize = 0;
24059  }
24060  ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
24061  for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) {
24062  U32 const litLength = inSeqs[idx].litLength;
24063  U32 const matchLength = inSeqs[idx].matchLength;
24064  U32 offBase;
24065 
24066  if (externalRepSearch == ZSTD_ps_disable) {
24067  offBase = OFFSET_TO_OFFBASE(inSeqs[idx].offset);
24068  } else {
24069  U32 const ll0 = (litLength == 0);
24070  offBase = ZSTD_finalizeOffBase(inSeqs[idx].offset, updatedRepcodes.rep, ll0);
24071  ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0);
24072  }
24073 
24074  DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
24075  if (cctx->appliedParams.validateSequences) {
24076  seqPos->posInSrc += litLength + matchLength;
24077  FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc,
24078  cctx->appliedParams.cParams.windowLog, dictSize, cctx->appliedParams.useSequenceProducer),
24079  "Sequence validation failed");
24080  }
24081  RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
24082  "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
24083  ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength);
24084  ip += matchLength + litLength;
24085  }
24086 
24087  /* If we skipped repcode search while parsing, we need to update repcodes now */
24088  assert(externalRepSearch != ZSTD_ps_auto);
24089  assert(idx >= startIdx);
24090  if (externalRepSearch == ZSTD_ps_disable && idx != startIdx) {
24091  U32* const rep = updatedRepcodes.rep;
24092  U32 lastSeqIdx = idx - 1; /* index of last non-block-delimiter sequence */
24093 
24094  if (lastSeqIdx >= startIdx + 2) {
24095  rep[2] = inSeqs[lastSeqIdx - 2].offset;
24096  rep[1] = inSeqs[lastSeqIdx - 1].offset;
24097  rep[0] = inSeqs[lastSeqIdx].offset;
24098  } else if (lastSeqIdx == startIdx + 1) {
24099  rep[2] = rep[0];
24100  rep[1] = inSeqs[lastSeqIdx - 1].offset;
24101  rep[0] = inSeqs[lastSeqIdx].offset;
24102  } else {
24103  assert(lastSeqIdx == startIdx);
24104  rep[2] = rep[1];
24105  rep[1] = rep[0];
24106  rep[0] = inSeqs[lastSeqIdx].offset;
24107  }
24108  }
24109 
24110  ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
24111 
24112  if (inSeqs[idx].litLength) {
24113  DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
24114  ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength);
24115  ip += inSeqs[idx].litLength;
24116  seqPos->posInSrc += inSeqs[idx].litLength;
24117  }
24118  RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!");
24119  seqPos->idx = idx+1;
24120  return 0;
24121 }
24122 
24123 size_t
24125  const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
24126  const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch)
24127 {
24128  U32 idx = seqPos->idx;
24129  U32 startPosInSequence = seqPos->posInSequence;
24130  U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
24131  size_t dictSize;
24132  BYTE const* ip = (BYTE const*)(src);
24133  BYTE const* iend = ip + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */
24134  repcodes_t updatedRepcodes;
24135  U32 bytesAdjustment = 0;
24136  U32 finalMatchSplit = 0;
24137 
24138  /* TODO(embg) support fast parsing mode in noBlockDelim mode */
24139  (void)externalRepSearch;
24140 
24141  if (cctx->cdict) {
24142  dictSize = cctx->cdict->dictContentSize;
24143  } else if (cctx->prefixDict.dict) {
24144  dictSize = cctx->prefixDict.dictSize;
24145  } else {
24146  dictSize = 0;
24147  }
24148  DEBUGLOG(5, "ZSTD_copySequencesToSeqStoreNoBlockDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
24149  DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
24150  ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(repcodes_t));
24151  while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
24152  const ZSTD_Sequence currSeq = inSeqs[idx];
24153  U32 litLength = currSeq.litLength;
24154  U32 matchLength = currSeq.matchLength;
24155  U32 const rawOffset = currSeq.offset;
24156  U32 offBase;
24157 
24158  /* Modify the sequence depending on where endPosInSequence lies */
24159  if (endPosInSequence >= currSeq.litLength + currSeq.matchLength) {
24160  if (startPosInSequence >= litLength) {
24161  startPosInSequence -= litLength;
24162  litLength = 0;
24163  matchLength -= startPosInSequence;
24164  } else {
24165  litLength -= startPosInSequence;
24166  }
24167  /* Move to the next sequence */
24168  endPosInSequence -= currSeq.litLength + currSeq.matchLength;
24169  startPosInSequence = 0;
24170  } else {
24171  /* This is the final (partial) sequence we're adding from inSeqs, and endPosInSequence
24172  does not reach the end of the match. So, we have to split the sequence */
24173  DEBUGLOG(6, "Require a split: diff: %u, idx: %u PIS: %u",
24174  currSeq.litLength + currSeq.matchLength - endPosInSequence, idx, endPosInSequence);
24175  if (endPosInSequence > litLength) {
24176  U32 firstHalfMatchLength;
24177  litLength = startPosInSequence >= litLength ? 0 : litLength - startPosInSequence;
24178  firstHalfMatchLength = endPosInSequence - startPosInSequence - litLength;
24179  if (matchLength > blockSize && firstHalfMatchLength >= cctx->appliedParams.cParams.minMatch) {
24180  /* Only ever split the match if it is larger than the block size */
24181  U32 secondHalfMatchLength = currSeq.matchLength + currSeq.litLength - endPosInSequence;
24182  if (secondHalfMatchLength < cctx->appliedParams.cParams.minMatch) {
24183  /* Move the endPosInSequence backward so that it creates match of minMatch length */
24184  endPosInSequence -= cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
24185  bytesAdjustment = cctx->appliedParams.cParams.minMatch - secondHalfMatchLength;
24186  firstHalfMatchLength -= bytesAdjustment;
24187  }
24188  matchLength = firstHalfMatchLength;
24189  /* Flag that we split the last match - after storing the sequence, exit the loop,
24190  but keep the value of endPosInSequence */
24191  finalMatchSplit = 1;
24192  } else {
24193  /* Move the position in sequence backwards so that we don't split match, and break to store
24194  * the last literals. We use the original currSeq.litLength as a marker for where endPosInSequence
24195  * should go. We prefer to do this whenever it is not necessary to split the match, or if doing so
24196  * would cause the first half of the match to be too small
24197  */
24198  bytesAdjustment = endPosInSequence - currSeq.litLength;
24199  endPosInSequence = currSeq.litLength;
24200  break;
24201  }
24202  } else {
24203  /* This sequence ends inside the literals, break to store the last literals */
24204  break;
24205  }
24206  }
24207  /* Check if this offset can be represented with a repcode */
24208  { U32 const ll0 = (litLength == 0);
24209  offBase = ZSTD_finalizeOffBase(rawOffset, updatedRepcodes.rep, ll0);
24210  ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0);
24211  }
24212 
24213  if (cctx->appliedParams.validateSequences) {
24214  seqPos->posInSrc += litLength + matchLength;
24215  FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, seqPos->posInSrc,
24216  cctx->appliedParams.cParams.windowLog, dictSize, cctx->appliedParams.useSequenceProducer),
24217  "Sequence validation failed");
24218  }
24219  DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
24220  RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
24221  "Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
24222  ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength);
24223  ip += matchLength + litLength;
24224  if (!finalMatchSplit)
24225  idx++; /* Next Sequence */
24226  }
24227  DEBUGLOG(5, "Ending seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
24228  assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
24229  seqPos->idx = idx;
24230  seqPos->posInSequence = endPosInSequence;
24231  ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(repcodes_t));
24232 
24233  iend -= bytesAdjustment;
24234  if (ip != iend) {
24235  /* Store any last literals */
24236  U32 lastLLSize = (U32)(iend - ip);
24237  assert(ip <= iend);
24238  DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
24239  ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
24240  seqPos->posInSrc += lastLLSize;
24241  }
24242 
24243  return bytesAdjustment;
24244 }
24245 
24246 typedef size_t (*ZSTD_sequenceCopier) (ZSTD_CCtx* cctx, ZSTD_sequencePosition* seqPos,
24247  const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
24248  const void* src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch);
24249 static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
24250 {
24251  ZSTD_sequenceCopier sequenceCopier = NULL;
24252  assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
24253  if (mode == ZSTD_sf_explicitBlockDelimiters) {
24255  } else if (mode == ZSTD_sf_noBlockDelimiters) {
24257  }
24258  assert(sequenceCopier != NULL);
24259  return sequenceCopier;
24260 }
24262 /* Discover the size of next block by searching for the delimiter.
24263  * Note that a block delimiter **must** exist in this mode,
24264  * otherwise it's an input error.
24265  * The block size retrieved will be later compared to ensure it remains within bounds */
24266 static size_t
24267 blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
24268 {
24269  int end = 0;
24270  size_t blockSize = 0;
24271  size_t spos = seqPos.idx;
24272  DEBUGLOG(6, "blockSize_explicitDelimiter : seq %zu / %zu", spos, inSeqsSize);
24273  assert(spos <= inSeqsSize);
24274  while (spos < inSeqsSize) {
24275  end = (inSeqs[spos].offset == 0);
24276  blockSize += inSeqs[spos].litLength + inSeqs[spos].matchLength;
24277  if (end) {
24278  if (inSeqs[spos].matchLength != 0)
24279  RETURN_ERROR(externalSequences_invalid, "delimiter format error : both matchlength and offset must be == 0");
24280  break;
24281  }
24282  spos++;
24283  }
24284  if (!end)
24285  RETURN_ERROR(externalSequences_invalid, "Reached end of sequences without finding a block delimiter");
24286  return blockSize;
24287 }
24288 
24289 /* More a "target" block size */
24290 static size_t blockSize_noDelimiter(size_t blockSize, size_t remaining)
24291 {
24292  int const lastBlock = (remaining <= blockSize);
24293  return lastBlock ? remaining : blockSize;
24294 }
24295 
24296 static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
24297  size_t blockSize, size_t remaining,
24298  const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
24299 {
24300  DEBUGLOG(6, "determine_blockSize : remainingSize = %zu", remaining);
24301  if (mode == ZSTD_sf_noBlockDelimiters)
24302  return blockSize_noDelimiter(blockSize, remaining);
24303  { size_t const explicitBlockSize = blockSize_explicitDelimiter(inSeqs, inSeqsSize, seqPos);
24304  FORWARD_IF_ERROR(explicitBlockSize, "Error while determining block size with explicit delimiters");
24305  if (explicitBlockSize > blockSize)
24306  RETURN_ERROR(externalSequences_invalid, "sequences incorrectly define a too large block");
24307  if (explicitBlockSize > remaining)
24308  RETURN_ERROR(externalSequences_invalid, "sequences define a frame longer than source");
24309  return explicitBlockSize;
24310  }
24311 }
24312 
24313 /* Compress, block-by-block, all of the sequences given.
24314  *
24315  * Returns the cumulative size of all compressed blocks (including their headers),
24316  * otherwise a ZSTD error.
24317  */
24318 static size_t
24320  void* dst, size_t dstCapacity,
24321  const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
24322  const void* src, size_t srcSize)
24323 {
24324  size_t cSize = 0;
24325  size_t remaining = srcSize;
24326  ZSTD_sequencePosition seqPos = {0, 0, 0};
24327 
24328  BYTE const* ip = (BYTE const*)src;
24329  BYTE* op = (BYTE*)dst;
24330  ZSTD_sequenceCopier const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
24331 
24332  DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
24333  /* Special case: empty frame */
24334  if (remaining == 0) {
24335  U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
24336  RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "No room for empty frame block header");
24337  MEM_writeLE32(op, cBlockHeader24);
24339  dstCapacity -= ZSTD_blockHeaderSize;
24340  cSize += ZSTD_blockHeaderSize;
24341  }
24342 
24343  while (remaining) {
24344  size_t compressedSeqsSize;
24345  size_t cBlockSize;
24346  size_t additionalByteAdjustment;
24347  size_t blockSize = determine_blockSize(cctx->appliedParams.blockDelimiters,
24348  cctx->blockSize, remaining,
24349  inSeqs, inSeqsSize, seqPos);
24350  U32 const lastBlock = (blockSize == remaining);
24351  FORWARD_IF_ERROR(blockSize, "Error while trying to determine block size");
24352  assert(blockSize <= remaining);
24353  ZSTD_resetSeqStore(&cctx->seqStore);
24354  DEBUGLOG(5, "Working on new block. Blocksize: %zu (total:%zu)", blockSize, (ip - (const BYTE*)src) + blockSize);
24355 
24356  additionalByteAdjustment = sequenceCopier(cctx, &seqPos, inSeqs, inSeqsSize, ip, blockSize, cctx->appliedParams.searchForExternalRepcodes);
24357  FORWARD_IF_ERROR(additionalByteAdjustment, "Bad sequence copy");
24358  blockSize -= additionalByteAdjustment;
24359 
24360  /* If blocks are too small, emit as a nocompress block */
24361  /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
24362  * additional 1. We need to revisit and change this logic to be more consistent */
24363  if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) {
24364  cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
24365  FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
24366  DEBUGLOG(5, "Block too small, writing out nocompress block: cSize: %zu", cBlockSize);
24367  cSize += cBlockSize;
24368  ip += blockSize;
24369  op += cBlockSize;
24370  remaining -= blockSize;
24371  dstCapacity -= cBlockSize;
24372  continue;
24373  }
24374 
24375  RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block");
24376  compressedSeqsSize = ZSTD_entropyCompressSeqStore(&cctx->seqStore,
24378  &cctx->appliedParams,
24379  op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
24380  blockSize,
24381  cctx->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
24382  cctx->bmi2);
24383  FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
24384  DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
24385 
24386  if (!cctx->isFirstBlock &&
24387  ZSTD_maybeRLE(&cctx->seqStore) &&
24388  ZSTD_isRLE(ip, blockSize)) {
24389  /* We don't want to emit our first block as a RLE even if it qualifies because
24390  * doing so will cause the decoder (cli only) to throw a "should consume all input error."
24391  * This is only an issue for zstd <= v1.4.3
24392  */
24393  compressedSeqsSize = 1;
24394  }
24395 
24396  if (compressedSeqsSize == 0) {
24397  /* ZSTD_noCompressBlock writes the block header as well */
24398  cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
24399  FORWARD_IF_ERROR(cBlockSize, "ZSTD_noCompressBlock failed");
24400  DEBUGLOG(5, "Writing out nocompress block, size: %zu", cBlockSize);
24401  } else if (compressedSeqsSize == 1) {
24402  cBlockSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, blockSize, lastBlock);
24403  FORWARD_IF_ERROR(cBlockSize, "ZSTD_rleCompressBlock failed");
24404  DEBUGLOG(5, "Writing out RLE block, size: %zu", cBlockSize);
24405  } else {
24406  U32 cBlockHeader;
24407  /* Error checking and repcodes update */
24411 
24412  /* Write block header into beginning of block*/
24413  cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
24414  MEM_writeLE24(op, cBlockHeader);
24415  cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
24416  DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize);
24417  }
24418 
24419  cSize += cBlockSize;
24420 
24421  if (lastBlock) {
24422  break;
24423  } else {
24424  ip += blockSize;
24425  op += cBlockSize;
24426  remaining -= blockSize;
24427  dstCapacity -= cBlockSize;
24428  cctx->isFirstBlock = 0;
24429  }
24430  DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity);
24431  }
24432 
24433  DEBUGLOG(4, "cSize final total: %zu", cSize);
24434  return cSize;
24435 }
24436 
24437 size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
24438  void* dst, size_t dstCapacity,
24439  const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
24440  const void* src, size_t srcSize)
24441 {
24442  BYTE* op = (BYTE*)dst;
24443  size_t cSize = 0;
24444  size_t compressedBlocksSize = 0;
24445  size_t frameHeaderSize = 0;
24446 
24447  /* Transparent initialization stage, same as compressStream2() */
24448  DEBUGLOG(4, "ZSTD_compressSequences (dstCapacity=%zu)", dstCapacity);
24449  assert(cctx != NULL);
24450  FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
24451  /* Begin writing output, starting with frame header */
24452  frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity, &cctx->appliedParams, srcSize, cctx->dictID);
24453  op += frameHeaderSize;
24454  dstCapacity -= frameHeaderSize;
24455  cSize += frameHeaderSize;
24456  if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
24457  XXH64_update(&cctx->xxhState, src, srcSize);
24458  }
24459  /* cSize includes block header size and compressed sequences size */
24460  compressedBlocksSize = ZSTD_compressSequences_internal(cctx,
24461  op, dstCapacity,
24462  inSeqs, inSeqsSize,
24463  src, srcSize);
24464  FORWARD_IF_ERROR(compressedBlocksSize, "Compressing blocks failed!");
24465  cSize += compressedBlocksSize;
24466  dstCapacity -= compressedBlocksSize;
24467 
24468  if (cctx->appliedParams.fParams.checksumFlag) {
24469  U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
24470  RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
24471  DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum);
24472  MEM_writeLE32((char*)dst + cSize, checksum);
24473  cSize += 4;
24474  }
24475 
24476  DEBUGLOG(4, "Final compressed size: %zu", cSize);
24477  return cSize;
24478 }
24479 
24480 /*====== Finalize ======*/
24481 
24483 {
24484  const ZSTD_inBuffer nullInput = { NULL, 0, 0 };
24485  const int stableInput = (zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
24486  return stableInput ? zcs->expectedInBuffer : nullInput;
24487 }
24488 
24492 {
24494  input.size = input.pos; /* do not ingest more input during flush */
24495  return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
24496 }
24497 
24498 
24500 {
24501  ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
24502  size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);
24503  FORWARD_IF_ERROR(remainingToFlush , "ZSTD_compressStream2(,,ZSTD_e_end) failed");
24504  if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush; /* minimal estimation */
24505  /* single thread mode : attempt to calculate remaining to flush more precisely */
24506  { size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;
24507  size_t const checksumSize = (size_t)(zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4);
24508  size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;
24509  DEBUGLOG(4, "ZSTD_endStream : remaining to flush : %u", (unsigned)toFlush);
24510  return toFlush;
24511  }
24512 }
24513 
24514 
24515 /*-===== Pre-defined compression levels =====-*/
24516 /**** start inlining clevels.h ****/
24517 /*
24518  * Copyright (c) Meta Platforms, Inc. and affiliates.
24519  * All rights reserved.
24520  *
24521  * This source code is licensed under both the BSD-style license (found in the
24522  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
24523  * in the COPYING file in the root directory of this source tree).
24524  * You may select, at your option, one of the above-listed licenses.
24525  */
24526 
24527 #ifndef ZSTD_CLEVELS_H
24528 #define ZSTD_CLEVELS_H
24530 #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */
24531 /**** skipping file: ../zstd.h ****/
24532 
24533 /*-===== Pre-defined compression levels =====-*/
24534 
24535 #define ZSTD_MAX_CLEVEL 22
24536 
24537 #ifdef __GNUC__
24538 __attribute__((__unused__))
24539 #endif
24540 
24541 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
24542 { /* "default" - for any srcSize > 256 KB */
24543  /* W, C, H, S, L, TL, strat */
24544  { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
24545  { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */
24546  { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */
24547  { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */
24548  { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */
24549  { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */
24550  { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */
24551  { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */
24552  { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */
24553  { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */
24554  { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */
24555  { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */
24556  { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */
24557  { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */
24558  { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */
24559  { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */
24560  { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */
24561  { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */
24562  { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */
24563  { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */
24564  { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */
24565  { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */
24566  { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */
24567 },
24568 { /* for srcSize <= 256 KB */
24569  /* W, C, H, S, L, T, strat */
24570  { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
24571  { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */
24572  { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */
24573  { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */
24574  { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/
24575  { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/
24576  { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/
24577  { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */
24578  { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
24579  { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
24580  { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
24581  { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/
24582  { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/
24583  { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */
24584  { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
24585  { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/
24586  { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/
24587  { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/
24588  { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/
24589  { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
24590  { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/
24591  { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/
24592  { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/
24593 },
24594 { /* for srcSize <= 128 KB */
24595  /* W, C, H, S, L, T, strat */
24596  { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
24597  { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */
24598  { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */
24599  { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */
24600  { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */
24601  { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */
24602  { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
24603  { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */
24604  { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
24605  { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
24606  { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
24607  { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */
24608  { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */
24609  { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/
24610  { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/
24611  { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/
24612  { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/
24613  { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/
24614  { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/
24615  { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/
24616  { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/
24617  { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
24618  { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/
24619 },
24620 { /* for srcSize <= 16 KB */
24621  /* W, C, H, S, L, T, strat */
24622  { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
24623  { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */
24624  { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */
24625  { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */
24626  { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */
24627  { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/
24628  { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */
24629  { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */
24630  { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/
24631  { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/
24632  { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/
24633  { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/
24634  { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/
24635  { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/
24636  { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/
24637  { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/
24638  { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/
24639  { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/
24640  { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/
24641  { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/
24642  { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/
24643  { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/
24644  { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/
24645 },
24646 };
24650 #endif /* ZSTD_CLEVELS_H */
24651 /**** ended inlining clevels.h ****/
24652 
24653 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
24654 int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }
24655 int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; }
24656 
24657 static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize)
24658 {
24659  ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict);
24660  switch (cParams.strategy) {
24661  case ZSTD_fast:
24662  case ZSTD_dfast:
24663  break;
24664  case ZSTD_greedy:
24665  case ZSTD_lazy:
24666  case ZSTD_lazy2:
24667  cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG;
24668  break;
24669  case ZSTD_btlazy2:
24670  case ZSTD_btopt:
24671  case ZSTD_btultra:
24673  break;
24674  }
24675  return cParams;
24676 }
24677 
24679  ZSTD_compressionParameters const* cParams)
24680 {
24681  return (cParams->strategy >= ZSTD_greedy)
24682  && (cParams->strategy <= ZSTD_lazy2)
24683  && (cParams->hashLog > cParams->chainLog)
24684  && (cParams->chainLog <= 24);
24685 }
24693  ZSTD_compressionParameters* cParams) {
24694  switch (cParams->strategy) {
24695  case ZSTD_fast:
24696  case ZSTD_dfast:
24697  break;
24698  case ZSTD_greedy:
24699  case ZSTD_lazy:
24700  case ZSTD_lazy2:
24701  cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
24702  if (cParams->hashLog < ZSTD_HASHLOG_MIN) {
24703  cParams->hashLog = ZSTD_HASHLOG_MIN;
24704  }
24705  break;
24706  case ZSTD_btlazy2:
24707  case ZSTD_btopt:
24709  case ZSTD_btultra2:
24710  break;
24711  }
24712 }
24713 
24714 static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
24715 {
24716  switch (mode) {
24717  case ZSTD_cpm_unknown:
24718  case ZSTD_cpm_noAttachDict:
24719  case ZSTD_cpm_createCDict:
24720  break;
24721  case ZSTD_cpm_attachDict:
24722  dictSize = 0;
24723  break;
24724  default:
24725  assert(0);
24726  break;
24727  }
24728  { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN;
24729  size_t const addedSize = unknown && dictSize > 0 ? 500 : 0;
24730  return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize;
24731  }
24732 }
24739 static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
24740 {
24741  U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
24742  U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
24743  int row;
24744  DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel);
24745 
24746  /* row */
24747  if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
24748  else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
24750  else row = compressionLevel;
24751 
24752  { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
24753  DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy);
24754  /* acceleration factor */
24755  if (compressionLevel < 0) {
24756  int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel);
24757  cp.targetLength = (unsigned)(-clampedCompressionLevel);
24758  }
24759  /* refine parameters based on srcSize & dictSize */
24760  return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode, ZSTD_ps_auto);
24761  }
24762 }
24763 
24767 ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
24768 {
24769  if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
24770  return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
24772 
24777 static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode) {
24778  ZSTD_parameters params;
24779  ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
24780  DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
24781  ZSTD_memset(&params, 0, sizeof(params));
24782  params.cParams = cParams;
24783  params.fParams.contentSizeFlag = 1;
24784  return params;
24786 
24791 ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
24792  if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
24793  return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
24794 }
24795 
24797  ZSTD_CCtx* zc, void* mState,
24798  ZSTD_sequenceProducer_F* mFinder
24799 ) {
24800  if (mFinder != NULL) {
24801  ZSTD_externalMatchCtx emctx;
24802  emctx.mState = mState;
24803  emctx.mFinder = mFinder;
24804  emctx.seqBuffer = NULL;
24805  emctx.seqBufferCapacity = 0;
24806  zc->externalMatchCtx = emctx;
24807  zc->requestedParams.useSequenceProducer = 1;
24808  } else {
24809  ZSTD_memset(&zc->externalMatchCtx, 0, sizeof(zc->externalMatchCtx));
24810  zc->requestedParams.useSequenceProducer = 0;
24811  }
24812 }
24813 /**** ended inlining compress/zstd_compress.c ****/
24814 /**** start inlining compress/zstd_double_fast.c ****/
24815 /*
24816  * Copyright (c) Meta Platforms, Inc. and affiliates.
24817  * All rights reserved.
24818  *
24819  * This source code is licensed under both the BSD-style license (found in the
24820  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
24821  * in the COPYING file in the root directory of this source tree).
24822  * You may select, at your option, one of the above-listed licenses.
24823  */
24824 
24825 /**** skipping file: zstd_compress_internal.h ****/
24826 /**** skipping file: zstd_double_fast.h ****/
24827 
24829  void const* end, ZSTD_dictTableLoadMethod_e dtlm)
24830 {
24831  const ZSTD_compressionParameters* const cParams = &ms->cParams;
24832  U32* const hashLarge = ms->hashTable;
24833  U32 const hBitsL = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
24834  U32 const mls = cParams->minMatch;
24835  U32* const hashSmall = ms->chainTable;
24836  U32 const hBitsS = cParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS;
24837  const BYTE* const base = ms->window.base;
24838  const BYTE* ip = base + ms->nextToUpdate;
24839  const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
24840  const U32 fastHashFillStep = 3;
24841 
24842  /* Always insert every fastHashFillStep position into the hash tables.
24843  * Insert the other positions into the large hash table if their entry
24844  * is empty.
24845  */
24846  for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
24847  U32 const curr = (U32)(ip - base);
24848  U32 i;
24849  for (i = 0; i < fastHashFillStep; ++i) {
24850  size_t const smHashAndTag = ZSTD_hashPtr(ip + i, hBitsS, mls);
24851  size_t const lgHashAndTag = ZSTD_hashPtr(ip + i, hBitsL, 8);
24852  if (i == 0) {
24853  ZSTD_writeTaggedIndex(hashSmall, smHashAndTag, curr + i);
24854  }
24855  if (i == 0 || hashLarge[lgHashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) {
24856  ZSTD_writeTaggedIndex(hashLarge, lgHashAndTag, curr + i);
24857  }
24858  /* Only load extra positions for ZSTD_dtlm_full */
24859  if (dtlm == ZSTD_dtlm_fast)
24860  break;
24861  } }
24862 }
24863 
24865  void const* end, ZSTD_dictTableLoadMethod_e dtlm)
24866 {
24867  const ZSTD_compressionParameters* const cParams = &ms->cParams;
24868  U32* const hashLarge = ms->hashTable;
24869  U32 const hBitsL = cParams->hashLog;
24870  U32 const mls = cParams->minMatch;
24871  U32* const hashSmall = ms->chainTable;
24872  U32 const hBitsS = cParams->chainLog;
24873  const BYTE* const base = ms->window.base;
24874  const BYTE* ip = base + ms->nextToUpdate;
24875  const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
24876  const U32 fastHashFillStep = 3;
24877 
24878  /* Always insert every fastHashFillStep position into the hash tables.
24879  * Insert the other positions into the large hash table if their entry
24880  * is empty.
24881  */
24882  for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
24883  U32 const curr = (U32)(ip - base);
24884  U32 i;
24885  for (i = 0; i < fastHashFillStep; ++i) {
24886  size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls);
24887  size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8);
24888  if (i == 0)
24889  hashSmall[smHash] = curr + i;
24890  if (i == 0 || hashLarge[lgHash] == 0)
24891  hashLarge[lgHash] = curr + i;
24892  /* Only load extra positions for ZSTD_dtlm_full */
24893  if (dtlm == ZSTD_dtlm_fast)
24894  break;
24895  } }
24896 }
24897 
24899  const void* const end,
24902 {
24903  if (tfp == ZSTD_tfp_forCDict) {
24904  ZSTD_fillDoubleHashTableForCDict(ms, end, dtlm);
24905  } else {
24907  }
24908 }
24909 
24910 
24913  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
24914  void const* src, size_t srcSize, U32 const mls /* template */)
24915 {
24916  ZSTD_compressionParameters const* cParams = &ms->cParams;
24917  U32* const hashLong = ms->hashTable;
24918  const U32 hBitsL = cParams->hashLog;
24919  U32* const hashSmall = ms->chainTable;
24920  const U32 hBitsS = cParams->chainLog;
24921  const BYTE* const base = ms->window.base;
24922  const BYTE* const istart = (const BYTE*)src;
24923  const BYTE* anchor = istart;
24924  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
24925  /* presumes that, if there is a dictionary, it must be using Attach mode */
24926  const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
24927  const BYTE* const prefixLowest = base + prefixLowestIndex;
24928  const BYTE* const iend = istart + srcSize;
24929  const BYTE* const ilimit = iend - HASH_READ_SIZE;
24930  U32 offset_1=rep[0], offset_2=rep[1];
24931  U32 offsetSaved1 = 0, offsetSaved2 = 0;
24932 
24933  size_t mLength;
24934  U32 offset;
24935  U32 curr;
24936 
24937  /* how many positions to search before increasing step size */
24938  const size_t kStepIncr = 1 << kSearchStrength;
24939  /* the position at which to increment the step size if no match is found */
24940  const BYTE* nextStep;
24941  size_t step; /* the current step size */
24942 
24943  size_t hl0; /* the long hash at ip */
24944  size_t hl1; /* the long hash at ip1 */
24945 
24946  U32 idxl0; /* the long match index for ip */
24947  U32 idxl1; /* the long match index for ip1 */
24948 
24949  const BYTE* matchl0; /* the long match for ip */
24950  const BYTE* matchs0; /* the short match for ip */
24951  const BYTE* matchl1; /* the long match for ip1 */
24952 
24953  const BYTE* ip = istart; /* the current position */
24954  const BYTE* ip1; /* the next position */
24955 
24956  DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic");
24957 
24958  /* init */
24959  ip += ((ip - prefixLowest) == 0);
24960  {
24961  U32 const current = (U32)(ip - base);
24962  U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
24963  U32 const maxRep = current - windowLow;
24964  if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0;
24965  if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0;
24966  }
24967 
24968  /* Outer Loop: one iteration per match found and stored */
24969  while (1) {
24970  step = 1;
24971  nextStep = ip + kStepIncr;
24972  ip1 = ip + step;
24973 
24974  if (ip1 > ilimit) {
24975  goto _cleanup;
24976  }
24977 
24978  hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
24979  idxl0 = hashLong[hl0];
24980  matchl0 = base + idxl0;
24981 
24982  /* Inner Loop: one iteration per search / position */
24983  do {
24984  const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
24985  const U32 idxs0 = hashSmall[hs0];
24986  curr = (U32)(ip-base);
24987  matchs0 = base + idxs0;
24988 
24989  hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */
24990 
24991  /* check noDict repcode */
24992  if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
24993  mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
24994  ip++;
24995  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
24996  goto _match_stored;
24997  }
24998 
24999  hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
25000 
25001  if (idxl0 > prefixLowestIndex) {
25002  /* check prefix long match */
25003  if (MEM_read64(matchl0) == MEM_read64(ip)) {
25004  mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8;
25005  offset = (U32)(ip-matchl0);
25006  while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */
25007  goto _match_found;
25008  }
25009  }
25010 
25011  idxl1 = hashLong[hl1];
25012  matchl1 = base + idxl1;
25013 
25014  if (idxs0 > prefixLowestIndex) {
25015  /* check prefix short match */
25016  if (MEM_read32(matchs0) == MEM_read32(ip)) {
25017  goto _search_next_long;
25018  }
25019  }
25020 
25021  if (ip1 >= nextStep) {
25022  PREFETCH_L1(ip1 + 64);
25023  PREFETCH_L1(ip1 + 128);
25024  step++;
25025  nextStep += kStepIncr;
25026  }
25027  ip = ip1;
25028  ip1 += step;
25029 
25030  hl0 = hl1;
25031  idxl0 = idxl1;
25032  matchl0 = matchl1;
25033  #if defined(__aarch64__)
25034  PREFETCH_L1(ip+256);
25035  #endif
25036  } while (ip1 <= ilimit);
25037 
25038 _cleanup:
25039  /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0),
25040  * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */
25041  offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2;
25042 
25043  /* save reps for next block */
25044  rep[0] = offset_1 ? offset_1 : offsetSaved1;
25045  rep[1] = offset_2 ? offset_2 : offsetSaved2;
25046 
25047  /* Return the last literals size */
25048  return (size_t)(iend - anchor);
25049 
25050 _search_next_long:
25051 
25052  /* check prefix long +1 match */
25053  if (idxl1 > prefixLowestIndex) {
25054  if (MEM_read64(matchl1) == MEM_read64(ip1)) {
25055  ip = ip1;
25056  mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8;
25057  offset = (U32)(ip-matchl1);
25058  while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */
25059  goto _match_found;
25060  }
25061  }
25062 
25063  /* if no long +1 match, explore the short match we found */
25064  mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4;
25065  offset = (U32)(ip - matchs0);
25066  while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */
25067 
25068  /* fall-through */
25069 
25070 _match_found: /* requires ip, offset, mLength */
25071  offset_2 = offset_1;
25072  offset_1 = offset;
25073 
25074  if (step < 4) {
25075  /* It is unsafe to write this value back to the hashtable when ip1 is
25076  * greater than or equal to the new ip we will have after we're done
25077  * processing this match. Rather than perform that test directly
25078  * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler
25079  * more predictable test. The minmatch even if we take a short match is
25080  * 4 bytes, so as long as step, the distance between ip and ip1
25081  * (initially) is less than 4, we know ip1 < new ip. */
25082  hashLong[hl1] = (U32)(ip1 - base);
25083  }
25084 
25085  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
25086 
25087 _match_stored:
25088  /* match found */
25089  ip += mLength;
25090  anchor = ip;
25091 
25092  if (ip <= ilimit) {
25093  /* Complementary insertion */
25094  /* done after iLimit test, as candidates could be > iend-8 */
25095  { U32 const indexToInsert = curr+2;
25096  hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
25097  hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
25098  hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
25099  hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
25100  }
25101 
25102  /* check immediate repcode */
25103  while ( (ip <= ilimit)
25104  && ( (offset_2>0)
25105  & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
25106  /* store sequence */
25107  size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
25108  U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
25109  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
25110  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
25111  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, rLength);
25112  ip += rLength;
25113  anchor = ip;
25114  continue; /* faster when present ... (?) */
25115  }
25116  }
25117  }
25118 }
25119 
25120 
25123  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25124  void const* src, size_t srcSize,
25125  U32 const mls /* template */)
25126 {
25127  ZSTD_compressionParameters const* cParams = &ms->cParams;
25128  U32* const hashLong = ms->hashTable;
25129  const U32 hBitsL = cParams->hashLog;
25130  U32* const hashSmall = ms->chainTable;
25131  const U32 hBitsS = cParams->chainLog;
25132  const BYTE* const base = ms->window.base;
25133  const BYTE* const istart = (const BYTE*)src;
25134  const BYTE* ip = istart;
25135  const BYTE* anchor = istart;
25136  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
25137  /* presumes that, if there is a dictionary, it must be using Attach mode */
25138  const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
25139  const BYTE* const prefixLowest = base + prefixLowestIndex;
25140  const BYTE* const iend = istart + srcSize;
25141  const BYTE* const ilimit = iend - HASH_READ_SIZE;
25142  U32 offset_1=rep[0], offset_2=rep[1];
25143 
25144  const ZSTD_matchState_t* const dms = ms->dictMatchState;
25145  const ZSTD_compressionParameters* const dictCParams = &dms->cParams;
25146  const U32* const dictHashLong = dms->hashTable;
25147  const U32* const dictHashSmall = dms->chainTable;
25148  const U32 dictStartIndex = dms->window.dictLimit;
25149  const BYTE* const dictBase = dms->window.base;
25150  const BYTE* const dictStart = dictBase + dictStartIndex;
25151  const BYTE* const dictEnd = dms->window.nextSrc;
25152  const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase);
25153  const U32 dictHBitsL = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
25154  const U32 dictHBitsS = dictCParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS;
25155  const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart));
25156 
25157  DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic");
25158 
25159  /* if a dictionary is attached, it must be within window range */
25160  assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex);
25161 
25162  if (ms->prefetchCDictTables) {
25163  size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32);
25164  size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32);
25165  PREFETCH_AREA(dictHashLong, hashTableBytes)
25166  PREFETCH_AREA(dictHashSmall, chainTableBytes)
25167  }
25168 
25169  /* init */
25170  ip += (dictAndPrefixLength == 0);
25171 
25172  /* dictMatchState repCode checks don't currently handle repCode == 0
25173  * disabling. */
25174  assert(offset_1 <= dictAndPrefixLength);
25175  assert(offset_2 <= dictAndPrefixLength);
25176 
25177  /* Main Search Loop */
25178  while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
25179  size_t mLength;
25180  U32 offset;
25181  size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
25182  size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
25183  size_t const dictHashAndTagL = ZSTD_hashPtr(ip, dictHBitsL, 8);
25184  size_t const dictHashAndTagS = ZSTD_hashPtr(ip, dictHBitsS, mls);
25185  U32 const dictMatchIndexAndTagL = dictHashLong[dictHashAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS];
25186  U32 const dictMatchIndexAndTagS = dictHashSmall[dictHashAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS];
25187  int const dictTagsMatchL = ZSTD_comparePackedTags(dictMatchIndexAndTagL, dictHashAndTagL);
25188  int const dictTagsMatchS = ZSTD_comparePackedTags(dictMatchIndexAndTagS, dictHashAndTagS);
25189  U32 const curr = (U32)(ip-base);
25190  U32 const matchIndexL = hashLong[h2];
25191  U32 matchIndexS = hashSmall[h];
25192  const BYTE* matchLong = base + matchIndexL;
25193  const BYTE* match = base + matchIndexS;
25194  const U32 repIndex = curr + 1 - offset_1;
25195  const BYTE* repMatch = (repIndex < prefixLowestIndex) ?
25196  dictBase + (repIndex - dictIndexDelta) :
25197  base + repIndex;
25198  hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
25199 
25200  /* check repcode */
25201  if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
25202  && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
25203  const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
25204  mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
25205  ip++;
25206  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
25207  goto _match_stored;
25208  }
25209 
25210  if (matchIndexL > prefixLowestIndex) {
25211  /* check prefix long match */
25212  if (MEM_read64(matchLong) == MEM_read64(ip)) {
25213  mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
25214  offset = (U32)(ip-matchLong);
25215  while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
25216  goto _match_found;
25217  }
25218  } else if (dictTagsMatchL) {
25219  /* check dictMatchState long match */
25220  U32 const dictMatchIndexL = dictMatchIndexAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS;
25221  const BYTE* dictMatchL = dictBase + dictMatchIndexL;
25222  assert(dictMatchL < dictEnd);
25223 
25224  if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) {
25225  mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8;
25226  offset = (U32)(curr - dictMatchIndexL - dictIndexDelta);
25227  while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
25228  goto _match_found;
25229  } }
25230 
25231  if (matchIndexS > prefixLowestIndex) {
25232  /* check prefix short match */
25233  if (MEM_read32(match) == MEM_read32(ip)) {
25234  goto _search_next_long;
25235  }
25236  } else if (dictTagsMatchS) {
25237  /* check dictMatchState short match */
25238  U32 const dictMatchIndexS = dictMatchIndexAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS;
25239  match = dictBase + dictMatchIndexS;
25240  matchIndexS = dictMatchIndexS + dictIndexDelta;
25241 
25242  if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) {
25243  goto _search_next_long;
25244  } }
25245 
25246  ip += ((ip-anchor) >> kSearchStrength) + 1;
25247 #if defined(__aarch64__)
25248  PREFETCH_L1(ip+256);
25249 #endif
25250  continue;
25251 
25252 _search_next_long:
25253  { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
25254  size_t const dictHashAndTagL3 = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
25255  U32 const matchIndexL3 = hashLong[hl3];
25256  U32 const dictMatchIndexAndTagL3 = dictHashLong[dictHashAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS];
25257  int const dictTagsMatchL3 = ZSTD_comparePackedTags(dictMatchIndexAndTagL3, dictHashAndTagL3);
25258  const BYTE* matchL3 = base + matchIndexL3;
25259  hashLong[hl3] = curr + 1;
25260 
25261  /* check prefix long +1 match */
25262  if (matchIndexL3 > prefixLowestIndex) {
25263  if (MEM_read64(matchL3) == MEM_read64(ip+1)) {
25264  mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
25265  ip++;
25266  offset = (U32)(ip-matchL3);
25267  while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
25268  goto _match_found;
25269  }
25270  } else if (dictTagsMatchL3) {
25271  /* check dict long +1 match */
25272  U32 const dictMatchIndexL3 = dictMatchIndexAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS;
25273  const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3;
25274  assert(dictMatchL3 < dictEnd);
25275  if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {
25276  mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8;
25277  ip++;
25278  offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta);
25279  while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
25280  goto _match_found;
25281  } } }
25282 
25283  /* if no long +1 match, explore the short match we found */
25284  if (matchIndexS < prefixLowestIndex) {
25285  mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
25286  offset = (U32)(curr - matchIndexS);
25287  while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
25288  } else {
25289  mLength = ZSTD_count(ip+4, match+4, iend) + 4;
25290  offset = (U32)(ip - match);
25291  while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
25292  }
25293 
25294 _match_found:
25295  offset_2 = offset_1;
25296  offset_1 = offset;
25297 
25298  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
25299 
25300 _match_stored:
25301  /* match found */
25302  ip += mLength;
25303  anchor = ip;
25304 
25305  if (ip <= ilimit) {
25306  /* Complementary insertion */
25307  /* done after iLimit test, as candidates could be > iend-8 */
25308  { U32 const indexToInsert = curr+2;
25309  hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
25310  hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
25311  hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
25312  hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
25313  }
25314 
25315  /* check immediate repcode */
25316  while (ip <= ilimit) {
25317  U32 const current2 = (U32)(ip-base);
25318  U32 const repIndex2 = current2 - offset_2;
25319  const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ?
25320  dictBase + repIndex2 - dictIndexDelta :
25321  base + repIndex2;
25322  if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
25323  && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
25324  const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
25325  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
25326  U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
25327  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
25328  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
25329  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
25330  ip += repLength2;
25331  anchor = ip;
25332  continue;
25333  }
25334  break;
25335  }
25336  }
25337  } /* while (ip < ilimit) */
25338 
25339  /* save reps for next block */
25340  rep[0] = offset_1;
25341  rep[1] = offset_2;
25342 
25343  /* Return the last literals size */
25344  return (size_t)(iend - anchor);
25345 }
25346 
25347 #define ZSTD_GEN_DFAST_FN(dictMode, mls) \
25348  static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \
25349  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
25350  void const* src, size_t srcSize) \
25351  { \
25352  return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \
25353  }
25354 
25359 
25360 ZSTD_GEN_DFAST_FN(dictMatchState, 4)
25361 ZSTD_GEN_DFAST_FN(dictMatchState, 5)
25362 ZSTD_GEN_DFAST_FN(dictMatchState, 6)
25363 ZSTD_GEN_DFAST_FN(dictMatchState, 7)
25364 
25365 
25367  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25368  void const* src, size_t srcSize)
25369 {
25370  const U32 mls = ms->cParams.minMatch;
25371  switch(mls)
25372  {
25373  default: /* includes case 3 */
25374  case 4 :
25375  return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize);
25376  case 5 :
25377  return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize);
25378  case 6 :
25379  return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize);
25380  case 7 :
25381  return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize);
25382  }
25383 }
25384 
25385 
25387  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25388  void const* src, size_t srcSize)
25389 {
25390  const U32 mls = ms->cParams.minMatch;
25391  switch(mls)
25392  {
25393  default: /* includes case 3 */
25394  case 4 :
25395  return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize);
25396  case 5 :
25397  return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize);
25398  case 6 :
25399  return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize);
25400  case 7 :
25401  return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize);
25402  }
25403 }
25404 
25405 
25407  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25408  void const* src, size_t srcSize,
25409  U32 const mls /* template */)
25410 {
25411  ZSTD_compressionParameters const* cParams = &ms->cParams;
25412  U32* const hashLong = ms->hashTable;
25413  U32 const hBitsL = cParams->hashLog;
25414  U32* const hashSmall = ms->chainTable;
25415  U32 const hBitsS = cParams->chainLog;
25416  const BYTE* const istart = (const BYTE*)src;
25417  const BYTE* ip = istart;
25418  const BYTE* anchor = istart;
25419  const BYTE* const iend = istart + srcSize;
25420  const BYTE* const ilimit = iend - 8;
25421  const BYTE* const base = ms->window.base;
25422  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
25423  const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
25424  const U32 dictStartIndex = lowLimit;
25425  const U32 dictLimit = ms->window.dictLimit;
25426  const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;
25427  const BYTE* const prefixStart = base + prefixStartIndex;
25428  const BYTE* const dictBase = ms->window.dictBase;
25429  const BYTE* const dictStart = dictBase + dictStartIndex;
25430  const BYTE* const dictEnd = dictBase + prefixStartIndex;
25431  U32 offset_1=rep[0], offset_2=rep[1];
25432 
25433  DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize);
25434 
25435  /* if extDict is invalidated due to maxDistance, switch to "regular" variant */
25436  if (prefixStartIndex == dictStartIndex)
25437  return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize);
25438 
25439  /* Search Loop */
25440  while (ip < ilimit) { /* < instead of <=, because (ip+1) */
25441  const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
25442  const U32 matchIndex = hashSmall[hSmall];
25443  const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;
25444  const BYTE* match = matchBase + matchIndex;
25445 
25446  const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
25447  const U32 matchLongIndex = hashLong[hLong];
25448  const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base;
25449  const BYTE* matchLong = matchLongBase + matchLongIndex;
25450 
25451  const U32 curr = (U32)(ip-base);
25452  const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */
25453  const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
25454  const BYTE* const repMatch = repBase + repIndex;
25455  size_t mLength;
25456  hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
25457 
25458  if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
25459  & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */
25460  && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
25461  const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
25462  mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
25463  ip++;
25464  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
25465  } else {
25466  if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
25467  const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
25468  const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart;
25469  U32 offset;
25470  mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8;
25471  offset = curr - matchLongIndex;
25472  while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
25473  offset_2 = offset_1;
25474  offset_1 = offset;
25475  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
25476 
25477  } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
25478  size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
25479  U32 const matchIndex3 = hashLong[h3];
25480  const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base;
25481  const BYTE* match3 = match3Base + matchIndex3;
25482  U32 offset;
25483  hashLong[h3] = curr + 1;
25484  if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
25485  const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend;
25486  const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart;
25487  mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8;
25488  ip++;
25489  offset = curr+1 - matchIndex3;
25490  while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
25491  } else {
25492  const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
25493  const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
25494  mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
25495  offset = curr - matchIndex;
25496  while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
25497  }
25498  offset_2 = offset_1;
25499  offset_1 = offset;
25500  ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
25501 
25502  } else {
25503  ip += ((ip-anchor) >> kSearchStrength) + 1;
25504  continue;
25505  } }
25506 
25507  /* move to next sequence start */
25508  ip += mLength;
25509  anchor = ip;
25510 
25511  if (ip <= ilimit) {
25512  /* Complementary insertion */
25513  /* done after iLimit test, as candidates could be > iend-8 */
25514  { U32 const indexToInsert = curr+2;
25515  hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
25516  hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
25517  hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
25518  hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
25519  }
25520 
25521  /* check immediate repcode */
25522  while (ip <= ilimit) {
25523  U32 const current2 = (U32)(ip-base);
25524  U32 const repIndex2 = current2 - offset_2;
25525  const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
25526  if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */
25527  & (offset_2 <= current2 - dictStartIndex))
25528  && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
25529  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
25530  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
25531  U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
25532  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
25533  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
25534  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
25535  ip += repLength2;
25536  anchor = ip;
25537  continue;
25538  }
25539  break;
25540  } } }
25541 
25542  /* save reps for next block */
25543  rep[0] = offset_1;
25544  rep[1] = offset_2;
25545 
25546  /* Return the last literals size */
25547  return (size_t)(iend - anchor);
25548 }
25550 ZSTD_GEN_DFAST_FN(extDict, 4)
25551 ZSTD_GEN_DFAST_FN(extDict, 5)
25552 ZSTD_GEN_DFAST_FN(extDict, 6)
25553 ZSTD_GEN_DFAST_FN(extDict, 7)
25554 
25556  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25557  void const* src, size_t srcSize)
25558 {
25559  U32 const mls = ms->cParams.minMatch;
25560  switch(mls)
25561  {
25562  default: /* includes case 3 */
25563  case 4 :
25564  return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize);
25565  case 5 :
25566  return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize);
25567  case 6 :
25568  return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize);
25569  case 7 :
25570  return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize);
25571  }
25572 }
25573 /**** ended inlining compress/zstd_double_fast.c ****/
25574 /**** start inlining compress/zstd_fast.c ****/
25575 /*
25576  * Copyright (c) Meta Platforms, Inc. and affiliates.
25577  * All rights reserved.
25578  *
25579  * This source code is licensed under both the BSD-style license (found in the
25580  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
25581  * in the COPYING file in the root directory of this source tree).
25582  * You may select, at your option, one of the above-listed licenses.
25583  */
25584 
25585 /**** skipping file: zstd_compress_internal.h ****/
25586 /**** skipping file: zstd_fast.h ****/
25587 
25589  const void* const end,
25591 {
25592  const ZSTD_compressionParameters* const cParams = &ms->cParams;
25593  U32* const hashTable = ms->hashTable;
25594  U32 const hBits = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
25595  U32 const mls = cParams->minMatch;
25596  const BYTE* const base = ms->window.base;
25597  const BYTE* ip = base + ms->nextToUpdate;
25598  const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
25599  const U32 fastHashFillStep = 3;
25600 
25601  /* Currently, we always use ZSTD_dtlm_full for filling CDict tables.
25602  * Feel free to remove this assert if there's a good reason! */
25603  assert(dtlm == ZSTD_dtlm_full);
25604 
25605  /* Always insert every fastHashFillStep position into the hash table.
25606  * Insert the other positions if their hash entry is empty.
25607  */
25608  for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {
25609  U32 const curr = (U32)(ip - base);
25610  { size_t const hashAndTag = ZSTD_hashPtr(ip, hBits, mls);
25611  ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr); }
25612 
25613  if (dtlm == ZSTD_dtlm_fast) continue;
25614  /* Only load extra positions for ZSTD_dtlm_full */
25615  { U32 p;
25616  for (p = 1; p < fastHashFillStep; ++p) {
25617  size_t const hashAndTag = ZSTD_hashPtr(ip + p, hBits, mls);
25618  if (hashTable[hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { /* not yet filled */
25619  ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr + p);
25620  } } } }
25621 }
25622 
25624  const void* const end,
25626 {
25627  const ZSTD_compressionParameters* const cParams = &ms->cParams;
25628  U32* const hashTable = ms->hashTable;
25629  U32 const hBits = cParams->hashLog;
25630  U32 const mls = cParams->minMatch;
25631  const BYTE* const base = ms->window.base;
25632  const BYTE* ip = base + ms->nextToUpdate;
25633  const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
25634  const U32 fastHashFillStep = 3;
25635 
25636  /* Currently, we always use ZSTD_dtlm_fast for filling CCtx tables.
25637  * Feel free to remove this assert if there's a good reason! */
25638  assert(dtlm == ZSTD_dtlm_fast);
25639 
25640  /* Always insert every fastHashFillStep position into the hash table.
25641  * Insert the other positions if their hash entry is empty.
25642  */
25643  for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {
25644  U32 const curr = (U32)(ip - base);
25645  size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls);
25646  hashTable[hash0] = curr;
25647  if (dtlm == ZSTD_dtlm_fast) continue;
25648  /* Only load extra positions for ZSTD_dtlm_full */
25649  { U32 p;
25650  for (p = 1; p < fastHashFillStep; ++p) {
25651  size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls);
25652  if (hashTable[hash] == 0) { /* not yet filled */
25653  hashTable[hash] = curr + p;
25654  } } } }
25655 }
25656 
25658  const void* const end,
25661 {
25662  if (tfp == ZSTD_tfp_forCDict) {
25663  ZSTD_fillHashTableForCDict(ms, end, dtlm);
25664  } else {
25665  ZSTD_fillHashTableForCCtx(ms, end, dtlm);
25666  }
25667 }
25668 
25669 
25716 FORCE_INLINE_TEMPLATE size_t
25718  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25719  void const* src, size_t srcSize,
25720  U32 const mls, U32 const hasStep)
25721 {
25722  const ZSTD_compressionParameters* const cParams = &ms->cParams;
25723  U32* const hashTable = ms->hashTable;
25724  U32 const hlog = cParams->hashLog;
25725  /* support stepSize of 0 */
25726  size_t const stepSize = hasStep ? (cParams->targetLength + !(cParams->targetLength) + 1) : 2;
25727  const BYTE* const base = ms->window.base;
25728  const BYTE* const istart = (const BYTE*)src;
25729  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
25730  const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
25731  const BYTE* const prefixStart = base + prefixStartIndex;
25732  const BYTE* const iend = istart + srcSize;
25733  const BYTE* const ilimit = iend - HASH_READ_SIZE;
25734 
25735  const BYTE* anchor = istart;
25736  const BYTE* ip0 = istart;
25737  const BYTE* ip1;
25738  const BYTE* ip2;
25739  const BYTE* ip3;
25740  U32 current0;
25741 
25742  U32 rep_offset1 = rep[0];
25743  U32 rep_offset2 = rep[1];
25744  U32 offsetSaved1 = 0, offsetSaved2 = 0;
25745 
25746  size_t hash0; /* hash for ip0 */
25747  size_t hash1; /* hash for ip1 */
25748  U32 idx; /* match idx for ip0 */
25749  U32 mval; /* src value at match idx */
25750 
25751  U32 offcode;
25752  const BYTE* match0;
25753  size_t mLength;
25754 
25755  /* ip0 and ip1 are always adjacent. The targetLength skipping and
25756  * uncompressibility acceleration is applied to every other position,
25757  * matching the behavior of #1562. step therefore represents the gap
25758  * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */
25759  size_t step;
25760  const BYTE* nextStep;
25761  const size_t kStepIncr = (1 << (kSearchStrength - 1));
25762 
25763  DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
25764  ip0 += (ip0 == prefixStart);
25765  { U32 const curr = (U32)(ip0 - base);
25766  U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
25767  U32 const maxRep = curr - windowLow;
25768  if (rep_offset2 > maxRep) offsetSaved2 = rep_offset2, rep_offset2 = 0;
25769  if (rep_offset1 > maxRep) offsetSaved1 = rep_offset1, rep_offset1 = 0;
25770  }
25771 
25772  /* start each op */
25773 _start: /* Requires: ip0 */
25774 
25775  step = stepSize;
25776  nextStep = ip0 + kStepIncr;
25777 
25778  /* calculate positions, ip0 - anchor == 0, so we skip step calc */
25779  ip1 = ip0 + 1;
25780  ip2 = ip0 + step;
25781  ip3 = ip2 + 1;
25782 
25783  if (ip3 >= ilimit) {
25784  goto _cleanup;
25785  }
25786 
25787  hash0 = ZSTD_hashPtr(ip0, hlog, mls);
25788  hash1 = ZSTD_hashPtr(ip1, hlog, mls);
25789 
25790  idx = hashTable[hash0];
25791 
25792  do {
25793  /* load repcode match for ip[2]*/
25794  const U32 rval = MEM_read32(ip2 - rep_offset1);
25795 
25796  /* write back hash table entry */
25797  current0 = (U32)(ip0 - base);
25798  hashTable[hash0] = current0;
25799 
25800  /* check repcode at ip[2] */
25801  if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) {
25802  ip0 = ip2;
25803  match0 = ip0 - rep_offset1;
25804  mLength = ip0[-1] == match0[-1];
25805  ip0 -= mLength;
25806  match0 -= mLength;
25807  offcode = REPCODE1_TO_OFFBASE;
25808  mLength += 4;
25809 
25810  /* First write next hash table entry; we've already calculated it.
25811  * This write is known to be safe because the ip1 is before the
25812  * repcode (ip2). */
25813  hashTable[hash1] = (U32)(ip1 - base);
25814 
25815  goto _match;
25816  }
25817 
25818  /* load match for ip[0] */
25819  if (idx >= prefixStartIndex) {
25820  mval = MEM_read32(base + idx);
25821  } else {
25822  mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
25823  }
25824 
25825  /* check match at ip[0] */
25826  if (MEM_read32(ip0) == mval) {
25827  /* found a match! */
25828 
25829  /* First write next hash table entry; we've already calculated it.
25830  * This write is known to be safe because the ip1 == ip0 + 1, so
25831  * we know we will resume searching after ip1 */
25832  hashTable[hash1] = (U32)(ip1 - base);
25833 
25834  goto _offset;
25835  }
25836 
25837  /* lookup ip[1] */
25838  idx = hashTable[hash1];
25839 
25840  /* hash ip[2] */
25841  hash0 = hash1;
25842  hash1 = ZSTD_hashPtr(ip2, hlog, mls);
25843 
25844  /* advance to next positions */
25845  ip0 = ip1;
25846  ip1 = ip2;
25847  ip2 = ip3;
25848 
25849  /* write back hash table entry */
25850  current0 = (U32)(ip0 - base);
25851  hashTable[hash0] = current0;
25852 
25853  /* load match for ip[0] */
25854  if (idx >= prefixStartIndex) {
25855  mval = MEM_read32(base + idx);
25856  } else {
25857  mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
25858  }
25859 
25860  /* check match at ip[0] */
25861  if (MEM_read32(ip0) == mval) {
25862  /* found a match! */
25863 
25864  /* first write next hash table entry; we've already calculated it */
25865  if (step <= 4) {
25866  /* We need to avoid writing an index into the hash table >= the
25867  * position at which we will pick up our searching after we've
25868  * taken this match.
25869  *
25870  * The minimum possible match has length 4, so the earliest ip0
25871  * can be after we take this match will be the current ip0 + 4.
25872  * ip1 is ip0 + step - 1. If ip1 is >= ip0 + 4, we can't safely
25873  * write this position.
25874  */
25875  hashTable[hash1] = (U32)(ip1 - base);
25876  }
25877 
25878  goto _offset;
25879  }
25880 
25881  /* lookup ip[1] */
25882  idx = hashTable[hash1];
25883 
25884  /* hash ip[2] */
25885  hash0 = hash1;
25886  hash1 = ZSTD_hashPtr(ip2, hlog, mls);
25887 
25888  /* advance to next positions */
25889  ip0 = ip1;
25890  ip1 = ip2;
25891  ip2 = ip0 + step;
25892  ip3 = ip1 + step;
25893 
25894  /* calculate step */
25895  if (ip2 >= nextStep) {
25896  step++;
25897  PREFETCH_L1(ip1 + 64);
25898  PREFETCH_L1(ip1 + 128);
25899  nextStep += kStepIncr;
25900  }
25901  } while (ip3 < ilimit);
25902 
25903 _cleanup:
25904  /* Note that there are probably still a couple positions we could search.
25905  * However, it seems to be a meaningful performance hit to try to search
25906  * them. So let's not. */
25907 
25908  /* When the repcodes are outside of the prefix, we set them to zero before the loop.
25909  * When the offsets are still zero, we need to restore them after the block to have a correct
25910  * repcode history. If only one offset was invalid, it is easy. The tricky case is when both
25911  * offsets were invalid. We need to figure out which offset to refill with.
25912  * - If both offsets are zero they are in the same order.
25913  * - If both offsets are non-zero, we won't restore the offsets from `offsetSaved[12]`.
25914  * - If only one is zero, we need to decide which offset to restore.
25915  * - If rep_offset1 is non-zero, then rep_offset2 must be offsetSaved1.
25916  * - It is impossible for rep_offset2 to be non-zero.
25917  *
25918  * So if rep_offset1 started invalid (offsetSaved1 != 0) and became valid (rep_offset1 != 0), then
25919  * set rep[0] = rep_offset1 and rep[1] = offsetSaved1.
25920  */
25921  offsetSaved2 = ((offsetSaved1 != 0) && (rep_offset1 != 0)) ? offsetSaved1 : offsetSaved2;
25922 
25923  /* save reps for next block */
25924  rep[0] = rep_offset1 ? rep_offset1 : offsetSaved1;
25925  rep[1] = rep_offset2 ? rep_offset2 : offsetSaved2;
25926 
25927  /* Return the last literals size */
25928  return (size_t)(iend - anchor);
25929 
25930 _offset: /* Requires: ip0, idx */
25931 
25932  /* Compute the offset code. */
25933  match0 = base + idx;
25934  rep_offset2 = rep_offset1;
25935  rep_offset1 = (U32)(ip0-match0);
25936  offcode = OFFSET_TO_OFFBASE(rep_offset1);
25937  mLength = 4;
25938 
25939  /* Count the backwards match length. */
25940  while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) {
25941  ip0--;
25942  match0--;
25943  mLength++;
25944  }
25945 
25946 _match: /* Requires: ip0, match0, offcode */
25947 
25948  /* Count the forward length. */
25949  mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend);
25950 
25951  ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength);
25952 
25953  ip0 += mLength;
25954  anchor = ip0;
25955 
25956  /* Fill table and check for immediate repcode. */
25957  if (ip0 <= ilimit) {
25958  /* Fill Table */
25959  assert(base+current0+2 > istart); /* check base overflow */
25960  hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
25961  hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
25962 
25963  if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */
25964  while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) {
25965  /* store sequence */
25966  size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4;
25967  { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */
25968  hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
25969  ip0 += rLength;
25970  ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, REPCODE1_TO_OFFBASE, rLength);
25971  anchor = ip0;
25972  continue; /* faster when present (confirmed on gcc-8) ... (?) */
25973  } } }
25974 
25975  goto _start;
25976 }
25977 
25978 #define ZSTD_GEN_FAST_FN(dictMode, mls, step) \
25979  static size_t ZSTD_compressBlock_fast_##dictMode##_##mls##_##step( \
25980  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
25981  void const* src, size_t srcSize) \
25982  { \
25983  return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls, step); \
25984  }
25985 
25986 ZSTD_GEN_FAST_FN(noDict, 4, 1)
25987 ZSTD_GEN_FAST_FN(noDict, 5, 1)
25988 ZSTD_GEN_FAST_FN(noDict, 6, 1)
25989 ZSTD_GEN_FAST_FN(noDict, 7, 1)
25991 ZSTD_GEN_FAST_FN(noDict, 4, 0)
25992 ZSTD_GEN_FAST_FN(noDict, 5, 0)
25993 ZSTD_GEN_FAST_FN(noDict, 6, 0)
25994 ZSTD_GEN_FAST_FN(noDict, 7, 0)
25995 
25997  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25998  void const* src, size_t srcSize)
25999 {
26000  U32 const mls = ms->cParams.minMatch;
26001  assert(ms->dictMatchState == NULL);
26002  if (ms->cParams.targetLength > 1) {
26003  switch(mls)
26004  {
26005  default: /* includes case 3 */
26006  case 4 :
26007  return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize);
26008  case 5 :
26009  return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize);
26010  case 6 :
26011  return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize);
26012  case 7 :
26013  return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize);
26014  }
26015  } else {
26016  switch(mls)
26017  {
26018  default: /* includes case 3 */
26019  case 4 :
26020  return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize);
26021  case 5 :
26022  return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize);
26023  case 6 :
26024  return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize);
26025  case 7 :
26026  return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize);
26027  }
26028 
26029  }
26030 }
26031 
26034  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
26035  void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
26036 {
26037  const ZSTD_compressionParameters* const cParams = &ms->cParams;
26038  U32* const hashTable = ms->hashTable;
26039  U32 const hlog = cParams->hashLog;
26040  /* support stepSize of 0 */
26041  U32 const stepSize = cParams->targetLength + !(cParams->targetLength);
26042  const BYTE* const base = ms->window.base;
26043  const BYTE* const istart = (const BYTE*)src;
26044  const BYTE* ip0 = istart;
26045  const BYTE* ip1 = ip0 + stepSize; /* we assert below that stepSize >= 1 */
26046  const BYTE* anchor = istart;
26047  const U32 prefixStartIndex = ms->window.dictLimit;
26048  const BYTE* const prefixStart = base + prefixStartIndex;
26049  const BYTE* const iend = istart + srcSize;
26050  const BYTE* const ilimit = iend - HASH_READ_SIZE;
26051  U32 offset_1=rep[0], offset_2=rep[1];
26052 
26053  const ZSTD_matchState_t* const dms = ms->dictMatchState;
26054  const ZSTD_compressionParameters* const dictCParams = &dms->cParams ;
26055  const U32* const dictHashTable = dms->hashTable;
26056  const U32 dictStartIndex = dms->window.dictLimit;
26057  const BYTE* const dictBase = dms->window.base;
26058  const BYTE* const dictStart = dictBase + dictStartIndex;
26059  const BYTE* const dictEnd = dms->window.nextSrc;
26060  const U32 dictIndexDelta = prefixStartIndex - (U32)(dictEnd - dictBase);
26061  const U32 dictAndPrefixLength = (U32)(istart - prefixStart + dictEnd - dictStart);
26062  const U32 dictHBits = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
26063 
26064  /* if a dictionary is still attached, it necessarily means that
26065  * it is within window size. So we just check it. */
26066  const U32 maxDistance = 1U << cParams->windowLog;
26067  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
26068  assert(endIndex - prefixStartIndex <= maxDistance);
26069  (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */
26070 
26071  (void)hasStep; /* not currently specialized on whether it's accelerated */
26072 
26073  /* ensure there will be no underflow
26074  * when translating a dict index into a local index */
26075  assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
26076 
26077  if (ms->prefetchCDictTables) {
26078  size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32);
26079  PREFETCH_AREA(dictHashTable, hashTableBytes)
26080  }
26081 
26082  /* init */
26083  DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic");
26084  ip0 += (dictAndPrefixLength == 0);
26085  /* dictMatchState repCode checks don't currently handle repCode == 0
26086  * disabling. */
26087  assert(offset_1 <= dictAndPrefixLength);
26088  assert(offset_2 <= dictAndPrefixLength);
26089 
26090  /* Outer search loop */
26091  assert(stepSize >= 1);
26092  while (ip1 <= ilimit) { /* repcode check at (ip0 + 1) is safe because ip0 < ip1 */
26093  size_t mLength;
26094  size_t hash0 = ZSTD_hashPtr(ip0, hlog, mls);
26095 
26096  size_t const dictHashAndTag0 = ZSTD_hashPtr(ip0, dictHBits, mls);
26097  U32 dictMatchIndexAndTag = dictHashTable[dictHashAndTag0 >> ZSTD_SHORT_CACHE_TAG_BITS];
26098  int dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag0);
26099 
26100  U32 matchIndex = hashTable[hash0];
26101  U32 curr = (U32)(ip0 - base);
26102  size_t step = stepSize;
26103  const size_t kStepIncr = 1 << kSearchStrength;
26104  const BYTE* nextStep = ip0 + kStepIncr;
26105 
26106  /* Inner search loop */
26107  while (1) {
26108  const BYTE* match = base + matchIndex;
26109  const U32 repIndex = curr + 1 - offset_1;
26110  const BYTE* repMatch = (repIndex < prefixStartIndex) ?
26111  dictBase + (repIndex - dictIndexDelta) :
26112  base + repIndex;
26113  const size_t hash1 = ZSTD_hashPtr(ip1, hlog, mls);
26114  size_t const dictHashAndTag1 = ZSTD_hashPtr(ip1, dictHBits, mls);
26115  hashTable[hash0] = curr; /* update hash table */
26116 
26117  if (((U32) ((prefixStartIndex - 1) - repIndex) >=
26118  3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */
26119  && (MEM_read32(repMatch) == MEM_read32(ip0 + 1))) {
26120  const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
26121  mLength = ZSTD_count_2segments(ip0 + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4;
26122  ip0++;
26123  ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
26124  break;
26125  }
26126 
26127  if (dictTagsMatch) {
26128  /* Found a possible dict match */
26129  const U32 dictMatchIndex = dictMatchIndexAndTag >> ZSTD_SHORT_CACHE_TAG_BITS;
26130  const BYTE* dictMatch = dictBase + dictMatchIndex;
26131  if (dictMatchIndex > dictStartIndex &&
26132  MEM_read32(dictMatch) == MEM_read32(ip0)) {
26133  /* To replicate extDict parse behavior, we only use dict matches when the normal matchIndex is invalid */
26134  if (matchIndex <= prefixStartIndex) {
26135  U32 const offset = (U32) (curr - dictMatchIndex - dictIndexDelta);
26136  mLength = ZSTD_count_2segments(ip0 + 4, dictMatch + 4, iend, dictEnd, prefixStart) + 4;
26137  while (((ip0 > anchor) & (dictMatch > dictStart))
26138  && (ip0[-1] == dictMatch[-1])) {
26139  ip0--;
26140  dictMatch--;
26141  mLength++;
26142  } /* catch up */
26143  offset_2 = offset_1;
26144  offset_1 = offset;
26145  ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
26146  break;
26147  }
26148  }
26149  }
26150 
26151  if (matchIndex > prefixStartIndex && MEM_read32(match) == MEM_read32(ip0)) {
26152  /* found a regular match */
26153  U32 const offset = (U32) (ip0 - match);
26154  mLength = ZSTD_count(ip0 + 4, match + 4, iend) + 4;
26155  while (((ip0 > anchor) & (match > prefixStart))
26156  && (ip0[-1] == match[-1])) {
26157  ip0--;
26158  match--;
26159  mLength++;
26160  } /* catch up */
26161  offset_2 = offset_1;
26162  offset_1 = offset;
26163  ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
26164  break;
26165  }
26166 
26167  /* Prepare for next iteration */
26168  dictMatchIndexAndTag = dictHashTable[dictHashAndTag1 >> ZSTD_SHORT_CACHE_TAG_BITS];
26169  dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag1);
26170  matchIndex = hashTable[hash1];
26171 
26172  if (ip1 >= nextStep) {
26173  step++;
26174  nextStep += kStepIncr;
26175  }
26176  ip0 = ip1;
26177  ip1 = ip1 + step;
26178  if (ip1 > ilimit) goto _cleanup;
26179 
26180  curr = (U32)(ip0 - base);
26181  hash0 = hash1;
26182  } /* end inner search loop */
26183 
26184  /* match found */
26185  assert(mLength);
26186  ip0 += mLength;
26187  anchor = ip0;
26188 
26189  if (ip0 <= ilimit) {
26190  /* Fill Table */
26191  assert(base+curr+2 > istart); /* check base overflow */
26192  hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */
26193  hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
26194 
26195  /* check immediate repcode */
26196  while (ip0 <= ilimit) {
26197  U32 const current2 = (U32)(ip0-base);
26198  U32 const repIndex2 = current2 - offset_2;
26199  const BYTE* repMatch2 = repIndex2 < prefixStartIndex ?
26200  dictBase - dictIndexDelta + repIndex2 :
26201  base + repIndex2;
26202  if ( ((U32)((prefixStartIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
26203  && (MEM_read32(repMatch2) == MEM_read32(ip0))) {
26204  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
26205  size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
26206  U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
26207  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
26208  hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = current2;
26209  ip0 += repLength2;
26210  anchor = ip0;
26211  continue;
26212  }
26213  break;
26214  }
26215  }
26216 
26217  /* Prepare for next iteration */
26218  assert(ip0 == anchor);
26219  ip1 = ip0 + stepSize;
26220  }
26221 
26222 _cleanup:
26223  /* save reps for next block */
26224  rep[0] = offset_1;
26225  rep[1] = offset_2;
26226 
26227  /* Return the last literals size */
26228  return (size_t)(iend - anchor);
26229 }
26230 
26232 ZSTD_GEN_FAST_FN(dictMatchState, 4, 0)
26233 ZSTD_GEN_FAST_FN(dictMatchState, 5, 0)
26234 ZSTD_GEN_FAST_FN(dictMatchState, 6, 0)
26235 ZSTD_GEN_FAST_FN(dictMatchState, 7, 0)
26236 
26238  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
26239  void const* src, size_t srcSize)
26240 {
26241  U32 const mls = ms->cParams.minMatch;
26242  assert(ms->dictMatchState != NULL);
26243  switch(mls)
26244  {
26245  default: /* includes case 3 */
26246  case 4 :
26247  return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize);
26248  case 5 :
26249  return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize);
26250  case 6 :
26251  return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize);
26252  case 7 :
26253  return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize);
26254  }
26255 }
26256 
26257 
26259  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
26260  void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
26261 {
26262  const ZSTD_compressionParameters* const cParams = &ms->cParams;
26263  U32* const hashTable = ms->hashTable;
26264  U32 const hlog = cParams->hashLog;
26265  /* support stepSize of 0 */
26266  size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1;
26267  const BYTE* const base = ms->window.base;
26268  const BYTE* const dictBase = ms->window.dictBase;
26269  const BYTE* const istart = (const BYTE*)src;
26270  const BYTE* anchor = istart;
26271  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
26272  const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
26273  const U32 dictStartIndex = lowLimit;
26274  const BYTE* const dictStart = dictBase + dictStartIndex;
26275  const U32 dictLimit = ms->window.dictLimit;
26276  const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit;
26277  const BYTE* const prefixStart = base + prefixStartIndex;
26278  const BYTE* const dictEnd = dictBase + prefixStartIndex;
26279  const BYTE* const iend = istart + srcSize;
26280  const BYTE* const ilimit = iend - 8;
26281  U32 offset_1=rep[0], offset_2=rep[1];
26282  U32 offsetSaved1 = 0, offsetSaved2 = 0;
26283 
26284  const BYTE* ip0 = istart;
26285  const BYTE* ip1;
26286  const BYTE* ip2;
26287  const BYTE* ip3;
26288  U32 current0;
26289 
26290 
26291  size_t hash0; /* hash for ip0 */
26292  size_t hash1; /* hash for ip1 */
26293  U32 idx; /* match idx for ip0 */
26294  const BYTE* idxBase; /* base pointer for idx */
26295 
26296  U32 offcode;
26297  const BYTE* match0;
26298  size_t mLength;
26299  const BYTE* matchEnd = 0; /* initialize to avoid warning, assert != 0 later */
26300 
26301  size_t step;
26302  const BYTE* nextStep;
26303  const size_t kStepIncr = (1 << (kSearchStrength - 1));
26304 
26305  (void)hasStep; /* not currently specialized on whether it's accelerated */
26306 
26307  DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1);
26308 
26309  /* switch to "regular" variant if extDict is invalidated due to maxDistance */
26310  if (prefixStartIndex == dictStartIndex)
26311  return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize);
26312 
26313  { U32 const curr = (U32)(ip0 - base);
26314  U32 const maxRep = curr - dictStartIndex;
26315  if (offset_2 >= maxRep) offsetSaved2 = offset_2, offset_2 = 0;
26316  if (offset_1 >= maxRep) offsetSaved1 = offset_1, offset_1 = 0;
26317  }
26318 
26319  /* start each op */
26320 _start: /* Requires: ip0 */
26321 
26322  step = stepSize;
26323  nextStep = ip0 + kStepIncr;
26324 
26325  /* calculate positions, ip0 - anchor == 0, so we skip step calc */
26326  ip1 = ip0 + 1;
26327  ip2 = ip0 + step;
26328  ip3 = ip2 + 1;
26329 
26330  if (ip3 >= ilimit) {
26331  goto _cleanup;
26332  }
26333 
26334  hash0 = ZSTD_hashPtr(ip0, hlog, mls);
26335  hash1 = ZSTD_hashPtr(ip1, hlog, mls);
26336 
26337  idx = hashTable[hash0];
26338  idxBase = idx < prefixStartIndex ? dictBase : base;
26339 
26340  do {
26341  { /* load repcode match for ip[2] */
26342  U32 const current2 = (U32)(ip2 - base);
26343  U32 const repIndex = current2 - offset_1;
26344  const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
26345  U32 rval;
26346  if ( ((U32)(prefixStartIndex - repIndex) >= 4) /* intentional underflow */
26347  & (offset_1 > 0) ) {
26348  rval = MEM_read32(repBase + repIndex);
26349  } else {
26350  rval = MEM_read32(ip2) ^ 1; /* guaranteed to not match. */
26351  }
26352 
26353  /* write back hash table entry */
26354  current0 = (U32)(ip0 - base);
26355  hashTable[hash0] = current0;
26356 
26357  /* check repcode at ip[2] */
26358  if (MEM_read32(ip2) == rval) {
26359  ip0 = ip2;
26360  match0 = repBase + repIndex;
26361  matchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
26362  assert((match0 != prefixStart) & (match0 != dictStart));
26363  mLength = ip0[-1] == match0[-1];
26364  ip0 -= mLength;
26365  match0 -= mLength;
26366  offcode = REPCODE1_TO_OFFBASE;
26367  mLength += 4;
26368  goto _match;
26369  } }
26370 
26371  { /* load match for ip[0] */
26372  U32 const mval = idx >= dictStartIndex ?
26373  MEM_read32(idxBase + idx) :
26374  MEM_read32(ip0) ^ 1; /* guaranteed not to match */
26375 
26376  /* check match at ip[0] */
26377  if (MEM_read32(ip0) == mval) {
26378  /* found a match! */
26379  goto _offset;
26380  } }
26381 
26382  /* lookup ip[1] */
26383  idx = hashTable[hash1];
26384  idxBase = idx < prefixStartIndex ? dictBase : base;
26385 
26386  /* hash ip[2] */
26387  hash0 = hash1;
26388  hash1 = ZSTD_hashPtr(ip2, hlog, mls);
26389 
26390  /* advance to next positions */
26391  ip0 = ip1;
26392  ip1 = ip2;
26393  ip2 = ip3;
26394 
26395  /* write back hash table entry */
26396  current0 = (U32)(ip0 - base);
26397  hashTable[hash0] = current0;
26398 
26399  { /* load match for ip[0] */
26400  U32 const mval = idx >= dictStartIndex ?
26401  MEM_read32(idxBase + idx) :
26402  MEM_read32(ip0) ^ 1; /* guaranteed not to match */
26403 
26404  /* check match at ip[0] */
26405  if (MEM_read32(ip0) == mval) {
26406  /* found a match! */
26407  goto _offset;
26408  } }
26409 
26410  /* lookup ip[1] */
26411  idx = hashTable[hash1];
26412  idxBase = idx < prefixStartIndex ? dictBase : base;
26413 
26414  /* hash ip[2] */
26415  hash0 = hash1;
26416  hash1 = ZSTD_hashPtr(ip2, hlog, mls);
26417 
26418  /* advance to next positions */
26419  ip0 = ip1;
26420  ip1 = ip2;
26421  ip2 = ip0 + step;
26422  ip3 = ip1 + step;
26423 
26424  /* calculate step */
26425  if (ip2 >= nextStep) {
26426  step++;
26427  PREFETCH_L1(ip1 + 64);
26428  PREFETCH_L1(ip1 + 128);
26429  nextStep += kStepIncr;
26430  }
26431  } while (ip3 < ilimit);
26432 
26433 _cleanup:
26434  /* Note that there are probably still a couple positions we could search.
26435  * However, it seems to be a meaningful performance hit to try to search
26436  * them. So let's not. */
26437 
26438  /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0),
26439  * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */
26440  offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2;
26441 
26442  /* save reps for next block */
26443  rep[0] = offset_1 ? offset_1 : offsetSaved1;
26444  rep[1] = offset_2 ? offset_2 : offsetSaved2;
26445 
26446  /* Return the last literals size */
26447  return (size_t)(iend - anchor);
26448 
26449 _offset: /* Requires: ip0, idx, idxBase */
26450 
26451  /* Compute the offset code. */
26452  { U32 const offset = current0 - idx;
26453  const BYTE* const lowMatchPtr = idx < prefixStartIndex ? dictStart : prefixStart;
26454  matchEnd = idx < prefixStartIndex ? dictEnd : iend;
26455  match0 = idxBase + idx;
26456  offset_2 = offset_1;
26457  offset_1 = offset;
26458  offcode = OFFSET_TO_OFFBASE(offset);
26459  mLength = 4;
26460 
26461  /* Count the backwards match length. */
26462  while (((ip0>anchor) & (match0>lowMatchPtr)) && (ip0[-1] == match0[-1])) {
26463  ip0--;
26464  match0--;
26465  mLength++;
26466  } }
26467 
26468 _match: /* Requires: ip0, match0, offcode, matchEnd */
26469 
26470  /* Count the forward length. */
26471  assert(matchEnd != 0);
26472  mLength += ZSTD_count_2segments(ip0 + mLength, match0 + mLength, iend, matchEnd, prefixStart);
26473 
26474  ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength);
26475 
26476  ip0 += mLength;
26477  anchor = ip0;
26478 
26479  /* write next hash table entry */
26480  if (ip1 < ip0) {
26481  hashTable[hash1] = (U32)(ip1 - base);
26482  }
26483 
26484  /* Fill table and check for immediate repcode. */
26485  if (ip0 <= ilimit) {
26486  /* Fill Table */
26487  assert(base+current0+2 > istart); /* check base overflow */
26488  hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
26489  hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
26490 
26491  while (ip0 <= ilimit) {
26492  U32 const repIndex2 = (U32)(ip0-base) - offset_2;
26493  const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
26494  if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 > 0)) /* intentional underflow */
26495  && (MEM_read32(repMatch2) == MEM_read32(ip0)) ) {
26496  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
26497  size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
26498  { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */
26499  ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
26500  hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
26501  ip0 += repLength2;
26502  anchor = ip0;
26503  continue;
26504  }
26505  break;
26506  } }
26507 
26508  goto _start;
26509 }
26511 ZSTD_GEN_FAST_FN(extDict, 4, 0)
26512 ZSTD_GEN_FAST_FN(extDict, 5, 0)
26513 ZSTD_GEN_FAST_FN(extDict, 6, 0)
26514 ZSTD_GEN_FAST_FN(extDict, 7, 0)
26515 
26517  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
26518  void const* src, size_t srcSize)
26519 {
26520  U32 const mls = ms->cParams.minMatch;
26521  assert(ms->dictMatchState == NULL);
26522  switch(mls)
26523  {
26524  default: /* includes case 3 */
26525  case 4 :
26526  return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize);
26527  case 5 :
26528  return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize);
26529  case 6 :
26530  return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize);
26531  case 7 :
26532  return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize);
26533  }
26534 }
26535 /**** ended inlining compress/zstd_fast.c ****/
26536 /**** start inlining compress/zstd_lazy.c ****/
26537 /*
26538  * Copyright (c) Meta Platforms, Inc. and affiliates.
26539  * All rights reserved.
26540  *
26541  * This source code is licensed under both the BSD-style license (found in the
26542  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
26543  * in the COPYING file in the root directory of this source tree).
26544  * You may select, at your option, one of the above-listed licenses.
26545  */
26546 
26547 /**** skipping file: zstd_compress_internal.h ****/
26548 /**** skipping file: zstd_lazy.h ****/
26549 /**** skipping file: ../common/bits.h ****/
26550 
26551 #define kLazySkippingStep 8
26552 
26554 /*-*************************************
26555 * Binary Tree search
26556 ***************************************/
26557 
26558 static void
26560  const BYTE* ip, const BYTE* iend,
26561  U32 mls)
26562 {
26563  const ZSTD_compressionParameters* const cParams = &ms->cParams;
26564  U32* const hashTable = ms->hashTable;
26565  U32 const hashLog = cParams->hashLog;
26566 
26567  U32* const bt = ms->chainTable;
26568  U32 const btLog = cParams->chainLog - 1;
26569  U32 const btMask = (1 << btLog) - 1;
26570 
26571  const BYTE* const base = ms->window.base;
26572  U32 const target = (U32)(ip - base);
26573  U32 idx = ms->nextToUpdate;
26574 
26575  if (idx != target)
26576  DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)",
26577  idx, target, ms->window.dictLimit);
26578  assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */
26579  (void)iend;
26580 
26581  assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */
26582  for ( ; idx < target ; idx++) {
26583  size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */
26584  U32 const matchIndex = hashTable[h];
26585 
26586  U32* const nextCandidatePtr = bt + 2*(idx&btMask);
26587  U32* const sortMarkPtr = nextCandidatePtr + 1;
26588 
26589  DEBUGLOG(8, "ZSTD_updateDUBT: insert %u", idx);
26590  hashTable[h] = idx; /* Update Hash Table */
26591  *nextCandidatePtr = matchIndex; /* update BT like a chain */
26592  *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK;
26593  }
26594  ms->nextToUpdate = target;
26595 }
26596 
26602 static void
26604  U32 curr, const BYTE* inputEnd,
26605  U32 nbCompares, U32 btLow,
26606  const ZSTD_dictMode_e dictMode)
26607 {
26608  const ZSTD_compressionParameters* const cParams = &ms->cParams;
26609  U32* const bt = ms->chainTable;
26610  U32 const btLog = cParams->chainLog - 1;
26611  U32 const btMask = (1 << btLog) - 1;
26612  size_t commonLengthSmaller=0, commonLengthLarger=0;
26613  const BYTE* const base = ms->window.base;
26614  const BYTE* const dictBase = ms->window.dictBase;
26615  const U32 dictLimit = ms->window.dictLimit;
26616  const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr;
26617  const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit;
26618  const BYTE* const dictEnd = dictBase + dictLimit;
26619  const BYTE* const prefixStart = base + dictLimit;
26620  const BYTE* match;
26621  U32* smallerPtr = bt + 2*(curr&btMask);
26622  U32* largerPtr = smallerPtr + 1;
26623  U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
26624  U32 dummy32; /* to be nullified at the end */
26625  U32 const windowValid = ms->window.lowLimit;
26626  U32 const maxDistance = 1U << cParams->windowLog;
26627  U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid;
26628 
26629 
26630  DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
26631  curr, dictLimit, windowLow);
26632  assert(curr >= btLow);
26633  assert(ip < iend); /* condition for ZSTD_count */
26634 
26635  for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
26636  U32* const nextPtr = bt + 2*(matchIndex & btMask);
26637  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
26638  assert(matchIndex < curr);
26639  /* note : all candidates are now supposed sorted,
26640  * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK
26641  * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */
26642 
26643  if ( (dictMode != ZSTD_extDict)
26644  || (matchIndex+matchLength >= dictLimit) /* both in current segment*/
26645  || (curr < dictLimit) /* both in extDict */) {
26646  const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
26647  || (matchIndex+matchLength >= dictLimit)) ?
26648  base : dictBase;
26649  assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */
26650  || (curr < dictLimit) );
26651  match = mBase + matchIndex;
26652  matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
26653  } else {
26654  match = dictBase + matchIndex;
26655  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
26656  if (matchIndex+matchLength >= dictLimit)
26657  match = base + matchIndex; /* preparation for next read of match[matchLength] */
26658  }
26659 
26660  DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ",
26661  curr, matchIndex, (U32)matchLength);
26662 
26663  if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
26664  break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
26665  }
26666 
26667  if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */
26668  /* match is smaller than current */
26669  *smallerPtr = matchIndex; /* update smaller idx */
26670  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
26671  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */
26672  DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u",
26673  matchIndex, btLow, nextPtr[1]);
26674  smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */
26675  matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */
26676  } else {
26677  /* match is larger than current */
26678  *largerPtr = matchIndex;
26679  commonLengthLarger = matchLength;
26680  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */
26681  DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u",
26682  matchIndex, btLow, nextPtr[0]);
26683  largerPtr = nextPtr;
26684  matchIndex = nextPtr[0];
26685  } }
26687  *smallerPtr = *largerPtr = 0;
26688 }
26689 
26690 
26691 static size_t
26693  const ZSTD_matchState_t* ms,
26694  const BYTE* const ip, const BYTE* const iend,
26695  size_t* offsetPtr,
26696  size_t bestLength,
26697  U32 nbCompares,
26698  U32 const mls,
26699  const ZSTD_dictMode_e dictMode)
26700 {
26701  const ZSTD_matchState_t * const dms = ms->dictMatchState;
26702  const ZSTD_compressionParameters* const dmsCParams = &dms->cParams;
26703  const U32 * const dictHashTable = dms->hashTable;
26704  U32 const hashLog = dmsCParams->hashLog;
26705  size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
26706  U32 dictMatchIndex = dictHashTable[h];
26707 
26708  const BYTE* const base = ms->window.base;
26709  const BYTE* const prefixStart = base + ms->window.dictLimit;
26710  U32 const curr = (U32)(ip-base);
26711  const BYTE* const dictBase = dms->window.base;
26712  const BYTE* const dictEnd = dms->window.nextSrc;
26713  U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);
26714  U32 const dictLowLimit = dms->window.lowLimit;
26715  U32 const dictIndexDelta = ms->window.lowLimit - dictHighLimit;
26716 
26717  U32* const dictBt = dms->chainTable;
26718  U32 const btLog = dmsCParams->chainLog - 1;
26719  U32 const btMask = (1 << btLog) - 1;
26720  U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask;
26721 
26722  size_t commonLengthSmaller=0, commonLengthLarger=0;
26723 
26724  (void)dictMode;
26725  assert(dictMode == ZSTD_dictMatchState);
26726 
26727  for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) {
26728  U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);
26729  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
26730  const BYTE* match = dictBase + dictMatchIndex;
26731  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
26732  if (dictMatchIndex+matchLength >= dictHighLimit)
26733  match = base + dictMatchIndex + dictIndexDelta; /* to prepare for next usage of match[matchLength] */
26734 
26735  if (matchLength > bestLength) {
26736  U32 matchIndex = dictMatchIndex + dictIndexDelta;
26737  if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
26738  DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
26739  curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, OFFSET_TO_OFFBASE(curr - matchIndex), dictMatchIndex, matchIndex);
26740  bestLength = matchLength, *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex);
26741  }
26742  if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
26743  break; /* drop, to guarantee consistency (miss a little bit of compression) */
26744  }
26745  }
26746 
26747  if (match[matchLength] < ip[matchLength]) {
26748  if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */
26749  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
26750  dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
26751  } else {
26752  /* match is larger than current */
26753  if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */
26754  commonLengthLarger = matchLength;
26755  dictMatchIndex = nextPtr[0];
26756  }
26757  }
26758 
26759  if (bestLength >= MINMATCH) {
26760  U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offsetPtr); (void)mIndex;
26761  DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
26762  curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
26763  }
26764  return bestLength;
26765 
26766 }
26767 
26768 
26769 static size_t
26771  const BYTE* const ip, const BYTE* const iend,
26772  size_t* offBasePtr,
26773  U32 const mls,
26774  const ZSTD_dictMode_e dictMode)
26775 {
26776  const ZSTD_compressionParameters* const cParams = &ms->cParams;
26777  U32* const hashTable = ms->hashTable;
26778  U32 const hashLog = cParams->hashLog;
26779  size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
26780  U32 matchIndex = hashTable[h];
26781 
26782  const BYTE* const base = ms->window.base;
26783  U32 const curr = (U32)(ip-base);
26784  U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
26785 
26786  U32* const bt = ms->chainTable;
26787  U32 const btLog = cParams->chainLog - 1;
26788  U32 const btMask = (1 << btLog) - 1;
26789  U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
26790  U32 const unsortLimit = MAX(btLow, windowLow);
26791 
26792  U32* nextCandidate = bt + 2*(matchIndex&btMask);
26793  U32* unsortedMark = bt + 2*(matchIndex&btMask) + 1;
26794  U32 nbCompares = 1U << cParams->searchLog;
26795  U32 nbCandidates = nbCompares;
26796  U32 previousCandidate = 0;
26797 
26798  DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr);
26799  assert(ip <= iend-8); /* required for h calculation */
26800  assert(dictMode != ZSTD_dedicatedDictSearch);
26801 
26802  /* reach end of unsorted candidates list */
26803  while ( (matchIndex > unsortLimit)
26804  && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK)
26805  && (nbCandidates > 1) ) {
26806  DEBUGLOG(8, "ZSTD_DUBT_findBestMatch: candidate %u is unsorted",
26807  matchIndex);
26808  *unsortedMark = previousCandidate; /* the unsortedMark becomes a reversed chain, to move up back to original position */
26809  previousCandidate = matchIndex;
26810  matchIndex = *nextCandidate;
26811  nextCandidate = bt + 2*(matchIndex&btMask);
26812  unsortedMark = bt + 2*(matchIndex&btMask) + 1;
26813  nbCandidates --;
26814  }
26815 
26816  /* nullify last candidate if it's still unsorted
26817  * simplification, detrimental to compression ratio, beneficial for speed */
26818  if ( (matchIndex > unsortLimit)
26819  && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) {
26820  DEBUGLOG(7, "ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u",
26821  matchIndex);
26822  *nextCandidate = *unsortedMark = 0;
26823  }
26824 
26825  /* batch sort stacked candidates */
26826  matchIndex = previousCandidate;
26827  while (matchIndex) { /* will end on matchIndex == 0 */
26828  U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1;
26829  U32 const nextCandidateIdx = *nextCandidateIdxPtr;
26830  ZSTD_insertDUBT1(ms, matchIndex, iend,
26831  nbCandidates, unsortLimit, dictMode);
26832  matchIndex = nextCandidateIdx;
26833  nbCandidates++;
26834  }
26835 
26836  /* find longest match */
26837  { size_t commonLengthSmaller = 0, commonLengthLarger = 0;
26838  const BYTE* const dictBase = ms->window.dictBase;
26839  const U32 dictLimit = ms->window.dictLimit;
26840  const BYTE* const dictEnd = dictBase + dictLimit;
26841  const BYTE* const prefixStart = base + dictLimit;
26842  U32* smallerPtr = bt + 2*(curr&btMask);
26843  U32* largerPtr = bt + 2*(curr&btMask) + 1;
26844  U32 matchEndIdx = curr + 8 + 1;
26845  U32 dummy32; /* to be nullified at the end */
26846  size_t bestLength = 0;
26847 
26848  matchIndex = hashTable[h];
26849  hashTable[h] = curr; /* Update Hash Table */
26850 
26851  for (; nbCompares && (matchIndex > windowLow); --nbCompares) {
26852  U32* const nextPtr = bt + 2*(matchIndex & btMask);
26853  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
26854  const BYTE* match;
26855 
26856  if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) {
26857  match = base + matchIndex;
26858  matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
26859  } else {
26860  match = dictBase + matchIndex;
26861  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
26862  if (matchIndex+matchLength >= dictLimit)
26863  match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
26864  }
26865 
26866  if (matchLength > bestLength) {
26867  if (matchLength > matchEndIdx - matchIndex)
26868  matchEndIdx = matchIndex + (U32)matchLength;
26869  if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)*offBasePtr)) )
26870  bestLength = matchLength, *offBasePtr = OFFSET_TO_OFFBASE(curr - matchIndex);
26871  if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
26872  if (dictMode == ZSTD_dictMatchState) {
26873  nbCompares = 0; /* in addition to avoiding checking any
26874  * further in this loop, make sure we
26875  * skip checking in the dictionary. */
26876  }
26877  break; /* drop, to guarantee consistency (miss a little bit of compression) */
26878  }
26879  }
26880 
26881  if (match[matchLength] < ip[matchLength]) {
26882  /* match is smaller than current */
26883  *smallerPtr = matchIndex; /* update smaller idx */
26884  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
26885  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
26886  smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
26887  matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
26888  } else {
26889  /* match is larger than current */
26890  *largerPtr = matchIndex;
26891  commonLengthLarger = matchLength;
26892  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
26893  largerPtr = nextPtr;
26894  matchIndex = nextPtr[0];
26895  } }
26896 
26897  *smallerPtr = *largerPtr = 0;
26898 
26899  assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
26900  if (dictMode == ZSTD_dictMatchState && nbCompares) {
26901  bestLength = ZSTD_DUBT_findBetterDictMatch(
26902  ms, ip, iend,
26903  offBasePtr, bestLength, nbCompares,
26904  mls, dictMode);
26905  }
26906 
26907  assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */
26908  ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
26909  if (bestLength >= MINMATCH) {
26910  U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offBasePtr); (void)mIndex;
26911  DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
26912  curr, (U32)bestLength, (U32)*offBasePtr, mIndex);
26913  }
26914  return bestLength;
26915  }
26916 }
26917 
26918 
26920 FORCE_INLINE_TEMPLATE size_t
26922  const BYTE* const ip, const BYTE* const iLimit,
26923  size_t* offBasePtr,
26924  const U32 mls /* template */,
26925  const ZSTD_dictMode_e dictMode)
26926 {
26927  DEBUGLOG(7, "ZSTD_BtFindBestMatch");
26928  if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
26929  ZSTD_updateDUBT(ms, ip, iLimit, mls);
26930  return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offBasePtr, mls, dictMode);
26932 
26933 /***********************************
26934 * Dedicated dict search
26935 ***********************************/
26936 
26938 {
26939  const BYTE* const base = ms->window.base;
26940  U32 const target = (U32)(ip - base);
26941  U32* const hashTable = ms->hashTable;
26942  U32* const chainTable = ms->chainTable;
26943  U32 const chainSize = 1 << ms->cParams.chainLog;
26944  U32 idx = ms->nextToUpdate;
26945  U32 const minChain = chainSize < target - idx ? target - chainSize : idx;
26946  U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG;
26947  U32 const cacheSize = bucketSize - 1;
26948  U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize;
26949  U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts;
26950 
26951  /* We know the hashtable is oversized by a factor of `bucketSize`.
26952  * We are going to temporarily pretend `bucketSize == 1`, keeping only a
26953  * single entry. We will use the rest of the space to construct a temporary
26954  * chaintable.
26955  */
26956  U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
26957  U32* const tmpHashTable = hashTable;
26958  U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
26959  U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
26960  U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
26961  U32 hashIdx;
26962 
26963  assert(ms->cParams.chainLog <= 24);
26964  assert(ms->cParams.hashLog > ms->cParams.chainLog);
26965  assert(idx != 0);
26966  assert(tmpMinChain <= minChain);
26967 
26968  /* fill conventional hash table and conventional chain table */
26969  for ( ; idx < target; idx++) {
26970  U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch);
26971  if (idx >= tmpMinChain) {
26972  tmpChainTable[idx - tmpMinChain] = hashTable[h];
26973  }
26974  tmpHashTable[h] = idx;
26975  }
26976 
26977  /* sort chains into ddss chain table */
26978  {
26979  U32 chainPos = 0;
26980  for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) {
26981  U32 count;
26982  U32 countBeyondMinChain = 0;
26983  U32 i = tmpHashTable[hashIdx];
26984  for (count = 0; i >= tmpMinChain && count < cacheSize; count++) {
26985  /* skip through the chain to the first position that won't be
26986  * in the hash cache bucket */
26987  if (i < minChain) {
26988  countBeyondMinChain++;
26989  }
26990  i = tmpChainTable[i - tmpMinChain];
26991  }
26992  if (count == cacheSize) {
26993  for (count = 0; count < chainLimit;) {
26994  if (i < minChain) {
26995  if (!i || ++countBeyondMinChain > cacheSize) {
26996  /* only allow pulling `cacheSize` number of entries
26997  * into the cache or chainTable beyond `minChain`,
26998  * to replace the entries pulled out of the
26999  * chainTable into the cache. This lets us reach
27000  * back further without increasing the total number
27001  * of entries in the chainTable, guaranteeing the
27002  * DDSS chain table will fit into the space
27003  * allocated for the regular one. */
27004  break;
27005  }
27006  }
27007  chainTable[chainPos++] = i;
27008  count++;
27009  if (i < tmpMinChain) {
27010  break;
27011  }
27012  i = tmpChainTable[i - tmpMinChain];
27013  }
27014  } else {
27015  count = 0;
27016  }
27017  if (count) {
27018  tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count;
27019  } else {
27020  tmpHashTable[hashIdx] = 0;
27021  }
27022  }
27023  assert(chainPos <= chainSize); /* I believe this is guaranteed... */
27024  }
27025 
27026  /* move chain pointers into the last entry of each hash bucket */
27027  for (hashIdx = (1 << hashLog); hashIdx; ) {
27028  U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG;
27029  U32 const chainPackedPointer = tmpHashTable[hashIdx];
27030  U32 i;
27031  for (i = 0; i < cacheSize; i++) {
27032  hashTable[bucketIdx + i] = 0;
27033  }
27034  hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer;
27035  }
27036 
27037  /* fill the buckets of the hash table */
27038  for (idx = ms->nextToUpdate; idx < target; idx++) {
27039  U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch)
27041  U32 i;
27042  /* Shift hash cache down 1. */
27043  for (i = cacheSize - 1; i; i--)
27044  hashTable[h + i] = hashTable[h + i - 1];
27045  hashTable[h] = idx;
27046  }
27047 
27048  ms->nextToUpdate = target;
27050 
27051 /* Returns the longest match length found in the dedicated dict search structure.
27052  * If none are longer than the argument ml, then ml will be returned.
27053  */
27055 size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nbAttempts,
27056  const ZSTD_matchState_t* const dms,
27057  const BYTE* const ip, const BYTE* const iLimit,
27058  const BYTE* const prefixStart, const U32 curr,
27059  const U32 dictLimit, const size_t ddsIdx) {
27060  const U32 ddsLowestIndex = dms->window.dictLimit;
27061  const BYTE* const ddsBase = dms->window.base;
27062  const BYTE* const ddsEnd = dms->window.nextSrc;
27063  const U32 ddsSize = (U32)(ddsEnd - ddsBase);
27064  const U32 ddsIndexDelta = dictLimit - ddsSize;
27065  const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
27066  const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
27067  U32 ddsAttempt;
27068  U32 matchIndex;
27069 
27070  for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
27071  PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
27072  }
27073 
27074  {
27075  U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
27076  U32 const chainIndex = chainPackedPointer >> 8;
27077 
27078  PREFETCH_L1(&dms->chainTable[chainIndex]);
27079  }
27080 
27081  for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
27082  size_t currentMl=0;
27083  const BYTE* match;
27084  matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
27085  match = ddsBase + matchIndex;
27086 
27087  if (!matchIndex) {
27088  return ml;
27089  }
27090 
27091  /* guaranteed by table construction */
27092  (void)ddsLowestIndex;
27093  assert(matchIndex >= ddsLowestIndex);
27094  assert(match+4 <= ddsEnd);
27095  if (MEM_read32(match) == MEM_read32(ip)) {
27096  /* assumption : matchIndex <= dictLimit-4 (by table construction) */
27097  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
27098  }
27099 
27100  /* save best solution */
27101  if (currentMl > ml) {
27102  ml = currentMl;
27103  *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta));
27104  if (ip+currentMl == iLimit) {
27105  /* best possible, avoids read overflow on next attempt */
27106  return ml;
27107  }
27108  }
27109  }
27110 
27111  {
27112  U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
27113  U32 chainIndex = chainPackedPointer >> 8;
27114  U32 const chainLength = chainPackedPointer & 0xFF;
27115  U32 const chainAttempts = nbAttempts - ddsAttempt;
27116  U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
27117  U32 chainAttempt;
27118 
27119  for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
27120  PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
27121  }
27122 
27123  for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
27124  size_t currentMl=0;
27125  const BYTE* match;
27126  matchIndex = dms->chainTable[chainIndex];
27127  match = ddsBase + matchIndex;
27128 
27129  /* guaranteed by table construction */
27130  assert(matchIndex >= ddsLowestIndex);
27131  assert(match+4 <= ddsEnd);
27132  if (MEM_read32(match) == MEM_read32(ip)) {
27133  /* assumption : matchIndex <= dictLimit-4 (by table construction) */
27134  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
27135  }
27136 
27137  /* save best solution */
27138  if (currentMl > ml) {
27139  ml = currentMl;
27140  *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta));
27141  if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
27142  }
27143  }
27144  }
27145  return ml;
27147 
27148 
27149 /* *********************************
27150 * Hash Chain
27151 ***********************************/
27152 #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)]
27153 
27154 /* Update chains up to ip (excluded)
27155  Assumption : always within prefix (i.e. not within extDict) */
27157  ZSTD_matchState_t* ms,
27158  const ZSTD_compressionParameters* const cParams,
27159  const BYTE* ip, U32 const mls, U32 const lazySkipping)
27160 {
27161  U32* const hashTable = ms->hashTable;
27162  const U32 hashLog = cParams->hashLog;
27163  U32* const chainTable = ms->chainTable;
27164  const U32 chainMask = (1 << cParams->chainLog) - 1;
27165  const BYTE* const base = ms->window.base;
27166  const U32 target = (U32)(ip - base);
27167  U32 idx = ms->nextToUpdate;
27168 
27169  while(idx < target) { /* catch up */
27170  size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
27171  NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
27172  hashTable[h] = idx;
27173  idx++;
27174  /* Stop inserting every position when in the lazy skipping mode. */
27175  if (lazySkipping)
27176  break;
27177  }
27178 
27179  ms->nextToUpdate = target;
27180  return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
27181 }
27182 
27184  const ZSTD_compressionParameters* const cParams = &ms->cParams;
27185  return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch, /* lazySkipping*/ 0);
27186 }
27187 
27188 /* inlining is important to hardwire a hot branch (template emulation) */
27190 size_t ZSTD_HcFindBestMatch(
27191  ZSTD_matchState_t* ms,
27192  const BYTE* const ip, const BYTE* const iLimit,
27193  size_t* offsetPtr,
27194  const U32 mls, const ZSTD_dictMode_e dictMode)
27195 {
27196  const ZSTD_compressionParameters* const cParams = &ms->cParams;
27197  U32* const chainTable = ms->chainTable;
27198  const U32 chainSize = (1 << cParams->chainLog);
27199  const U32 chainMask = chainSize-1;
27200  const BYTE* const base = ms->window.base;
27201  const BYTE* const dictBase = ms->window.dictBase;
27202  const U32 dictLimit = ms->window.dictLimit;
27203  const BYTE* const prefixStart = base + dictLimit;
27204  const BYTE* const dictEnd = dictBase + dictLimit;
27205  const U32 curr = (U32)(ip-base);
27206  const U32 maxDistance = 1U << cParams->windowLog;
27207  const U32 lowestValid = ms->window.lowLimit;
27208  const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
27209  const U32 isDictionary = (ms->loadedDictEnd != 0);
27210  const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
27211  const U32 minChain = curr > chainSize ? curr - chainSize : 0;
27212  U32 nbAttempts = 1U << cParams->searchLog;
27213  size_t ml=4-1;
27214 
27215  const ZSTD_matchState_t* const dms = ms->dictMatchState;
27216  const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch
27217  ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
27218  const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch
27219  ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
27220 
27221  U32 matchIndex;
27222 
27223  if (dictMode == ZSTD_dedicatedDictSearch) {
27224  const U32* entry = &dms->hashTable[ddsIdx];
27225  PREFETCH_L1(entry);
27226  }
27227 
27228  /* HC4 match finder */
27229  matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls, ms->lazySkipping);
27230 
27231  for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) {
27232  size_t currentMl=0;
27233  if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
27234  const BYTE* const match = base + matchIndex;
27235  assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */
27236  /* read 4B starting from (match + ml + 1 - sizeof(U32)) */
27237  if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */
27238  currentMl = ZSTD_count(ip, match, iLimit);
27239  } else {
27240  const BYTE* const match = dictBase + matchIndex;
27241  assert(match+4 <= dictEnd);
27242  if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
27243  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
27244  }
27245 
27246  /* save best solution */
27247  if (currentMl > ml) {
27248  ml = currentMl;
27249  *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex);
27250  if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
27251  }
27252 
27253  if (matchIndex <= minChain) break;
27254  matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
27255  }
27256 
27257  assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
27258  if (dictMode == ZSTD_dedicatedDictSearch) {
27259  ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms,
27260  ip, iLimit, prefixStart, curr, dictLimit, ddsIdx);
27261  } else if (dictMode == ZSTD_dictMatchState) {
27262  const U32* const dmsChainTable = dms->chainTable;
27263  const U32 dmsChainSize = (1 << dms->cParams.chainLog);
27264  const U32 dmsChainMask = dmsChainSize - 1;
27265  const U32 dmsLowestIndex = dms->window.dictLimit;
27266  const BYTE* const dmsBase = dms->window.base;
27267  const BYTE* const dmsEnd = dms->window.nextSrc;
27268  const U32 dmsSize = (U32)(dmsEnd - dmsBase);
27269  const U32 dmsIndexDelta = dictLimit - dmsSize;
27270  const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0;
27271 
27272  matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];
27273 
27274  for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
27275  size_t currentMl=0;
27276  const BYTE* const match = dmsBase + matchIndex;
27277  assert(match+4 <= dmsEnd);
27278  if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
27279  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;
27280 
27281  /* save best solution */
27282  if (currentMl > ml) {
27283  ml = currentMl;
27284  assert(curr > matchIndex + dmsIndexDelta);
27285  *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta));
27286  if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
27287  }
27288 
27289  if (matchIndex <= dmsMinChain) break;
27290 
27291  matchIndex = dmsChainTable[matchIndex & dmsChainMask];
27292  }
27293  }
27294 
27295  return ml;
27298 /* *********************************
27299 * (SIMD) Row-based matchfinder
27300 ***********************************/
27301 /* Constants for row-based hash */
27302 #define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1)
27303 #define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */
27304 
27305 #define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1)
27306 
27307 typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */
27308 
27309 /* ZSTD_VecMask_next():
27310  * Starting from the LSB, returns the idx of the next non-zero bit.
27311  * Basically counting the nb of trailing zeroes.
27312  */
27314  return ZSTD_countTrailingZeros64(val);
27316 
27317 /* ZSTD_row_nextIndex():
27318  * Returns the next index to insert at within a tagTable row, and updates the "head"
27319  * value to reflect the update. Essentially cycles backwards from [1, {entries per row})
27320  */
27321 FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) {
27322  U32 next = (*tagRow-1) & rowMask;
27323  next += (next == 0) ? rowMask : 0; /* skip first position */
27324  *tagRow = (BYTE)next;
27325  return next;
27326 }
27327 
27328 /* ZSTD_isAligned():
27329  * Checks that a pointer is aligned to "align" bytes which must be a power of 2.
27330  */
27331 MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) {
27332  assert((align & (align - 1)) == 0);
27333  return (((size_t)ptr) & (align - 1)) == 0;
27334 }
27335 
27336 /* ZSTD_row_prefetch():
27337  * Performs prefetching for the hashTable and tagTable at a given row.
27338  */
27339 FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, BYTE const* tagTable, U32 const relRow, U32 const rowLog) {
27340  PREFETCH_L1(hashTable + relRow);
27341  if (rowLog >= 5) {
27342  PREFETCH_L1(hashTable + relRow + 16);
27343  /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */
27344  }
27345  PREFETCH_L1(tagTable + relRow);
27346  if (rowLog == 6) {
27347  PREFETCH_L1(tagTable + relRow + 32);
27348  }
27349  assert(rowLog == 4 || rowLog == 5 || rowLog == 6);
27350  assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */
27351  assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */
27353 
27354 /* ZSTD_row_fillHashCache():
27355  * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries,
27356  * but not beyond iLimit.
27357  */
27359  U32 const rowLog, U32 const mls,
27360  U32 idx, const BYTE* const iLimit)
27361 {
27362  U32 const* const hashTable = ms->hashTable;
27363  BYTE const* const tagTable = ms->tagTable;
27364  U32 const hashLog = ms->rowHashLog;
27365  U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1);
27366  U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch);
27367 
27368  for (; idx < lim; ++idx) {
27369  U32 const hash = (U32)ZSTD_hashPtrSalted(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt);
27370  U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
27371  ZSTD_row_prefetch(hashTable, tagTable, row, rowLog);
27373  }
27374 
27375  DEBUGLOG(6, "ZSTD_row_fillHashCache(): [%u %u %u %u %u %u %u %u]", ms->hashCache[0], ms->hashCache[1],
27376  ms->hashCache[2], ms->hashCache[3], ms->hashCache[4],
27377  ms->hashCache[5], ms->hashCache[6], ms->hashCache[7]);
27379 
27380 /* ZSTD_row_nextCachedHash():
27381  * Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at
27382  * base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable.
27383  */
27384 FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable,
27385  BYTE const* tagTable, BYTE const* base,
27386  U32 idx, U32 const hashLog,
27387  U32 const rowLog, U32 const mls,
27388  U64 const hashSalt)
27389 {
27390  U32 const newHash = (U32)ZSTD_hashPtrSalted(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt);
27391  U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
27392  ZSTD_row_prefetch(hashTable, tagTable, row, rowLog);
27393  { U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK];
27394  cache[idx & ZSTD_ROW_HASH_CACHE_MASK] = newHash;
27395  return hash;
27396  }
27397 }
27398 
27399 /* ZSTD_row_update_internalImpl():
27400  * Updates the hash table with positions starting from updateStartIdx until updateEndIdx.
27401  */
27403  U32 updateStartIdx, U32 const updateEndIdx,
27404  U32 const mls, U32 const rowLog,
27405  U32 const rowMask, U32 const useCache)
27406 {
27407  U32* const hashTable = ms->hashTable;
27408  BYTE* const tagTable = ms->tagTable;
27409  U32 const hashLog = ms->rowHashLog;
27410  const BYTE* const base = ms->window.base;
27411 
27412  DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx);
27413  for (; updateStartIdx < updateEndIdx; ++updateStartIdx) {
27414  U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls, ms->hashSalt)
27415  : (U32)ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt);
27416  U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
27417  U32* const row = hashTable + relRow;
27418  BYTE* tagRow = tagTable + relRow;
27419  U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask);
27420 
27421  assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt));
27422  tagRow[pos] = hash & ZSTD_ROW_HASH_TAG_MASK;
27423  row[pos] = updateStartIdx;
27424  }
27426 
27427 /* ZSTD_row_update_internal():
27428  * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate.
27429  * Skips sections of long matches as is necessary.
27430  */
27432  U32 const mls, U32 const rowLog,
27433  U32 const rowMask, U32 const useCache)
27434 {
27435  U32 idx = ms->nextToUpdate;
27436  const BYTE* const base = ms->window.base;
27437  const U32 target = (U32)(ip - base);
27438  const U32 kSkipThreshold = 384;
27439  const U32 kMaxMatchStartPositionsToUpdate = 96;
27440  const U32 kMaxMatchEndPositionsToUpdate = 32;
27441 
27442  if (useCache) {
27443  /* Only skip positions when using hash cache, i.e.
27444  * if we are loading a dict, don't skip anything.
27445  * If we decide to skip, then we only update a set number
27446  * of positions at the beginning and end of the match.
27447  */
27448  if (UNLIKELY(target - idx > kSkipThreshold)) {
27449  U32 const bound = idx + kMaxMatchStartPositionsToUpdate;
27450  ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache);
27451  idx = target - kMaxMatchEndPositionsToUpdate;
27452  ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1);
27453  }
27454  }
27455  assert(target >= idx);
27456  ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache);
27457  ms->nextToUpdate = target;
27459 
27460 /* ZSTD_row_update():
27461  * External wrapper for ZSTD_row_update_internal(). Used for filling the hashtable during dictionary
27462  * processing.
27463  */
27464 void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) {
27465  const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
27466  const U32 rowMask = (1u << rowLog) - 1;
27467  const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */);
27468 
27469  DEBUGLOG(5, "ZSTD_row_update(), rowLog=%u", rowLog);
27470  ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* don't use cache */);
27471 }
27473 /* Returns the mask width of bits group of which will be set to 1. Given not all
27474  * architectures have easy movemask instruction, this helps to iterate over
27475  * groups of bits easier and faster.
27476  */
27478 ZSTD_row_matchMaskGroupWidth(const U32 rowEntries)
27479 {
27480  assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64);
27481  assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES);
27482  (void)rowEntries;
27483 #if defined(ZSTD_ARCH_ARM_NEON)
27484  /* NEON path only works for little endian */
27485  if (!MEM_isLittleEndian()) {
27486  return 1;
27487  }
27488  if (rowEntries == 16) {
27489  return 4;
27490  }
27491  if (rowEntries == 32) {
27492  return 2;
27493  }
27494  if (rowEntries == 64) {
27495  return 1;
27496  }
27497 #endif
27498  return 1;
27499 }
27500 
27501 #if defined(ZSTD_ARCH_X86_SSE2)
27503 ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head)
27504 {
27505  const __m128i comparisonMask = _mm_set1_epi8((char)tag);
27506  int matches[4] = {0};
27507  int i;
27508  assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4);
27509  for (i=0; i<nbChunks; i++) {
27510  const __m128i chunk = _mm_loadu_si128((const __m128i*)(const void*)(src + 16*i));
27511  const __m128i equalMask = _mm_cmpeq_epi8(chunk, comparisonMask);
27512  matches[i] = _mm_movemask_epi8(equalMask);
27513  }
27514  if (nbChunks == 1) return ZSTD_rotateRight_U16((U16)matches[0], head);
27515  if (nbChunks == 2) return ZSTD_rotateRight_U32((U32)matches[1] << 16 | (U32)matches[0], head);
27516  assert(nbChunks == 4);
27517  return ZSTD_rotateRight_U64((U64)matches[3] << 48 | (U64)matches[2] << 32 | (U64)matches[1] << 16 | (U64)matches[0], head);
27518 }
27519 #endif
27520 
27521 #if defined(ZSTD_ARCH_ARM_NEON)
27523 ZSTD_row_getNEONMask(const U32 rowEntries, const BYTE* const src, const BYTE tag, const U32 headGrouped)
27524 {
27525  assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64);
27526  if (rowEntries == 16) {
27527  /* vshrn_n_u16 shifts by 4 every u16 and narrows to 8 lower bits.
27528  * After that groups of 4 bits represent the equalMask. We lower
27529  * all bits except the highest in these groups by doing AND with
27530  * 0x88 = 0b10001000.
27531  */
27532  const uint8x16_t chunk = vld1q_u8(src);
27533  const uint16x8_t equalMask = vreinterpretq_u16_u8(vceqq_u8(chunk, vdupq_n_u8(tag)));
27534  const uint8x8_t res = vshrn_n_u16(equalMask, 4);
27535  const U64 matches = vget_lane_u64(vreinterpret_u64_u8(res), 0);
27536  return ZSTD_rotateRight_U64(matches, headGrouped) & 0x8888888888888888ull;
27537  } else if (rowEntries == 32) {
27538  /* Same idea as with rowEntries == 16 but doing AND with
27539  * 0x55 = 0b01010101.
27540  */
27541  const uint16x8x2_t chunk = vld2q_u16((const uint16_t*)(const void*)src);
27542  const uint8x16_t chunk0 = vreinterpretq_u8_u16(chunk.val[0]);
27543  const uint8x16_t chunk1 = vreinterpretq_u8_u16(chunk.val[1]);
27544  const uint8x16_t dup = vdupq_n_u8(tag);
27545  const uint8x8_t t0 = vshrn_n_u16(vreinterpretq_u16_u8(vceqq_u8(chunk0, dup)), 6);
27546  const uint8x8_t t1 = vshrn_n_u16(vreinterpretq_u16_u8(vceqq_u8(chunk1, dup)), 6);
27547  const uint8x8_t res = vsli_n_u8(t0, t1, 4);
27548  const U64 matches = vget_lane_u64(vreinterpret_u64_u8(res), 0) ;
27549  return ZSTD_rotateRight_U64(matches, headGrouped) & 0x5555555555555555ull;
27550  } else { /* rowEntries == 64 */
27551  const uint8x16x4_t chunk = vld4q_u8(src);
27552  const uint8x16_t dup = vdupq_n_u8(tag);
27553  const uint8x16_t cmp0 = vceqq_u8(chunk.val[0], dup);
27554  const uint8x16_t cmp1 = vceqq_u8(chunk.val[1], dup);
27555  const uint8x16_t cmp2 = vceqq_u8(chunk.val[2], dup);
27556  const uint8x16_t cmp3 = vceqq_u8(chunk.val[3], dup);
27557 
27558  const uint8x16_t t0 = vsriq_n_u8(cmp1, cmp0, 1);
27559  const uint8x16_t t1 = vsriq_n_u8(cmp3, cmp2, 1);
27560  const uint8x16_t t2 = vsriq_n_u8(t1, t0, 2);
27561  const uint8x16_t t3 = vsriq_n_u8(t2, t2, 4);
27562  const uint8x8_t t4 = vshrn_n_u16(vreinterpretq_u16_u8(t3), 4);
27563  const U64 matches = vget_lane_u64(vreinterpret_u64_u8(t4), 0);
27564  return ZSTD_rotateRight_U64(matches, headGrouped);
27565  }
27566 }
27567 #endif
27568 
27569 /* Returns a ZSTD_VecMask (U64) that has the nth group (determined by
27570  * ZSTD_row_matchMaskGroupWidth) of bits set to 1 if the newly-computed "tag"
27571  * matches the hash at the nth position in a row of the tagTable.
27572  * Each row is a circular buffer beginning at the value of "headGrouped". So we
27573  * must rotate the "matches" bitfield to match up with the actual layout of the
27574  * entries within the hashTable */
27576 ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 headGrouped, const U32 rowEntries)
27577 {
27578  const BYTE* const src = tagRow;
27579  assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64);
27580  assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES);
27581  assert(ZSTD_row_matchMaskGroupWidth(rowEntries) * rowEntries <= sizeof(ZSTD_VecMask) * 8);
27582 
27583 #if defined(ZSTD_ARCH_X86_SSE2)
27584 
27585  return ZSTD_row_getSSEMask(rowEntries / 16, src, tag, headGrouped);
27586 
27587 #else /* SW or NEON-LE */
27588 
27589 # if defined(ZSTD_ARCH_ARM_NEON)
27590  /* This NEON path only works for little endian - otherwise use SWAR below */
27591  if (MEM_isLittleEndian()) {
27592  return ZSTD_row_getNEONMask(rowEntries, src, tag, headGrouped);
27593  }
27594 # endif /* ZSTD_ARCH_ARM_NEON */
27595  /* SWAR */
27596  { const int chunkSize = sizeof(size_t);
27597  const size_t shiftAmount = ((chunkSize * 8) - chunkSize);
27598  const size_t xFF = ~((size_t)0);
27599  const size_t x01 = xFF / 0xFF;
27600  const size_t x80 = x01 << 7;
27601  const size_t splatChar = tag * x01;
27602  ZSTD_VecMask matches = 0;
27603  int i = rowEntries - chunkSize;
27604  assert((sizeof(size_t) == 4) || (sizeof(size_t) == 8));
27605  if (MEM_isLittleEndian()) { /* runtime check so have two loops */
27606  const size_t extractMagic = (xFF / 0x7F) >> chunkSize;
27607  do {
27608  size_t chunk = MEM_readST(&src[i]);
27609  chunk ^= splatChar;
27610  chunk = (((chunk | x80) - x01) | chunk) & x80;
27611  matches <<= chunkSize;
27612  matches |= (chunk * extractMagic) >> shiftAmount;
27613  i -= chunkSize;
27614  } while (i >= 0);
27615  } else { /* big endian: reverse bits during extraction */
27616  const size_t msb = xFF ^ (xFF >> 1);
27617  const size_t extractMagic = (msb / 0x1FF) | msb;
27618  do {
27619  size_t chunk = MEM_readST(&src[i]);
27620  chunk ^= splatChar;
27621  chunk = (((chunk | x80) - x01) | chunk) & x80;
27622  matches <<= chunkSize;
27623  matches |= ((chunk >> 7) * extractMagic) >> shiftAmount;
27624  i -= chunkSize;
27625  } while (i >= 0);
27626  }
27627  matches = ~matches;
27628  if (rowEntries == 16) {
27629  return ZSTD_rotateRight_U16((U16)matches, headGrouped);
27630  } else if (rowEntries == 32) {
27631  return ZSTD_rotateRight_U32((U32)matches, headGrouped);
27632  } else {
27633  return ZSTD_rotateRight_U64((U64)matches, headGrouped);
27634  }
27635  }
27636 #endif
27637 }
27638 
27639 /* The high-level approach of the SIMD row based match finder is as follows:
27640  * - Figure out where to insert the new entry:
27641  * - Generate a hash from a byte along with an additional 1-byte "short hash". The additional byte is our "tag"
27642  * - The hashTable is effectively split into groups or "rows" of 16 or 32 entries of U32, and the hash determines
27643  * which row to insert into.
27644  * - Determine the correct position within the row to insert the entry into. Each row of 16 or 32 can
27645  * be considered as a circular buffer with a "head" index that resides in the tagTable.
27646  * - Also insert the "tag" into the equivalent row and position in the tagTable.
27647  * - Note: The tagTable has 17 or 33 1-byte entries per row, due to 16 or 32 tags, and 1 "head" entry.
27648  * The 17 or 33 entry rows are spaced out to occur every 32 or 64 bytes, respectively,
27649  * for alignment/performance reasons, leaving some bytes unused.
27650  * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte "short hash" and
27651  * generate a bitfield that we can cycle through to check the collisions in the hash table.
27652  * - Pick the longest match.
27653  */
27655 size_t ZSTD_RowFindBestMatch(
27656  ZSTD_matchState_t* ms,
27657  const BYTE* const ip, const BYTE* const iLimit,
27658  size_t* offsetPtr,
27659  const U32 mls, const ZSTD_dictMode_e dictMode,
27660  const U32 rowLog)
27661 {
27662  U32* const hashTable = ms->hashTable;
27663  BYTE* const tagTable = ms->tagTable;
27664  U32* const hashCache = ms->hashCache;
27665  const U32 hashLog = ms->rowHashLog;
27666  const ZSTD_compressionParameters* const cParams = &ms->cParams;
27667  const BYTE* const base = ms->window.base;
27668  const BYTE* const dictBase = ms->window.dictBase;
27669  const U32 dictLimit = ms->window.dictLimit;
27670  const BYTE* const prefixStart = base + dictLimit;
27671  const BYTE* const dictEnd = dictBase + dictLimit;
27672  const U32 curr = (U32)(ip-base);
27673  const U32 maxDistance = 1U << cParams->windowLog;
27674  const U32 lowestValid = ms->window.lowLimit;
27675  const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
27676  const U32 isDictionary = (ms->loadedDictEnd != 0);
27677  const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
27678  const U32 rowEntries = (1U << rowLog);
27679  const U32 rowMask = rowEntries - 1;
27680  const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */
27681  const U32 groupWidth = ZSTD_row_matchMaskGroupWidth(rowEntries);
27682  const U64 hashSalt = ms->hashSalt;
27683  U32 nbAttempts = 1U << cappedSearchLog;
27684  size_t ml=4-1;
27685  U32 hash;
27686 
27687  /* DMS/DDS variables that may be referenced laster */
27688  const ZSTD_matchState_t* const dms = ms->dictMatchState;
27689 
27690  /* Initialize the following variables to satisfy static analyzer */
27691  size_t ddsIdx = 0;
27692  U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */
27693  U32 dmsTag = 0;
27694  U32* dmsRow = NULL;
27695  BYTE* dmsTagRow = NULL;
27696 
27697  if (dictMode == ZSTD_dedicatedDictSearch) {
27698  const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
27699  { /* Prefetch DDS hashtable entry */
27700  ddsIdx = ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG;
27701  PREFETCH_L1(&dms->hashTable[ddsIdx]);
27702  }
27703  ddsExtraAttempts = cParams->searchLog > rowLog ? 1U << (cParams->searchLog - rowLog) : 0;
27704  }
27705 
27706  if (dictMode == ZSTD_dictMatchState) {
27707  /* Prefetch DMS rows */
27708  U32* const dmsHashTable = dms->hashTable;
27709  BYTE* const dmsTagTable = dms->tagTable;
27710  U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls);
27711  U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
27712  dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK;
27713  dmsTagRow = (BYTE*)(dmsTagTable + dmsRelRow);
27714  dmsRow = dmsHashTable + dmsRelRow;
27715  ZSTD_row_prefetch(dmsHashTable, dmsTagTable, dmsRelRow, rowLog);
27716  }
27717 
27718  /* Update the hashTable and tagTable up to (but not including) ip */
27719  if (!ms->lazySkipping) {
27720  ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */);
27721  hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls, hashSalt);
27722  } else {
27723  /* Stop inserting every position when in the lazy skipping mode.
27724  * The hash cache is also not kept up to date in this mode.
27725  */
27726  hash = (U32)ZSTD_hashPtrSalted(ip, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt);
27727  ms->nextToUpdate = curr;
27728  }
27729  ms->hashSaltEntropy += hash; /* collect salt entropy */
27730 
27731  { /* Get the hash for ip, compute the appropriate row */
27732  U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog;
27733  U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK;
27734  U32* const row = hashTable + relRow;
27735  BYTE* tagRow = (BYTE*)(tagTable + relRow);
27736  U32 const headGrouped = (*tagRow & rowMask) * groupWidth;
27737  U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES];
27738  size_t numMatches = 0;
27739  size_t currMatch = 0;
27740  ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, headGrouped, rowEntries);
27741 
27742  /* Cycle through the matches and prefetch */
27743  for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) {
27744  U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask;
27745  U32 const matchIndex = row[matchPos];
27746  if(matchPos == 0) continue;
27747  assert(numMatches < rowEntries);
27748  if (matchIndex < lowLimit)
27749  break;
27750  if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
27751  PREFETCH_L1(base + matchIndex);
27752  } else {
27753  PREFETCH_L1(dictBase + matchIndex);
27754  }
27755  matchBuffer[numMatches++] = matchIndex;
27756  --nbAttempts;
27757  }
27758 
27759  /* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop
27760  in ZSTD_row_update_internal() at the next search. */
27761  {
27762  U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask);
27763  tagRow[pos] = (BYTE)tag;
27764  row[pos] = ms->nextToUpdate++;
27765  }
27766 
27767  /* Return the longest match */
27768  for (; currMatch < numMatches; ++currMatch) {
27769  U32 const matchIndex = matchBuffer[currMatch];
27770  size_t currentMl=0;
27771  assert(matchIndex < curr);
27772  assert(matchIndex >= lowLimit);
27773 
27774  if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
27775  const BYTE* const match = base + matchIndex;
27776  assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */
27777  /* read 4B starting from (match + ml + 1 - sizeof(U32)) */
27778  if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */
27779  currentMl = ZSTD_count(ip, match, iLimit);
27780  } else {
27781  const BYTE* const match = dictBase + matchIndex;
27782  assert(match+4 <= dictEnd);
27783  if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
27784  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
27785  }
27786 
27787  /* Save best solution */
27788  if (currentMl > ml) {
27789  ml = currentMl;
27790  *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex);
27791  if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
27792  }
27793  }
27794  }
27795 
27796  assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
27797  if (dictMode == ZSTD_dedicatedDictSearch) {
27798  ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms,
27799  ip, iLimit, prefixStart, curr, dictLimit, ddsIdx);
27800  } else if (dictMode == ZSTD_dictMatchState) {
27801  /* TODO: Measure and potentially add prefetching to DMS */
27802  const U32 dmsLowestIndex = dms->window.dictLimit;
27803  const BYTE* const dmsBase = dms->window.base;
27804  const BYTE* const dmsEnd = dms->window.nextSrc;
27805  const U32 dmsSize = (U32)(dmsEnd - dmsBase);
27806  const U32 dmsIndexDelta = dictLimit - dmsSize;
27807 
27808  { U32 const headGrouped = (*dmsTagRow & rowMask) * groupWidth;
27809  U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES];
27810  size_t numMatches = 0;
27811  size_t currMatch = 0;
27812  ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, headGrouped, rowEntries);
27813 
27814  for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) {
27815  U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask;
27816  U32 const matchIndex = dmsRow[matchPos];
27817  if(matchPos == 0) continue;
27818  if (matchIndex < dmsLowestIndex)
27819  break;
27820  PREFETCH_L1(dmsBase + matchIndex);
27821  matchBuffer[numMatches++] = matchIndex;
27822  --nbAttempts;
27823  }
27824 
27825  /* Return the longest match */
27826  for (; currMatch < numMatches; ++currMatch) {
27827  U32 const matchIndex = matchBuffer[currMatch];
27828  size_t currentMl=0;
27829  assert(matchIndex >= dmsLowestIndex);
27830  assert(matchIndex < curr);
27831 
27832  { const BYTE* const match = dmsBase + matchIndex;
27833  assert(match+4 <= dmsEnd);
27834  if (MEM_read32(match) == MEM_read32(ip))
27835  currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;
27836  }
27837 
27838  if (currentMl > ml) {
27839  ml = currentMl;
27840  assert(curr > matchIndex + dmsIndexDelta);
27841  *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta));
27842  if (ip+currentMl == iLimit) break;
27843  }
27844  }
27845  }
27846  }
27847  return ml;
27848 }
27849 
27850 
27873 #define ZSTD_BT_SEARCH_FN(dictMode, mls) ZSTD_BtFindBestMatch_##dictMode##_##mls
27874 #define ZSTD_HC_SEARCH_FN(dictMode, mls) ZSTD_HcFindBestMatch_##dictMode##_##mls
27875 #define ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog
27876 
27877 #define ZSTD_SEARCH_FN_ATTRS FORCE_NOINLINE
27878 
27879 #define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls) \
27880  ZSTD_SEARCH_FN_ATTRS size_t ZSTD_BT_SEARCH_FN(dictMode, mls)( \
27881  ZSTD_matchState_t* ms, \
27882  const BYTE* ip, const BYTE* const iLimit, \
27883  size_t* offBasePtr) \
27884  { \
27885  assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
27886  return ZSTD_BtFindBestMatch(ms, ip, iLimit, offBasePtr, mls, ZSTD_##dictMode); \
27887  } \
27888 
27889 #define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls) \
27890  ZSTD_SEARCH_FN_ATTRS size_t ZSTD_HC_SEARCH_FN(dictMode, mls)( \
27891  ZSTD_matchState_t* ms, \
27892  const BYTE* ip, const BYTE* const iLimit, \
27893  size_t* offsetPtr) \
27894  { \
27895  assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
27896  return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \
27897  } \
27898 
27899 #define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) \
27900  ZSTD_SEARCH_FN_ATTRS size_t ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)( \
27901  ZSTD_matchState_t* ms, \
27902  const BYTE* ip, const BYTE* const iLimit, \
27903  size_t* offsetPtr) \
27904  { \
27905  assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \
27906  assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \
27907  return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \
27908  } \
27910 #define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \
27911  X(dictMode, mls, 4) \
27912  X(dictMode, mls, 5) \
27913  X(dictMode, mls, 6)
27915 #define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \
27916  ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \
27917  ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \
27918  ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6)
27920 #define ZSTD_FOR_EACH_MLS(X, dictMode) \
27921  X(dictMode, 4) \
27922  X(dictMode, 5) \
27923  X(dictMode, 6)
27924 
27925 #define ZSTD_FOR_EACH_DICT_MODE(X, ...) \
27926  X(__VA_ARGS__, noDict) \
27927  X(__VA_ARGS__, extDict) \
27928  X(__VA_ARGS__, dictMatchState) \
27929  X(__VA_ARGS__, dedicatedDictSearch)
27930 
27931 /* Generate row search fns for each combination of (dictMode, mls, rowLog) */
27933 /* Generate binary Tree search fns for each combination of (dictMode, mls) */
27935 /* Generate hash chain search fns for each combination of (dictMode, mls) */
27939 
27940 #define GEN_ZSTD_CALL_BT_SEARCH_FN(dictMode, mls) \
27941  case mls: \
27942  return ZSTD_BT_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr);
27943 #define GEN_ZSTD_CALL_HC_SEARCH_FN(dictMode, mls) \
27944  case mls: \
27945  return ZSTD_HC_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr);
27946 #define GEN_ZSTD_CALL_ROW_SEARCH_FN(dictMode, mls, rowLog) \
27947  case rowLog: \
27948  return ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)(ms, ip, iend, offsetPtr);
27950 #define ZSTD_SWITCH_MLS(X, dictMode) \
27951  switch (mls) { \
27952  ZSTD_FOR_EACH_MLS(X, dictMode) \
27953  }
27954 
27955 #define ZSTD_SWITCH_ROWLOG(dictMode, mls) \
27956  case mls: \
27957  switch (rowLog) { \
27958  ZSTD_FOR_EACH_ROWLOG(GEN_ZSTD_CALL_ROW_SEARCH_FN, dictMode, mls) \
27959  } \
27960  ZSTD_UNREACHABLE; \
27961  break;
27962 
27963 #define ZSTD_SWITCH_SEARCH_METHOD(dictMode) \
27964  switch (searchMethod) { \
27965  case search_hashChain: \
27966  ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_HC_SEARCH_FN, dictMode) \
27967  break; \
27968  case search_binaryTree: \
27969  ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_BT_SEARCH_FN, dictMode) \
27970  break; \
27971  case search_rowHash: \
27972  ZSTD_SWITCH_MLS(ZSTD_SWITCH_ROWLOG, dictMode) \
27973  break; \
27974  } \
27975  ZSTD_UNREACHABLE;
27976 
28002  ZSTD_matchState_t* ms,
28003  const BYTE* ip,
28004  const BYTE* iend,
28005  size_t* offsetPtr,
28006  U32 const mls,
28007  U32 const rowLog,
28008  searchMethod_e const searchMethod,
28009  ZSTD_dictMode_e const dictMode)
28010 {
28011  if (dictMode == ZSTD_noDict) {
28013  } else if (dictMode == ZSTD_extDict) {
28014  ZSTD_SWITCH_SEARCH_METHOD(extDict)
28015  } else if (dictMode == ZSTD_dictMatchState) {
28016  ZSTD_SWITCH_SEARCH_METHOD(dictMatchState)
28017  } else if (dictMode == ZSTD_dedicatedDictSearch) {
28018  ZSTD_SWITCH_SEARCH_METHOD(dedicatedDictSearch)
28019  }
28021  return 0;
28022 }
28024 /* *******************************
28025 * Common parser - lazy strategy
28026 *********************************/
28027 
28028 FORCE_INLINE_TEMPLATE size_t
28030  ZSTD_matchState_t* ms, seqStore_t* seqStore,
28031  U32 rep[ZSTD_REP_NUM],
28032  const void* src, size_t srcSize,
28033  const searchMethod_e searchMethod, const U32 depth,
28034  ZSTD_dictMode_e const dictMode)
28035 {
28036  const BYTE* const istart = (const BYTE*)src;
28037  const BYTE* ip = istart;
28038  const BYTE* anchor = istart;
28039  const BYTE* const iend = istart + srcSize;
28040  const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8;
28041  const BYTE* const base = ms->window.base;
28042  const U32 prefixLowestIndex = ms->window.dictLimit;
28043  const BYTE* const prefixLowest = base + prefixLowestIndex;
28044  const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6);
28045  const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
28046 
28047  U32 offset_1 = rep[0], offset_2 = rep[1];
28048  U32 offsetSaved1 = 0, offsetSaved2 = 0;
28049 
28050  const int isDMS = dictMode == ZSTD_dictMatchState;
28051  const int isDDS = dictMode == ZSTD_dedicatedDictSearch;
28052  const int isDxS = isDMS || isDDS;
28053  const ZSTD_matchState_t* const dms = ms->dictMatchState;
28054  const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0;
28055  const BYTE* const dictBase = isDxS ? dms->window.base : NULL;
28056  const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL;
28057  const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL;
28058  const U32 dictIndexDelta = isDxS ?
28059  prefixLowestIndex - (U32)(dictEnd - dictBase) :
28060  0;
28061  const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
28062 
28063  DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod);
28064  ip += (dictAndPrefixLength == 0);
28065  if (dictMode == ZSTD_noDict) {
28066  U32 const curr = (U32)(ip - base);
28067  U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog);
28068  U32 const maxRep = curr - windowLow;
28069  if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0;
28070  if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0;
28071  }
28072  if (isDxS) {
28073  /* dictMatchState repCode checks don't currently handle repCode == 0
28074  * disabling. */
28075  assert(offset_1 <= dictAndPrefixLength);
28076  assert(offset_2 <= dictAndPrefixLength);
28077  }
28078 
28079  /* Reset the lazy skipping state */
28080  ms->lazySkipping = 0;
28081 
28082  if (searchMethod == search_rowHash) {
28083  ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit);
28084  }
28085 
28086  /* Match Loop */
28087 #if defined(__GNUC__) && defined(__x86_64__)
28088  /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the
28089  * code alignment is perturbed. To fix the instability align the loop on 32-bytes.
28090  */
28091  __asm__(".p2align 5");
28092 #endif
28093  while (ip < ilimit) {
28094  size_t matchLength=0;
28095  size_t offBase = REPCODE1_TO_OFFBASE;
28096  const BYTE* start=ip+1;
28097  DEBUGLOG(7, "search baseline (depth 0)");
28098 
28099  /* check repCode */
28100  if (isDxS) {
28101  const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
28102  const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch)
28103  && repIndex < prefixLowestIndex) ?
28104  dictBase + (repIndex - dictIndexDelta) :
28105  base + repIndex;
28106  if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
28107  && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
28108  const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
28109  matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
28110  if (depth==0) goto _storeSequence;
28111  }
28112  }
28113  if ( dictMode == ZSTD_noDict
28114  && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
28115  matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
28116  if (depth==0) goto _storeSequence;
28117  }
28118 
28119  /* first search (depth 0) */
28120  { size_t offbaseFound = 999999999;
28121  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offbaseFound, mls, rowLog, searchMethod, dictMode);
28122  if (ml2 > matchLength)
28123  matchLength = ml2, start = ip, offBase = offbaseFound;
28124  }
28125 
28126  if (matchLength < 4) {
28127  size_t const step = ((size_t)(ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */;
28128  ip += step;
28129  /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time.
28130  * In this mode we stop inserting every position into our tables, and only insert
28131  * positions that we search, which is one in step positions.
28132  * The exact cutoff is flexible, I've just chosen a number that is reasonably high,
28133  * so we minimize the compression ratio loss in "normal" scenarios. This mode gets
28134  * triggered once we've gone 2KB without finding any matches.
28135  */
28136  ms->lazySkipping = step > kLazySkippingStep;
28137  continue;
28138  }
28139 
28140  /* let's try to find a better solution */
28141  if (depth>=1)
28142  while (ip<ilimit) {
28143  DEBUGLOG(7, "search depth 1");
28144  ip ++;
28145  if ( (dictMode == ZSTD_noDict)
28146  && (offBase) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
28147  size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
28148  int const gain2 = (int)(mlRep * 3);
28149  int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1);
28150  if ((mlRep >= 4) && (gain2 > gain1))
28151  matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip;
28152  }
28153  if (isDxS) {
28154  const U32 repIndex = (U32)(ip - base) - offset_1;
28155  const BYTE* repMatch = repIndex < prefixLowestIndex ?
28156  dictBase + (repIndex - dictIndexDelta) :
28157  base + repIndex;
28158  if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
28159  && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
28160  const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
28161  size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
28162  int const gain2 = (int)(mlRep * 3);
28163  int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1);
28164  if ((mlRep >= 4) && (gain2 > gain1))
28165  matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip;
28166  }
28167  }
28168  { size_t ofbCandidate=999999999;
28169  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode);
28170  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */
28171  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4);
28172  if ((ml2 >= 4) && (gain2 > gain1)) {
28173  matchLength = ml2, offBase = ofbCandidate, start = ip;
28174  continue; /* search a better one */
28175  } }
28176 
28177  /* let's find an even better one */
28178  if ((depth==2) && (ip<ilimit)) {
28179  DEBUGLOG(7, "search depth 2");
28180  ip ++;
28181  if ( (dictMode == ZSTD_noDict)
28182  && (offBase) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
28183  size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
28184  int const gain2 = (int)(mlRep * 4);
28185  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1);
28186  if ((mlRep >= 4) && (gain2 > gain1))
28187  matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip;
28188  }
28189  if (isDxS) {
28190  const U32 repIndex = (U32)(ip - base) - offset_1;
28191  const BYTE* repMatch = repIndex < prefixLowestIndex ?
28192  dictBase + (repIndex - dictIndexDelta) :
28193  base + repIndex;
28194  if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
28195  && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
28196  const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
28197  size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
28198  int const gain2 = (int)(mlRep * 4);
28199  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1);
28200  if ((mlRep >= 4) && (gain2 > gain1))
28201  matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip;
28202  }
28203  }
28204  { size_t ofbCandidate=999999999;
28205  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode);
28206  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */
28207  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7);
28208  if ((ml2 >= 4) && (gain2 > gain1)) {
28209  matchLength = ml2, offBase = ofbCandidate, start = ip;
28210  continue;
28211  } } }
28212  break; /* nothing found : store previous solution */
28213  }
28214 
28215  /* NOTE:
28216  * Pay attention that `start[-value]` can lead to strange undefined behavior
28217  * notably if `value` is unsigned, resulting in a large positive `-value`.
28218  */
28219  /* catch up */
28220  if (OFFBASE_IS_OFFSET(offBase)) {
28221  if (dictMode == ZSTD_noDict) {
28222  while ( ((start > anchor) & (start - OFFBASE_TO_OFFSET(offBase) > prefixLowest))
28223  && (start[-1] == (start-OFFBASE_TO_OFFSET(offBase))[-1]) ) /* only search for offset within prefix */
28224  { start--; matchLength++; }
28225  }
28226  if (isDxS) {
28227  U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase));
28228  const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
28229  const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
28230  while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
28231  }
28232  offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase);
28233  }
28234  /* store sequence */
28235 _storeSequence:
28236  { size_t const litLength = (size_t)(start - anchor);
28237  ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength);
28238  anchor = ip = start + matchLength;
28239  }
28240  if (ms->lazySkipping) {
28241  /* We've found a match, disable lazy skipping mode, and refill the hash cache. */
28242  if (searchMethod == search_rowHash) {
28243  ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit);
28244  }
28245  ms->lazySkipping = 0;
28246  }
28247 
28248  /* check immediate repcode */
28249  if (isDxS) {
28250  while (ip <= ilimit) {
28251  U32 const current2 = (U32)(ip-base);
28252  U32 const repIndex = current2 - offset_2;
28253  const BYTE* repMatch = repIndex < prefixLowestIndex ?
28254  dictBase - dictIndexDelta + repIndex :
28255  base + repIndex;
28256  if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
28257  && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
28258  const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;
28259  matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;
28260  offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset_2 <=> offset_1 */
28261  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength);
28262  ip += matchLength;
28263  anchor = ip;
28264  continue;
28265  }
28266  break;
28267  }
28268  }
28269 
28270  if (dictMode == ZSTD_noDict) {
28271  while ( ((ip <= ilimit) & (offset_2>0))
28272  && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
28273  /* store sequence */
28274  matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
28275  offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap repcodes */
28276  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength);
28277  ip += matchLength;
28278  anchor = ip;
28279  continue; /* faster when present ... (?) */
28280  } } }
28281 
28282  /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0),
28283  * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */
28284  offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2;
28285 
28286  /* save reps for next block */
28287  rep[0] = offset_1 ? offset_1 : offsetSaved1;
28288  rep[1] = offset_2 ? offset_2 : offsetSaved2;
28290  /* Return the last literals size */
28291  return (size_t)(iend - anchor);
28292 }
28293 
28294 
28297  void const* src, size_t srcSize)
28298 {
28299  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict);
28300 }
28301 
28304  void const* src, size_t srcSize)
28305 {
28306  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict);
28307 }
28308 
28311  void const* src, size_t srcSize)
28312 {
28313  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict);
28314 }
28315 
28318  void const* src, size_t srcSize)
28319 {
28320  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict);
28321 }
28322 
28325  void const* src, size_t srcSize)
28326 {
28328 }
28329 
28332  void const* src, size_t srcSize)
28333 {
28334  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState);
28335 }
28336 
28339  void const* src, size_t srcSize)
28340 {
28341  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState);
28342 }
28343 
28345  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28346  void const* src, size_t srcSize)
28347 {
28348  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState);
28349 }
28350 
28351 
28354  void const* src, size_t srcSize)
28355 {
28357 }
28358 
28361  void const* src, size_t srcSize)
28362 {
28364 }
28365 
28367  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28368  void const* src, size_t srcSize)
28369 {
28371 }
28372 
28373 /* Row-based matchfinder */
28376  void const* src, size_t srcSize)
28377 {
28378  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict);
28379 }
28380 
28383  void const* src, size_t srcSize)
28384 {
28385  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict);
28386 }
28387 
28390  void const* src, size_t srcSize)
28391 {
28392  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict);
28393 }
28394 
28397  void const* src, size_t srcSize)
28398 {
28399  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState);
28400 }
28401 
28404  void const* src, size_t srcSize)
28405 {
28406  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState);
28407 }
28408 
28410  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28411  void const* src, size_t srcSize)
28412 {
28413  return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState);
28414 }
28415 
28416 
28419  void const* src, size_t srcSize)
28420 {
28422 }
28423 
28426  void const* src, size_t srcSize)
28427 {
28429 }
28430 
28432  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28433  void const* src, size_t srcSize)
28434 {
28436 }
28437 
28440  ZSTD_matchState_t* ms, seqStore_t* seqStore,
28441  U32 rep[ZSTD_REP_NUM],
28442  const void* src, size_t srcSize,
28443  const searchMethod_e searchMethod, const U32 depth)
28444 {
28445  const BYTE* const istart = (const BYTE*)src;
28446  const BYTE* ip = istart;
28447  const BYTE* anchor = istart;
28448  const BYTE* const iend = istart + srcSize;
28449  const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8;
28450  const BYTE* const base = ms->window.base;
28451  const U32 dictLimit = ms->window.dictLimit;
28452  const BYTE* const prefixStart = base + dictLimit;
28453  const BYTE* const dictBase = ms->window.dictBase;
28454  const BYTE* const dictEnd = dictBase + dictLimit;
28455  const BYTE* const dictStart = dictBase + ms->window.lowLimit;
28456  const U32 windowLog = ms->cParams.windowLog;
28457  const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6);
28458  const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6);
28459 
28460  U32 offset_1 = rep[0], offset_2 = rep[1];
28461 
28462  DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod);
28463 
28464  /* Reset the lazy skipping state */
28465  ms->lazySkipping = 0;
28466 
28467  /* init */
28468  ip += (ip == prefixStart);
28469  if (searchMethod == search_rowHash) {
28470  ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit);
28471  }
28472 
28473  /* Match Loop */
28474 #if defined(__GNUC__) && defined(__x86_64__)
28475  /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the
28476  * code alignment is perturbed. To fix the instability align the loop on 32-bytes.
28477  */
28478  __asm__(".p2align 5");
28479 #endif
28480  while (ip < ilimit) {
28481  size_t matchLength=0;
28482  size_t offBase = REPCODE1_TO_OFFBASE;
28483  const BYTE* start=ip+1;
28484  U32 curr = (U32)(ip-base);
28485 
28486  /* check repCode */
28487  { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog);
28488  const U32 repIndex = (U32)(curr+1 - offset_1);
28489  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
28490  const BYTE* const repMatch = repBase + repIndex;
28491  if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
28492  & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */
28493  if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
28494  /* repcode detected we should take it */
28495  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
28496  matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;
28497  if (depth==0) goto _storeSequence;
28498  } }
28499 
28500  /* first search (depth 0) */
28501  { size_t ofbCandidate = 999999999;
28502  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict);
28503  if (ml2 > matchLength)
28504  matchLength = ml2, start = ip, offBase = ofbCandidate;
28505  }
28506 
28507  if (matchLength < 4) {
28508  size_t const step = ((size_t)(ip-anchor) >> kSearchStrength);
28509  ip += step + 1; /* jump faster over incompressible sections */
28510  /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time.
28511  * In this mode we stop inserting every position into our tables, and only insert
28512  * positions that we search, which is one in step positions.
28513  * The exact cutoff is flexible, I've just chosen a number that is reasonably high,
28514  * so we minimize the compression ratio loss in "normal" scenarios. This mode gets
28515  * triggered once we've gone 2KB without finding any matches.
28516  */
28517  ms->lazySkipping = step > kLazySkippingStep;
28518  continue;
28519  }
28520 
28521  /* let's try to find a better solution */
28522  if (depth>=1)
28523  while (ip<ilimit) {
28524  ip ++;
28525  curr++;
28526  /* check repCode */
28527  if (offBase) {
28528  const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
28529  const U32 repIndex = (U32)(curr - offset_1);
28530  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
28531  const BYTE* const repMatch = repBase + repIndex;
28532  if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
28533  & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
28534  if (MEM_read32(ip) == MEM_read32(repMatch)) {
28535  /* repcode detected */
28536  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
28537  size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
28538  int const gain2 = (int)(repLength * 3);
28539  int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1);
28540  if ((repLength >= 4) && (gain2 > gain1))
28541  matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip;
28542  } }
28543 
28544  /* search match, depth 1 */
28545  { size_t ofbCandidate = 999999999;
28546  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict);
28547  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */
28548  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4);
28549  if ((ml2 >= 4) && (gain2 > gain1)) {
28550  matchLength = ml2, offBase = ofbCandidate, start = ip;
28551  continue; /* search a better one */
28552  } }
28553 
28554  /* let's find an even better one */
28555  if ((depth==2) && (ip<ilimit)) {
28556  ip ++;
28557  curr++;
28558  /* check repCode */
28559  if (offBase) {
28560  const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
28561  const U32 repIndex = (U32)(curr - offset_1);
28562  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
28563  const BYTE* const repMatch = repBase + repIndex;
28564  if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
28565  & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
28566  if (MEM_read32(ip) == MEM_read32(repMatch)) {
28567  /* repcode detected */
28568  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
28569  size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
28570  int const gain2 = (int)(repLength * 4);
28571  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1);
28572  if ((repLength >= 4) && (gain2 > gain1))
28573  matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip;
28574  } }
28575 
28576  /* search match, depth 2 */
28577  { size_t ofbCandidate = 999999999;
28578  size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict);
28579  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */
28580  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7);
28581  if ((ml2 >= 4) && (gain2 > gain1)) {
28582  matchLength = ml2, offBase = ofbCandidate, start = ip;
28583  continue;
28584  } } }
28585  break; /* nothing found : store previous solution */
28586  }
28587 
28588  /* catch up */
28589  if (OFFBASE_IS_OFFSET(offBase)) {
28590  U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase));
28591  const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
28592  const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
28593  while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
28594  offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase);
28595  }
28596 
28597  /* store sequence */
28598 _storeSequence:
28599  { size_t const litLength = (size_t)(start - anchor);
28600  ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength);
28601  anchor = ip = start + matchLength;
28602  }
28603  if (ms->lazySkipping) {
28604  /* We've found a match, disable lazy skipping mode, and refill the hash cache. */
28605  if (searchMethod == search_rowHash) {
28606  ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit);
28607  }
28608  ms->lazySkipping = 0;
28609  }
28610 
28611  /* check immediate repcode */
28612  while (ip <= ilimit) {
28613  const U32 repCurrent = (U32)(ip-base);
28614  const U32 windowLow = ZSTD_getLowestMatchIndex(ms, repCurrent, windowLog);
28615  const U32 repIndex = repCurrent - offset_2;
28616  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
28617  const BYTE* const repMatch = repBase + repIndex;
28618  if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */
28619  & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */
28620  if (MEM_read32(ip) == MEM_read32(repMatch)) {
28621  /* repcode detected we should take it */
28622  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
28623  matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
28624  offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset history */
28625  ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength);
28626  ip += matchLength;
28627  anchor = ip;
28628  continue; /* faster when present ... (?) */
28629  }
28630  break;
28631  } }
28632 
28633  /* Save reps for next block */
28634  rep[0] = offset_1;
28635  rep[1] = offset_2;
28637  /* Return the last literals size */
28638  return (size_t)(iend - anchor);
28639 }
28640 
28641 
28644  void const* src, size_t srcSize)
28645 {
28646  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0);
28647 }
28648 
28650  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28651  void const* src, size_t srcSize)
28652 
28653 {
28654  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1);
28655 }
28656 
28658  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28659  void const* src, size_t srcSize)
28660 
28661 {
28662  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2);
28663 }
28664 
28666  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28667  void const* src, size_t srcSize)
28668 
28669 {
28670  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2);
28671 }
28672 
28675  void const* src, size_t srcSize)
28676 {
28677  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0);
28678 }
28679 
28681  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28682  void const* src, size_t srcSize)
28683 
28684 {
28685  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1);
28686 }
28687 
28689  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28690  void const* src, size_t srcSize)
28691 {
28692  return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2);
28693 }
28694 /**** ended inlining compress/zstd_lazy.c ****/
28695 /**** start inlining compress/zstd_ldm.c ****/
28696 /*
28697  * Copyright (c) Meta Platforms, Inc. and affiliates.
28698  * All rights reserved.
28699  *
28700  * This source code is licensed under both the BSD-style license (found in the
28701  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
28702  * in the COPYING file in the root directory of this source tree).
28703  * You may select, at your option, one of the above-listed licenses.
28704  */
28705 
28706 /**** skipping file: zstd_ldm.h ****/
28707 
28708 /**** skipping file: ../common/debug.h ****/
28709 /**** skipping file: ../common/xxhash.h ****/
28710 /**** skipping file: zstd_fast.h ****/
28711 /**** skipping file: zstd_double_fast.h ****/
28712 /**** start inlining zstd_ldm_geartab.h ****/
28713 /*
28714  * Copyright (c) Meta Platforms, Inc. and affiliates.
28715  * All rights reserved.
28716  *
28717  * This source code is licensed under both the BSD-style license (found in the
28718  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
28719  * in the COPYING file in the root directory of this source tree).
28720  * You may select, at your option, one of the above-listed licenses.
28721  */
28722 
28723 #ifndef ZSTD_LDM_GEARTAB_H
28724 #define ZSTD_LDM_GEARTAB_H
28725 
28726 /**** skipping file: ../common/compiler.h ****/
28727 /**** skipping file: ../common/mem.h ****/
28728 
28729 static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = {
28730  0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc,
28731  0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05,
28732  0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e,
28733  0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889,
28734  0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e,
28735  0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140,
28736  0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e,
28737  0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f,
28738  0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391,
28739  0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210,
28740  0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be,
28741  0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a,
28742  0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b,
28743  0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4,
28744  0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb,
28745  0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312,
28746  0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01,
28747  0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc,
28748  0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967,
28749  0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553,
28750  0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f,
28751  0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2,
28752  0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d,
28753  0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a,
28754  0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74,
28755  0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3,
28756  0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1,
28757  0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b,
28758  0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568,
28759  0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a,
28760  0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1,
28761  0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9,
28762  0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463,
28763  0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba,
28764  0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9,
28765  0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61,
28766  0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec,
28767  0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6,
28768  0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab,
28769  0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5,
28770  0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59,
28771  0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7,
28772  0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc,
28773  0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb,
28774  0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be,
28775  0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312,
28776  0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1,
28777  0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc,
28778  0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d,
28779  0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445,
28780  0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c,
28781  0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5,
28782  0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5,
28783  0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28,
28784  0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a,
28785  0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9,
28786  0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15,
28787  0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef,
28788  0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2,
28789  0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375,
28790  0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3,
28791  0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595,
28792  0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389,
28793  0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4,
28794  0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756,
28795  0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc,
28796  0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45,
28797  0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea,
28798  0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f,
28799  0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc,
28800  0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c,
28801  0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a,
28802  0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17,
28803  0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3,
28804  0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4,
28805  0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91,
28806  0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40,
28807  0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741,
28808  0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f,
28809  0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4,
28810  0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad,
28811  0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047,
28812  0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2,
28813  0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e,
28814  0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b,
28815  0x2b4da14f2613d8f4
28816 };
28818 #endif /* ZSTD_LDM_GEARTAB_H */
28819 /**** ended inlining zstd_ldm_geartab.h ****/
28821 #define LDM_BUCKET_SIZE_LOG 3
28822 #define LDM_MIN_MATCH_LENGTH 64
28823 #define LDM_HASH_RLOG 7
28824 
28825 typedef struct {
28826  U64 rolling;
28827  U64 stopMask;
28829 
28834 static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const* params)
28835 {
28836  unsigned maxBitsInMask = MIN(params->minMatchLength, 64);
28837  unsigned hashRateLog = params->hashRateLog;
28838 
28839  state->rolling = ~(U32)0;
28840 
28841  /* The choice of the splitting criterion is subject to two conditions:
28842  * 1. it has to trigger on average every 2^(hashRateLog) bytes;
28843  * 2. ideally, it has to depend on a window of minMatchLength bytes.
28844  *
28845  * In the gear hash algorithm, bit n depends on the last n bytes;
28846  * so in order to obtain a good quality splitting criterion it is
28847  * preferable to use bits with high weight.
28848  *
28849  * To match condition 1 we use a mask with hashRateLog bits set
28850  * and, because of the previous remark, we make sure these bits
28851  * have the highest possible weight while still respecting
28852  * condition 2.
28853  */
28854  if (hashRateLog > 0 && hashRateLog <= maxBitsInMask) {
28855  state->stopMask = (((U64)1 << hashRateLog) - 1) << (maxBitsInMask - hashRateLog);
28856  } else {
28857  /* In this degenerate case we simply honor the hash rate. */
28858  state->stopMask = ((U64)1 << hashRateLog) - 1;
28859  }
28860 }
28868  BYTE const* data, size_t minMatchLength)
28869 {
28870  U64 hash = state->rolling;
28871  size_t n = 0;
28872 
28873 #define GEAR_ITER_ONCE() do { \
28874  hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \
28875  n += 1; \
28876  } while (0)
28877  while (n + 3 < minMatchLength) {
28878  GEAR_ITER_ONCE();
28879  GEAR_ITER_ONCE();
28880  GEAR_ITER_ONCE();
28881  GEAR_ITER_ONCE();
28882  }
28883  while (n < minMatchLength) {
28884  GEAR_ITER_ONCE();
28885  }
28886 #undef GEAR_ITER_ONCE
28887 }
28888 
28899  BYTE const* data, size_t size,
28900  size_t* splits, unsigned* numSplits)
28901 {
28902  size_t n;
28903  U64 hash, mask;
28904 
28905  hash = state->rolling;
28906  mask = state->stopMask;
28907  n = 0;
28908 
28909 #define GEAR_ITER_ONCE() do { \
28910  hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \
28911  n += 1; \
28912  if (UNLIKELY((hash & mask) == 0)) { \
28913  splits[*numSplits] = n; \
28914  *numSplits += 1; \
28915  if (*numSplits == LDM_BATCH_SIZE) \
28916  goto done; \
28917  } \
28918  } while (0)
28919 
28920  while (n + 3 < size) {
28921  GEAR_ITER_ONCE();
28922  GEAR_ITER_ONCE();
28923  GEAR_ITER_ONCE();
28924  GEAR_ITER_ONCE();
28925  }
28926  while (n < size) {
28927  GEAR_ITER_ONCE();
28928  }
28929 
28930 #undef GEAR_ITER_ONCE
28932 done:
28933  state->rolling = hash;
28934  return n;
28935 }
28936 
28938  ZSTD_compressionParameters const* cParams)
28939 {
28940  params->windowLog = cParams->windowLog;
28941  ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX);
28942  DEBUGLOG(4, "ZSTD_ldm_adjustParameters");
28943  if (!params->bucketSizeLog) params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;
28944  if (!params->minMatchLength) params->minMatchLength = LDM_MIN_MATCH_LENGTH;
28945  if (params->hashLog == 0) {
28946  params->hashLog = MAX(ZSTD_HASHLOG_MIN, params->windowLog - LDM_HASH_RLOG);
28947  assert(params->hashLog <= ZSTD_HASHLOG_MAX);
28948  }
28949  if (params->hashRateLog == 0) {
28950  params->hashRateLog = params->windowLog < params->hashLog
28951  ? 0
28952  : params->windowLog - params->hashLog;
28953  }
28954  params->bucketSizeLog = MIN(params->bucketSizeLog, params->hashLog);
28955 }
28956 
28957 size_t ZSTD_ldm_getTableSize(ldmParams_t params)
28958 {
28959  size_t const ldmHSize = ((size_t)1) << params.hashLog;
28960  size_t const ldmBucketSizeLog = MIN(params.bucketSizeLog, params.hashLog);
28961  size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog);
28962  size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize)
28963  + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t));
28964  return params.enableLdm == ZSTD_ps_enable ? totalSize : 0;
28965 }
28966 
28967 size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize)
28969  return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0;
28970 }
28971 
28975  ldmState_t* ldmState, size_t hash, ldmParams_t const ldmParams)
28977  return ldmState->hashTable + (hash << ldmParams.bucketSizeLog);
28978 }
28979 
28982 static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
28983  size_t const hash, const ldmEntry_t entry,
28984  ldmParams_t const ldmParams)
28985 {
28986  BYTE* const pOffset = ldmState->bucketOffsets + hash;
28987  unsigned const offset = *pOffset;
28988 
28989  *(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + offset) = entry;
28990  *pOffset = (BYTE)((offset + 1) & ((1u << ldmParams.bucketSizeLog) - 1));
28991 
28993 
28998 static size_t ZSTD_ldm_countBackwardsMatch(
28999  const BYTE* pIn, const BYTE* pAnchor,
29000  const BYTE* pMatch, const BYTE* pMatchBase)
29001 {
29002  size_t matchLength = 0;
29003  while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) {
29004  pIn--;
29005  pMatch--;
29006  matchLength++;
29007  }
29008  return matchLength;
29009 }
29017  const BYTE* pIn, const BYTE* pAnchor,
29018  const BYTE* pMatch, const BYTE* pMatchBase,
29019  const BYTE* pExtDictStart, const BYTE* pExtDictEnd)
29020 {
29021  size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase);
29022  if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) {
29023  /* If backwards match is entirely in the extDict or prefix, immediately return */
29024  return matchLength;
29025  }
29026  DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength);
29027  matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart);
29028  DEBUGLOG(7, "final backwards match length = %zu", matchLength);
29029  return matchLength;
29030 }
29031 
29039 static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms,
29040  void const* end)
29041 {
29042  const BYTE* const iend = (const BYTE*)end;
29043 
29044  switch(ms->cParams.strategy)
29045  {
29046  case ZSTD_fast:
29048  break;
29049 
29050  case ZSTD_dfast:
29052  break;
29053 
29054  case ZSTD_greedy:
29055  case ZSTD_lazy:
29056  case ZSTD_lazy2:
29057  case ZSTD_btlazy2:
29058  case ZSTD_btopt:
29059  case ZSTD_btultra:
29060  case ZSTD_btultra2:
29061  break;
29062  default:
29063  assert(0); /* not possible : not a valid strategy id */
29064  }
29065 
29066  return 0;
29067 }
29068 
29070  ldmState_t* ldmState, const BYTE* ip,
29071  const BYTE* iend, ldmParams_t const* params)
29072 {
29073  U32 const minMatchLength = params->minMatchLength;
29074  U32 const hBits = params->hashLog - params->bucketSizeLog;
29075  BYTE const* const base = ldmState->window.base;
29076  BYTE const* const istart = ip;
29077  ldmRollingHashState_t hashState;
29078  size_t* const splits = ldmState->splitIndices;
29079  unsigned numSplits;
29080 
29081  DEBUGLOG(5, "ZSTD_ldm_fillHashTable");
29082 
29083  ZSTD_ldm_gear_init(&hashState, params);
29084  while (ip < iend) {
29085  size_t hashed;
29086  unsigned n;
29087 
29088  numSplits = 0;
29089  hashed = ZSTD_ldm_gear_feed(&hashState, ip, iend - ip, splits, &numSplits);
29090 
29091  for (n = 0; n < numSplits; n++) {
29092  if (ip + splits[n] >= istart + minMatchLength) {
29093  BYTE const* const split = ip + splits[n] - minMatchLength;
29094  U64 const xxhash = XXH64(split, minMatchLength, 0);
29095  U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1));
29096  ldmEntry_t entry;
29097 
29098  entry.offset = (U32)(split - base);
29099  entry.checksum = (U32)(xxhash >> 32);
29100  ZSTD_ldm_insertEntry(ldmState, hash, entry, *params);
29101  }
29102  }
29103 
29104  ip += hashed;
29105  }
29106 }
29107 
29114 static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor)
29115 {
29116  U32 const curr = (U32)(anchor - ms->window.base);
29117  if (curr > ms->nextToUpdate + 1024) {
29118  ms->nextToUpdate =
29119  curr - MIN(512, curr - ms->nextToUpdate - 1024);
29120  }
29121 }
29122 
29124  ldmState_t* ldmState, rawSeqStore_t* rawSeqStore,
29125  ldmParams_t const* params, void const* src, size_t srcSize)
29126 {
29127  /* LDM parameters */
29128  int const extDict = ZSTD_window_hasExtDict(ldmState->window);
29129  U32 const minMatchLength = params->minMatchLength;
29130  U32 const entsPerBucket = 1U << params->bucketSizeLog;
29131  U32 const hBits = params->hashLog - params->bucketSizeLog;
29132  /* Prefix and extDict parameters */
29133  U32 const dictLimit = ldmState->window.dictLimit;
29134  U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit;
29135  BYTE const* const base = ldmState->window.base;
29136  BYTE const* const dictBase = extDict ? ldmState->window.dictBase : NULL;
29137  BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL;
29138  BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL;
29139  BYTE const* const lowPrefixPtr = base + dictLimit;
29140  /* Input bounds */
29141  BYTE const* const istart = (BYTE const*)src;
29142  BYTE const* const iend = istart + srcSize;
29143  BYTE const* const ilimit = iend - HASH_READ_SIZE;
29144  /* Input positions */
29145  BYTE const* anchor = istart;
29146  BYTE const* ip = istart;
29147  /* Rolling hash state */
29148  ldmRollingHashState_t hashState;
29149  /* Arrays for staged-processing */
29150  size_t* const splits = ldmState->splitIndices;
29151  ldmMatchCandidate_t* const candidates = ldmState->matchCandidates;
29152  unsigned numSplits;
29153 
29154  if (srcSize < minMatchLength)
29155  return iend - anchor;
29156 
29157  /* Initialize the rolling hash state with the first minMatchLength bytes */
29158  ZSTD_ldm_gear_init(&hashState, params);
29159  ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength);
29160  ip += minMatchLength;
29161 
29162  while (ip < ilimit) {
29163  size_t hashed;
29164  unsigned n;
29165 
29166  numSplits = 0;
29167  hashed = ZSTD_ldm_gear_feed(&hashState, ip, ilimit - ip,
29168  splits, &numSplits);
29169 
29170  for (n = 0; n < numSplits; n++) {
29171  BYTE const* const split = ip + splits[n] - minMatchLength;
29172  U64 const xxhash = XXH64(split, minMatchLength, 0);
29173  U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1));
29174 
29175  candidates[n].split = split;
29176  candidates[n].hash = hash;
29177  candidates[n].checksum = (U32)(xxhash >> 32);
29178  candidates[n].bucket = ZSTD_ldm_getBucket(ldmState, hash, *params);
29179  PREFETCH_L1(candidates[n].bucket);
29180  }
29181 
29182  for (n = 0; n < numSplits; n++) {
29183  size_t forwardMatchLength = 0, backwardMatchLength = 0,
29184  bestMatchLength = 0, mLength;
29185  U32 offset;
29186  BYTE const* const split = candidates[n].split;
29187  U32 const checksum = candidates[n].checksum;
29188  U32 const hash = candidates[n].hash;
29189  ldmEntry_t* const bucket = candidates[n].bucket;
29190  ldmEntry_t const* cur;
29191  ldmEntry_t const* bestEntry = NULL;
29192  ldmEntry_t newEntry;
29193 
29194  newEntry.offset = (U32)(split - base);
29195  newEntry.checksum = checksum;
29196 
29197  /* If a split point would generate a sequence overlapping with
29198  * the previous one, we merely register it in the hash table and
29199  * move on */
29200  if (split < anchor) {
29201  ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
29202  continue;
29203  }
29204 
29205  for (cur = bucket; cur < bucket + entsPerBucket; cur++) {
29206  size_t curForwardMatchLength, curBackwardMatchLength,
29207  curTotalMatchLength;
29208  if (cur->checksum != checksum || cur->offset <= lowestIndex) {
29209  continue;
29210  }
29211  if (extDict) {
29212  BYTE const* const curMatchBase =
29213  cur->offset < dictLimit ? dictBase : base;
29214  BYTE const* const pMatch = curMatchBase + cur->offset;
29215  BYTE const* const matchEnd =
29216  cur->offset < dictLimit ? dictEnd : iend;
29217  BYTE const* const lowMatchPtr =
29218  cur->offset < dictLimit ? dictStart : lowPrefixPtr;
29219  curForwardMatchLength =
29220  ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr);
29221  if (curForwardMatchLength < minMatchLength) {
29222  continue;
29223  }
29224  curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments(
29225  split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd);
29226  } else { /* !extDict */
29227  BYTE const* const pMatch = base + cur->offset;
29228  curForwardMatchLength = ZSTD_count(split, pMatch, iend);
29229  if (curForwardMatchLength < minMatchLength) {
29230  continue;
29231  }
29232  curBackwardMatchLength =
29233  ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr);
29234  }
29235  curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength;
29236 
29237  if (curTotalMatchLength > bestMatchLength) {
29238  bestMatchLength = curTotalMatchLength;
29239  forwardMatchLength = curForwardMatchLength;
29240  backwardMatchLength = curBackwardMatchLength;
29241  bestEntry = cur;
29242  }
29243  }
29244 
29245  /* No match found -- insert an entry into the hash table
29246  * and process the next candidate match */
29247  if (bestEntry == NULL) {
29248  ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
29249  continue;
29250  }
29251 
29252  /* Match found */
29253  offset = (U32)(split - base) - bestEntry->offset;
29254  mLength = forwardMatchLength + backwardMatchLength;
29255  {
29256  rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
29257 
29258  /* Out of sequence storage */
29259  if (rawSeqStore->size == rawSeqStore->capacity)
29260  return ERROR(dstSize_tooSmall);
29261  seq->litLength = (U32)(split - backwardMatchLength - anchor);
29262  seq->matchLength = (U32)mLength;
29263  seq->offset = offset;
29264  rawSeqStore->size++;
29265  }
29266 
29267  /* Insert the current entry into the hash table --- it must be
29268  * done after the previous block to avoid clobbering bestEntry */
29269  ZSTD_ldm_insertEntry(ldmState, hash, newEntry, *params);
29270 
29271  anchor = split + forwardMatchLength;
29272 
29273  /* If we find a match that ends after the data that we've hashed
29274  * then we have a repeating, overlapping, pattern. E.g. all zeros.
29275  * If one repetition of the pattern matches our `stopMask` then all
29276  * repetitions will. We don't need to insert them all into out table,
29277  * only the first one. So skip over overlapping matches.
29278  * This is a major speed boost (20x) for compressing a single byte
29279  * repeated, when that byte ends up in the table.
29280  */
29281  if (anchor > ip + hashed) {
29282  ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength);
29283  /* Continue the outer loop at anchor (ip + hashed == anchor). */
29284  ip = anchor - hashed;
29285  break;
29286  }
29287  }
29288 
29289  ip += hashed;
29290  }
29292  return iend - anchor;
29293 }
29294 
29297 static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size,
29298  U32 const reducerValue)
29299 {
29300  U32 u;
29301  for (u = 0; u < size; u++) {
29302  if (table[u].offset < reducerValue) table[u].offset = 0;
29303  else table[u].offset -= reducerValue;
29304  }
29305 }
29306 
29308  ldmState_t* ldmState, rawSeqStore_t* sequences,
29309  ldmParams_t const* params, void const* src, size_t srcSize)
29310 {
29311  U32 const maxDist = 1U << params->windowLog;
29312  BYTE const* const istart = (BYTE const*)src;
29313  BYTE const* const iend = istart + srcSize;
29314  size_t const kMaxChunkSize = 1 << 20;
29315  size_t const nbChunks = (srcSize / kMaxChunkSize) + ((srcSize % kMaxChunkSize) != 0);
29316  size_t chunk;
29317  size_t leftoverSize = 0;
29318 
29319  assert(ZSTD_CHUNKSIZE_MAX >= kMaxChunkSize);
29320  /* Check that ZSTD_window_update() has been called for this chunk prior
29321  * to passing it to this function.
29322  */
29323  assert(ldmState->window.nextSrc >= (BYTE const*)src + srcSize);
29324  /* The input could be very large (in zstdmt), so it must be broken up into
29325  * chunks to enforce the maximum distance and handle overflow correction.
29326  */
29327  assert(sequences->pos <= sequences->size);
29328  assert(sequences->size <= sequences->capacity);
29329  for (chunk = 0; chunk < nbChunks && sequences->size < sequences->capacity; ++chunk) {
29330  BYTE const* const chunkStart = istart + chunk * kMaxChunkSize;
29331  size_t const remaining = (size_t)(iend - chunkStart);
29332  BYTE const *const chunkEnd =
29333  (remaining < kMaxChunkSize) ? iend : chunkStart + kMaxChunkSize;
29334  size_t const chunkSize = chunkEnd - chunkStart;
29335  size_t newLeftoverSize;
29336  size_t const prevSize = sequences->size;
29337 
29338  assert(chunkStart < iend);
29339  /* 1. Perform overflow correction if necessary. */
29340  if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) {
29341  U32 const ldmHSize = 1U << params->hashLog;
29342  U32 const correction = ZSTD_window_correctOverflow(
29343  &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);
29344  ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction);
29345  /* invalidate dictionaries on overflow correction */
29346  ldmState->loadedDictEnd = 0;
29347  }
29348  /* 2. We enforce the maximum offset allowed.
29349  *
29350  * kMaxChunkSize should be small enough that we don't lose too much of
29351  * the window through early invalidation.
29352  * TODO: * Test the chunk size.
29353  * * Try invalidation after the sequence generation and test the
29354  * offset against maxDist directly.
29355  *
29356  * NOTE: Because of dictionaries + sequence splitting we MUST make sure
29357  * that any offset used is valid at the END of the sequence, since it may
29358  * be split into two sequences. This condition holds when using
29359  * ZSTD_window_enforceMaxDist(), but if we move to checking offsets
29360  * against maxDist directly, we'll have to carefully handle that case.
29361  */
29362  ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, &ldmState->loadedDictEnd, NULL);
29363  /* 3. Generate the sequences for the chunk, and get newLeftoverSize. */
29364  newLeftoverSize = ZSTD_ldm_generateSequences_internal(
29365  ldmState, sequences, params, chunkStart, chunkSize);
29366  if (ZSTD_isError(newLeftoverSize))
29367  return newLeftoverSize;
29368  /* 4. We add the leftover literals from previous iterations to the first
29369  * newly generated sequence, or add the `newLeftoverSize` if none are
29370  * generated.
29371  */
29372  /* Prepend the leftover literals from the last call */
29373  if (prevSize < sequences->size) {
29374  sequences->seq[prevSize].litLength += (U32)leftoverSize;
29375  leftoverSize = newLeftoverSize;
29376  } else {
29377  assert(newLeftoverSize == chunkSize);
29378  leftoverSize += chunkSize;
29379  }
29380  }
29381  return 0;
29382 }
29383 
29384 void
29385 ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch)
29386 {
29387  while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) {
29388  rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos;
29389  if (srcSize <= seq->litLength) {
29390  /* Skip past srcSize literals */
29391  seq->litLength -= (U32)srcSize;
29392  return;
29393  }
29394  srcSize -= seq->litLength;
29395  seq->litLength = 0;
29396  if (srcSize < seq->matchLength) {
29397  /* Skip past the first srcSize of the match */
29398  seq->matchLength -= (U32)srcSize;
29399  if (seq->matchLength < minMatch) {
29400  /* The match is too short, omit it */
29401  if (rawSeqStore->pos + 1 < rawSeqStore->size) {
29402  seq[1].litLength += seq[0].matchLength;
29403  }
29404  rawSeqStore->pos++;
29405  }
29406  return;
29407  }
29408  srcSize -= seq->matchLength;
29409  seq->matchLength = 0;
29410  rawSeqStore->pos++;
29411  }
29412 }
29413 
29421 static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore,
29422  U32 const remaining, U32 const minMatch)
29423 {
29424  rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos];
29425  assert(sequence.offset > 0);
29426  /* Likely: No partial sequence */
29427  if (remaining >= sequence.litLength + sequence.matchLength) {
29428  rawSeqStore->pos++;
29429  return sequence;
29430  }
29431  /* Cut the sequence short (offset == 0 ==> rest is literals). */
29432  if (remaining <= sequence.litLength) {
29433  sequence.offset = 0;
29434  } else if (remaining < sequence.litLength + sequence.matchLength) {
29435  sequence.matchLength = remaining - sequence.litLength;
29436  if (sequence.matchLength < minMatch) {
29437  sequence.offset = 0;
29438  }
29439  }
29440  /* Skip past `remaining` bytes for the future sequences. */
29441  ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch);
29442  return sequence;
29443 }
29444 
29445 void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
29446  U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
29447  while (currPos && rawSeqStore->pos < rawSeqStore->size) {
29448  rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
29449  if (currPos >= currSeq.litLength + currSeq.matchLength) {
29450  currPos -= currSeq.litLength + currSeq.matchLength;
29451  rawSeqStore->pos++;
29452  } else {
29453  rawSeqStore->posInSequence = currPos;
29454  break;
29455  }
29456  }
29457  if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
29458  rawSeqStore->posInSequence = 0;
29459  }
29460 }
29461 
29462 size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
29463  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
29464  ZSTD_paramSwitch_e useRowMatchFinder,
29465  void const* src, size_t srcSize)
29466 {
29467  const ZSTD_compressionParameters* const cParams = &ms->cParams;
29468  unsigned const minMatch = cParams->minMatch;
29469  ZSTD_blockCompressor const blockCompressor =
29470  ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms));
29471  /* Input bounds */
29472  BYTE const* const istart = (BYTE const*)src;
29473  BYTE const* const iend = istart + srcSize;
29474  /* Input positions */
29475  BYTE const* ip = istart;
29476 
29477  DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize);
29478  /* If using opt parser, use LDMs only as candidates rather than always accepting them */
29479  if (cParams->strategy >= ZSTD_btopt) {
29480  size_t lastLLSize;
29481  ms->ldmSeqStore = rawSeqStore;
29482  lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize);
29483  ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
29484  return lastLLSize;
29485  }
29486 
29487  assert(rawSeqStore->pos <= rawSeqStore->size);
29488  assert(rawSeqStore->size <= rawSeqStore->capacity);
29489  /* Loop through each sequence and apply the block compressor to the literals */
29490  while (rawSeqStore->pos < rawSeqStore->size && ip < iend) {
29491  /* maybeSplitSequence updates rawSeqStore->pos */
29492  rawSeq const sequence = maybeSplitSequence(rawSeqStore,
29493  (U32)(iend - ip), minMatch);
29494  int i;
29495  /* End signal */
29496  if (sequence.offset == 0)
29497  break;
29498 
29499  assert(ip + sequence.litLength + sequence.matchLength <= iend);
29500 
29501  /* Fill tables for block compressor */
29504  /* Run the block compressor */
29505  DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength);
29506  {
29507  size_t const newLitLength =
29508  blockCompressor(ms, seqStore, rep, ip, sequence.litLength);
29509  ip += sequence.litLength;
29510  /* Update the repcodes */
29511  for (i = ZSTD_REP_NUM - 1; i > 0; i--)
29512  rep[i] = rep[i-1];
29513  rep[0] = sequence.offset;
29514  /* Store the sequence */
29515  ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend,
29516  OFFSET_TO_OFFBASE(sequence.offset),
29517  sequence.matchLength);
29518  ip += sequence.matchLength;
29519  }
29520  }
29521  /* Fill the tables for the block compressor */
29524  /* Compress the last literals */
29525  return blockCompressor(ms, seqStore, rep, ip, iend - ip);
29526 }
29527 /**** ended inlining compress/zstd_ldm.c ****/
29528 /**** start inlining compress/zstd_opt.c ****/
29529 /*
29530  * Copyright (c) Meta Platforms, Inc. and affiliates.
29531  * All rights reserved.
29532  *
29533  * This source code is licensed under both the BSD-style license (found in the
29534  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
29535  * in the COPYING file in the root directory of this source tree).
29536  * You may select, at your option, one of the above-listed licenses.
29537  */
29539 /**** skipping file: zstd_compress_internal.h ****/
29540 /**** skipping file: hist.h ****/
29541 /**** skipping file: zstd_opt.h ****/
29542 
29543 
29544 #define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */
29545 #define ZSTD_MAX_PRICE (1<<30)
29546 
29547 #define ZSTD_PREDEF_THRESHOLD 8 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */
29548 
29549 
29550 /*-*************************************
29551 * Price functions for optimal parser
29552 ***************************************/
29553 
29554 #if 0 /* approximation at bit level (for tests) */
29555 # define BITCOST_ACCURACY 0
29556 # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
29557 # define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat))
29558 #elif 0 /* fractional bit accuracy (for tests) */
29559 # define BITCOST_ACCURACY 8
29560 # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
29561 # define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat))
29562 #else /* opt==approx, ultra==accurate */
29563 # define BITCOST_ACCURACY 8
29564 # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
29565 # define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat))
29566 #endif
29567 
29568 /* ZSTD_bitWeight() :
29569  * provide estimated "cost" of a stat in full bits only */
29571 {
29573 }
29574 
29575 /* ZSTD_fracWeight() :
29576  * provide fractional-bit "cost" of a stat,
29577  * using linear interpolation approximation */
29579 {
29580  U32 const stat = rawStat + 1;
29581  U32 const hb = ZSTD_highbit32(stat);
29582  U32 const BWeight = hb * BITCOST_MULTIPLIER;
29583  /* Fweight was meant for "Fractional weight"
29584  * but it's effectively a value between 1 and 2
29585  * using fixed point arithmetic */
29586  U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb;
29587  U32 const weight = BWeight + FWeight;
29588  assert(hb + BITCOST_ACCURACY < 31);
29589  return weight;
29590 }
29591 
29592 #if (DEBUGLEVEL>=2)
29593 /* debugging function,
29594  * @return price in bytes as fractional value
29595  * for debug messages only */
29596 MEM_STATIC double ZSTD_fCost(int price)
29597 {
29598  return (double)price / (BITCOST_MULTIPLIER*8);
29599 }
29600 #endif
29602 static int ZSTD_compressedLiterals(optState_t const* const optPtr)
29603 {
29604  return optPtr->literalCompressionMode != ZSTD_ps_disable;
29605 }
29606 
29607 static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel)
29608 {
29609  if (ZSTD_compressedLiterals(optPtr))
29610  optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel);
29611  optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel);
29612  optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel);
29613  optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel);
29614 }
29615 
29616 
29617 static U32 sum_u32(const unsigned table[], size_t nbElts)
29618 {
29619  size_t n;
29620  U32 total = 0;
29621  for (n=0; n<nbElts; n++) {
29622  total += table[n];
29623  }
29624  return total;
29625 }
29626 
29627 typedef enum { base_0possible=0, base_1guaranteed=1 } base_directive_e;
29628 
29629 static U32
29630 ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift, base_directive_e base1)
29631 {
29632  U32 s, sum=0;
29633  DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)",
29634  (unsigned)lastEltIndex+1, (unsigned)shift );
29635  assert(shift < 30);
29636  for (s=0; s<lastEltIndex+1; s++) {
29637  unsigned const base = base1 ? 1 : (table[s]>0);
29638  unsigned const newStat = base + (table[s] >> shift);
29639  sum += newStat;
29640  table[s] = newStat;
29641  }
29642  return sum;
29643 }
29644 
29645 /* ZSTD_scaleStats() :
29646  * reduce all elt frequencies in table if sum too large
29647  * return the resulting sum of elements */
29648 static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget)
29649 {
29650  U32 const prevsum = sum_u32(table, lastEltIndex+1);
29651  U32 const factor = prevsum >> logTarget;
29652  DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget);
29653  assert(logTarget < 30);
29654  if (factor <= 1) return prevsum;
29655  return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed);
29656 }
29657 
29658 /* ZSTD_rescaleFreqs() :
29659  * if first block (detected by optPtr->litLengthSum == 0) : init statistics
29660  * take hints from dictionary if there is one
29661  * and init from zero if there is none,
29662  * using src for literals stats, and baseline stats for sequence symbols
29663  * otherwise downscale existing stats, to be used as seed for next block.
29664  */
29665 static void
29666 ZSTD_rescaleFreqs(optState_t* const optPtr,
29667  const BYTE* const src, size_t const srcSize,
29668  int const optLevel)
29669 {
29670  int const compressedLiterals = ZSTD_compressedLiterals(optPtr);
29671  DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize);
29672  optPtr->priceType = zop_dynamic;
29673 
29674  if (optPtr->litLengthSum == 0) { /* no literals stats collected -> first block assumed -> init */
29675 
29676  /* heuristic: use pre-defined stats for too small inputs */
29677  if (srcSize <= ZSTD_PREDEF_THRESHOLD) {
29678  DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD);
29679  optPtr->priceType = zop_predef;
29680  }
29681 
29682  assert(optPtr->symbolCosts != NULL);
29683  if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) {
29684 
29685  /* huffman stats covering the full value set : table presumed generated by dictionary */
29686  optPtr->priceType = zop_dynamic;
29687 
29688  if (compressedLiterals) {
29689  /* generate literals statistics from huffman table */
29690  unsigned lit;
29691  assert(optPtr->litFreq != NULL);
29692  optPtr->litSum = 0;
29693  for (lit=0; lit<=MaxLit; lit++) {
29694  U32 const scaleLog = 11; /* scale to 2K */
29695  U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit);
29696  assert(bitCost <= scaleLog);
29697  optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
29698  optPtr->litSum += optPtr->litFreq[lit];
29699  } }
29700 
29701  { unsigned ll;
29702  FSE_CState_t llstate;
29703  FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable);
29704  optPtr->litLengthSum = 0;
29705  for (ll=0; ll<=MaxLL; ll++) {
29706  U32 const scaleLog = 10; /* scale to 1K */
29707  U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll);
29708  assert(bitCost < scaleLog);
29709  optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
29710  optPtr->litLengthSum += optPtr->litLengthFreq[ll];
29711  } }
29712 
29713  { unsigned ml;
29714  FSE_CState_t mlstate;
29715  FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable);
29716  optPtr->matchLengthSum = 0;
29717  for (ml=0; ml<=MaxML; ml++) {
29718  U32 const scaleLog = 10;
29719  U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml);
29720  assert(bitCost < scaleLog);
29721  optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
29722  optPtr->matchLengthSum += optPtr->matchLengthFreq[ml];
29723  } }
29724 
29725  { unsigned of;
29726  FSE_CState_t ofstate;
29727  FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable);
29728  optPtr->offCodeSum = 0;
29729  for (of=0; of<=MaxOff; of++) {
29730  U32 const scaleLog = 10;
29731  U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of);
29732  assert(bitCost < scaleLog);
29733  optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
29734  optPtr->offCodeSum += optPtr->offCodeFreq[of];
29735  } }
29736 
29737  } else { /* first block, no dictionary */
29738 
29739  assert(optPtr->litFreq != NULL);
29740  if (compressedLiterals) {
29741  /* base initial cost of literals on direct frequency within src */
29742  unsigned lit = MaxLit;
29743  HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */
29744  optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible);
29745  }
29746 
29747  { unsigned const baseLLfreqs[MaxLL+1] = {
29748  4, 2, 1, 1, 1, 1, 1, 1,
29749  1, 1, 1, 1, 1, 1, 1, 1,
29750  1, 1, 1, 1, 1, 1, 1, 1,
29751  1, 1, 1, 1, 1, 1, 1, 1,
29752  1, 1, 1, 1
29753  };
29754  ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs));
29755  optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1);
29756  }
29757 
29758  { unsigned ml;
29759  for (ml=0; ml<=MaxML; ml++)
29760  optPtr->matchLengthFreq[ml] = 1;
29761  }
29762  optPtr->matchLengthSum = MaxML+1;
29763 
29764  { unsigned const baseOFCfreqs[MaxOff+1] = {
29765  6, 2, 1, 1, 2, 3, 4, 4,
29766  4, 3, 2, 1, 1, 1, 1, 1,
29767  1, 1, 1, 1, 1, 1, 1, 1,
29768  1, 1, 1, 1, 1, 1, 1, 1
29769  };
29770  ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs));
29771  optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1);
29772  }
29773 
29774  }
29775 
29776  } else { /* new block : scale down accumulated statistics */
29777 
29778  if (compressedLiterals)
29779  optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12);
29780  optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11);
29781  optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11);
29782  optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11);
29783  }
29784 
29785  ZSTD_setBasePrices(optPtr, optLevel);
29786 }
29787 
29788 /* ZSTD_rawLiteralsCost() :
29789  * price of literals (only) in specified segment (which length can be 0).
29790  * does not include price of literalLength symbol */
29791 static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength,
29792  const optState_t* const optPtr,
29793  int optLevel)
29794 {
29795  if (litLength == 0) return 0;
29796 
29797  if (!ZSTD_compressedLiterals(optPtr))
29798  return (litLength << 3) * BITCOST_MULTIPLIER; /* Uncompressed - 8 bytes per literal. */
29799 
29800  if (optPtr->priceType == zop_predef)
29801  return (litLength*6) * BITCOST_MULTIPLIER; /* 6 bit per literal - no statistic used */
29802 
29803  /* dynamic statistics */
29804  { U32 price = optPtr->litSumBasePrice * litLength;
29805  U32 const litPriceMax = optPtr->litSumBasePrice - BITCOST_MULTIPLIER;
29806  U32 u;
29808  for (u=0; u < litLength; u++) {
29809  U32 litPrice = WEIGHT(optPtr->litFreq[literals[u]], optLevel);
29810  if (UNLIKELY(litPrice > litPriceMax)) litPrice = litPriceMax;
29811  price -= litPrice;
29812  }
29813  return price;
29814  }
29815 }
29816 
29817 /* ZSTD_litLengthPrice() :
29818  * cost of literalLength symbol */
29819 static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel)
29820 {
29821  assert(litLength <= ZSTD_BLOCKSIZE_MAX);
29822  if (optPtr->priceType == zop_predef)
29823  return WEIGHT(litLength, optLevel);
29824 
29825  /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX
29826  * because it isn't representable in the zstd format.
29827  * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1.
29828  * In such a case, the block would be all literals.
29829  */
29830  if (litLength == ZSTD_BLOCKSIZE_MAX)
29831  return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel);
29832 
29833  /* dynamic statistics */
29834  { U32 const llCode = ZSTD_LLcode(litLength);
29835  return (LL_bits[llCode] * BITCOST_MULTIPLIER)
29836  + optPtr->litLengthSumBasePrice
29837  - WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
29838  }
29839 }
29840 
29841 /* ZSTD_getMatchPrice() :
29842  * Provides the cost of the match part (offset + matchLength) of a sequence.
29843  * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
29844  * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq()
29845  * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency)
29846  */
29848 ZSTD_getMatchPrice(U32 const offBase,
29849  U32 const matchLength,
29850  const optState_t* const optPtr,
29851  int const optLevel)
29852 {
29853  U32 price;
29854  U32 const offCode = ZSTD_highbit32(offBase);
29855  U32 const mlBase = matchLength - MINMATCH;
29856  assert(matchLength >= MINMATCH);
29857 
29858  if (optPtr->priceType == zop_predef) /* fixed scheme, does not use statistics */
29859  return WEIGHT(mlBase, optLevel)
29860  + ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */
29861 
29862  /* dynamic statistics */
29863  price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel));
29864  if ((optLevel<2) /*static*/ && offCode >= 20)
29865  price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */
29866 
29867  /* match Length */
29868  { U32 const mlCode = ZSTD_MLcode(mlBase);
29869  price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel));
29870  }
29871 
29872  price += BITCOST_MULTIPLIER / 5; /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */
29873 
29874  DEBUGLOG(8, "ZSTD_getMatchPrice(ml:%u) = %u", matchLength, price);
29875  return price;
29876 }
29877 
29878 /* ZSTD_updateStats() :
29879  * assumption : literals + litLength <= iend */
29880 static void ZSTD_updateStats(optState_t* const optPtr,
29881  U32 litLength, const BYTE* literals,
29882  U32 offBase, U32 matchLength)
29883 {
29884  /* literals */
29885  if (ZSTD_compressedLiterals(optPtr)) {
29886  U32 u;
29887  for (u=0; u < litLength; u++)
29888  optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
29889  optPtr->litSum += litLength*ZSTD_LITFREQ_ADD;
29890  }
29891 
29892  /* literal Length */
29893  { U32 const llCode = ZSTD_LLcode(litLength);
29894  optPtr->litLengthFreq[llCode]++;
29895  optPtr->litLengthSum++;
29896  }
29897 
29898  /* offset code : follows storeSeq() numeric representation */
29899  { U32 const offCode = ZSTD_highbit32(offBase);
29900  assert(offCode <= MaxOff);
29901  optPtr->offCodeFreq[offCode]++;
29902  optPtr->offCodeSum++;
29903  }
29904 
29905  /* match Length */
29906  { U32 const mlBase = matchLength - MINMATCH;
29907  U32 const mlCode = ZSTD_MLcode(mlBase);
29908  optPtr->matchLengthFreq[mlCode]++;
29909  optPtr->matchLengthSum++;
29910  }
29912 
29913 
29914 /* ZSTD_readMINMATCH() :
29915  * function safe only for comparisons
29916  * assumption : memPtr must be at least 4 bytes before end of buffer */
29917 MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
29918 {
29919  switch (length)
29920  {
29921  default :
29922  case 4 : return MEM_read32(memPtr);
29923  case 3 : if (MEM_isLittleEndian())
29924  return MEM_read32(memPtr)<<8;
29925  else
29926  return MEM_read32(memPtr)>>8;
29927  }
29928 }
29929 
29930 
29931 /* Update hashTable3 up to ip (excluded)
29932  Assumption : always within prefix (i.e. not within extDict) */
29934  U32* nextToUpdate3,
29935  const BYTE* const ip)
29936 {
29937  U32* const hashTable3 = ms->hashTable3;
29938  U32 const hashLog3 = ms->hashLog3;
29939  const BYTE* const base = ms->window.base;
29940  U32 idx = *nextToUpdate3;
29941  U32 const target = (U32)(ip - base);
29942  size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);
29943  assert(hashLog3 > 0);
29944 
29945  while(idx < target) {
29946  hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
29947  idx++;
29948  }
29949 
29950  *nextToUpdate3 = target;
29951  return hashTable3[hash3];
29952 }
29953 
29954 
29955 /*-*************************************
29956 * Binary Tree search
29957 ***************************************/
29962 static U32 ZSTD_insertBt1(
29963  const ZSTD_matchState_t* ms,
29964  const BYTE* const ip, const BYTE* const iend,
29965  U32 const target,
29966  U32 const mls, const int extDict)
29967 {
29968  const ZSTD_compressionParameters* const cParams = &ms->cParams;
29969  U32* const hashTable = ms->hashTable;
29970  U32 const hashLog = cParams->hashLog;
29971  size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
29972  U32* const bt = ms->chainTable;
29973  U32 const btLog = cParams->chainLog - 1;
29974  U32 const btMask = (1 << btLog) - 1;
29975  U32 matchIndex = hashTable[h];
29976  size_t commonLengthSmaller=0, commonLengthLarger=0;
29977  const BYTE* const base = ms->window.base;
29978  const BYTE* const dictBase = ms->window.dictBase;
29979  const U32 dictLimit = ms->window.dictLimit;
29980  const BYTE* const dictEnd = dictBase + dictLimit;
29981  const BYTE* const prefixStart = base + dictLimit;
29982  const BYTE* match;
29983  const U32 curr = (U32)(ip-base);
29984  const U32 btLow = btMask >= curr ? 0 : curr - btMask;
29985  U32* smallerPtr = bt + 2*(curr&btMask);
29986  U32* largerPtr = smallerPtr + 1;
29987  U32 dummy32; /* to be nullified at the end */
29988  /* windowLow is based on target because
29989  * we only need positions that will be in the window at the end of the tree update.
29990  */
29991  U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog);
29992  U32 matchEndIdx = curr+8+1;
29993  size_t bestLength = 8;
29994  U32 nbCompares = 1U << cParams->searchLog;
29995 #ifdef ZSTD_C_PREDICT
29996  U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
29997  U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
29998  predictedSmall += (predictedSmall>0);
29999  predictedLarge += (predictedLarge>0);
30000 #endif /* ZSTD_C_PREDICT */
30001 
30002  DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
30003 
30004  assert(curr <= target);
30005  assert(ip <= iend-8); /* required for h calculation */
30006  hashTable[h] = curr; /* Update Hash Table */
30007 
30008  assert(windowLow > 0);
30009  for (; nbCompares && (matchIndex >= windowLow); --nbCompares) {
30010  U32* const nextPtr = bt + 2*(matchIndex & btMask);
30011  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
30012  assert(matchIndex < curr);
30013 
30014 #ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
30015  const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
30016  if (matchIndex == predictedSmall) {
30017  /* no need to check length, result known */
30018  *smallerPtr = matchIndex;
30019  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
30020  smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
30021  matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
30022  predictedSmall = predictPtr[1] + (predictPtr[1]>0);
30023  continue;
30024  }
30025  if (matchIndex == predictedLarge) {
30026  *largerPtr = matchIndex;
30027  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
30028  largerPtr = nextPtr;
30029  matchIndex = nextPtr[0];
30030  predictedLarge = predictPtr[0] + (predictPtr[0]>0);
30031  continue;
30032  }
30033 #endif
30034 
30035  if (!extDict || (matchIndex+matchLength >= dictLimit)) {
30036  assert(matchIndex+matchLength >= dictLimit); /* might be wrong if actually extDict */
30037  match = base + matchIndex;
30038  matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
30039  } else {
30040  match = dictBase + matchIndex;
30041  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
30042  if (matchIndex+matchLength >= dictLimit)
30043  match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
30044  }
30045 
30046  if (matchLength > bestLength) {
30047  bestLength = matchLength;
30048  if (matchLength > matchEndIdx - matchIndex)
30049  matchEndIdx = matchIndex + (U32)matchLength;
30050  }
30051 
30052  if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
30053  break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
30054  }
30055 
30056  if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */
30057  /* match is smaller than current */
30058  *smallerPtr = matchIndex; /* update smaller idx */
30059  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
30060  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */
30061  smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */
30062  matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */
30063  } else {
30064  /* match is larger than current */
30065  *largerPtr = matchIndex;
30066  commonLengthLarger = matchLength;
30067  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */
30068  largerPtr = nextPtr;
30069  matchIndex = nextPtr[0];
30070  } }
30071 
30072  *smallerPtr = *largerPtr = 0;
30073  { U32 positions = 0;
30074  if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */
30075  assert(matchEndIdx > curr + 8);
30076  return MAX(positions, matchEndIdx - (curr + 8));
30077  }
30078 }
30079 
30082  ZSTD_matchState_t* ms,
30083  const BYTE* const ip, const BYTE* const iend,
30084  const U32 mls, const ZSTD_dictMode_e dictMode)
30085 {
30086  const BYTE* const base = ms->window.base;
30087  U32 const target = (U32)(ip - base);
30088  U32 idx = ms->nextToUpdate;
30089  DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)",
30090  idx, target, dictMode);
30091 
30092  while(idx < target) {
30093  U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict);
30094  assert(idx < (U32)(idx + forward));
30095  idx += forward;
30096  }
30097  assert((size_t)(ip - base) <= (size_t)(U32)(-1));
30098  assert((size_t)(iend - base) <= (size_t)(U32)(-1));
30099  ms->nextToUpdate = target;
30100 }
30102 void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
30103  ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict);
30104 }
30105 
30108  ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */
30109  ZSTD_matchState_t* ms,
30110  U32* nextToUpdate3,
30111  const BYTE* const ip, const BYTE* const iLimit,
30112  const ZSTD_dictMode_e dictMode,
30113  const U32 rep[ZSTD_REP_NUM],
30114  const U32 ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */
30115  const U32 lengthToBeat,
30116  const U32 mls /* template */)
30117 {
30118  const ZSTD_compressionParameters* const cParams = &ms->cParams;
30119  U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
30120  const BYTE* const base = ms->window.base;
30121  U32 const curr = (U32)(ip-base);
30122  U32 const hashLog = cParams->hashLog;
30123  U32 const minMatch = (mls==3) ? 3 : 4;
30124  U32* const hashTable = ms->hashTable;
30125  size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
30126  U32 matchIndex = hashTable[h];
30127  U32* const bt = ms->chainTable;
30128  U32 const btLog = cParams->chainLog - 1;
30129  U32 const btMask= (1U << btLog) - 1;
30130  size_t commonLengthSmaller=0, commonLengthLarger=0;
30131  const BYTE* const dictBase = ms->window.dictBase;
30132  U32 const dictLimit = ms->window.dictLimit;
30133  const BYTE* const dictEnd = dictBase + dictLimit;
30134  const BYTE* const prefixStart = base + dictLimit;
30135  U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
30136  U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
30137  U32 const matchLow = windowLow ? windowLow : 1;
30138  U32* smallerPtr = bt + 2*(curr&btMask);
30139  U32* largerPtr = bt + 2*(curr&btMask) + 1;
30140  U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */
30141  U32 dummy32; /* to be nullified at the end */
30142  U32 mnum = 0;
30143  U32 nbCompares = 1U << cParams->searchLog;
30144 
30145  const ZSTD_matchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL;
30146  const ZSTD_compressionParameters* const dmsCParams =
30147  dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL;
30148  const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL;
30149  const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL;
30150  U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0;
30151  U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0;
30152  U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0;
30153  U32 const dmsHashLog = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog;
30154  U32 const dmsBtLog = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog;
30155  U32 const dmsBtMask = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0;
30156  U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
30157 
30158  size_t bestLength = lengthToBeat-1;
30159  DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr);
30160 
30161  /* check repCode */
30162  assert(ll0 <= 1); /* necessarily 1 or 0 */
30163  { U32 const lastR = ZSTD_REP_NUM + ll0;
30164  U32 repCode;
30165  for (repCode = ll0; repCode < lastR; repCode++) {
30166  U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
30167  U32 const repIndex = curr - repOffset;
30168  U32 repLen = 0;
30169  assert(curr >= dictLimit);
30170  if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */
30171  /* We must validate the repcode offset because when we're using a dictionary the
30172  * valid offset range shrinks when the dictionary goes out of bounds.
30173  */
30174  if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
30175  repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
30176  }
30177  } else { /* repIndex < dictLimit || repIndex >= curr */
30178  const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
30179  dmsBase + repIndex - dmsIndexDelta :
30180  dictBase + repIndex;
30181  assert(curr >= windowLow);
30182  if ( dictMode == ZSTD_extDict
30183  && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */
30184  & (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
30185  && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
30186  repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
30187  }
30188  if (dictMode == ZSTD_dictMatchState
30189  && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */
30190  & ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
30191  && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
30192  repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
30193  } }
30194  /* save longer solution */
30195  if (repLen > bestLength) {
30196  DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u",
30197  repCode, ll0, repOffset, repLen);
30198  bestLength = repLen;
30199  matches[mnum].off = REPCODE_TO_OFFBASE(repCode - ll0 + 1); /* expect value between 1 and 3 */
30200  matches[mnum].len = (U32)repLen;
30201  mnum++;
30202  if ( (repLen > sufficient_len)
30203  | (ip+repLen == iLimit) ) { /* best possible */
30204  return mnum;
30205  } } } }
30206 
30207  /* HC3 match finder */
30208  if ((mls == 3) /*static*/ && (bestLength < mls)) {
30209  U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
30210  if ((matchIndex3 >= matchLow)
30211  & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
30212  size_t mlen;
30213  if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
30214  const BYTE* const match = base + matchIndex3;
30215  mlen = ZSTD_count(ip, match, iLimit);
30216  } else {
30217  const BYTE* const match = dictBase + matchIndex3;
30218  mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart);
30219  }
30220 
30221  /* save best solution */
30222  if (mlen >= mls /* == 3 > bestLength */) {
30223  DEBUGLOG(8, "found small match with hlog3, of length %u",
30224  (U32)mlen);
30225  bestLength = mlen;
30226  assert(curr > matchIndex3);
30227  assert(mnum==0); /* no prior solution */
30228  matches[0].off = OFFSET_TO_OFFBASE(curr - matchIndex3);
30229  matches[0].len = (U32)mlen;
30230  mnum = 1;
30231  if ( (mlen > sufficient_len) |
30232  (ip+mlen == iLimit) ) { /* best possible length */
30233  ms->nextToUpdate = curr+1; /* skip insertion */
30234  return 1;
30235  } } }
30236  /* no dictMatchState lookup: dicts don't have a populated HC3 table */
30237  } /* if (mls == 3) */
30238 
30239  hashTable[h] = curr; /* Update Hash Table */
30240 
30241  for (; nbCompares && (matchIndex >= matchLow); --nbCompares) {
30242  U32* const nextPtr = bt + 2*(matchIndex & btMask);
30243  const BYTE* match;
30244  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
30245  assert(curr > matchIndex);
30246 
30247  if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
30248  assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
30249  match = base + matchIndex;
30250  if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
30251  matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
30252  } else {
30253  match = dictBase + matchIndex;
30254  assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
30255  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
30256  if (matchIndex+matchLength >= dictLimit)
30257  match = base + matchIndex; /* prepare for match[matchLength] read */
30258  }
30259 
30260  if (matchLength > bestLength) {
30261  DEBUGLOG(8, "found match of length %u at distance %u (offBase=%u)",
30262  (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex));
30263  assert(matchEndIdx > matchIndex);
30264  if (matchLength > matchEndIdx - matchIndex)
30265  matchEndIdx = matchIndex + (U32)matchLength;
30266  bestLength = matchLength;
30267  matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex);
30268  matches[mnum].len = (U32)matchLength;
30269  mnum++;
30270  if ( (matchLength > ZSTD_OPT_NUM)
30271  | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
30272  if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */
30273  break; /* drop, to preserve bt consistency (miss a little bit of compression) */
30274  } }
30275 
30276  if (match[matchLength] < ip[matchLength]) {
30277  /* match smaller than current */
30278  *smallerPtr = matchIndex; /* update smaller idx */
30279  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
30280  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
30281  smallerPtr = nextPtr+1; /* new candidate => larger than match, which was smaller than current */
30282  matchIndex = nextPtr[1]; /* new matchIndex, larger than previous, closer to current */
30283  } else {
30284  *largerPtr = matchIndex;
30285  commonLengthLarger = matchLength;
30286  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
30287  largerPtr = nextPtr;
30288  matchIndex = nextPtr[0];
30289  } }
30290 
30291  *smallerPtr = *largerPtr = 0;
30292 
30293  assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
30294  if (dictMode == ZSTD_dictMatchState && nbCompares) {
30295  size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
30296  U32 dictMatchIndex = dms->hashTable[dmsH];
30297  const U32* const dmsBt = dms->chainTable;
30298  commonLengthSmaller = commonLengthLarger = 0;
30299  for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) {
30300  const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
30301  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
30302  const BYTE* match = dmsBase + dictMatchIndex;
30303  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart);
30304  if (dictMatchIndex+matchLength >= dmsHighLimit)
30305  match = base + dictMatchIndex + dmsIndexDelta; /* to prepare for next usage of match[matchLength] */
30306 
30307  if (matchLength > bestLength) {
30308  matchIndex = dictMatchIndex + dmsIndexDelta;
30309  DEBUGLOG(8, "found dms match of length %u at distance %u (offBase=%u)",
30310  (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex));
30311  if (matchLength > matchEndIdx - matchIndex)
30312  matchEndIdx = matchIndex + (U32)matchLength;
30313  bestLength = matchLength;
30314  matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex);
30315  matches[mnum].len = (U32)matchLength;
30316  mnum++;
30317  if ( (matchLength > ZSTD_OPT_NUM)
30318  | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
30319  break; /* drop, to guarantee consistency (miss a little bit of compression) */
30320  } }
30321 
30322  if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */
30323  if (match[matchLength] < ip[matchLength]) {
30324  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
30325  dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
30326  } else {
30327  /* match is larger than current */
30328  commonLengthLarger = matchLength;
30329  dictMatchIndex = nextPtr[0];
30330  } } } /* if (dictMode == ZSTD_dictMatchState) */
30332  assert(matchEndIdx > curr+8);
30333  ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
30334  return mnum;
30335 }
30336 
30337 typedef U32 (*ZSTD_getAllMatchesFn)(
30338  ZSTD_match_t*,
30340  U32*,
30341  const BYTE*,
30342  const BYTE*,
30343  const U32 rep[ZSTD_REP_NUM],
30344  U32 const ll0,
30345  U32 const lengthToBeat);
30346 
30348  ZSTD_match_t* matches,
30349  ZSTD_matchState_t* ms,
30350  U32* nextToUpdate3,
30351  const BYTE* ip,
30352  const BYTE* const iHighLimit,
30353  const U32 rep[ZSTD_REP_NUM],
30354  U32 const ll0,
30355  U32 const lengthToBeat,
30356  const ZSTD_dictMode_e dictMode,
30357  const U32 mls)
30358 {
30359  assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls);
30360  DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls);
30361  if (ip < ms->window.base + ms->nextToUpdate)
30362  return 0; /* skipped area */
30363  ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode);
30364  return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls);
30365 }
30366 
30367 #define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls
30368 
30369 #define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \
30370  static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \
30371  ZSTD_match_t* matches, \
30372  ZSTD_matchState_t* ms, \
30373  U32* nextToUpdate3, \
30374  const BYTE* ip, \
30375  const BYTE* const iHighLimit, \
30376  const U32 rep[ZSTD_REP_NUM], \
30377  U32 const ll0, \
30378  U32 const lengthToBeat) \
30379  { \
30380  return ZSTD_btGetAllMatches_internal( \
30381  matches, ms, nextToUpdate3, ip, iHighLimit, \
30382  rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \
30383  }
30384 
30385 #define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \
30386  GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \
30387  GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \
30388  GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \
30389  GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6)
30390 
30393 GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState)
30394 
30395 #define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \
30396  { \
30397  ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \
30398  ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \
30399  ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \
30400  ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \
30401  }
30402 
30403 static ZSTD_getAllMatchesFn
30405 {
30406  ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = {
30409  ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState)
30410  };
30411  U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6);
30412  assert((U32)dictMode < 3);
30413  assert(mls - 3 < 4);
30414  return getAllMatchesFns[(int)dictMode][mls - 3];
30415 }
30417 /*************************
30418 * LDM helper functions *
30419 *************************/
30421 /* Struct containing info needed to make decision about ldm inclusion */
30422 typedef struct {
30423  rawSeqStore_t seqStore; /* External match candidates store for this block */
30424  U32 startPosInBlock; /* Start position of the current match candidate */
30425  U32 endPosInBlock; /* End position of the current match candidate */
30426  U32 offset; /* Offset of the match candidate */
30428 
30429 /* ZSTD_optLdm_skipRawSeqStoreBytes():
30430  * Moves forward in @rawSeqStore by @nbBytes,
30431  * which will update the fields 'pos' and 'posInSequence'.
30432  */
30433 static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes)
30434 {
30435  U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
30436  while (currPos && rawSeqStore->pos < rawSeqStore->size) {
30437  rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
30438  if (currPos >= currSeq.litLength + currSeq.matchLength) {
30439  currPos -= currSeq.litLength + currSeq.matchLength;
30440  rawSeqStore->pos++;
30441  } else {
30442  rawSeqStore->posInSequence = currPos;
30443  break;
30444  }
30445  }
30446  if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
30447  rawSeqStore->posInSequence = 0;
30448  }
30449 }
30451 /* ZSTD_opt_getNextMatchAndUpdateSeqStore():
30452  * Calculates the beginning and end of the next match in the current block.
30453  * Updates 'pos' and 'posInSequence' of the ldmSeqStore.
30454  */
30455 static void
30457  U32 blockBytesRemaining)
30458 {
30459  rawSeq currSeq;
30460  U32 currBlockEndPos;
30461  U32 literalsBytesRemaining;
30462  U32 matchBytesRemaining;
30463 
30464  /* Setting match end position to MAX to ensure we never use an LDM during this block */
30465  if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
30466  optLdm->startPosInBlock = UINT_MAX;
30467  optLdm->endPosInBlock = UINT_MAX;
30468  return;
30469  }
30470  /* Calculate appropriate bytes left in matchLength and litLength
30471  * after adjusting based on ldmSeqStore->posInSequence */
30472  currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
30473  assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
30474  currBlockEndPos = currPosInBlock + blockBytesRemaining;
30475  literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
30476  currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
30477  0;
30478  matchBytesRemaining = (literalsBytesRemaining == 0) ?
30479  currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
30480  currSeq.matchLength;
30481 
30482  /* If there are more literal bytes than bytes remaining in block, no ldm is possible */
30483  if (literalsBytesRemaining >= blockBytesRemaining) {
30484  optLdm->startPosInBlock = UINT_MAX;
30485  optLdm->endPosInBlock = UINT_MAX;
30486  ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
30487  return;
30488  }
30489 
30490  /* Matches may be < MINMATCH by this process. In that case, we will reject them
30491  when we are deciding whether or not to add the ldm */
30492  optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining;
30493  optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining;
30494  optLdm->offset = currSeq.offset;
30495 
30496  if (optLdm->endPosInBlock > currBlockEndPos) {
30497  /* Match ends after the block ends, we can't use the whole match */
30498  optLdm->endPosInBlock = currBlockEndPos;
30499  ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
30500  } else {
30501  /* Consume nb of bytes equal to size of sequence left */
30502  ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
30503  }
30504 }
30506 /* ZSTD_optLdm_maybeAddMatch():
30507  * Adds a match if it's long enough,
30508  * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock',
30509  * into 'matches'. Maintains the correct ordering of 'matches'.
30510  */
30511 static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
30512  const ZSTD_optLdm_t* optLdm, U32 currPosInBlock)
30513 {
30514  U32 const posDiff = currPosInBlock - optLdm->startPosInBlock;
30515  /* Note: ZSTD_match_t actually contains offBase and matchLength (before subtracting MINMATCH) */
30516  U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
30517 
30518  /* Ensure that current block position is not outside of the match */
30519  if (currPosInBlock < optLdm->startPosInBlock
30520  || currPosInBlock >= optLdm->endPosInBlock
30521  || candidateMatchLength < MINMATCH) {
30522  return;
30523  }
30524 
30525  if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
30526  U32 const candidateOffBase = OFFSET_TO_OFFBASE(optLdm->offset);
30527  DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offBase: %u matchLength %u) at block position=%u",
30528  candidateOffBase, candidateMatchLength, currPosInBlock);
30529  matches[*nbMatches].len = candidateMatchLength;
30530  matches[*nbMatches].off = candidateOffBase;
30531  (*nbMatches)++;
30532  }
30534 
30535 /* ZSTD_optLdm_processMatchCandidate():
30536  * Wrapper function to update ldm seq store and call ldm functions as necessary.
30537  */
30538 static void
30540  ZSTD_match_t* matches, U32* nbMatches,
30541  U32 currPosInBlock, U32 remainingBytes)
30542 {
30543  if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
30544  return;
30545  }
30546 
30547  if (currPosInBlock >= optLdm->endPosInBlock) {
30548  if (currPosInBlock > optLdm->endPosInBlock) {
30549  /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
30550  * at the end of a match from the ldm seq store, and will often be some bytes
30551  * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
30552  */
30553  U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock;
30554  ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
30555  }
30556  ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
30557  }
30558  ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
30559 }
30561 
30562 /*-*******************************
30563 * Optimal parser
30564 *********************************/
30565 
30567 {
30568  return sol.litlen + sol.mlen;
30569 }
30570 
30571 #if 0 /* debug */
30572 
30573 static void
30574 listStats(const U32* table, int lastEltID)
30575 {
30576  int const nbElts = lastEltID + 1;
30577  int enb;
30578  for (enb=0; enb < nbElts; enb++) {
30579  (void)table;
30580  /* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */
30581  RAWLOG(2, "%4i,", table[enb]);
30582  }
30583  RAWLOG(2, " \n");
30584 }
30585 
30586 #endif
30587 
30588 FORCE_INLINE_TEMPLATE size_t
30590  seqStore_t* seqStore,
30591  U32 rep[ZSTD_REP_NUM],
30592  const void* src, size_t srcSize,
30593  const int optLevel,
30594  const ZSTD_dictMode_e dictMode)
30595 {
30596  optState_t* const optStatePtr = &ms->opt;
30597  const BYTE* const istart = (const BYTE*)src;
30598  const BYTE* ip = istart;
30599  const BYTE* anchor = istart;
30600  const BYTE* const iend = istart + srcSize;
30601  const BYTE* const ilimit = iend - 8;
30602  const BYTE* const base = ms->window.base;
30603  const BYTE* const prefixStart = base + ms->window.dictLimit;
30604  const ZSTD_compressionParameters* const cParams = &ms->cParams;
30605 
30606  ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode);
30607 
30608  U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
30609  U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
30610  U32 nextToUpdate3 = ms->nextToUpdate;
30611 
30612  ZSTD_optimal_t* const opt = optStatePtr->priceTable;
30613  ZSTD_match_t* const matches = optStatePtr->matchTable;
30614  ZSTD_optimal_t lastSequence;
30615  ZSTD_optLdm_t optLdm;
30616 
30617  ZSTD_memset(&lastSequence, 0, sizeof(ZSTD_optimal_t));
30618 
30619  optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore;
30620  optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0;
30621  ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
30622 
30623  /* init */
30624  DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
30625  (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);
30626  assert(optLevel <= 2);
30627  ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);
30628  ip += (ip==prefixStart);
30629 
30630  /* Match Loop */
30631  while (ip < ilimit) {
30632  U32 cur, last_pos = 0;
30633 
30634  /* find first match */
30635  { U32 const litlen = (U32)(ip - anchor);
30636  U32 const ll0 = !litlen;
30637  U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch);
30638  ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
30639  (U32)(ip-istart), (U32)(iend - ip));
30640  if (!nbMatches) { ip++; continue; }
30641 
30642  /* initialize opt[0] */
30643  { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
30644  opt[0].mlen = 0; /* means is_a_literal */
30645  opt[0].litlen = litlen;
30646  /* We don't need to include the actual price of the literals because
30647  * it is static for the duration of the forward pass, and is included
30648  * in every price. We include the literal length to avoid negative
30649  * prices when we subtract the previous literal length.
30650  */
30651  opt[0].price = (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
30652 
30653  /* large match -> immediate encoding */
30654  { U32 const maxML = matches[nbMatches-1].len;
30655  U32 const maxOffBase = matches[nbMatches-1].off;
30656  DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffBase=%u at cPos=%u => start new series",
30657  nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart));
30658 
30659  if (maxML > sufficient_len) {
30660  lastSequence.litlen = litlen;
30661  lastSequence.mlen = maxML;
30662  lastSequence.off = maxOffBase;
30663  DEBUGLOG(6, "large match (%u>%u), immediate encoding",
30664  maxML, sufficient_len);
30665  cur = 0;
30666  last_pos = ZSTD_totalLen(lastSequence);
30667  goto _shortestPath;
30668  } }
30669 
30670  /* set prices for first matches starting position == 0 */
30671  assert(opt[0].price >= 0);
30672  { U32 const literalsPrice = (U32)opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
30673  U32 pos;
30674  U32 matchNb;
30675  for (pos = 1; pos < minMatch; pos++) {
30676  opt[pos].price = ZSTD_MAX_PRICE; /* mlen, litlen and price will be fixed during forward scanning */
30677  }
30678  for (matchNb = 0; matchNb < nbMatches; matchNb++) {
30679  U32 const offBase = matches[matchNb].off;
30680  U32 const end = matches[matchNb].len;
30681  for ( ; pos <= end ; pos++ ) {
30682  U32 const matchPrice = ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel);
30683  U32 const sequencePrice = literalsPrice + matchPrice;
30684  DEBUGLOG(7, "rPos:%u => set initial price : %.2f",
30685  pos, ZSTD_fCost((int)sequencePrice));
30686  opt[pos].mlen = pos;
30687  opt[pos].off = offBase;
30688  opt[pos].litlen = litlen;
30689  opt[pos].price = (int)sequencePrice;
30690  } }
30691  last_pos = pos-1;
30692  }
30693  }
30694 
30695  /* check further positions */
30696  for (cur = 1; cur <= last_pos; cur++) {
30697  const BYTE* const inr = ip + cur;
30698  assert(cur < ZSTD_OPT_NUM);
30699  DEBUGLOG(7, "cPos:%zi==rPos:%u", inr-istart, cur)
30700 
30701  /* Fix current position with one literal if cheaper */
30702  { U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1;
30703  int const price = opt[cur-1].price
30704  + (int)ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel)
30705  + (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel)
30706  - (int)ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel);
30707  assert(price < 1000000000); /* overflow check */
30708  if (price <= opt[cur].price) {
30709  DEBUGLOG(7, "cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)",
30710  inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen,
30711  opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]);
30712  opt[cur].mlen = 0;
30713  opt[cur].off = 0;
30714  opt[cur].litlen = litlen;
30715  opt[cur].price = price;
30716  } else {
30717  DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)",
30718  inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),
30719  opt[cur].rep[0], opt[cur].rep[1], opt[cur].rep[2]);
30720  }
30721  }
30722 
30723  /* Set the repcodes of the current position. We must do it here
30724  * because we rely on the repcodes of the 2nd to last sequence being
30725  * correct to set the next chunks repcodes during the backward
30726  * traversal.
30727  */
30728  ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t));
30729  assert(cur >= opt[cur].mlen);
30730  if (opt[cur].mlen != 0) {
30731  U32 const prev = cur - opt[cur].mlen;
30732  repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
30733  ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
30734  } else {
30735  ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
30736  }
30737 
30738  /* last match must start at a minimum distance of 8 from oend */
30739  if (inr > ilimit) continue;
30740 
30741  if (cur == last_pos) break;
30742 
30743  if ( (optLevel==0) /*static_test*/
30744  && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) {
30745  DEBUGLOG(7, "move to next rPos:%u : price is <=", cur+1);
30746  continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */
30747  }
30748 
30749  assert(opt[cur].price >= 0);
30750  { U32 const ll0 = (opt[cur].mlen != 0);
30751  U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
30752  U32 const previousPrice = (U32)opt[cur].price;
30753  U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
30754  U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch);
30755  U32 matchNb;
30756 
30757  ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
30758  (U32)(inr-istart), (U32)(iend-inr));
30759 
30760  if (!nbMatches) {
30761  DEBUGLOG(7, "rPos:%u : no match found", cur);
30762  continue;
30763  }
30764 
30765  { U32 const maxML = matches[nbMatches-1].len;
30766  DEBUGLOG(7, "cPos:%zi==rPos:%u, found %u matches, of maxLength=%u",
30767  inr-istart, cur, nbMatches, maxML);
30768 
30769  if ( (maxML > sufficient_len)
30770  || (cur + maxML >= ZSTD_OPT_NUM) ) {
30771  lastSequence.mlen = maxML;
30772  lastSequence.off = matches[nbMatches-1].off;
30773  lastSequence.litlen = litlen;
30774  cur -= (opt[cur].mlen==0) ? opt[cur].litlen : 0; /* last sequence is actually only literals, fix cur to last match - note : may underflow, in which case, it's first sequence, and it's okay */
30775  last_pos = cur + ZSTD_totalLen(lastSequence);
30776  if (cur > ZSTD_OPT_NUM) cur = 0; /* underflow => first match */
30777  goto _shortestPath;
30778  } }
30779 
30780  /* set prices using matches found at position == cur */
30781  for (matchNb = 0; matchNb < nbMatches; matchNb++) {
30782  U32 const offset = matches[matchNb].off;
30783  U32 const lastML = matches[matchNb].len;
30784  U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;
30785  U32 mlen;
30786 
30787  DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u",
30788  matchNb, matches[matchNb].off, lastML, litlen);
30789 
30790  for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */
30791  U32 const pos = cur + mlen;
30792  int const price = (int)basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel);
30793 
30794  if ((pos > last_pos) || (price < opt[pos].price)) {
30795  DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)",
30796  pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
30797  while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } /* fill empty positions */
30798  opt[pos].mlen = mlen;
30799  opt[pos].off = offset;
30800  opt[pos].litlen = litlen;
30801  opt[pos].price = price;
30802  } else {
30803  DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)",
30804  pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
30805  if (optLevel==0) break; /* early update abort; gets ~+10% speed for about -0.01 ratio loss */
30806  }
30807  } } }
30808  } /* for (cur = 1; cur <= last_pos; cur++) */
30809 
30810  lastSequence = opt[last_pos];
30811  cur = last_pos > ZSTD_totalLen(lastSequence) ? last_pos - ZSTD_totalLen(lastSequence) : 0; /* single sequence, and it starts before `ip` */
30812  assert(cur < ZSTD_OPT_NUM); /* control overflow*/
30813 
30814 _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
30815  assert(opt[0].mlen == 0);
30816 
30817  /* Set the next chunk's repcodes based on the repcodes of the beginning
30818  * of the last match, and the last sequence. This avoids us having to
30819  * update them while traversing the sequences.
30820  */
30821  if (lastSequence.mlen != 0) {
30822  repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
30823  ZSTD_memcpy(rep, &reps, sizeof(reps));
30824  } else {
30825  ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
30826  }
30827 
30828  { U32 const storeEnd = cur + 1;
30829  U32 storeStart = storeEnd;
30830  U32 seqPos = cur;
30831 
30832  DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)",
30833  last_pos, cur); (void)last_pos;
30834  assert(storeEnd < ZSTD_OPT_NUM);
30835  DEBUGLOG(6, "last sequence copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
30836  storeEnd, lastSequence.litlen, lastSequence.mlen, lastSequence.off);
30837  opt[storeEnd] = lastSequence;
30838  while (seqPos > 0) {
30839  U32 const backDist = ZSTD_totalLen(opt[seqPos]);
30840  storeStart--;
30841  DEBUGLOG(6, "sequence from rPos=%u copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
30842  seqPos, storeStart, opt[seqPos].litlen, opt[seqPos].mlen, opt[seqPos].off);
30843  opt[storeStart] = opt[seqPos];
30844  seqPos = (seqPos > backDist) ? seqPos - backDist : 0;
30845  }
30846 
30847  /* save sequences */
30848  DEBUGLOG(6, "sending selected sequences into seqStore")
30849  { U32 storePos;
30850  for (storePos=storeStart; storePos <= storeEnd; storePos++) {
30851  U32 const llen = opt[storePos].litlen;
30852  U32 const mlen = opt[storePos].mlen;
30853  U32 const offBase = opt[storePos].off;
30854  U32 const advance = llen + mlen;
30855  DEBUGLOG(6, "considering seq starting at %zi, llen=%u, mlen=%u",
30856  anchor - istart, (unsigned)llen, (unsigned)mlen);
30857 
30858  if (mlen==0) { /* only literals => must be last "sequence", actually starting a new stream of sequences */
30859  assert(storePos == storeEnd); /* must be last sequence */
30860  ip = anchor + llen; /* last "sequence" is a bunch of literals => don't progress anchor */
30861  continue; /* will finish */
30862  }
30863 
30864  assert(anchor + llen <= iend);
30865  ZSTD_updateStats(optStatePtr, llen, anchor, offBase, mlen);
30866  ZSTD_storeSeq(seqStore, llen, anchor, iend, offBase, mlen);
30867  anchor += advance;
30868  ip = anchor;
30869  } }
30870  ZSTD_setBasePrices(optStatePtr, optLevel);
30871  }
30872  } /* while (ip < ilimit) */
30873 
30874  /* Return the last literals size */
30875  return (size_t)(iend - anchor);
30876 }
30877 
30878 static size_t ZSTD_compressBlock_opt0(
30880  const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
30881 {
30882  return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode);
30883 }
30884 
30885 static size_t ZSTD_compressBlock_opt2(
30887  const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
30888 {
30889  return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode);
30890 }
30891 
30893  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
30894  const void* src, size_t srcSize)
30895 {
30896  DEBUGLOG(5, "ZSTD_compressBlock_btopt");
30897  return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
30898 }
30899 
30900 
30901 
30902 
30903 /* ZSTD_initStats_ultra():
30904  * make a first compression pass, just to seed stats with more accurate starting values.
30905  * only works on first block, with no dictionary and no ldm.
30906  * this function cannot error out, its narrow contract must be respected.
30907  */
30908 static void
30910  seqStore_t* seqStore,
30911  U32 rep[ZSTD_REP_NUM],
30912  const void* src, size_t srcSize)
30913 {
30914  U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */
30915  ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep));
30916 
30917  DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize);
30918  assert(ms->opt.litLengthSum == 0); /* first block */
30919  assert(seqStore->sequences == seqStore->sequencesStart); /* no ldm */
30920  assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */
30921  assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */
30922 
30923  ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/
30924 
30925  /* invalidate first scan from history, only keep entropy stats */
30926  ZSTD_resetSeqStore(seqStore);
30927  ms->window.base -= srcSize;
30929  ms->window.lowLimit = ms->window.dictLimit;
30930  ms->nextToUpdate = ms->window.dictLimit;
30931 
30932 }
30933 
30935  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
30936  const void* src, size_t srcSize)
30937 {
30938  DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize);
30939  return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
30940 }
30941 
30943  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
30944  const void* src, size_t srcSize)
30945 {
30946  U32 const curr = (U32)((const BYTE*)src - ms->window.base);
30947  DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
30948 
30949  /* 2-passes strategy:
30950  * this strategy makes a first pass over first block to collect statistics
30951  * in order to seed next round's statistics with it.
30952  * After 1st pass, function forgets history, and starts a new block.
30953  * Consequently, this can only work if no data has been previously loaded in tables,
30954  * aka, no dictionary, no prefix, no ldm preprocessing.
30955  * The compression ratio gain is generally small (~0.5% on first block),
30956  ** the cost is 2x cpu time on first block. */
30958  if ( (ms->opt.litLengthSum==0) /* first block */
30959  && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */
30960  && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */
30961  && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */
30962  && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */
30963  ) {
30964  ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
30965  }
30966 
30967  return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
30968 }
30969 
30972  const void* src, size_t srcSize)
30973 {
30974  return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
30975 }
30976 
30979  const void* src, size_t srcSize)
30980 {
30981  return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
30982 }
30983 
30986  const void* src, size_t srcSize)
30987 {
30988  return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
30989 }
30990 
30992  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
30993  const void* src, size_t srcSize)
30994 {
30995  return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
30996 }
30997 
30998 /* note : no btultra2 variant for extDict nor dictMatchState,
30999  * because btultra2 is not meant to work with dictionaries
31000  * and is only specific for the first block (no prefix) */
31001 /**** ended inlining compress/zstd_opt.c ****/
31002 #ifdef ZSTD_MULTITHREAD
31003 /**** start inlining compress/zstdmt_compress.c ****/
31004 /*
31005  * Copyright (c) Meta Platforms, Inc. and affiliates.
31006  * All rights reserved.
31007  *
31008  * This source code is licensed under both the BSD-style license (found in the
31009  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
31010  * in the COPYING file in the root directory of this source tree).
31011  * You may select, at your option, one of the above-listed licenses.
31012  */
31013 
31014 
31015 /* ====== Compiler specifics ====== */
31016 #if defined(_MSC_VER)
31017 # pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
31018 #endif
31019 
31020 
31021 /* ====== Constants ====== */
31022 #define ZSTDMT_OVERLAPLOG_DEFAULT 0
31023 
31024 
31025 /* ====== Dependencies ====== */
31026 /**** skipping file: ../common/allocations.h ****/
31027 /**** skipping file: ../common/zstd_deps.h ****/
31028 /**** skipping file: ../common/mem.h ****/
31029 /**** skipping file: ../common/pool.h ****/
31030 /**** skipping file: ../common/threading.h ****/
31031 /**** skipping file: zstd_compress_internal.h ****/
31032 /**** skipping file: zstd_ldm.h ****/
31033 /**** skipping file: zstdmt_compress.h ****/
31034 
31035 /* Guards code to support resizing the SeqPool.
31036  * We will want to resize the SeqPool to save memory in the future.
31037  * Until then, comment the code out since it is unused.
31038  */
31039 #define ZSTD_RESIZE_SEQPOOL 0
31040 
31041 /* ====== Debug ====== */
31042 #if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2) \
31043  && !defined(_MSC_VER) \
31044  && !defined(__MINGW32__)
31045 
31046 # include <stdio.h>
31047 # include <unistd.h>
31048 # include <sys/times.h>
31049 
31050 # define DEBUG_PRINTHEX(l,p,n) { \
31051  unsigned debug_u; \
31052  for (debug_u=0; debug_u<(n); debug_u++) \
31053  RAWLOG(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \
31054  RAWLOG(l, " \n"); \
31055 }
31056 
31057 static unsigned long long GetCurrentClockTimeMicroseconds(void)
31058 {
31059  static clock_t _ticksPerSecond = 0;
31060  if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK);
31061 
31062  { struct tms junk; clock_t newTicks = (clock_t) times(&junk);
31063  return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond);
31064 } }
31065 
31066 #define MUTEX_WAIT_TIME_DLEVEL 6
31067 #define ZSTD_PTHREAD_MUTEX_LOCK(mutex) { \
31068  if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) { \
31069  unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
31070  ZSTD_pthread_mutex_lock(mutex); \
31071  { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
31072  unsigned long long const elapsedTime = (afterTime-beforeTime); \
31073  if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \
31074  DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
31075  elapsedTime, #mutex); \
31076  } } \
31077  } else { \
31078  ZSTD_pthread_mutex_lock(mutex); \
31079  } \
31080 }
31081 
31082 #else
31083 
31084 # define ZSTD_PTHREAD_MUTEX_LOCK(m) ZSTD_pthread_mutex_lock(m)
31085 # define DEBUG_PRINTHEX(l,p,n) {}
31086 
31087 #endif
31090 /* ===== Buffer Pool ===== */
31091 /* a single Buffer Pool can be invoked from multiple threads in parallel */
31093 typedef struct buffer_s {
31094  void* start;
31095  size_t capacity;
31098 static const buffer_t g_nullBuffer = { NULL, 0 };
31100 typedef struct ZSTDMT_bufferPool_s {
31102  size_t bufferSize;
31103  unsigned totalBuffers;
31104  unsigned nbBuffers;
31105  ZSTD_customMem cMem;
31106  buffer_t bTable[1]; /* variable size */
31108 
31109 static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem)
31110 {
31112  sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
31113  if (bufPool==NULL) return NULL;
31114  if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) {
31115  ZSTD_customFree(bufPool, cMem);
31116  return NULL;
31117  }
31118  bufPool->bufferSize = 64 KB;
31119  bufPool->totalBuffers = maxNbBuffers;
31120  bufPool->nbBuffers = 0;
31121  bufPool->cMem = cMem;
31122  return bufPool;
31123 }
31124 
31125 static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
31126 {
31127  unsigned u;
31128  DEBUGLOG(3, "ZSTDMT_freeBufferPool (address:%08X)", (U32)(size_t)bufPool);
31129  if (!bufPool) return; /* compatibility with free on NULL */
31130  for (u=0; u<bufPool->totalBuffers; u++) {
31131  DEBUGLOG(4, "free buffer %2u (address:%08X)", u, (U32)(size_t)bufPool->bTable[u].start);
31132  ZSTD_customFree(bufPool->bTable[u].start, bufPool->cMem);
31133  }
31134  ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);
31135  ZSTD_customFree(bufPool, bufPool->cMem);
31136 }
31137 
31138 /* only works at initialization, not during compression */
31139 static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool)
31140 {
31141  size_t const poolSize = sizeof(*bufPool)
31142  + (bufPool->totalBuffers - 1) * sizeof(buffer_t);
31143  unsigned u;
31144  size_t totalBufferSize = 0;
31146  for (u=0; u<bufPool->totalBuffers; u++)
31147  totalBufferSize += bufPool->bTable[u].capacity;
31149 
31150  return poolSize + totalBufferSize;
31152 
31153 /* ZSTDMT_setBufferSize() :
31154  * all future buffers provided by this buffer pool will have _at least_ this size
31155  * note : it's better for all buffers to have same size,
31156  * as they become freely interchangeable, reducing malloc/free usages and memory fragmentation */
31157 static void ZSTDMT_setBufferSize(ZSTDMT_bufferPool* const bufPool, size_t const bSize)
31158 {
31160  DEBUGLOG(4, "ZSTDMT_setBufferSize: bSize = %u", (U32)bSize);
31161  bufPool->bufferSize = bSize;
31163 }
31164 
31165 
31166 static ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool, unsigned maxNbBuffers)
31167 {
31168  if (srcBufPool==NULL) return NULL;
31169  if (srcBufPool->totalBuffers >= maxNbBuffers) /* good enough */
31170  return srcBufPool;
31171  /* need a larger buffer pool */
31172  { ZSTD_customMem const cMem = srcBufPool->cMem;
31173  size_t const bSize = srcBufPool->bufferSize; /* forward parameters */
31174  ZSTDMT_bufferPool* newBufPool;
31175  ZSTDMT_freeBufferPool(srcBufPool);
31176  newBufPool = ZSTDMT_createBufferPool(maxNbBuffers, cMem);
31177  if (newBufPool==NULL) return newBufPool;
31178  ZSTDMT_setBufferSize(newBufPool, bSize);
31179  return newBufPool;
31180  }
31182 
31188 {
31189  size_t const bSize = bufPool->bufferSize;
31190  DEBUGLOG(5, "ZSTDMT_getBuffer: bSize = %u", (U32)bufPool->bufferSize);
31192  if (bufPool->nbBuffers) { /* try to use an existing buffer */
31193  buffer_t const buf = bufPool->bTable[--(bufPool->nbBuffers)];
31194  size_t const availBufferSize = buf.capacity;
31195  bufPool->bTable[bufPool->nbBuffers] = g_nullBuffer;
31196  if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) {
31197  /* large enough, but not too much */
31198  DEBUGLOG(5, "ZSTDMT_getBuffer: provide buffer %u of size %u",
31199  bufPool->nbBuffers, (U32)buf.capacity);
31201  return buf;
31202  }
31203  /* size conditions not respected : scratch this buffer, create new one */
31204  DEBUGLOG(5, "ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing");
31205  ZSTD_customFree(buf.start, bufPool->cMem);
31206  }
31208  /* create new buffer */
31209  DEBUGLOG(5, "ZSTDMT_getBuffer: create a new buffer");
31210  { buffer_t buffer;
31211  void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
31212  buffer.start = start; /* note : start can be NULL if malloc fails ! */
31213  buffer.capacity = (start==NULL) ? 0 : bSize;
31214  if (start==NULL) {
31215  DEBUGLOG(5, "ZSTDMT_getBuffer: buffer allocation failure !!");
31216  } else {
31217  DEBUGLOG(5, "ZSTDMT_getBuffer: created buffer of size %u", (U32)bSize);
31218  }
31219  return buffer;
31220  }
31221 }
31222 
31223 #if ZSTD_RESIZE_SEQPOOL
31224 
31229 static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
31230 {
31231  size_t const bSize = bufPool->bufferSize;
31232  if (buffer.capacity < bSize) {
31233  void* const start = ZSTD_customMalloc(bSize, bufPool->cMem);
31234  buffer_t newBuffer;
31235  newBuffer.start = start;
31236  newBuffer.capacity = start == NULL ? 0 : bSize;
31237  if (start != NULL) {
31238  assert(newBuffer.capacity >= buffer.capacity);
31239  ZSTD_memcpy(newBuffer.start, buffer.start, buffer.capacity);
31240  DEBUGLOG(5, "ZSTDMT_resizeBuffer: created buffer of size %u", (U32)bSize);
31241  return newBuffer;
31242  }
31243  DEBUGLOG(5, "ZSTDMT_resizeBuffer: buffer allocation failure !!");
31244  }
31245  return buffer;
31246 }
31247 #endif
31248 
31249 /* store buffer for later re-use, up to pool capacity */
31250 static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
31251 {
31252  DEBUGLOG(5, "ZSTDMT_releaseBuffer");
31253  if (buf.start == NULL) return; /* compatible with release on NULL */
31255  if (bufPool->nbBuffers < bufPool->totalBuffers) {
31256  bufPool->bTable[bufPool->nbBuffers++] = buf; /* stored for later use */
31257  DEBUGLOG(5, "ZSTDMT_releaseBuffer: stored buffer of size %u in slot %u",
31258  (U32)buf.capacity, (U32)(bufPool->nbBuffers-1));
31260  return;
31261  }
31263  /* Reached bufferPool capacity (should not happen) */
31264  DEBUGLOG(5, "ZSTDMT_releaseBuffer: pool capacity reached => freeing ");
31265  ZSTD_customFree(buf.start, bufPool->cMem);
31266 }
31268 /* We need 2 output buffers per worker since each dstBuff must be flushed after it is released.
31269  * The 3 additional buffers are as follows:
31270  * 1 buffer for input loading
31271  * 1 buffer for "next input" when submitting current one
31272  * 1 buffer stuck in queue */
31273 #define BUF_POOL_MAX_NB_BUFFERS(nbWorkers) (2*(nbWorkers) + 3)
31274 
31275 /* After a worker releases its rawSeqStore, it is immediately ready for reuse.
31276  * So we only need one seq buffer per worker. */
31277 #define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers) (nbWorkers)
31278 
31279 /* ===== Seq Pool Wrapper ====== */
31280 
31283 static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)
31284 {
31285  return ZSTDMT_sizeof_bufferPool(seqPool);
31286 }
31287 
31288 static rawSeqStore_t bufferToSeq(buffer_t buffer)
31289 {
31291  seq.seq = (rawSeq*)buffer.start;
31292  seq.capacity = buffer.capacity / sizeof(rawSeq);
31293  return seq;
31294 }
31295 
31297 {
31298  buffer_t buffer;
31299  buffer.start = seq.seq;
31300  buffer.capacity = seq.capacity * sizeof(rawSeq);
31301  return buffer;
31302 }
31303 
31305 {
31306  if (seqPool->bufferSize == 0) {
31307  return kNullRawSeqStore;
31308  }
31309  return bufferToSeq(ZSTDMT_getBuffer(seqPool));
31310 }
31311 
31312 #if ZSTD_RESIZE_SEQPOOL
31313 static rawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
31314 {
31315  return bufferToSeq(ZSTDMT_resizeBuffer(seqPool, seqToBuffer(seq)));
31316 }
31317 #endif
31319 static void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)
31320 {
31321  ZSTDMT_releaseBuffer(seqPool, seqToBuffer(seq));
31322 }
31324 static void ZSTDMT_setNbSeq(ZSTDMT_seqPool* const seqPool, size_t const nbSeq)
31325 {
31326  ZSTDMT_setBufferSize(seqPool, nbSeq * sizeof(rawSeq));
31327 }
31328 
31329 static ZSTDMT_seqPool* ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem)
31330 {
31332  if (seqPool == NULL) return NULL;
31333  ZSTDMT_setNbSeq(seqPool, 0);
31334  return seqPool;
31335 }
31337 static void ZSTDMT_freeSeqPool(ZSTDMT_seqPool* seqPool)
31338 {
31339  ZSTDMT_freeBufferPool(seqPool);
31340 }
31341 
31342 static ZSTDMT_seqPool* ZSTDMT_expandSeqPool(ZSTDMT_seqPool* pool, U32 nbWorkers)
31343 {
31344  return ZSTDMT_expandBufferPool(pool, SEQ_POOL_MAX_NB_BUFFERS(nbWorkers));
31348 /* ===== CCtx Pool ===== */
31349 /* a single CCtx Pool can be invoked from multiple threads in parallel */
31351 typedef struct {
31352  ZSTD_pthread_mutex_t poolMutex;
31353  int totalCCtx;
31354  int availCCtx;
31355  ZSTD_customMem cMem;
31356  ZSTD_CCtx* cctx[1]; /* variable size */
31357 } ZSTDMT_CCtxPool;
31358 
31359 /* note : all CCtx borrowed from the pool should be released back to the pool _before_ freeing the pool */
31360 static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
31361 {
31362  int cid;
31363  for (cid=0; cid<pool->totalCCtx; cid++)
31364  ZSTD_freeCCtx(pool->cctx[cid]); /* note : compatible with free on NULL */
31366  ZSTD_customFree(pool, pool->cMem);
31367 }
31368 
31369 /* ZSTDMT_createCCtxPool() :
31370  * implies nbWorkers >= 1 , checked by caller ZSTDMT_createCCtx() */
31371 static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers,
31372  ZSTD_customMem cMem)
31373 {
31374  ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_customCalloc(
31375  sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem);
31376  assert(nbWorkers > 0);
31377  if (!cctxPool) return NULL;
31378  if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) {
31379  ZSTD_customFree(cctxPool, cMem);
31380  return NULL;
31381  }
31382  cctxPool->cMem = cMem;
31383  cctxPool->totalCCtx = nbWorkers;
31384  cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */
31385  cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem);
31386  if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }
31387  DEBUGLOG(3, "cctxPool created, with %u workers", nbWorkers);
31388  return cctxPool;
31389 }
31390 
31392  int nbWorkers)
31393 {
31394  if (srcPool==NULL) return NULL;
31395  if (nbWorkers <= srcPool->totalCCtx) return srcPool; /* good enough */
31396  /* need a larger cctx pool */
31397  { ZSTD_customMem const cMem = srcPool->cMem;
31399  return ZSTDMT_createCCtxPool(nbWorkers, cMem);
31400  }
31401 }
31402 
31403 /* only works during initialization phase, not during compression */
31404 static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool)
31405 {
31406  ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);
31407  { unsigned const nbWorkers = cctxPool->totalCCtx;
31408  size_t const poolSize = sizeof(*cctxPool)
31409  + (nbWorkers-1) * sizeof(ZSTD_CCtx*);
31410  unsigned u;
31411  size_t totalCCtxSize = 0;
31412  for (u=0; u<nbWorkers; u++) {
31413  totalCCtxSize += ZSTD_sizeof_CCtx(cctxPool->cctx[u]);
31414  }
31416  assert(nbWorkers > 0);
31417  return poolSize + totalCCtxSize;
31418  }
31419 }
31420 
31421 static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* cctxPool)
31422 {
31423  DEBUGLOG(5, "ZSTDMT_getCCtx");
31424  ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);
31425  if (cctxPool->availCCtx) {
31426  cctxPool->availCCtx--;
31427  { ZSTD_CCtx* const cctx = cctxPool->cctx[cctxPool->availCCtx];
31429  return cctx;
31430  } }
31432  DEBUGLOG(5, "create one more CCtx");
31433  return ZSTD_createCCtx_advanced(cctxPool->cMem); /* note : can be NULL, when creation fails ! */
31434 }
31435 
31436 static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)
31437 {
31438  if (cctx==NULL) return; /* compatibility with release on NULL */
31440  if (pool->availCCtx < pool->totalCCtx)
31441  pool->cctx[pool->availCCtx++] = cctx;
31442  else {
31443  /* pool overflow : should not happen, since totalCCtx==nbWorkers */
31444  DEBUGLOG(4, "CCtx pool overflow : free cctx");
31445  ZSTD_freeCCtx(cctx);
31446  }
31449 
31450 /* ==== Serial State ==== */
31452 typedef struct {
31453  void const* start;
31454  size_t size;
31457 typedef struct {
31458  /* All variables in the struct are protected by mutex. */
31459  ZSTD_pthread_mutex_t mutex;
31461  ZSTD_CCtx_params params;
31462  ldmState_t ldmState;
31463  XXH64_state_t xxhState;
31464  unsigned nextJobID;
31465  /* Protects ldmWindow.
31466  * Must be acquired after the main mutex when acquiring both.
31467  */
31468  ZSTD_pthread_mutex_t ldmWindowMutex;
31469  ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is updated */
31470  ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
31471 } serialState_t;
31472 
31473 static int
31475  ZSTDMT_seqPool* seqPool,
31476  ZSTD_CCtx_params params,
31477  size_t jobSize,
31478  const void* dict, size_t const dictSize,
31479  ZSTD_dictContentType_e dictContentType)
31480 {
31481  /* Adjust parameters */
31482  if (params.ldmParams.enableLdm == ZSTD_ps_enable) {
31483  DEBUGLOG(4, "LDM window size = %u KB", (1U << params.cParams.windowLog) >> 10);
31484  ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);
31485  assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
31486  assert(params.ldmParams.hashRateLog < 32);
31487  } else {
31488  ZSTD_memset(&params.ldmParams, 0, sizeof(params.ldmParams));
31489  }
31490  serialState->nextJobID = 0;
31491  if (params.fParams.checksumFlag)
31492  XXH64_reset(&serialState->xxhState, 0);
31493  if (params.ldmParams.enableLdm == ZSTD_ps_enable) {
31494  ZSTD_customMem cMem = params.customMem;
31495  unsigned const hashLog = params.ldmParams.hashLog;
31496  size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t);
31497  unsigned const bucketLog =
31498  params.ldmParams.hashLog - params.ldmParams.bucketSizeLog;
31499  unsigned const prevBucketLog =
31500  serialState->params.ldmParams.hashLog -
31501  serialState->params.ldmParams.bucketSizeLog;
31502  size_t const numBuckets = (size_t)1 << bucketLog;
31503  /* Size the seq pool tables */
31504  ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));
31505  /* Reset the window */
31506  ZSTD_window_init(&serialState->ldmState.window);
31507  /* Resize tables and output space if necessary. */
31508  if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {
31509  ZSTD_customFree(serialState->ldmState.hashTable, cMem);
31510  serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_customMalloc(hashSize, cMem);
31511  }
31512  if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) {
31513  ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
31514  serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_customMalloc(numBuckets, cMem);
31515  }
31516  if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets)
31517  return 1;
31518  /* Zero the tables */
31519  ZSTD_memset(serialState->ldmState.hashTable, 0, hashSize);
31520  ZSTD_memset(serialState->ldmState.bucketOffsets, 0, numBuckets);
31521 
31522  /* Update window state and fill hash table with dict */
31523  serialState->ldmState.loadedDictEnd = 0;
31524  if (dictSize > 0) {
31525  if (dictContentType == ZSTD_dct_rawContent) {
31526  BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
31527  ZSTD_window_update(&serialState->ldmState.window, dict, dictSize, /* forceNonContiguous */ 0);
31528  ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, &params.ldmParams);
31529  serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
31530  } else {
31531  /* don't even load anything */
31532  }
31533  }
31534 
31535  /* Initialize serialState's copy of ldmWindow. */
31536  serialState->ldmWindow = serialState->ldmState.window;
31537  }
31539  serialState->params = params;
31540  serialState->params.jobSize = (U32)jobSize;
31541  return 0;
31542 }
31543 
31544 static int ZSTDMT_serialState_init(serialState_t* serialState)
31545 {
31546  int initError = 0;
31547  ZSTD_memset(serialState, 0, sizeof(*serialState));
31548  initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL);
31549  initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL);
31550  initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL);
31551  initError |= ZSTD_pthread_cond_init(&serialState->ldmWindowCond, NULL);
31552  return initError;
31553 }
31554 
31555 static void ZSTDMT_serialState_free(serialState_t* serialState)
31556 {
31557  ZSTD_customMem cMem = serialState->params.customMem;
31558  ZSTD_pthread_mutex_destroy(&serialState->mutex);
31559  ZSTD_pthread_cond_destroy(&serialState->cond);
31562  ZSTD_customFree(serialState->ldmState.hashTable, cMem);
31563  ZSTD_customFree(serialState->ldmState.bucketOffsets, cMem);
31564 }
31565 
31566 static void ZSTDMT_serialState_update(serialState_t* serialState,
31567  ZSTD_CCtx* jobCCtx, rawSeqStore_t seqStore,
31568  range_t src, unsigned jobID)
31569 {
31570  /* Wait for our turn */
31571  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
31572  while (serialState->nextJobID < jobID) {
31573  DEBUGLOG(5, "wait for serialState->cond");
31574  ZSTD_pthread_cond_wait(&serialState->cond, &serialState->mutex);
31575  }
31576  /* A future job may error and skip our job */
31577  if (serialState->nextJobID == jobID) {
31578  /* It is now our turn, do any processing necessary */
31579  if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) {
31580  size_t error;
31581  assert(seqStore.seq != NULL && seqStore.pos == 0 &&
31582  seqStore.size == 0 && seqStore.capacity > 0);
31583  assert(src.size <= serialState->params.jobSize);
31584  ZSTD_window_update(&serialState->ldmState.window, src.start, src.size, /* forceNonContiguous */ 0);
31586  &serialState->ldmState, &seqStore,
31587  &serialState->params.ldmParams, src.start, src.size);
31588  /* We provide a large enough buffer to never fail. */
31590  /* Update ldmWindow to match the ldmState.window and signal the main
31591  * thread if it is waiting for a buffer.
31592  */
31593  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);
31594  serialState->ldmWindow = serialState->ldmState.window;
31595  ZSTD_pthread_cond_signal(&serialState->ldmWindowCond);
31597  }
31598  if (serialState->params.fParams.checksumFlag && src.size > 0)
31599  XXH64_update(&serialState->xxhState, src.start, src.size);
31600  }
31601  /* Now it is the next jobs turn */
31602  serialState->nextJobID++;
31603  ZSTD_pthread_cond_broadcast(&serialState->cond);
31604  ZSTD_pthread_mutex_unlock(&serialState->mutex);
31605 
31606  if (seqStore.size > 0) {
31607  size_t const err = ZSTD_referenceExternalSequences(
31608  jobCCtx, seqStore.seq, seqStore.size);
31609  assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable);
31610  assert(!ZSTD_isError(err));
31611  (void)err;
31612  }
31613 }
31614 
31615 static void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,
31616  unsigned jobID, size_t cSize)
31617 {
31618  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
31619  if (serialState->nextJobID <= jobID) {
31620  assert(ZSTD_isError(cSize)); (void)cSize;
31621  DEBUGLOG(5, "Skipping past job %u because of error", jobID);
31622  serialState->nextJobID = jobID + 1;
31623  ZSTD_pthread_cond_broadcast(&serialState->cond);
31624 
31625  ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);
31626  ZSTD_window_clear(&serialState->ldmWindow);
31627  ZSTD_pthread_cond_signal(&serialState->ldmWindowCond);
31629  }
31630  ZSTD_pthread_mutex_unlock(&serialState->mutex);
31631 
31632 }
31634 
31635 /* ------------------------------------------ */
31636 /* ===== Worker thread ===== */
31637 /* ------------------------------------------ */
31639 static const range_t kNullRange = { NULL, 0 };
31641 typedef struct {
31642  size_t consumed; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */
31643  size_t cSize; /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */
31644  ZSTD_pthread_mutex_t job_mutex; /* Thread-safe - used by mtctx and worker */
31645  ZSTD_pthread_cond_t job_cond; /* Thread-safe - used by mtctx and worker */
31646  ZSTDMT_CCtxPool* cctxPool; /* Thread-safe - used by mtctx and (all) workers */
31647  ZSTDMT_bufferPool* bufPool; /* Thread-safe - used by mtctx and (all) workers */
31648  ZSTDMT_seqPool* seqPool; /* Thread-safe - used by mtctx and (all) workers */
31649  serialState_t* serial; /* Thread-safe - used by mtctx and (all) workers */
31650  buffer_t dstBuff; /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */
31651  range_t prefix; /* set by mtctx, then read by worker & mtctx => no barrier */
31652  range_t src; /* set by mtctx, then read by worker & mtctx => no barrier */
31653  unsigned jobID; /* set by mtctx, then read by worker => no barrier */
31654  unsigned firstJob; /* set by mtctx, then read by worker => no barrier */
31655  unsigned lastJob; /* set by mtctx, then read by worker => no barrier */
31656  ZSTD_CCtx_params params; /* set by mtctx, then read by worker => no barrier */
31657  const ZSTD_CDict* cdict; /* set by mtctx, then read by worker => no barrier */
31658  unsigned long long fullFrameSize; /* set by mtctx, then read by worker => no barrier */
31659  size_t dstFlushed; /* used only by mtctx */
31660  unsigned frameChecksumNeeded; /* used only by mtctx */
31662 
31663 #define JOB_ERROR(e) { \
31664  ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \
31665  job->cSize = e; \
31666  ZSTD_pthread_mutex_unlock(&job->job_mutex); \
31667  goto _endJob; \
31668 }
31669 
31670 /* ZSTDMT_compressionJob() is a POOL_function type */
31671 static void ZSTDMT_compressionJob(void* jobDescription)
31672 {
31673  ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
31674  ZSTD_CCtx_params jobParams = job->params; /* do not modify job->params ! copy it, modify the copy */
31675  ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool);
31676  rawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
31677  buffer_t dstBuff = job->dstBuff;
31678  size_t lastCBlockSize = 0;
31679 
31680  /* resources */
31681  if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));
31682  if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */
31683  dstBuff = ZSTDMT_getBuffer(job->bufPool);
31684  if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation));
31685  job->dstBuff = dstBuff; /* this value can be read in ZSTDMT_flush, when it copies the whole job */
31686  }
31687  if (jobParams.ldmParams.enableLdm == ZSTD_ps_enable && rawSeqStore.seq == NULL)
31688  JOB_ERROR(ERROR(memory_allocation));
31689 
31690  /* Don't compute the checksum for chunks, since we compute it externally,
31691  * but write it in the header.
31692  */
31693  if (job->jobID != 0) jobParams.fParams.checksumFlag = 0;
31694  /* Don't run LDM for the chunks, since we handle it externally */
31695  jobParams.ldmParams.enableLdm = ZSTD_ps_disable;
31696  /* Correct nbWorkers to 0. */
31697  jobParams.nbWorkers = 0;
31698 
31699 
31700  /* init */
31701  if (job->cdict) {
31702  size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);
31703  assert(job->firstJob); /* only allowed for first job */
31704  if (ZSTD_isError(initError)) JOB_ERROR(initError);
31705  } else { /* srcStart points at reloaded section */
31706  U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;
31707  { size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
31708  if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
31709  }
31710  if (!job->firstJob) {
31711  size_t const err = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_deterministicRefPrefix, 0);
31712  if (ZSTD_isError(err)) JOB_ERROR(err);
31713  }
31714  { size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
31715  job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
31717  NULL, /*cdict*/
31718  &jobParams, pledgedSrcSize);
31719  if (ZSTD_isError(initError)) JOB_ERROR(initError);
31720  } }
31721 
31722  /* Perform serial step as early as possible, but after CCtx initialization */
31723  ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID);
31724 
31725  if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */
31726  size_t const hSize = ZSTD_compressContinue_public(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);
31727  if (ZSTD_isError(hSize)) JOB_ERROR(hSize);
31728  DEBUGLOG(5, "ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)", (U32)hSize);
31730  }
31731 
31732  /* compress */
31733  { size_t const chunkSize = 4*ZSTD_BLOCKSIZE_MAX;
31734  int const nbChunks = (int)((job->src.size + (chunkSize-1)) / chunkSize);
31735  const BYTE* ip = (const BYTE*) job->src.start;
31736  BYTE* const ostart = (BYTE*)dstBuff.start;
31737  BYTE* op = ostart;
31738  BYTE* oend = op + dstBuff.capacity;
31739  int chunkNb;
31740  if (sizeof(size_t) > sizeof(int)) assert(job->src.size < ((size_t)INT_MAX) * chunkSize); /* check overflow */
31741  DEBUGLOG(5, "ZSTDMT_compressionJob: compress %u bytes in %i blocks", (U32)job->src.size, nbChunks);
31742  assert(job->cSize == 0);
31743  for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) {
31744  size_t const cSize = ZSTD_compressContinue_public(cctx, op, oend-op, ip, chunkSize);
31745  if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
31746  ip += chunkSize;
31747  op += cSize; assert(op < oend);
31748  /* stats */
31750  job->cSize += cSize;
31751  job->consumed = chunkSize * chunkNb;
31752  DEBUGLOG(5, "ZSTDMT_compressionJob: compress new block : cSize==%u bytes (total: %u)",
31753  (U32)cSize, (U32)job->cSize);
31754  ZSTD_pthread_cond_signal(&job->job_cond); /* warns some more data is ready to be flushed */
31756  }
31757  /* last block */
31758  assert(chunkSize > 0);
31759  assert((chunkSize & (chunkSize - 1)) == 0); /* chunkSize must be power of 2 for mask==(chunkSize-1) to work */
31760  if ((nbChunks > 0) | job->lastJob /*must output a "last block" flag*/ ) {
31761  size_t const lastBlockSize1 = job->src.size & (chunkSize-1);
31762  size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1;
31763  size_t const cSize = (job->lastJob) ?
31764  ZSTD_compressEnd_public(cctx, op, oend-op, ip, lastBlockSize) :
31765  ZSTD_compressContinue_public(cctx, op, oend-op, ip, lastBlockSize);
31766  if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
31767  lastCBlockSize = cSize;
31768  } }
31769  if (!job->firstJob) {
31770  /* Double check that we don't have an ext-dict, because then our
31771  * repcode invalidation doesn't work.
31772  */
31774  }
31775  ZSTD_CCtx_trace(cctx, 0);
31776 
31777 _endJob:
31779  if (job->prefix.size > 0)
31780  DEBUGLOG(5, "Finished with prefix: %zx", (size_t)job->prefix.start);
31781  DEBUGLOG(5, "Finished with source: %zx", (size_t)job->src.start);
31782  /* release resources */
31783  ZSTDMT_releaseSeq(job->seqPool, rawSeqStore);
31784  ZSTDMT_releaseCCtx(job->cctxPool, cctx);
31785  /* report */
31787  if (ZSTD_isError(job->cSize)) assert(lastCBlockSize == 0);
31788  job->cSize += lastCBlockSize;
31789  job->consumed = job->src.size; /* when job->consumed == job->src.size , compression job is presumed completed */
31792 }
31795 /* ------------------------------------------ */
31796 /* ===== Multi-threaded compression ===== */
31797 /* ------------------------------------------ */
31798 
31799 typedef struct {
31800  range_t prefix; /* read-only non-owned prefix buffer */
31801  buffer_t buffer;
31802  size_t filled;
31803 } inBuff_t;
31804 
31805 typedef struct {
31806  BYTE* buffer; /* The round input buffer. All jobs get references
31807  * to pieces of the buffer. ZSTDMT_tryGetInputRange()
31808  * handles handing out job input buffers, and makes
31809  * sure it doesn't overlap with any pieces still in use.
31810  */
31811  size_t capacity; /* The capacity of buffer. */
31812  size_t pos; /* The position of the current inBuff in the round
31813  * buffer. Updated past the end if the inBuff once
31814  * the inBuff is sent to the worker thread.
31815  * pos <= capacity.
31816  */
31817 } roundBuff_t;
31818 
31819 static const roundBuff_t kNullRoundBuff = {NULL, 0, 0};
31820 
31821 #define RSYNC_LENGTH 32
31822 /* Don't create chunks smaller than the zstd block size.
31823  * This stops us from regressing compression ratio too much,
31824  * and ensures our output fits in ZSTD_compressBound().
31825  *
31826  * If this is shrunk < ZSTD_BLOCKSIZELOG_MIN then
31827  * ZSTD_COMPRESSBOUND() will need to be updated.
31828  */
31829 #define RSYNC_MIN_BLOCK_LOG ZSTD_BLOCKSIZELOG_MAX
31830 #define RSYNC_MIN_BLOCK_SIZE (1<<RSYNC_MIN_BLOCK_LOG)
31831 
31832 typedef struct {
31834  U64 hitMask;
31835  U64 primePower;
31844  ZSTD_CCtx_params params;
31847  int jobReady; /* 1 => one job is already prepared, but pool has shortage of workers. Don't create a new job. */
31852  unsigned jobIDMask;
31853  unsigned doneJobID;
31854  unsigned nextJobID;
31855  unsigned frameEnded;
31857  unsigned long long frameContentSize;
31858  unsigned long long consumed;
31859  unsigned long long produced;
31860  ZSTD_customMem cMem;
31862  const ZSTD_CDict* cdict;
31863  unsigned providedFactory: 1;
31864 };
31865 
31866 static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem)
31867 {
31868  U32 jobNb;
31869  if (jobTable == NULL) return;
31870  for (jobNb=0; jobNb<nbJobs; jobNb++) {
31871  ZSTD_pthread_mutex_destroy(&jobTable[jobNb].job_mutex);
31872  ZSTD_pthread_cond_destroy(&jobTable[jobNb].job_cond);
31873  }
31874  ZSTD_customFree(jobTable, cMem);
31875 }
31876 
31877 /* ZSTDMT_allocJobsTable()
31878  * allocate and init a job table.
31879  * update *nbJobsPtr to next power of 2 value, as size of table */
31880 static ZSTDMT_jobDescription* ZSTDMT_createJobsTable(U32* nbJobsPtr, ZSTD_customMem cMem)
31881 {
31882  U32 const nbJobsLog2 = ZSTD_highbit32(*nbJobsPtr) + 1;
31883  U32 const nbJobs = 1 << nbJobsLog2;
31884  U32 jobNb;
31885  ZSTDMT_jobDescription* const jobTable = (ZSTDMT_jobDescription*)
31886  ZSTD_customCalloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem);
31887  int initError = 0;
31888  if (jobTable==NULL) return NULL;
31889  *nbJobsPtr = nbJobs;
31890  for (jobNb=0; jobNb<nbJobs; jobNb++) {
31891  initError |= ZSTD_pthread_mutex_init(&jobTable[jobNb].job_mutex, NULL);
31892  initError |= ZSTD_pthread_cond_init(&jobTable[jobNb].job_cond, NULL);
31893  }
31894  if (initError != 0) {
31895  ZSTDMT_freeJobsTable(jobTable, nbJobs, cMem);
31896  return NULL;
31897  }
31898  return jobTable;
31899 }
31900 
31901 static size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) {
31902  U32 nbJobs = nbWorkers + 2;
31903  if (nbJobs > mtctx->jobIDMask+1) { /* need more job capacity */
31904  ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);
31905  mtctx->jobIDMask = 0;
31906  mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, mtctx->cMem);
31907  if (mtctx->jobs==NULL) return ERROR(memory_allocation);
31908  assert((nbJobs != 0) && ((nbJobs & (nbJobs - 1)) == 0)); /* ensure nbJobs is a power of 2 */
31909  mtctx->jobIDMask = nbJobs - 1;
31910  }
31911  return 0;
31912 }
31913 
31914 
31915 /* ZSTDMT_CCtxParam_setNbWorkers():
31916  * Internal use only */
31917 static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
31918 {
31919  return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers);
31920 }
31921 
31922 MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
31923 {
31924  ZSTDMT_CCtx* mtctx;
31925  U32 nbJobs = nbWorkers + 2;
31926  int initError;
31927  DEBUGLOG(3, "ZSTDMT_createCCtx_advanced (nbWorkers = %u)", nbWorkers);
31928 
31929  if (nbWorkers < 1) return NULL;
31930  nbWorkers = MIN(nbWorkers , ZSTDMT_NBWORKERS_MAX);
31931  if ((cMem.customAlloc!=NULL) ^ (cMem.customFree!=NULL))
31932  /* invalid custom allocator */
31933  return NULL;
31934 
31935  mtctx = (ZSTDMT_CCtx*) ZSTD_customCalloc(sizeof(ZSTDMT_CCtx), cMem);
31936  if (!mtctx) return NULL;
31937  ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);
31938  mtctx->cMem = cMem;
31939  mtctx->allJobsCompleted = 1;
31940  if (pool != NULL) {
31941  mtctx->factory = pool;
31942  mtctx->providedFactory = 1;
31943  }
31944  else {
31945  mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem);
31946  mtctx->providedFactory = 0;
31947  }
31948  mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem);
31949  assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0); /* ensure nbJobs is a power of 2 */
31950  mtctx->jobIDMask = nbJobs - 1;
31951  mtctx->bufPool = ZSTDMT_createBufferPool(BUF_POOL_MAX_NB_BUFFERS(nbWorkers), cMem);
31952  mtctx->cctxPool = ZSTDMT_createCCtxPool(nbWorkers, cMem);
31953  mtctx->seqPool = ZSTDMT_createSeqPool(nbWorkers, cMem);
31954  initError = ZSTDMT_serialState_init(&mtctx->serial);
31955  mtctx->roundBuff = kNullRoundBuff;
31956  if (!mtctx->factory | !mtctx->jobs | !mtctx->bufPool | !mtctx->cctxPool | !mtctx->seqPool | initError) {
31957  ZSTDMT_freeCCtx(mtctx);
31958  return NULL;
31959  }
31960  DEBUGLOG(3, "mt_cctx created, for %u threads", nbWorkers);
31961  return mtctx;
31962 }
31963 
31964 ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool* pool)
31965 {
31966 #ifdef ZSTD_MULTITHREAD
31967  return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem, pool);
31968 #else
31969  (void)nbWorkers;
31970  (void)cMem;
31971  (void)pool;
31972  return NULL;
31973 #endif
31974 }
31975 
31976 
31977 /* ZSTDMT_releaseAllJobResources() :
31978  * note : ensure all workers are killed first ! */
31979 static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
31980 {
31981  unsigned jobID;
31982  DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
31983  for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
31984  /* Copy the mutex/cond out */
31985  ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
31986  ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;
31987 
31988  DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);
31989  ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
31990 
31991  /* Clear the job description, but keep the mutex/cond */
31992  ZSTD_memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
31993  mtctx->jobs[jobID].job_mutex = mutex;
31994  mtctx->jobs[jobID].job_cond = cond;
31995  }
31996  mtctx->inBuff.buffer = g_nullBuffer;
31997  mtctx->inBuff.filled = 0;
31998  mtctx->allJobsCompleted = 1;
31999 }
32000 
32001 static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)
32002 {
32003  DEBUGLOG(4, "ZSTDMT_waitForAllJobsCompleted");
32004  while (mtctx->doneJobID < mtctx->nextJobID) {
32005  unsigned const jobID = mtctx->doneJobID & mtctx->jobIDMask;
32006  ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);
32007  while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {
32008  DEBUGLOG(4, "waiting for jobCompleted signal from job %u", mtctx->doneJobID); /* we want to block when waiting for data to flush */
32009  ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);
32010  }
32011  ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);
32012  mtctx->doneJobID++;
32013  }
32014 }
32015 
32016 size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
32017 {
32018  if (mtctx==NULL) return 0; /* compatible with free on NULL */
32019  if (!mtctx->providedFactory)
32020  POOL_free(mtctx->factory); /* stop and free worker threads */
32021  ZSTDMT_releaseAllJobResources(mtctx); /* release job resources into pools first */
32022  ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);
32024  ZSTDMT_freeCCtxPool(mtctx->cctxPool);
32025  ZSTDMT_freeSeqPool(mtctx->seqPool);
32027  ZSTD_freeCDict(mtctx->cdictLocal);
32028  if (mtctx->roundBuff.buffer)
32029  ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
32030  ZSTD_customFree(mtctx, mtctx->cMem);
32031  return 0;
32032 }
32033 
32034 size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
32035 {
32036  if (mtctx == NULL) return 0; /* supports sizeof NULL */
32037  return sizeof(*mtctx)
32038  + POOL_sizeof(mtctx->factory)
32040  + (mtctx->jobIDMask+1) * sizeof(ZSTDMT_jobDescription)
32042  + ZSTDMT_sizeof_seqPool(mtctx->seqPool)
32043  + ZSTD_sizeof_CDict(mtctx->cdictLocal)
32045 }
32046 
32047 
32048 /* ZSTDMT_resize() :
32049  * @return : error code if fails, 0 on success */
32050 static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
32051 {
32052  if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);
32053  FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , "");
32054  mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, BUF_POOL_MAX_NB_BUFFERS(nbWorkers));
32055  if (mtctx->bufPool == NULL) return ERROR(memory_allocation);
32056  mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);
32057  if (mtctx->cctxPool == NULL) return ERROR(memory_allocation);
32058  mtctx->seqPool = ZSTDMT_expandSeqPool(mtctx->seqPool, nbWorkers);
32059  if (mtctx->seqPool == NULL) return ERROR(memory_allocation);
32060  ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);
32061  return 0;
32063 
32064 
32068 void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams)
32069 {
32070  U32 const saved_wlog = mtctx->params.cParams.windowLog; /* Do not modify windowLog while compressing */
32071  int const compressionLevel = cctxParams->compressionLevel;
32072  DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)",
32074  mtctx->params.compressionLevel = compressionLevel;
32075  { ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
32076  cParams.windowLog = saved_wlog;
32077  mtctx->params.cParams = cParams;
32078  }
32080 
32081 /* ZSTDMT_getFrameProgression():
32082  * tells how much data has been consumed (input) and produced (output) for current frame.
32083  * able to count progression inside worker threads.
32084  * Note : mutex will be acquired during statistics collection inside workers. */
32085 ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx)
32086 {
32087  ZSTD_frameProgression fps;
32088  DEBUGLOG(5, "ZSTDMT_getFrameProgression");
32089  fps.ingested = mtctx->consumed + mtctx->inBuff.filled;
32090  fps.consumed = mtctx->consumed;
32091  fps.produced = fps.flushed = mtctx->produced;
32092  fps.currentJobID = mtctx->nextJobID;
32093  fps.nbActiveWorkers = 0;
32094  { unsigned jobNb;
32095  unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1);
32096  DEBUGLOG(6, "ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)",
32097  mtctx->doneJobID, lastJobNb, mtctx->jobReady)
32098  for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) {
32099  unsigned const wJobID = jobNb & mtctx->jobIDMask;
32100  ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID];
32102  { size_t const cResult = jobPtr->cSize;
32103  size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
32104  size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
32105  assert(flushed <= produced);
32106  fps.ingested += jobPtr->src.size;
32107  fps.consumed += jobPtr->consumed;
32108  fps.produced += produced;
32109  fps.flushed += flushed;
32110  fps.nbActiveWorkers += (jobPtr->consumed < jobPtr->src.size);
32111  }
32112  ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
32113  }
32114  }
32115  return fps;
32116 }
32117 
32118 
32119 size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
32120 {
32121  size_t toFlush;
32122  unsigned const jobID = mtctx->doneJobID;
32123  assert(jobID <= mtctx->nextJobID);
32124  if (jobID == mtctx->nextJobID) return 0; /* no active job => nothing to flush */
32125 
32126  /* look into oldest non-fully-flushed job */
32127  { unsigned const wJobID = jobID & mtctx->jobIDMask;
32128  ZSTDMT_jobDescription* const jobPtr = &mtctx->jobs[wJobID];
32130  { size_t const cResult = jobPtr->cSize;
32131  size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
32132  size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
32133  assert(flushed <= produced);
32134  assert(jobPtr->consumed <= jobPtr->src.size);
32135  toFlush = produced - flushed;
32136  /* if toFlush==0, nothing is available to flush.
32137  * However, jobID is expected to still be active:
32138  * if jobID was already completed and fully flushed,
32139  * ZSTDMT_flushProduced() should have already moved onto next job.
32140  * Therefore, some input has not yet been consumed. */
32141  if (toFlush==0) {
32142  assert(jobPtr->consumed < jobPtr->src.size);
32143  }
32144  }
32145  ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
32146  }
32147 
32148  return toFlush;
32149 }
32151 
32152 /* ------------------------------------------ */
32153 /* ===== Multi-threaded compression ===== */
32154 /* ------------------------------------------ */
32155 
32156 static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)
32157 {
32158  unsigned jobLog;
32159  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
32160  /* In Long Range Mode, the windowLog is typically oversized.
32161  * In which case, it's preferable to determine the jobSize
32162  * based on cycleLog instead. */
32163  jobLog = MAX(21, ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy) + 3);
32164  } else {
32165  jobLog = MAX(20, params->cParams.windowLog + 2);
32166  }
32167  return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX);
32168 }
32169 
32170 static int ZSTDMT_overlapLog_default(ZSTD_strategy strat)
32171 {
32172  switch(strat)
32173  {
32174  case ZSTD_btultra2:
32175  return 9;
32176  case ZSTD_btultra:
32177  case ZSTD_btopt:
32178  return 8;
32179  case ZSTD_btlazy2:
32180  case ZSTD_lazy2:
32181  return 7;
32182  case ZSTD_lazy:
32183  case ZSTD_greedy:
32184  case ZSTD_dfast:
32186  default:;
32187  }
32188  return 6;
32189 }
32190 
32191 static int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat)
32193  assert(0 <= ovlog && ovlog <= 9);
32194  if (ovlog == 0) return ZSTDMT_overlapLog_default(strat);
32195  return ovlog;
32196 }
32197 
32198 static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)
32199 {
32200  int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy);
32201  int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog);
32202  assert(0 <= overlapRLog && overlapRLog <= 8);
32203  if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
32204  /* In Long Range Mode, the windowLog is typically oversized.
32205  * In which case, it's preferable to determine the jobSize
32206  * based on chainLog instead.
32207  * Then, ovLog becomes a fraction of the jobSize, rather than windowSize */
32208  ovLog = MIN(params->cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2)
32209  - overlapRLog;
32210  }
32211  assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX);
32212  DEBUGLOG(4, "overlapLog : %i", params->overlapLog);
32213  DEBUGLOG(4, "overlap size : %i", 1 << ovLog);
32214  return (ovLog==0) ? 0 : (size_t)1 << ovLog;
32216 
32217 /* ====================================== */
32218 /* ======= Streaming API ======= */
32219 /* ====================================== */
32220 
32222  ZSTDMT_CCtx* mtctx,
32223  const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,
32224  const ZSTD_CDict* cdict, ZSTD_CCtx_params params,
32225  unsigned long long pledgedSrcSize)
32226 {
32227  DEBUGLOG(4, "ZSTDMT_initCStream_internal (pledgedSrcSize=%u, nbWorkers=%u, cctxPool=%u)",
32228  (U32)pledgedSrcSize, params.nbWorkers, mtctx->cctxPool->totalCCtx);
32229 
32230  /* params supposed partially fully validated at this point */
32231  assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
32232  assert(!((dict) && (cdict))); /* either dict or cdict, not both */
32233 
32234  /* init */
32235  if (params.nbWorkers != mtctx->params.nbWorkers)
32236  FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) , "");
32237 
32238  if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
32239  if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
32240 
32241  DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
32242 
32243  if (mtctx->allJobsCompleted == 0) { /* previous compression not correctly finished */
32246  mtctx->allJobsCompleted = 1;
32247  }
32248 
32249  mtctx->params = params;
32250  mtctx->frameContentSize = pledgedSrcSize;
32251  if (dict) {
32252  ZSTD_freeCDict(mtctx->cdictLocal);
32253  mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
32254  ZSTD_dlm_byCopy, dictContentType, /* note : a loadPrefix becomes an internal CDict */
32255  params.cParams, mtctx->cMem);
32256  mtctx->cdict = mtctx->cdictLocal;
32257  if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);
32258  } else {
32259  ZSTD_freeCDict(mtctx->cdictLocal);
32260  mtctx->cdictLocal = NULL;
32261  mtctx->cdict = cdict;
32262  }
32263 
32264  mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(&params);
32265  DEBUGLOG(4, "overlapLog=%i => %u KB", params.overlapLog, (U32)(mtctx->targetPrefixSize>>10));
32266  mtctx->targetSectionSize = params.jobSize;
32267  if (mtctx->targetSectionSize == 0) {
32268  mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(&params);
32269  }
32270  assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX);
32271 
32272  if (params.rsyncable) {
32273  /* Aim for the targetsectionSize as the average job size. */
32274  U32 const jobSizeKB = (U32)(mtctx->targetSectionSize >> 10);
32275  U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10);
32276  /* We refuse to create jobs < RSYNC_MIN_BLOCK_SIZE bytes, so make sure our
32277  * expected job size is at least 4x larger. */
32278  assert(rsyncBits >= RSYNC_MIN_BLOCK_LOG + 2);
32279  DEBUGLOG(4, "rsyncLog = %u", rsyncBits);
32280  mtctx->rsync.hash = 0;
32281  mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1;
32283  }
32284  if (mtctx->targetSectionSize < mtctx->targetPrefixSize) mtctx->targetSectionSize = mtctx->targetPrefixSize; /* job size must be >= overlap size */
32285  DEBUGLOG(4, "Job Size : %u KB (note : set to %u)", (U32)(mtctx->targetSectionSize>>10), (U32)params.jobSize);
32286  DEBUGLOG(4, "inBuff Size : %u KB", (U32)(mtctx->targetSectionSize>>10));
32288  {
32289  /* If ldm is enabled we need windowSize space. */
32290  size_t const windowSize = mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable ? (1U << mtctx->params.cParams.windowLog) : 0;
32291  /* Two buffers of slack, plus extra space for the overlap
32292  * This is the minimum slack that LDM works with. One extra because
32293  * flush might waste up to targetSectionSize-1 bytes. Another extra
32294  * for the overlap (if > 0), then one to fill which doesn't overlap
32295  * with the LDM window.
32296  */
32297  size_t const nbSlackBuffers = 2 + (mtctx->targetPrefixSize > 0);
32298  size_t const slackSize = mtctx->targetSectionSize * nbSlackBuffers;
32299  /* Compute the total size, and always have enough slack */
32300  size_t const nbWorkers = MAX(mtctx->params.nbWorkers, 1);
32301  size_t const sectionsSize = mtctx->targetSectionSize * nbWorkers;
32302  size_t const capacity = MAX(windowSize, sectionsSize) + slackSize;
32303  if (mtctx->roundBuff.capacity < capacity) {
32304  if (mtctx->roundBuff.buffer)
32305  ZSTD_customFree(mtctx->roundBuff.buffer, mtctx->cMem);
32306  mtctx->roundBuff.buffer = (BYTE*)ZSTD_customMalloc(capacity, mtctx->cMem);
32307  if (mtctx->roundBuff.buffer == NULL) {
32308  mtctx->roundBuff.capacity = 0;
32309  return ERROR(memory_allocation);
32310  }
32311  mtctx->roundBuff.capacity = capacity;
32312  }
32313  }
32314  DEBUGLOG(4, "roundBuff capacity : %u KB", (U32)(mtctx->roundBuff.capacity>>10));
32315  mtctx->roundBuff.pos = 0;
32316  mtctx->inBuff.buffer = g_nullBuffer;
32317  mtctx->inBuff.filled = 0;
32318  mtctx->inBuff.prefix = kNullRange;
32319  mtctx->doneJobID = 0;
32320  mtctx->nextJobID = 0;
32321  mtctx->frameEnded = 0;
32322  mtctx->allJobsCompleted = 0;
32323  mtctx->consumed = 0;
32324  mtctx->produced = 0;
32325  if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
32326  dict, dictSize, dictContentType))
32327  return ERROR(memory_allocation);
32328  return 0;
32329 }
32330 
32332 /* ZSTDMT_writeLastEmptyBlock()
32333  * Write a single empty block with an end-of-frame to finish a frame.
32334  * Job must be created from streaming variant.
32335  * This function is always successful if expected conditions are fulfilled.
32336  */
32338 {
32339  assert(job->lastJob == 1);
32340  assert(job->src.size == 0); /* last job is empty -> will be simplified into a last empty block */
32341  assert(job->firstJob == 0); /* cannot be first job, as it also needs to create frame header */
32342  assert(job->dstBuff.start == NULL); /* invoked from streaming variant only (otherwise, dstBuff might be user's output) */
32343  job->dstBuff = ZSTDMT_getBuffer(job->bufPool);
32344  if (job->dstBuff.start == NULL) {
32345  job->cSize = ERROR(memory_allocation);
32346  return;
32347  }
32348  assert(job->dstBuff.capacity >= ZSTD_blockHeaderSize); /* no buffer should ever be that small */
32349  job->src = kNullRange;
32351  assert(!ZSTD_isError(job->cSize));
32352  assert(job->consumed == 0);
32353 }
32354 
32355 static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZSTD_EndDirective endOp)
32356 {
32357  unsigned const jobID = mtctx->nextJobID & mtctx->jobIDMask;
32358  int const endFrame = (endOp == ZSTD_e_end);
32359 
32360  if (mtctx->nextJobID > mtctx->doneJobID + mtctx->jobIDMask) {
32361  DEBUGLOG(5, "ZSTDMT_createCompressionJob: will not create new job : table is full");
32362  assert((mtctx->nextJobID & mtctx->jobIDMask) == (mtctx->doneJobID & mtctx->jobIDMask));
32363  return 0;
32364  }
32365 
32366  if (!mtctx->jobReady) {
32367  BYTE const* src = (BYTE const*)mtctx->inBuff.buffer.start;
32368  DEBUGLOG(5, "ZSTDMT_createCompressionJob: preparing job %u to compress %u bytes with %u preload ",
32369  mtctx->nextJobID, (U32)srcSize, (U32)mtctx->inBuff.prefix.size);
32370  mtctx->jobs[jobID].src.start = src;
32371  mtctx->jobs[jobID].src.size = srcSize;
32372  assert(mtctx->inBuff.filled >= srcSize);
32373  mtctx->jobs[jobID].prefix = mtctx->inBuff.prefix;
32374  mtctx->jobs[jobID].consumed = 0;
32375  mtctx->jobs[jobID].cSize = 0;
32376  mtctx->jobs[jobID].params = mtctx->params;
32377  mtctx->jobs[jobID].cdict = mtctx->nextJobID==0 ? mtctx->cdict : NULL;
32378  mtctx->jobs[jobID].fullFrameSize = mtctx->frameContentSize;
32379  mtctx->jobs[jobID].dstBuff = g_nullBuffer;
32380  mtctx->jobs[jobID].cctxPool = mtctx->cctxPool;
32381  mtctx->jobs[jobID].bufPool = mtctx->bufPool;
32382  mtctx->jobs[jobID].seqPool = mtctx->seqPool;
32383  mtctx->jobs[jobID].serial = &mtctx->serial;
32384  mtctx->jobs[jobID].jobID = mtctx->nextJobID;
32385  mtctx->jobs[jobID].firstJob = (mtctx->nextJobID==0);
32386  mtctx->jobs[jobID].lastJob = endFrame;
32387  mtctx->jobs[jobID].frameChecksumNeeded = mtctx->params.fParams.checksumFlag && endFrame && (mtctx->nextJobID>0);
32388  mtctx->jobs[jobID].dstFlushed = 0;
32389 
32390  /* Update the round buffer pos and clear the input buffer to be reset */
32391  mtctx->roundBuff.pos += srcSize;
32392  mtctx->inBuff.buffer = g_nullBuffer;
32393  mtctx->inBuff.filled = 0;
32394  /* Set the prefix */
32395  if (!endFrame) {
32396  size_t const newPrefixSize = MIN(srcSize, mtctx->targetPrefixSize);
32397  mtctx->inBuff.prefix.start = src + srcSize - newPrefixSize;
32398  mtctx->inBuff.prefix.size = newPrefixSize;
32399  } else { /* endFrame==1 => no need for another input buffer */
32400  mtctx->inBuff.prefix = kNullRange;
32401  mtctx->frameEnded = endFrame;
32402  if (mtctx->nextJobID == 0) {
32403  /* single job exception : checksum is already calculated directly within worker thread */
32404  mtctx->params.fParams.checksumFlag = 0;
32405  } }
32406 
32407  if ( (srcSize == 0)
32408  && (mtctx->nextJobID>0)/*single job must also write frame header*/ ) {
32409  DEBUGLOG(5, "ZSTDMT_createCompressionJob: creating a last empty block to end frame");
32410  assert(endOp == ZSTD_e_end); /* only possible case : need to end the frame with an empty last block */
32411  ZSTDMT_writeLastEmptyBlock(mtctx->jobs + jobID);
32412  mtctx->nextJobID++;
32413  return 0;
32414  }
32415  }
32416 
32417  DEBUGLOG(5, "ZSTDMT_createCompressionJob: posting job %u : %u bytes (end:%u, jobNb == %u (mod:%u))",
32418  mtctx->nextJobID,
32419  (U32)mtctx->jobs[jobID].src.size,
32420  mtctx->jobs[jobID].lastJob,
32421  mtctx->nextJobID,
32422  jobID);
32423  if (POOL_tryAdd(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[jobID])) {
32424  mtctx->nextJobID++;
32425  mtctx->jobReady = 0;
32426  } else {
32427  DEBUGLOG(5, "ZSTDMT_createCompressionJob: no worker available for job %u", mtctx->nextJobID);
32428  mtctx->jobReady = 1;
32429  }
32430  return 0;
32431 }
32432 
32433 
32440 static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, unsigned blockToFlush, ZSTD_EndDirective end)
32441 {
32442  unsigned const wJobID = mtctx->doneJobID & mtctx->jobIDMask;
32443  DEBUGLOG(5, "ZSTDMT_flushProduced (blocking:%u , job %u <= %u)",
32444  blockToFlush, mtctx->doneJobID, mtctx->nextJobID);
32445  assert(output->size >= output->pos);
32446 
32447  ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex);
32448  if ( blockToFlush
32449  && (mtctx->doneJobID < mtctx->nextJobID) ) {
32450  assert(mtctx->jobs[wJobID].dstFlushed <= mtctx->jobs[wJobID].cSize);
32451  while (mtctx->jobs[wJobID].dstFlushed == mtctx->jobs[wJobID].cSize) { /* nothing to flush */
32452  if (mtctx->jobs[wJobID].consumed == mtctx->jobs[wJobID].src.size) {
32453  DEBUGLOG(5, "job %u is completely consumed (%u == %u) => don't wait for cond, there will be none",
32454  mtctx->doneJobID, (U32)mtctx->jobs[wJobID].consumed, (U32)mtctx->jobs[wJobID].src.size);
32455  break;
32456  }
32457  DEBUGLOG(5, "waiting for something to flush from job %u (currently flushed: %u bytes)",
32458  mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed);
32459  ZSTD_pthread_cond_wait(&mtctx->jobs[wJobID].job_cond, &mtctx->jobs[wJobID].job_mutex); /* block when nothing to flush but some to come */
32460  } }
32461 
32462  /* try to flush something */
32463  { size_t cSize = mtctx->jobs[wJobID].cSize; /* shared */
32464  size_t const srcConsumed = mtctx->jobs[wJobID].consumed; /* shared */
32465  size_t const srcSize = mtctx->jobs[wJobID].src.size; /* read-only, could be done after mutex lock, but no-declaration-after-statement */
32466  ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
32467  if (ZSTD_isError(cSize)) {
32468  DEBUGLOG(5, "ZSTDMT_flushProduced: job %u : compression error detected : %s",
32469  mtctx->doneJobID, ZSTD_getErrorName(cSize));
32472  return cSize;
32473  }
32474  /* add frame checksum if necessary (can only happen once) */
32475  assert(srcConsumed <= srcSize);
32476  if ( (srcConsumed == srcSize) /* job completed -> worker no longer active */
32477  && mtctx->jobs[wJobID].frameChecksumNeeded ) {
32478  U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState);
32479  DEBUGLOG(4, "ZSTDMT_flushProduced: writing checksum : %08X \n", checksum);
32480  MEM_writeLE32((char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].cSize, checksum);
32481  cSize += 4;
32482  mtctx->jobs[wJobID].cSize += 4; /* can write this shared value, as worker is no longer active */
32483  mtctx->jobs[wJobID].frameChecksumNeeded = 0;
32484  }
32485 
32486  if (cSize > 0) { /* compression is ongoing or completed */
32487  size_t const toFlush = MIN(cSize - mtctx->jobs[wJobID].dstFlushed, output->size - output->pos);
32488  DEBUGLOG(5, "ZSTDMT_flushProduced: Flushing %u bytes from job %u (completion:%u/%u, generated:%u)",
32489  (U32)toFlush, mtctx->doneJobID, (U32)srcConsumed, (U32)srcSize, (U32)cSize);
32490  assert(mtctx->doneJobID < mtctx->nextJobID);
32491  assert(cSize >= mtctx->jobs[wJobID].dstFlushed);
32492  assert(mtctx->jobs[wJobID].dstBuff.start != NULL);
32493  if (toFlush > 0) {
32494  ZSTD_memcpy((char*)output->dst + output->pos,
32495  (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
32496  toFlush);
32497  }
32498  output->pos += toFlush;
32499  mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */
32500 
32501  if ( (srcConsumed == srcSize) /* job is completed */
32502  && (mtctx->jobs[wJobID].dstFlushed == cSize) ) { /* output buffer fully flushed => free this job position */
32503  DEBUGLOG(5, "Job %u completed (%u bytes), moving to next one",
32504  mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed);
32505  ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[wJobID].dstBuff);
32506  DEBUGLOG(5, "dstBuffer released");
32507  mtctx->jobs[wJobID].dstBuff = g_nullBuffer;
32508  mtctx->jobs[wJobID].cSize = 0; /* ensure this job slot is considered "not started" in future check */
32509  mtctx->consumed += srcSize;
32510  mtctx->produced += cSize;
32511  mtctx->doneJobID++;
32512  } }
32513 
32514  /* return value : how many bytes left in buffer ; fake it to 1 when unknown but >0 */
32515  if (cSize > mtctx->jobs[wJobID].dstFlushed) return (cSize - mtctx->jobs[wJobID].dstFlushed);
32516  if (srcSize > srcConsumed) return 1; /* current job not completely compressed */
32517  }
32518  if (mtctx->doneJobID < mtctx->nextJobID) return 1; /* some more jobs ongoing */
32519  if (mtctx->jobReady) return 1; /* one job is ready to push, just not yet in the list */
32520  if (mtctx->inBuff.filled > 0) return 1; /* input is not empty, and still needs to be converted into a job */
32521  mtctx->allJobsCompleted = mtctx->frameEnded; /* all jobs are entirely flushed => if this one is last one, frame is completed */
32522  if (end == ZSTD_e_end) return !mtctx->frameEnded; /* for ZSTD_e_end, question becomes : is frame completed ? instead of : are internal buffers fully flushed ? */
32523  return 0; /* internal buffers fully flushed */
32524 }
32532 {
32533  unsigned const firstJobID = mtctx->doneJobID;
32534  unsigned const lastJobID = mtctx->nextJobID;
32535  unsigned jobID;
32536 
32537  for (jobID = firstJobID; jobID < lastJobID; ++jobID) {
32538  unsigned const wJobID = jobID & mtctx->jobIDMask;
32539  size_t consumed;
32540 
32541  ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex);
32542  consumed = mtctx->jobs[wJobID].consumed;
32543  ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
32544 
32545  if (consumed < mtctx->jobs[wJobID].src.size) {
32546  range_t range = mtctx->jobs[wJobID].prefix;
32547  if (range.size == 0) {
32548  /* Empty prefix */
32549  range = mtctx->jobs[wJobID].src;
32550  }
32551  /* Job source in multiple segments not supported yet */
32552  assert(range.start <= mtctx->jobs[wJobID].src.start);
32553  return range;
32554  }
32555  }
32556  return kNullRange;
32557 }
32558 
32562 static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
32563 {
32564  BYTE const* const bufferStart = (BYTE const*)buffer.start;
32565  BYTE const* const rangeStart = (BYTE const*)range.start;
32566 
32567  if (rangeStart == NULL || bufferStart == NULL)
32568  return 0;
32569 
32570  {
32571  BYTE const* const bufferEnd = bufferStart + buffer.capacity;
32572  BYTE const* const rangeEnd = rangeStart + range.size;
32573 
32574  /* Empty ranges cannot overlap */
32575  if (bufferStart == bufferEnd || rangeStart == rangeEnd)
32576  return 0;
32577 
32578  return bufferStart < rangeEnd && rangeStart < bufferEnd;
32579  }
32580 }
32581 
32582 static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
32583 {
32584  range_t extDict;
32585  range_t prefix;
32586 
32587  DEBUGLOG(5, "ZSTDMT_doesOverlapWindow");
32588  extDict.start = window.dictBase + window.lowLimit;
32589  extDict.size = window.dictLimit - window.lowLimit;
32590 
32591  prefix.start = window.base + window.dictLimit;
32592  prefix.size = window.nextSrc - (window.base + window.dictLimit);
32593  DEBUGLOG(5, "extDict [0x%zx, 0x%zx)",
32594  (size_t)extDict.start,
32595  (size_t)extDict.start + extDict.size);
32596  DEBUGLOG(5, "prefix [0x%zx, 0x%zx)",
32597  (size_t)prefix.start,
32598  (size_t)prefix.start + prefix.size);
32599 
32600  return ZSTDMT_isOverlapped(buffer, extDict)
32601  || ZSTDMT_isOverlapped(buffer, prefix);
32602 }
32603 
32604 static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
32605 {
32606  if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) {
32607  ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;
32608  DEBUGLOG(5, "ZSTDMT_waitForLdmComplete");
32609  DEBUGLOG(5, "source [0x%zx, 0x%zx)",
32610  (size_t)buffer.start,
32611  (size_t)buffer.start + buffer.capacity);
32612  ZSTD_PTHREAD_MUTEX_LOCK(mutex);
32613  while (ZSTDMT_doesOverlapWindow(buffer, mtctx->serial.ldmWindow)) {
32614  DEBUGLOG(5, "Waiting for LDM to finish...");
32616  }
32617  DEBUGLOG(6, "Done waiting for LDM to finish");
32619  }
32620 }
32627 static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
32628 {
32629  range_t const inUse = ZSTDMT_getInputDataInUse(mtctx);
32630  size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos;
32631  size_t const target = mtctx->targetSectionSize;
32632  buffer_t buffer;
32633 
32634  DEBUGLOG(5, "ZSTDMT_tryGetInputRange");
32635  assert(mtctx->inBuff.buffer.start == NULL);
32636  assert(mtctx->roundBuff.capacity >= target);
32637 
32638  if (spaceLeft < target) {
32639  /* ZSTD_invalidateRepCodes() doesn't work for extDict variants.
32640  * Simply copy the prefix to the beginning in that case.
32641  */
32642  BYTE* const start = (BYTE*)mtctx->roundBuff.buffer;
32643  size_t const prefixSize = mtctx->inBuff.prefix.size;
32644 
32645  buffer.start = start;
32646  buffer.capacity = prefixSize;
32647  if (ZSTDMT_isOverlapped(buffer, inUse)) {
32648  DEBUGLOG(5, "Waiting for buffer...");
32649  return 0;
32650  }
32651  ZSTDMT_waitForLdmComplete(mtctx, buffer);
32652  ZSTD_memmove(start, mtctx->inBuff.prefix.start, prefixSize);
32653  mtctx->inBuff.prefix.start = start;
32654  mtctx->roundBuff.pos = prefixSize;
32655  }
32656  buffer.start = mtctx->roundBuff.buffer + mtctx->roundBuff.pos;
32657  buffer.capacity = target;
32658 
32659  if (ZSTDMT_isOverlapped(buffer, inUse)) {
32660  DEBUGLOG(5, "Waiting for buffer...");
32661  return 0;
32662  }
32663  assert(!ZSTDMT_isOverlapped(buffer, mtctx->inBuff.prefix));
32664 
32665  ZSTDMT_waitForLdmComplete(mtctx, buffer);
32666 
32667  DEBUGLOG(5, "Using prefix range [%zx, %zx)",
32668  (size_t)mtctx->inBuff.prefix.start,
32669  (size_t)mtctx->inBuff.prefix.start + mtctx->inBuff.prefix.size);
32670  DEBUGLOG(5, "Using source range [%zx, %zx)",
32671  (size_t)buffer.start,
32672  (size_t)buffer.start + buffer.capacity);
32673 
32674 
32675  mtctx->inBuff.buffer = buffer;
32676  mtctx->inBuff.filled = 0;
32677  assert(mtctx->roundBuff.pos + buffer.capacity <= mtctx->roundBuff.capacity);
32678  return 1;
32679 }
32680 
32681 typedef struct {
32682  size_t toLoad; /* The number of bytes to load from the input. */
32683  int flush; /* Boolean declaring if we must flush because we found a synchronization point. */
32684 } syncPoint_t;
32685 
32692 static syncPoint_t
32693 findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)
32694 {
32695  BYTE const* const istart = (BYTE const*)input.src + input.pos;
32696  U64 const primePower = mtctx->rsync.primePower;
32697  U64 const hitMask = mtctx->rsync.hitMask;
32698 
32699  syncPoint_t syncPoint;
32700  U64 hash;
32701  BYTE const* prev;
32702  size_t pos;
32703 
32704  syncPoint.toLoad = MIN(input.size - input.pos, mtctx->targetSectionSize - mtctx->inBuff.filled);
32705  syncPoint.flush = 0;
32706  if (!mtctx->params.rsyncable)
32707  /* Rsync is disabled. */
32708  return syncPoint;
32709  if (mtctx->inBuff.filled + input.size - input.pos < RSYNC_MIN_BLOCK_SIZE)
32710  /* We don't emit synchronization points if it would produce too small blocks.
32711  * We don't have enough input to find a synchronization point, so don't look.
32712  */
32713  return syncPoint;
32714  if (mtctx->inBuff.filled + syncPoint.toLoad < RSYNC_LENGTH)
32715  /* Not enough to compute the hash.
32716  * We will miss any synchronization points in this RSYNC_LENGTH byte
32717  * window. However, since it depends only in the internal buffers, if the
32718  * state is already synchronized, we will remain synchronized.
32719  * Additionally, the probability that we miss a synchronization point is
32720  * low: RSYNC_LENGTH / targetSectionSize.
32721  */
32722  return syncPoint;
32723  /* Initialize the loop variables. */
32724  if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE) {
32725  /* We don't need to scan the first RSYNC_MIN_BLOCK_SIZE positions
32726  * because they can't possibly be a sync point. So we can start
32727  * part way through the input buffer.
32728  */
32729  pos = RSYNC_MIN_BLOCK_SIZE - mtctx->inBuff.filled;
32730  if (pos >= RSYNC_LENGTH) {
32731  prev = istart + pos - RSYNC_LENGTH;
32733  } else {
32734  assert(mtctx->inBuff.filled >= RSYNC_LENGTH);
32735  prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
32736  hash = ZSTD_rollingHash_compute(prev + pos, (RSYNC_LENGTH - pos));
32737  hash = ZSTD_rollingHash_append(hash, istart, pos);
32738  }
32739  } else {
32740  /* We have enough bytes buffered to initialize the hash,
32741  * and have processed enough bytes to find a sync point.
32742  * Start scanning at the beginning of the input.
32743  */
32746  pos = 0;
32747  prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;
32749  if ((hash & hitMask) == hitMask) {
32750  /* We're already at a sync point so don't load any more until
32751  * we're able to flush this sync point.
32752  * This likely happened because the job table was full so we
32753  * couldn't add our job.
32754  */
32755  syncPoint.toLoad = 0;
32756  syncPoint.flush = 1;
32757  return syncPoint;
32758  }
32759  }
32760  /* Starting with the hash of the previous RSYNC_LENGTH bytes, roll
32761  * through the input. If we hit a synchronization point, then cut the
32762  * job off, and tell the compressor to flush the job. Otherwise, load
32763  * all the bytes and continue as normal.
32764  * If we go too long without a synchronization point (targetSectionSize)
32765  * then a block will be emitted anyways, but this is okay, since if we
32766  * are already synchronized we will remain synchronized.
32767  */
32769  for (; pos < syncPoint.toLoad; ++pos) {
32770  BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH];
32771  /* This assert is very expensive, and Debian compiles with asserts enabled.
32772  * So disable it for now. We can get similar coverage by checking it at the
32773  * beginning & end of the loop.
32774  * assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash);
32775  */
32776  hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower);
32777  assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE);
32778  if ((hash & hitMask) == hitMask) {
32779  syncPoint.toLoad = pos + 1;
32780  syncPoint.flush = 1;
32781  ++pos; /* for assert */
32782  break;
32783  }
32784  }
32786  return syncPoint;
32787 }
32788 
32789 size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx)
32790 {
32791  size_t hintInSize = mtctx->targetSectionSize - mtctx->inBuff.filled;
32792  if (hintInSize==0) hintInSize = mtctx->targetSectionSize;
32793  return hintInSize;
32795 
32802  ZSTD_inBuffer* input,
32803  ZSTD_EndDirective endOp)
32804 {
32805  unsigned forwardInputProgress = 0;
32806  DEBUGLOG(5, "ZSTDMT_compressStream_generic (endOp=%u, srcSize=%u)",
32807  (U32)endOp, (U32)(input->size - input->pos));
32808  assert(output->pos <= output->size);
32809  assert(input->pos <= input->size);
32810 
32811  if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) {
32812  /* current frame being ended. Only flush/end are allowed */
32813  return ERROR(stage_wrong);
32814  }
32815 
32816  /* fill input buffer */
32817  if ( (!mtctx->jobReady)
32818  && (input->size > input->pos) ) { /* support NULL input */
32819  if (mtctx->inBuff.buffer.start == NULL) {
32820  assert(mtctx->inBuff.filled == 0); /* Can't fill an empty buffer */
32821  if (!ZSTDMT_tryGetInputRange(mtctx)) {
32822  /* It is only possible for this operation to fail if there are
32823  * still compression jobs ongoing.
32824  */
32825  DEBUGLOG(5, "ZSTDMT_tryGetInputRange failed");
32826  assert(mtctx->doneJobID != mtctx->nextJobID);
32827  } else
32828  DEBUGLOG(5, "ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p", mtctx->inBuff.buffer.start);
32829  }
32830  if (mtctx->inBuff.buffer.start != NULL) {
32831  syncPoint_t const syncPoint = findSynchronizationPoint(mtctx, *input);
32832  if (syncPoint.flush && endOp == ZSTD_e_continue) {
32833  endOp = ZSTD_e_flush;
32834  }
32835  assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize);
32836  DEBUGLOG(5, "ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u",
32837  (U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize);
32838  ZSTD_memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad);
32839  input->pos += syncPoint.toLoad;
32840  mtctx->inBuff.filled += syncPoint.toLoad;
32841  forwardInputProgress = syncPoint.toLoad>0;
32842  }
32843  }
32844  if ((input->pos < input->size) && (endOp == ZSTD_e_end)) {
32845  /* Can't end yet because the input is not fully consumed.
32846  * We are in one of these cases:
32847  * - mtctx->inBuff is NULL & empty: we couldn't get an input buffer so don't create a new job.
32848  * - We filled the input buffer: flush this job but don't end the frame.
32849  * - We hit a synchronization point: flush this job but don't end the frame.
32850  */
32851  assert(mtctx->inBuff.filled == 0 || mtctx->inBuff.filled == mtctx->targetSectionSize || mtctx->params.rsyncable);
32852  endOp = ZSTD_e_flush;
32853  }
32854 
32855  if ( (mtctx->jobReady)
32856  || (mtctx->inBuff.filled >= mtctx->targetSectionSize) /* filled enough : let's compress */
32857  || ((endOp != ZSTD_e_continue) && (mtctx->inBuff.filled > 0)) /* something to flush : let's go */
32858  || ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */
32859  size_t const jobSize = mtctx->inBuff.filled;
32860  assert(mtctx->inBuff.filled <= mtctx->targetSectionSize);
32861  FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) , "");
32862  }
32863 
32864  /* check for potential compressed data ready to be flushed */
32865  { size_t const remainingToFlush = ZSTDMT_flushProduced(mtctx, output, !forwardInputProgress, endOp); /* block if there was no forward input progress */
32866  if (input->pos < input->size) return MAX(remainingToFlush, 1); /* input not consumed : do not end flush yet */
32867  DEBUGLOG(5, "end of ZSTDMT_compressStream_generic: remainingToFlush = %u", (U32)remainingToFlush);
32868  return remainingToFlush;
32869  }
32870 }
32871 /**** ended inlining compress/zstdmt_compress.c ****/
32872 #endif
32873 
32874 /**** start inlining decompress/huf_decompress.c ****/
32875 /* ******************************************************************
32876  * huff0 huffman decoder,
32877  * part of Finite State Entropy library
32878  * Copyright (c) Meta Platforms, Inc. and affiliates.
32879  *
32880  * You can contact the author at :
32881  * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
32882  *
32883  * This source code is licensed under both the BSD-style license (found in the
32884  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
32885  * in the COPYING file in the root directory of this source tree).
32886  * You may select, at your option, one of the above-listed licenses.
32887 ****************************************************************** */
32888 
32889 /* **************************************************************
32890 * Dependencies
32891 ****************************************************************/
32892 /**** skipping file: ../common/zstd_deps.h ****/
32893 /**** skipping file: ../common/compiler.h ****/
32894 /**** skipping file: ../common/bitstream.h ****/
32895 /**** skipping file: ../common/fse.h ****/
32896 /**** skipping file: ../common/huf.h ****/
32897 /**** skipping file: ../common/error_private.h ****/
32898 /**** skipping file: ../common/zstd_internal.h ****/
32899 /**** skipping file: ../common/bits.h ****/
32900 
32901 /* **************************************************************
32902 * Constants
32903 ****************************************************************/
32904 
32905 #define HUF_DECODER_FAST_TABLELOG 11
32906 
32907 /* **************************************************************
32908 * Macros
32909 ****************************************************************/
32910 
32911 /* These two optional macros force the use one way or another of the two
32912  * Huffman decompression implementations. You can't force in both directions
32913  * at the same time.
32914  */
32915 #if defined(HUF_FORCE_DECOMPRESS_X1) && \
32916  defined(HUF_FORCE_DECOMPRESS_X2)
32917 #error "Cannot force the use of the X1 and X2 decoders at the same time!"
32918 #endif
32919 
32920 /* When DYNAMIC_BMI2 is enabled, fast decoders are only called when bmi2 is
32921  * supported at runtime, so we can add the BMI2 target attribute.
32922  * When it is disabled, we will still get BMI2 if it is enabled statically.
32923  */
32924 #if DYNAMIC_BMI2
32925 # define HUF_FAST_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE
32926 #else
32927 # define HUF_FAST_BMI2_ATTRS
32928 #endif
32930 #ifdef __cplusplus
32931 # define HUF_EXTERN_C extern "C"
32932 #else
32933 # define HUF_EXTERN_C
32934 #endif
32935 #define HUF_ASM_DECL HUF_EXTERN_C
32936 
32937 #if DYNAMIC_BMI2
32938 # define HUF_NEED_BMI2_FUNCTION 1
32939 #else
32940 # define HUF_NEED_BMI2_FUNCTION 0
32941 #endif
32942 
32943 /* **************************************************************
32944 * Error Management
32945 ****************************************************************/
32946 #define HUF_isError ERR_isError
32948 
32949 /* **************************************************************
32950 * Byte alignment for workSpace management
32951 ****************************************************************/
32952 #define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1)
32953 #define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
32954 
32955 
32956 /* **************************************************************
32957 * BMI2 Variant Wrappers
32958 ****************************************************************/
32959 typedef size_t (*HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize,
32960  const void *cSrc,
32961  size_t cSrcSize,
32962  const HUF_DTable *DTable);
32963 
32964 #if DYNAMIC_BMI2
32965 
32966 #define HUF_DGEN(fn) \
32967  \
32968  static size_t fn##_default( \
32969  void* dst, size_t dstSize, \
32970  const void* cSrc, size_t cSrcSize, \
32971  const HUF_DTable* DTable) \
32972  { \
32973  return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
32974  } \
32975  \
32976  static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \
32977  void* dst, size_t dstSize, \
32978  const void* cSrc, size_t cSrcSize, \
32979  const HUF_DTable* DTable) \
32980  { \
32981  return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
32982  } \
32983  \
32984  static size_t fn(void* dst, size_t dstSize, void const* cSrc, \
32985  size_t cSrcSize, HUF_DTable const* DTable, int flags) \
32986  { \
32987  if (flags & HUF_flags_bmi2) { \
32988  return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \
32989  } \
32990  return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \
32991  }
32992 
32993 #else
32994 
32995 #define HUF_DGEN(fn) \
32996  static size_t fn(void* dst, size_t dstSize, void const* cSrc, \
32997  size_t cSrcSize, HUF_DTable const* DTable, int flags) \
32998  { \
32999  (void)flags; \
33000  return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
33001  }
33002 
33003 #endif
33004 
33006 /*-***************************/
33007 /* generic DTableDesc */
33008 /*-***************************/
33009 typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
33010 
33013  DTableDesc dtd;
33014  ZSTD_memcpy(&dtd, table, sizeof(dtd));
33015  return dtd;
33016 }
33017 
33018 static size_t HUF_initFastDStream(BYTE const* ip) {
33019  BYTE const lastByte = ip[7];
33020  size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0;
33021  size_t const value = MEM_readLEST(ip) | 1;
33022  assert(bitsConsumed <= 8);
33023  assert(sizeof(size_t) == 8);
33024  return value << bitsConsumed;
33025 }
33026 
33027 
33040 typedef struct {
33041  BYTE const* ip[4];
33042  BYTE* op[4];
33043  U64 bits[4];
33044  void const* dt;
33045  BYTE const* ilimit;
33046  BYTE* oend;
33047  BYTE const* iend[4];
33049 
33051 
33058 static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable)
33059 {
33060  void const* dt = DTable + 1;
33061  U32 const dtLog = HUF_getDTableDesc(DTable).tableLog;
33062 
33063  const BYTE* const ilimit = (const BYTE*)src + 6 + 8;
33064 
33065  BYTE* const oend = (BYTE*)dst + dstSize;
33066 
33067  /* The fast decoding loop assumes 64-bit little-endian.
33068  * This condition is false on x32.
33069  */
33070  if (!MEM_isLittleEndian() || MEM_32bits())
33071  return 0;
33072 
33073  /* strict minimum : jump table + 1 byte per stream */
33074  if (srcSize < 10)
33075  return ERROR(corruption_detected);
33076 
33077  /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers.
33078  * If table log is not correct at this point, fallback to the old decoder.
33079  * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder.
33080  */
33081  if (dtLog != HUF_DECODER_FAST_TABLELOG)
33082  return 0;
33083 
33084  /* Read the jump table. */
33085  {
33086  const BYTE* const istart = (const BYTE*)src;
33087  size_t const length1 = MEM_readLE16(istart);
33088  size_t const length2 = MEM_readLE16(istart+2);
33089  size_t const length3 = MEM_readLE16(istart+4);
33090  size_t const length4 = srcSize - (length1 + length2 + length3 + 6);
33091  args->iend[0] = istart + 6; /* jumpTable */
33092  args->iend[1] = args->iend[0] + length1;
33093  args->iend[2] = args->iend[1] + length2;
33094  args->iend[3] = args->iend[2] + length3;
33095 
33096  /* HUF_initFastDStream() requires this, and this small of an input
33097  * won't benefit from the ASM loop anyways.
33098  * length1 must be >= 16 so that ip[0] >= ilimit before the loop
33099  * starts.
33100  */
33101  if (length1 < 16 || length2 < 8 || length3 < 8 || length4 < 8)
33102  return 0;
33103  if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */
33104  }
33105  /* ip[] contains the position that is currently loaded into bits[]. */
33106  args->ip[0] = args->iend[1] - sizeof(U64);
33107  args->ip[1] = args->iend[2] - sizeof(U64);
33108  args->ip[2] = args->iend[3] - sizeof(U64);
33109  args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64);
33110 
33111  /* op[] contains the output pointers. */
33112  args->op[0] = (BYTE*)dst;
33113  args->op[1] = args->op[0] + (dstSize+3)/4;
33114  args->op[2] = args->op[1] + (dstSize+3)/4;
33115  args->op[3] = args->op[2] + (dstSize+3)/4;
33116 
33117  /* No point to call the ASM loop for tiny outputs. */
33118  if (args->op[3] >= oend)
33119  return 0;
33120 
33121  /* bits[] is the bit container.
33122  * It is read from the MSB down to the LSB.
33123  * It is shifted left as it is read, and zeros are
33124  * shifted in. After the lowest valid bit a 1 is
33125  * set, so that CountTrailingZeros(bits[]) can be used
33126  * to count how many bits we've consumed.
33127  */
33128  args->bits[0] = HUF_initFastDStream(args->ip[0]);
33129  args->bits[1] = HUF_initFastDStream(args->ip[1]);
33130  args->bits[2] = HUF_initFastDStream(args->ip[2]);
33131  args->bits[3] = HUF_initFastDStream(args->ip[3]);
33132 
33133  /* If ip[] >= ilimit, it is guaranteed to be safe to
33134  * reload bits[]. It may be beyond its section, but is
33135  * guaranteed to be valid (>= istart).
33136  */
33137  args->ilimit = ilimit;
33138 
33139  args->oend = oend;
33140  args->dt = dt;
33141 
33142  return 1;
33143 }
33144 
33145 static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd)
33146 {
33147  /* Validate that we haven't overwritten. */
33148  if (args->op[stream] > segmentEnd)
33149  return ERROR(corruption_detected);
33150  /* Validate that we haven't read beyond iend[].
33151  * Note that ip[] may be < iend[] because the MSB is
33152  * the next bit to read, and we may have consumed 100%
33153  * of the stream, so down to iend[i] - 8 is valid.
33154  */
33155  if (args->ip[stream] < args->iend[stream] - 8)
33156  return ERROR(corruption_detected);
33157 
33158  /* Construct the BIT_DStream_t. */
33159  assert(sizeof(size_t) == 8);
33160  bit->bitContainer = MEM_readLEST(args->ip[stream]);
33161  bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]);
33162  bit->start = (const char*)args->iend[0];
33163  bit->limitPtr = bit->start + sizeof(size_t);
33164  bit->ptr = (const char*)args->ip[stream];
33165 
33166  return 0;
33167 }
33168 
33170 #ifndef HUF_FORCE_DECOMPRESS_X2
33171 
33172 /*-***************************/
33173 /* single-symbol decoding */
33174 /*-***************************/
33175 typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */
33176 
33181 static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
33182  U64 D4;
33183  if (MEM_isLittleEndian()) {
33184  D4 = (U64)((symbol << 8) + nbBits);
33185  } else {
33186  D4 = (U64)(symbol + (nbBits << 8));
33187  }
33188  assert(D4 < (1U << 16));
33189  D4 *= 0x0001000100010001ULL;
33190  return D4;
33191 }
33198 static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog)
33199 {
33200  if (tableLog > targetTableLog)
33201  return tableLog;
33202  if (tableLog < targetTableLog) {
33203  U32 const scale = targetTableLog - tableLog;
33204  U32 s;
33205  /* Increase the weight for all non-zero probability symbols by scale. */
33206  for (s = 0; s < nbSymbols; ++s) {
33207  huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale);
33208  }
33209  /* Update rankVal to reflect the new weights.
33210  * All weights except 0 get moved to weight + scale.
33211  * Weights [1, scale] are empty.
33212  */
33213  for (s = targetTableLog; s > scale; --s) {
33214  rankVal[s] = rankVal[s - scale];
33215  }
33216  for (s = scale; s > 0; --s) {
33217  rankVal[s] = 0;
33218  }
33219  }
33220  return targetTableLog;
33223 typedef struct {
33224  U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
33227  BYTE symbols[HUF_SYMBOLVALUE_MAX + 1];
33228  BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
33230 
33231 size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags)
33232 {
33233  U32 tableLog = 0;
33234  U32 nbSymbols = 0;
33235  size_t iSize;
33236  void* const dtPtr = DTable + 1;
33237  HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
33239 
33241  if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
33242 
33243  DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
33244  /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
33245 
33246  iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags);
33247  if (HUF_isError(iSize)) return iSize;
33248 
33249 
33250  /* Table header */
33251  { DTableDesc dtd = HUF_getDTableDesc(DTable);
33252  U32 const maxTableLog = dtd.maxTableLog + 1;
33253  U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG);
33254  tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog);
33255  if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
33256  dtd.tableType = 0;
33257  dtd.tableLog = (BYTE)tableLog;
33258  ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
33259  }
33260 
33261  /* Compute symbols and rankStart given rankVal:
33262  *
33263  * rankVal already contains the number of values of each weight.
33264  *
33265  * symbols contains the symbols ordered by weight. First are the rankVal[0]
33266  * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on.
33267  * symbols[0] is filled (but unused) to avoid a branch.
33268  *
33269  * rankStart contains the offset where each rank belongs in the DTable.
33270  * rankStart[0] is not filled because there are no entries in the table for
33271  * weight 0.
33272  */
33273  { int n;
33274  U32 nextRankStart = 0;
33275  int const unroll = 4;
33276  int const nLimit = (int)nbSymbols - unroll + 1;
33277  for (n=0; n<(int)tableLog+1; n++) {
33278  U32 const curr = nextRankStart;
33279  nextRankStart += wksp->rankVal[n];
33280  wksp->rankStart[n] = curr;
33281  }
33282  for (n=0; n < nLimit; n += unroll) {
33283  int u;
33284  for (u=0; u < unroll; ++u) {
33285  size_t const w = wksp->huffWeight[n+u];
33286  wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
33287  }
33288  }
33289  for (; n < (int)nbSymbols; ++n) {
33290  size_t const w = wksp->huffWeight[n];
33291  wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
33292  }
33293  }
33294 
33295  /* fill DTable
33296  * We fill all entries of each weight in order.
33297  * That way length is a constant for each iteration of the outer loop.
33298  * We can switch based on the length to a different inner loop which is
33299  * optimized for that particular case.
33300  */
33301  { U32 w;
33302  int symbol = wksp->rankVal[0];
33303  int rankStart = 0;
33304  for (w=1; w<tableLog+1; ++w) {
33305  int const symbolCount = wksp->rankVal[w];
33306  int const length = (1 << w) >> 1;
33307  int uStart = rankStart;
33308  BYTE const nbBits = (BYTE)(tableLog + 1 - w);
33309  int s;
33310  int u;
33311  switch (length) {
33312  case 1:
33313  for (s=0; s<symbolCount; ++s) {
33314  HUF_DEltX1 D;
33315  D.byte = wksp->symbols[symbol + s];
33316  D.nbBits = nbBits;
33317  dt[uStart] = D;
33318  uStart += 1;
33319  }
33320  break;
33321  case 2:
33322  for (s=0; s<symbolCount; ++s) {
33323  HUF_DEltX1 D;
33324  D.byte = wksp->symbols[symbol + s];
33325  D.nbBits = nbBits;
33326  dt[uStart+0] = D;
33327  dt[uStart+1] = D;
33328  uStart += 2;
33329  }
33330  break;
33331  case 4:
33332  for (s=0; s<symbolCount; ++s) {
33333  U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
33334  MEM_write64(dt + uStart, D4);
33335  uStart += 4;
33336  }
33337  break;
33338  case 8:
33339  for (s=0; s<symbolCount; ++s) {
33340  U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
33341  MEM_write64(dt + uStart, D4);
33342  MEM_write64(dt + uStart + 4, D4);
33343  uStart += 8;
33344  }
33345  break;
33346  default:
33347  for (s=0; s<symbolCount; ++s) {
33348  U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
33349  for (u=0; u < length; u += 16) {
33350  MEM_write64(dt + uStart + u + 0, D4);
33351  MEM_write64(dt + uStart + u + 4, D4);
33352  MEM_write64(dt + uStart + u + 8, D4);
33353  MEM_write64(dt + uStart + u + 12, D4);
33354  }
33355  assert(u == length);
33356  uStart += length;
33357  }
33358  break;
33359  }
33360  symbol += symbolCount;
33361  rankStart += symbolCount * length;
33362  }
33363  }
33364  return iSize;
33365 }
33366 
33368 HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
33369 {
33370  size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
33371  BYTE const c = dt[val].byte;
33372  BIT_skipBits(Dstream, dt[val].nbBits);
33373  return c;
33374 }
33375 
33376 #define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \
33377  *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog)
33378 
33379 #define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \
33380  if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
33381  HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
33383 #define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \
33384  if (MEM_64bits()) \
33385  HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
33386 
33387 HINT_INLINE size_t
33388 HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog)
33389 {
33390  BYTE* const pStart = p;
33391 
33392  /* up to 4 symbols at a time */
33393  if ((pEnd - p) > 3) {
33394  while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
33395  HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
33396  HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
33397  HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
33398  HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
33399  }
33400  } else {
33401  BIT_reloadDStream(bitDPtr);
33402  }
33403 
33404  /* [0-3] symbols remaining */
33405  if (MEM_32bits())
33406  while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd))
33407  HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
33408 
33409  /* no more data to retrieve from bitstream, no need to reload */
33410  while (p < pEnd)
33412 
33413  return (size_t)(pEnd-pStart);
33414 }
33415 
33416 FORCE_INLINE_TEMPLATE size_t
33418  void* dst, size_t dstSize,
33419  const void* cSrc, size_t cSrcSize,
33420  const HUF_DTable* DTable)
33421 {
33422  BYTE* op = (BYTE*)dst;
33423  BYTE* const oend = op + dstSize;
33424  const void* dtPtr = DTable + 1;
33425  const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
33426  BIT_DStream_t bitD;
33427  DTableDesc const dtd = HUF_getDTableDesc(DTable);
33428  U32 const dtLog = dtd.tableLog;
33429 
33430  CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
33431 
33432  HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);
33433 
33434  if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
33435 
33436  return dstSize;
33437 }
33439 /* HUF_decompress4X1_usingDTable_internal_body():
33440  * Conditions :
33441  * @dstSize >= 6
33442  */
33443 FORCE_INLINE_TEMPLATE size_t
33445  void* dst, size_t dstSize,
33446  const void* cSrc, size_t cSrcSize,
33447  const HUF_DTable* DTable)
33448 {
33449  /* Check */
33450  if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
33451 
33452  { const BYTE* const istart = (const BYTE*) cSrc;
33453  BYTE* const ostart = (BYTE*) dst;
33454  BYTE* const oend = ostart + dstSize;
33455  BYTE* const olimit = oend - 3;
33456  const void* const dtPtr = DTable + 1;
33457  const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
33458 
33459  /* Init */
33460  BIT_DStream_t bitD1;
33461  BIT_DStream_t bitD2;
33462  BIT_DStream_t bitD3;
33463  BIT_DStream_t bitD4;
33464  size_t const length1 = MEM_readLE16(istart);
33465  size_t const length2 = MEM_readLE16(istart+2);
33466  size_t const length3 = MEM_readLE16(istart+4);
33467  size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
33468  const BYTE* const istart1 = istart + 6; /* jumpTable */
33469  const BYTE* const istart2 = istart1 + length1;
33470  const BYTE* const istart3 = istart2 + length2;
33471  const BYTE* const istart4 = istart3 + length3;
33472  const size_t segmentSize = (dstSize+3) / 4;
33473  BYTE* const opStart2 = ostart + segmentSize;
33474  BYTE* const opStart3 = opStart2 + segmentSize;
33475  BYTE* const opStart4 = opStart3 + segmentSize;
33476  BYTE* op1 = ostart;
33477  BYTE* op2 = opStart2;
33478  BYTE* op3 = opStart3;
33479  BYTE* op4 = opStart4;
33480  DTableDesc const dtd = HUF_getDTableDesc(DTable);
33481  U32 const dtLog = dtd.tableLog;
33482  U32 endSignal = 1;
33483 
33484  if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
33485  if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
33486  if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */
33487  CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
33488  CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
33489  CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
33490  CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
33491 
33492  /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
33493  if ((size_t)(oend - op4) >= sizeof(size_t)) {
33494  for ( ; (endSignal) & (op4 < olimit) ; ) {
33495  HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
33496  HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
33497  HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
33498  HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
33499  HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
33500  HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
33501  HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
33502  HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
33503  HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
33504  HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
33505  HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
33506  HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
33507  HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
33508  HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
33509  HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
33510  HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
33511  endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
33512  endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
33513  endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
33514  endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
33515  }
33516  }
33517 
33518  /* check corruption */
33519  /* note : should not be necessary : op# advance in lock step, and we control op4.
33520  * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */
33521  if (op1 > opStart2) return ERROR(corruption_detected);
33522  if (op2 > opStart3) return ERROR(corruption_detected);
33523  if (op3 > opStart4) return ERROR(corruption_detected);
33524  /* note : op4 supposed already verified within main loop */
33525 
33526  /* finish bitStreams one by one */
33527  HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);
33528  HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);
33529  HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);
33530  HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog);
33531 
33532  /* check */
33533  { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
33534  if (!endCheck) return ERROR(corruption_detected); }
33535 
33536  /* decoded size */
33537  return dstSize;
33538  }
33539 }
33540 
33541 #if HUF_NEED_BMI2_FUNCTION
33542 static BMI2_TARGET_ATTRIBUTE
33543 size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
33544  size_t cSrcSize, HUF_DTable const* DTable) {
33545  return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
33546 }
33547 #endif
33548 
33549 static
33550 size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
33551  size_t cSrcSize, HUF_DTable const* DTable) {
33552  return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
33553 }
33554 
33555 #if ZSTD_ENABLE_ASM_X86_64_BMI2
33557 HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN;
33558 
33559 #endif
33560 
33561 static HUF_FAST_BMI2_ATTRS
33563 {
33564  U64 bits[4];
33565  BYTE const* ip[4];
33566  BYTE* op[4];
33567  U16 const* const dtable = (U16 const*)args->dt;
33568  BYTE* const oend = args->oend;
33569  BYTE const* const ilimit = args->ilimit;
33570 
33571  /* Copy the arguments to local variables */
33572  ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
33573  ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
33574  ZSTD_memcpy(&op, &args->op, sizeof(op));
33575 
33577  assert(!MEM_32bits());
33578 
33579  for (;;) {
33580  BYTE* olimit;
33581  int stream;
33582  int symbol;
33583 
33584  /* Assert loop preconditions */
33585 #ifndef NDEBUG
33586  for (stream = 0; stream < 4; ++stream) {
33587  assert(op[stream] <= (stream == 3 ? oend : op[stream + 1]));
33588  assert(ip[stream] >= ilimit);
33589  }
33590 #endif
33591  /* Compute olimit */
33592  {
33593  /* Each iteration produces 5 output symbols per stream */
33594  size_t const oiters = (size_t)(oend - op[3]) / 5;
33595  /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes
33596  * per stream.
33597  */
33598  size_t const iiters = (size_t)(ip[0] - ilimit) / 7;
33599  /* We can safely run iters iterations before running bounds checks */
33600  size_t const iters = MIN(oiters, iiters);
33601  size_t const symbols = iters * 5;
33602 
33603  /* We can simply check that op[3] < olimit, instead of checking all
33604  * of our bounds, since we can't hit the other bounds until we've run
33605  * iters iterations, which only happens when op[3] == olimit.
33606  */
33607  olimit = op[3] + symbols;
33608 
33609  /* Exit fast decoding loop once we get close to the end. */
33610  if (op[3] + 20 > olimit)
33611  break;
33612 
33613  /* Exit the decoding loop if any input pointer has crossed the
33614  * previous one. This indicates corruption, and a precondition
33615  * to our loop is that ip[i] >= ip[0].
33616  */
33617  for (stream = 1; stream < 4; ++stream) {
33618  if (ip[stream] < ip[stream - 1])
33619  goto _out;
33620  }
33621  }
33622 
33623 #ifndef NDEBUG
33624  for (stream = 1; stream < 4; ++stream) {
33625  assert(ip[stream] >= ip[stream - 1]);
33626  }
33627 #endif
33628 
33629  do {
33630  /* Decode 5 symbols in each of the 4 streams */
33631  for (symbol = 0; symbol < 5; ++symbol) {
33632  for (stream = 0; stream < 4; ++stream) {
33633  int const index = (int)(bits[stream] >> 53);
33634  int const entry = (int)dtable[index];
33635  bits[stream] <<= (entry & 63);
33636  op[stream][symbol] = (BYTE)((entry >> 8) & 0xFF);
33637  }
33638  }
33639  /* Reload the bitstreams */
33640  for (stream = 0; stream < 4; ++stream) {
33641  int const ctz = ZSTD_countTrailingZeros64(bits[stream]);
33642  int const nbBits = ctz & 7;
33643  int const nbBytes = ctz >> 3;
33644  op[stream] += 5;
33645  ip[stream] -= nbBytes;
33646  bits[stream] = MEM_read64(ip[stream]) | 1;
33647  bits[stream] <<= nbBits;
33648  }
33649  } while (op[3] < olimit);
33650  }
33651 
33652 _out:
33653 
33654  /* Save the final values of each of the state variables back to args. */
33655  ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
33656  ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
33657  ZSTD_memcpy(&args->op, &op, sizeof(op));
33658 }
33659 
33665 static HUF_FAST_BMI2_ATTRS
33666 size_t
33668  void* dst, size_t dstSize,
33669  const void* cSrc, size_t cSrcSize,
33670  const HUF_DTable* DTable,
33671  HUF_DecompressFastLoopFn loopFn)
33672 {
33673  void const* dt = DTable + 1;
33674  const BYTE* const iend = (const BYTE*)cSrc + 6;
33675  BYTE* const oend = (BYTE*)dst + dstSize;
33677  { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
33678  FORWARD_IF_ERROR(ret, "Failed to init fast loop args");
33679  if (ret == 0)
33680  return 0;
33681  }
33682 
33683  assert(args.ip[0] >= args.ilimit);
33684  loopFn(&args);
33685 
33686  /* Our loop guarantees that ip[] >= ilimit and that we haven't
33687  * overwritten any op[].
33688  */
33689  assert(args.ip[0] >= iend);
33690  assert(args.ip[1] >= iend);
33691  assert(args.ip[2] >= iend);
33692  assert(args.ip[3] >= iend);
33693  assert(args.op[3] <= oend);
33694  (void)iend;
33695 
33696  /* finish bit streams one by one. */
33697  { size_t const segmentSize = (dstSize+3) / 4;
33698  BYTE* segmentEnd = (BYTE*)dst;
33699  int i;
33700  for (i = 0; i < 4; ++i) {
33701  BIT_DStream_t bit;
33702  if (segmentSize <= (size_t)(oend - segmentEnd))
33703  segmentEnd += segmentSize;
33704  else
33705  segmentEnd = oend;
33706  FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
33707  /* Decompress and validate that we've produced exactly the expected length. */
33708  args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG);
33709  if (args.op[i] != segmentEnd) return ERROR(corruption_detected);
33710  }
33711  }
33712 
33713  /* decoded size */
33714  assert(dstSize != 0);
33715  return dstSize;
33716 }
33717 
33718 HUF_DGEN(HUF_decompress1X1_usingDTable_internal)
33719 
33720 static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
33721  size_t cSrcSize, HUF_DTable const* DTable, int flags)
33722 {
33725 
33726 #if DYNAMIC_BMI2
33727  if (flags & HUF_flags_bmi2) {
33728  fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2;
33729 # if ZSTD_ENABLE_ASM_X86_64_BMI2
33730  if (!(flags & HUF_flags_disableAsm)) {
33731  loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop;
33732  }
33733 # endif
33734  } else {
33735  return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
33736  }
33737 #endif
33738 
33739 #if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
33740  if (!(flags & HUF_flags_disableAsm)) {
33741  loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop;
33742  }
33743 #endif
33744 
33745  if (!(flags & HUF_flags_disableFast)) {
33746  size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
33747  if (ret != 0)
33748  return ret;
33749  }
33750  return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
33751 }
33752 
33753 static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
33754  const void* cSrc, size_t cSrcSize,
33755  void* workSpace, size_t wkspSize, int flags)
33756 {
33757  const BYTE* ip = (const BYTE*) cSrc;
33758 
33759  size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
33760  if (HUF_isError(hSize)) return hSize;
33761  if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
33762  ip += hSize; cSrcSize -= hSize;
33763 
33764  return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
33765 }
33766 
33767 #endif /* HUF_FORCE_DECOMPRESS_X2 */
33768 
33769 
33770 #ifndef HUF_FORCE_DECOMPRESS_X1
33772 /* *************************/
33773 /* double-symbols decoding */
33774 /* *************************/
33775 
33776 typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */
33777 typedef struct { BYTE symbol; } sortedSymbol_t;
33780 
33784 static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level)
33785 {
33786  U32 seq;
33787  DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0);
33788  DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2);
33789  DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3);
33790  DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32));
33791  if (MEM_isLittleEndian()) {
33792  seq = level == 1 ? symbol : (baseSeq + (symbol << 8));
33793  return seq + (nbBits << 16) + ((U32)level << 24);
33794  } else {
33795  seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol);
33796  return (seq << 16) + (nbBits << 8) + (U32)level;
33797  }
33798 }
33799 
33803 static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
33804 {
33805  HUF_DEltX2 DElt;
33806  U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
33807  DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val));
33808  ZSTD_memcpy(&DElt, &val, sizeof(val));
33809  return DElt;
33810 }
33811 
33815 static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level)
33816 {
33817  U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
33818  return (U64)DElt + ((U64)DElt << 32);
33819 }
33820 
33833 static void HUF_fillDTableX2ForWeight(
33834  HUF_DEltX2* DTableRank,
33835  sortedSymbol_t const* begin, sortedSymbol_t const* end,
33836  U32 nbBits, U32 tableLog,
33837  U16 baseSeq, int const level)
33838 {
33839  U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */);
33840  const sortedSymbol_t* ptr;
33841  assert(level >= 1 && level <= 2);
33842  switch (length) {
33843  case 1:
33844  for (ptr = begin; ptr != end; ++ptr) {
33845  HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
33846  *DTableRank++ = DElt;
33847  }
33848  break;
33849  case 2:
33850  for (ptr = begin; ptr != end; ++ptr) {
33851  HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
33852  DTableRank[0] = DElt;
33853  DTableRank[1] = DElt;
33854  DTableRank += 2;
33855  }
33856  break;
33857  case 4:
33858  for (ptr = begin; ptr != end; ++ptr) {
33859  U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
33860  ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
33861  ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
33862  DTableRank += 4;
33863  }
33864  break;
33865  case 8:
33866  for (ptr = begin; ptr != end; ++ptr) {
33867  U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
33868  ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
33869  ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
33870  ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
33871  ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
33872  DTableRank += 8;
33873  }
33874  break;
33875  default:
33876  for (ptr = begin; ptr != end; ++ptr) {
33877  U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
33878  HUF_DEltX2* const DTableRankEnd = DTableRank + length;
33879  for (; DTableRank != DTableRankEnd; DTableRank += 8) {
33880  ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
33881  ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
33882  ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
33883  ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
33884  }
33885  }
33886  break;
33887  }
33888 }
33889 
33890 /* HUF_fillDTableX2Level2() :
33891  * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
33892 static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits,
33893  const U32* rankVal, const int minWeight, const int maxWeight1,
33894  const sortedSymbol_t* sortedSymbols, U32 const* rankStart,
33895  U32 nbBitsBaseline, U16 baseSeq)
33896 {
33897  /* Fill skipped values (all positions up to rankVal[minWeight]).
33898  * These are positions only get a single symbol because the combined weight
33899  * is too large.
33900  */
33901  if (minWeight>1) {
33902  U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */);
33903  U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1);
33904  int const skipSize = rankVal[minWeight];
33905  assert(length > 1);
33906  assert((U32)skipSize < length);
33907  switch (length) {
33908  case 2:
33909  assert(skipSize == 1);
33910  ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2));
33911  break;
33912  case 4:
33913  assert(skipSize <= 4);
33914  ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2));
33915  ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2));
33916  break;
33917  default:
33918  {
33919  int i;
33920  for (i = 0; i < skipSize; i += 8) {
33921  ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2));
33922  ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2));
33923  ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2));
33924  ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2));
33925  }
33926  }
33927  }
33928  }
33929 
33930  /* Fill each of the second level symbols by weight. */
33931  {
33932  int w;
33933  for (w = minWeight; w < maxWeight1; ++w) {
33934  int const begin = rankStart[w];
33935  int const end = rankStart[w+1];
33936  U32 const nbBits = nbBitsBaseline - w;
33937  U32 const totalBits = nbBits + consumedBits;
33939  DTable + rankVal[w],
33940  sortedSymbols + begin, sortedSymbols + end,
33941  totalBits, targetLog,
33942  baseSeq, /* level */ 2);
33943  }
33944  }
33945 }
33946 
33947 static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
33948  const sortedSymbol_t* sortedList,
33949  const U32* rankStart, rankValCol_t* rankValOrigin, const U32 maxWeight,
33950  const U32 nbBitsBaseline)
33951 {
33952  U32* const rankVal = rankValOrigin[0];
33953  const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
33954  const U32 minBits = nbBitsBaseline - maxWeight;
33955  int w;
33956  int const wEnd = (int)maxWeight + 1;
33957 
33958  /* Fill DTable in order of weight. */
33959  for (w = 1; w < wEnd; ++w) {
33960  int const begin = (int)rankStart[w];
33961  int const end = (int)rankStart[w+1];
33962  U32 const nbBits = nbBitsBaseline - w;
33963 
33964  if (targetLog-nbBits >= minBits) {
33965  /* Enough room for a second symbol. */
33966  int start = rankVal[w];
33967  U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */);
33968  int minWeight = nbBits + scaleLog;
33969  int s;
33970  if (minWeight < 1) minWeight = 1;
33971  /* Fill the DTable for every symbol of weight w.
33972  * These symbols get at least 1 second symbol.
33973  */
33974  for (s = begin; s != end; ++s) {
33976  DTable + start, targetLog, nbBits,
33977  rankValOrigin[nbBits], minWeight, wEnd,
33978  sortedList, rankStart,
33979  nbBitsBaseline, sortedList[s].symbol);
33980  start += length;
33981  }
33982  } else {
33983  /* Only a single symbol. */
33985  DTable + rankVal[w],
33986  sortedList + begin, sortedList + end,
33987  nbBits, targetLog,
33988  /* baseSeq */ 0, /* level */ 1);
33989  }
33990  }
33993 typedef struct {
33994  rankValCol_t rankVal[HUF_TABLELOG_MAX];
33995  U32 rankStats[HUF_TABLELOG_MAX + 1];
33996  U32 rankStart0[HUF_TABLELOG_MAX + 3];
33997  sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
33998  BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
34001 
34002 size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
34003  const void* src, size_t srcSize,
34004  void* workSpace, size_t wkspSize, int flags)
34005 {
34006  U32 tableLog, maxW, nbSymbols;
34007  DTableDesc dtd = HUF_getDTableDesc(DTable);
34008  U32 maxTableLog = dtd.maxTableLog;
34009  size_t iSize;
34010  void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */
34011  HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
34012  U32 *rankStart;
34013 
34014  HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
34015 
34016  if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
34017 
34018  rankStart = wksp->rankStart0 + 1;
34019  ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
34020  ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
34021 
34022  DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
34023  if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
34024  /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
34025 
34026  iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags);
34027  if (HUF_isError(iSize)) return iSize;
34028 
34029  /* check result */
34030  if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
34031  if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG;
34032 
34033  /* find maxWeight */
34034  for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
34035 
34036  /* Get start index of each weight */
34037  { U32 w, nextRankStart = 0;
34038  for (w=1; w<maxW+1; w++) {
34039  U32 curr = nextRankStart;
34040  nextRankStart += wksp->rankStats[w];
34041  rankStart[w] = curr;
34042  }
34043  rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
34044  rankStart[maxW+1] = nextRankStart;
34045  }
34046 
34047  /* sort symbols by weight */
34048  { U32 s;
34049  for (s=0; s<nbSymbols; s++) {
34050  U32 const w = wksp->weightList[s];
34051  U32 const r = rankStart[w]++;
34052  wksp->sortedSymbol[r].symbol = (BYTE)s;
34053  }
34054  rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
34055  }
34056 
34057  /* Build rankVal */
34058  { U32* const rankVal0 = wksp->rankVal[0];
34059  { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
34060  U32 nextRankVal = 0;
34061  U32 w;
34062  for (w=1; w<maxW+1; w++) {
34063  U32 curr = nextRankVal;
34064  nextRankVal += wksp->rankStats[w] << (w+rescale);
34065  rankVal0[w] = curr;
34066  } }
34067  { U32 const minBits = tableLog+1 - maxW;
34068  U32 consumed;
34069  for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
34070  U32* const rankValPtr = wksp->rankVal[consumed];
34071  U32 w;
34072  for (w = 1; w < maxW+1; w++) {
34073  rankValPtr[w] = rankVal0[w] >> consumed;
34074  } } } }
34075 
34076  HUF_fillDTableX2(dt, maxTableLog,
34077  wksp->sortedSymbol,
34078  wksp->rankStart0, wksp->rankVal, maxW,
34079  tableLog+1);
34080 
34081  dtd.tableLog = (BYTE)maxTableLog;
34082  dtd.tableType = 1;
34083  ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
34084  return iSize;
34085 }
34086 
34087 
34089 HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
34090 {
34091  size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
34092  ZSTD_memcpy(op, &dt[val].sequence, 2);
34093  BIT_skipBits(DStream, dt[val].nbBits);
34094  return dt[val].length;
34095 }
34096 
34098 HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
34099 {
34100  size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
34101  ZSTD_memcpy(op, &dt[val].sequence, 1);
34102  if (dt[val].length==1) {
34103  BIT_skipBits(DStream, dt[val].nbBits);
34104  } else {
34105  if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
34106  BIT_skipBits(DStream, dt[val].nbBits);
34107  if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
34108  /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
34109  DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
34110  }
34111  }
34112  return 1;
34113 }
34114 
34115 #define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
34116  ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
34117 
34118 #define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
34119  if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
34120  ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
34122 #define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
34123  if (MEM_64bits()) \
34124  ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
34125 
34126 HINT_INLINE size_t
34127 HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,
34128  const HUF_DEltX2* const dt, const U32 dtLog)
34129 {
34130  BYTE* const pStart = p;
34131 
34132  /* up to 8 symbols at a time */
34133  if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) {
34134  if (dtLog <= 11 && MEM_64bits()) {
34135  /* up to 10 symbols at a time */
34136  while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) {
34137  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34138  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34139  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34140  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34141  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34142  }
34143  } else {
34144  /* up to 8 symbols at a time */
34145  while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
34146  HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
34147  HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
34148  HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
34149  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34150  }
34151  }
34152  } else {
34153  BIT_reloadDStream(bitDPtr);
34154  }
34155 
34156  /* closer to end : up to 2 symbols at a time */
34157  if ((size_t)(pEnd - p) >= 2) {
34158  while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
34159  HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
34160 
34161  while (p <= pEnd-2)
34162  HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
34163  }
34164 
34165  if (p < pEnd)
34166  p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
34167 
34168  return p-pStart;
34169 }
34170 
34171 FORCE_INLINE_TEMPLATE size_t
34173  void* dst, size_t dstSize,
34174  const void* cSrc, size_t cSrcSize,
34175  const HUF_DTable* DTable)
34176 {
34177  BIT_DStream_t bitD;
34178 
34179  /* Init */
34180  CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
34181 
34182  /* decode */
34183  { BYTE* const ostart = (BYTE*) dst;
34184  BYTE* const oend = ostart + dstSize;
34185  const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
34186  const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
34187  DTableDesc const dtd = HUF_getDTableDesc(DTable);
34188  HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog);
34189  }
34190 
34191  /* check */
34192  if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
34193 
34194  /* decoded size */
34195  return dstSize;
34196 }
34198 /* HUF_decompress4X2_usingDTable_internal_body():
34199  * Conditions:
34200  * @dstSize >= 6
34201  */
34202 FORCE_INLINE_TEMPLATE size_t
34204  void* dst, size_t dstSize,
34205  const void* cSrc, size_t cSrcSize,
34206  const HUF_DTable* DTable)
34207 {
34208  if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
34209 
34210  { const BYTE* const istart = (const BYTE*) cSrc;
34211  BYTE* const ostart = (BYTE*) dst;
34212  BYTE* const oend = ostart + dstSize;
34213  BYTE* const olimit = oend - (sizeof(size_t)-1);
34214  const void* const dtPtr = DTable+1;
34215  const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
34216 
34217  /* Init */
34218  BIT_DStream_t bitD1;
34219  BIT_DStream_t bitD2;
34220  BIT_DStream_t bitD3;
34221  BIT_DStream_t bitD4;
34222  size_t const length1 = MEM_readLE16(istart);
34223  size_t const length2 = MEM_readLE16(istart+2);
34224  size_t const length3 = MEM_readLE16(istart+4);
34225  size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
34226  const BYTE* const istart1 = istart + 6; /* jumpTable */
34227  const BYTE* const istart2 = istart1 + length1;
34228  const BYTE* const istart3 = istart2 + length2;
34229  const BYTE* const istart4 = istart3 + length3;
34230  size_t const segmentSize = (dstSize+3) / 4;
34231  BYTE* const opStart2 = ostart + segmentSize;
34232  BYTE* const opStart3 = opStart2 + segmentSize;
34233  BYTE* const opStart4 = opStart3 + segmentSize;
34234  BYTE* op1 = ostart;
34235  BYTE* op2 = opStart2;
34236  BYTE* op3 = opStart3;
34237  BYTE* op4 = opStart4;
34238  U32 endSignal = 1;
34239  DTableDesc const dtd = HUF_getDTableDesc(DTable);
34240  U32 const dtLog = dtd.tableLog;
34241 
34242  if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
34243  if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
34244  if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */
34245  CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
34246  CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
34247  CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
34248  CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
34249 
34250  /* 16-32 symbols per loop (4-8 symbols per stream) */
34251  if ((size_t)(oend - op4) >= sizeof(size_t)) {
34252  for ( ; (endSignal) & (op4 < olimit); ) {
34253 #if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
34254  HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
34255  HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
34256  HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
34257  HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
34258  HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
34259  HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
34260  HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
34261  HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
34262  endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
34263  endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
34264  HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
34265  HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
34266  HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
34267  HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
34268  HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
34269  HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
34270  HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
34271  HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
34272  endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
34273  endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
34274 #else
34275  HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
34276  HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
34277  HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
34278  HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
34279  HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
34280  HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
34281  HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
34282  HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
34283  HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
34284  HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
34285  HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
34286  HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
34287  HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
34288  HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
34289  HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
34290  HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
34291  endSignal = (U32)LIKELY((U32)
34296 #endif
34297  }
34298  }
34299 
34300  /* check corruption */
34301  if (op1 > opStart2) return ERROR(corruption_detected);
34302  if (op2 > opStart3) return ERROR(corruption_detected);
34303  if (op3 > opStart4) return ERROR(corruption_detected);
34304  /* note : op4 already verified within main loop */
34305 
34306  /* finish bitStreams one by one */
34307  HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
34308  HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
34309  HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
34310  HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
34311 
34312  /* check */
34313  { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
34314  if (!endCheck) return ERROR(corruption_detected); }
34315 
34316  /* decoded size */
34317  return dstSize;
34318  }
34319 }
34320 
34321 #if HUF_NEED_BMI2_FUNCTION
34322 static BMI2_TARGET_ATTRIBUTE
34323 size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
34324  size_t cSrcSize, HUF_DTable const* DTable) {
34325  return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
34326 }
34327 #endif
34328 
34329 static
34330 size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
34331  size_t cSrcSize, HUF_DTable const* DTable) {
34332  return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
34333 }
34334 
34335 #if ZSTD_ENABLE_ASM_X86_64_BMI2
34337 HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN;
34338 
34339 #endif
34340 
34341 static HUF_FAST_BMI2_ATTRS
34343 {
34344  U64 bits[4];
34345  BYTE const* ip[4];
34346  BYTE* op[4];
34347  BYTE* oend[4];
34348  HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt;
34349  BYTE const* const ilimit = args->ilimit;
34350 
34351  /* Copy the arguments to local registers. */
34352  ZSTD_memcpy(&bits, &args->bits, sizeof(bits));
34353  ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip));
34354  ZSTD_memcpy(&op, &args->op, sizeof(op));
34355 
34356  oend[0] = op[1];
34357  oend[1] = op[2];
34358  oend[2] = op[3];
34359  oend[3] = args->oend;
34360 
34362  assert(!MEM_32bits());
34363 
34364  for (;;) {
34365  BYTE* olimit;
34366  int stream;
34367  int symbol;
34368 
34369  /* Assert loop preconditions */
34370 #ifndef NDEBUG
34371  for (stream = 0; stream < 4; ++stream) {
34372  assert(op[stream] <= oend[stream]);
34373  assert(ip[stream] >= ilimit);
34374  }
34375 #endif
34376  /* Compute olimit */
34377  {
34378  /* Each loop does 5 table lookups for each of the 4 streams.
34379  * Each table lookup consumes up to 11 bits of input, and produces
34380  * up to 2 bytes of output.
34381  */
34382  /* We can consume up to 7 bytes of input per iteration per stream.
34383  * We also know that each input pointer is >= ip[0]. So we can run
34384  * iters loops before running out of input.
34385  */
34386  size_t iters = (size_t)(ip[0] - ilimit) / 7;
34387  /* Each iteration can produce up to 10 bytes of output per stream.
34388  * Each output stream my advance at different rates. So take the
34389  * minimum number of safe iterations among all the output streams.
34390  */
34391  for (stream = 0; stream < 4; ++stream) {
34392  size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10;
34393  iters = MIN(iters, oiters);
34394  }
34395 
34396  /* Each iteration produces at least 5 output symbols. So until
34397  * op[3] crosses olimit, we know we haven't executed iters
34398  * iterations yet. This saves us maintaining an iters counter,
34399  * at the expense of computing the remaining # of iterations
34400  * more frequently.
34401  */
34402  olimit = op[3] + (iters * 5);
34403 
34404  /* Exit the fast decoding loop if we are too close to the end. */
34405  if (op[3] + 10 > olimit)
34406  break;
34407 
34408  /* Exit the decoding loop if any input pointer has crossed the
34409  * previous one. This indicates corruption, and a precondition
34410  * to our loop is that ip[i] >= ip[0].
34411  */
34412  for (stream = 1; stream < 4; ++stream) {
34413  if (ip[stream] < ip[stream - 1])
34414  goto _out;
34415  }
34416  }
34417 
34418 #ifndef NDEBUG
34419  for (stream = 1; stream < 4; ++stream) {
34420  assert(ip[stream] >= ip[stream - 1]);
34421  }
34422 #endif
34423 
34424  do {
34425  /* Do 5 table lookups for each of the first 3 streams */
34426  for (symbol = 0; symbol < 5; ++symbol) {
34427  for (stream = 0; stream < 3; ++stream) {
34428  int const index = (int)(bits[stream] >> 53);
34429  HUF_DEltX2 const entry = dtable[index];
34430  MEM_write16(op[stream], entry.sequence);
34431  bits[stream] <<= (entry.nbBits);
34432  op[stream] += (entry.length);
34433  }
34434  }
34435  /* Do 1 table lookup from the final stream */
34436  {
34437  int const index = (int)(bits[3] >> 53);
34438  HUF_DEltX2 const entry = dtable[index];
34439  MEM_write16(op[3], entry.sequence);
34440  bits[3] <<= (entry.nbBits);
34441  op[3] += (entry.length);
34442  }
34443  /* Do 4 table lookups from the final stream & reload bitstreams */
34444  for (stream = 0; stream < 4; ++stream) {
34445  /* Do a table lookup from the final stream.
34446  * This is interleaved with the reloading to reduce register
34447  * pressure. This shouldn't be necessary, but compilers can
34448  * struggle with codegen with high register pressure.
34449  */
34450  {
34451  int const index = (int)(bits[3] >> 53);
34452  HUF_DEltX2 const entry = dtable[index];
34453  MEM_write16(op[3], entry.sequence);
34454  bits[3] <<= (entry.nbBits);
34455  op[3] += (entry.length);
34456  }
34457  /* Reload the bistreams. The final bitstream must be reloaded
34458  * after the 5th symbol was decoded.
34459  */
34460  {
34461  int const ctz = ZSTD_countTrailingZeros64(bits[stream]);
34462  int const nbBits = ctz & 7;
34463  int const nbBytes = ctz >> 3;
34464  ip[stream] -= nbBytes;
34465  bits[stream] = MEM_read64(ip[stream]) | 1;
34466  bits[stream] <<= nbBits;
34467  }
34468  }
34469  } while (op[3] < olimit);
34470  }
34471 
34472 _out:
34473 
34474  /* Save the final values of each of the state variables back to args. */
34475  ZSTD_memcpy(&args->bits, &bits, sizeof(bits));
34476  ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip));
34477  ZSTD_memcpy(&args->op, &op, sizeof(op));
34478 }
34479 
34480 
34481 static HUF_FAST_BMI2_ATTRS size_t
34483  void* dst, size_t dstSize,
34484  const void* cSrc, size_t cSrcSize,
34485  const HUF_DTable* DTable,
34486  HUF_DecompressFastLoopFn loopFn) {
34487  void const* dt = DTable + 1;
34488  const BYTE* const iend = (const BYTE*)cSrc + 6;
34489  BYTE* const oend = (BYTE*)dst + dstSize;
34491  {
34492  size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
34493  FORWARD_IF_ERROR(ret, "Failed to init asm args");
34494  if (ret == 0)
34495  return 0;
34496  }
34497 
34498  assert(args.ip[0] >= args.ilimit);
34499  loopFn(&args);
34500 
34501  /* note : op4 already verified within main loop */
34502  assert(args.ip[0] >= iend);
34503  assert(args.ip[1] >= iend);
34504  assert(args.ip[2] >= iend);
34505  assert(args.ip[3] >= iend);
34506  assert(args.op[3] <= oend);
34507  (void)iend;
34508 
34509  /* finish bitStreams one by one */
34510  {
34511  size_t const segmentSize = (dstSize+3) / 4;
34512  BYTE* segmentEnd = (BYTE*)dst;
34513  int i;
34514  for (i = 0; i < 4; ++i) {
34515  BIT_DStream_t bit;
34516  if (segmentSize <= (size_t)(oend - segmentEnd))
34517  segmentEnd += segmentSize;
34518  else
34519  segmentEnd = oend;
34520  FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
34521  args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG);
34522  if (args.op[i] != segmentEnd)
34523  return ERROR(corruption_detected);
34524  }
34525  }
34526 
34527  /* decoded size */
34528  return dstSize;
34529 }
34530 
34531 static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
34532  size_t cSrcSize, HUF_DTable const* DTable, int flags)
34533 {
34536 
34537 #if DYNAMIC_BMI2
34538  if (flags & HUF_flags_bmi2) {
34539  fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2;
34540 # if ZSTD_ENABLE_ASM_X86_64_BMI2
34541  if (!(flags & HUF_flags_disableAsm)) {
34542  loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
34543  }
34544 # endif
34545  } else {
34546  return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
34547  }
34548 #endif
34549 
34550 #if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
34551  if (!(flags & HUF_flags_disableAsm)) {
34552  loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop;
34553  }
34554 #endif
34555 
34556  if (!(flags & HUF_flags_disableFast)) {
34557  size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn);
34558  if (ret != 0)
34559  return ret;
34560  }
34561  return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable);
34562 }
34563 
34564 HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
34565 
34566 size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
34567  const void* cSrc, size_t cSrcSize,
34568  void* workSpace, size_t wkspSize, int flags)
34569 {
34570  const BYTE* ip = (const BYTE*) cSrc;
34571 
34572  size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,
34573  workSpace, wkspSize, flags);
34574  if (HUF_isError(hSize)) return hSize;
34575  if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
34576  ip += hSize; cSrcSize -= hSize;
34577 
34578  return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags);
34579 }
34580 
34581 static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
34582  const void* cSrc, size_t cSrcSize,
34583  void* workSpace, size_t wkspSize, int flags)
34584 {
34585  const BYTE* ip = (const BYTE*) cSrc;
34586 
34587  size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,
34588  workSpace, wkspSize, flags);
34589  if (HUF_isError(hSize)) return hSize;
34590  if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
34591  ip += hSize; cSrcSize -= hSize;
34592 
34593  return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
34594 }
34595 
34596 #endif /* HUF_FORCE_DECOMPRESS_X1 */
34597 
34598 
34599 /* ***********************************/
34600 /* Universal decompression selectors */
34601 /* ***********************************/
34602 
34603 
34604 #if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
34605 typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
34606 static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] =
34607 {
34608  /* single, double, quad */
34609  {{0,0}, {1,1}}, /* Q==0 : impossible */
34610  {{0,0}, {1,1}}, /* Q==1 : impossible */
34611  {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */
34612  {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */
34613  {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */
34614  {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */
34615  {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */
34616  {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */
34617  {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */
34618  {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */
34619  {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */
34620  {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */
34621  {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */
34622  {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */
34623  {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */
34624  {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */
34625 };
34626 #endif
34633 U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
34634 {
34635  assert(dstSize > 0);
34636  assert(dstSize <= 128*1024);
34637 #if defined(HUF_FORCE_DECOMPRESS_X1)
34638  (void)dstSize;
34639  (void)cSrcSize;
34640  return 0;
34641 #elif defined(HUF_FORCE_DECOMPRESS_X2)
34642  (void)dstSize;
34643  (void)cSrcSize;
34644  return 1;
34645 #else
34646  /* decoder timing evaluation */
34647  { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */
34648  U32 const D256 = (U32)(dstSize >> 8);
34649  U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
34650  U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
34651  DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */
34652  return DTime1 < DTime0;
34653  }
34654 #endif
34655 }
34656 
34657 size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
34658  const void* cSrc, size_t cSrcSize,
34659  void* workSpace, size_t wkspSize, int flags)
34660 {
34661  /* validation checks */
34662  if (dstSize == 0) return ERROR(dstSize_tooSmall);
34663  if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
34664  if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
34665  if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
34666 
34667  { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
34668 #if defined(HUF_FORCE_DECOMPRESS_X1)
34669  (void)algoNb;
34670  assert(algoNb == 0);
34671  return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
34672  cSrcSize, workSpace, wkspSize, flags);
34673 #elif defined(HUF_FORCE_DECOMPRESS_X2)
34674  (void)algoNb;
34675  assert(algoNb == 1);
34676  return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
34677  cSrcSize, workSpace, wkspSize, flags);
34678 #else
34679  return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
34680  cSrcSize, workSpace, wkspSize, flags):
34681  HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
34682  cSrcSize, workSpace, wkspSize, flags);
34683 #endif
34684  }
34685 }
34686 
34687 
34688 size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
34689 {
34690  DTableDesc const dtd = HUF_getDTableDesc(DTable);
34691 #if defined(HUF_FORCE_DECOMPRESS_X1)
34692  (void)dtd;
34693  assert(dtd.tableType == 0);
34694  return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34695 #elif defined(HUF_FORCE_DECOMPRESS_X2)
34696  (void)dtd;
34697  assert(dtd.tableType == 1);
34698  return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34699 #else
34700  return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
34701  HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34702 #endif
34703 }
34704 
34705 #ifndef HUF_FORCE_DECOMPRESS_X2
34706 size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags)
34707 {
34708  const BYTE* ip = (const BYTE*) cSrc;
34709 
34710  size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags);
34711  if (HUF_isError(hSize)) return hSize;
34712  if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
34713  ip += hSize; cSrcSize -= hSize;
34714 
34715  return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags);
34716 }
34717 #endif
34718 
34719 size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags)
34720 {
34721  DTableDesc const dtd = HUF_getDTableDesc(DTable);
34722 #if defined(HUF_FORCE_DECOMPRESS_X1)
34723  (void)dtd;
34724  assert(dtd.tableType == 0);
34725  return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34726 #elif defined(HUF_FORCE_DECOMPRESS_X2)
34727  (void)dtd;
34728  assert(dtd.tableType == 1);
34729  return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34730 #else
34731  return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) :
34732  HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags);
34733 #endif
34734 }
34735 
34736 size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags)
34737 {
34738  /* validation checks */
34739  if (dstSize == 0) return ERROR(dstSize_tooSmall);
34740  if (cSrcSize == 0) return ERROR(corruption_detected);
34741 
34742  { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
34743 #if defined(HUF_FORCE_DECOMPRESS_X1)
34744  (void)algoNb;
34745  assert(algoNb == 0);
34746  return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
34747 #elif defined(HUF_FORCE_DECOMPRESS_X2)
34748  (void)algoNb;
34749  assert(algoNb == 1);
34750  return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
34751 #else
34752  return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) :
34753  HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags);
34754 #endif
34755  }
34756 }
34757 /**** ended inlining decompress/huf_decompress.c ****/
34758 /**** start inlining decompress/zstd_ddict.c ****/
34759 /*
34760  * Copyright (c) Meta Platforms, Inc. and affiliates.
34761  * All rights reserved.
34762  *
34763  * This source code is licensed under both the BSD-style license (found in the
34764  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
34765  * in the COPYING file in the root directory of this source tree).
34766  * You may select, at your option, one of the above-listed licenses.
34767  */
34768 
34769 /* zstd_ddict.c :
34770  * concentrates all logic that needs to know the internals of ZSTD_DDict object */
34771 
34772 /*-*******************************************************
34773 * Dependencies
34774 *********************************************************/
34775 /**** skipping file: ../common/allocations.h ****/
34776 /**** skipping file: ../common/zstd_deps.h ****/
34777 /**** skipping file: ../common/cpu.h ****/
34778 /**** skipping file: ../common/mem.h ****/
34779 #define FSE_STATIC_LINKING_ONLY
34780 /**** skipping file: ../common/fse.h ****/
34781 /**** skipping file: ../common/huf.h ****/
34782 /**** start inlining zstd_decompress_internal.h ****/
34783 /*
34784  * Copyright (c) Meta Platforms, Inc. and affiliates.
34785  * All rights reserved.
34786  *
34787  * This source code is licensed under both the BSD-style license (found in the
34788  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
34789  * in the COPYING file in the root directory of this source tree).
34790  * You may select, at your option, one of the above-listed licenses.
34791  */
34793 
34794 /* zstd_decompress_internal:
34795  * objects and definitions shared within lib/decompress modules */
34796 
34797  #ifndef ZSTD_DECOMPRESS_INTERNAL_H
34798  #define ZSTD_DECOMPRESS_INTERNAL_H
34799 
34800 
34801 /*-*******************************************************
34802  * Dependencies
34803  *********************************************************/
34804 /**** skipping file: ../common/mem.h ****/
34805 /**** skipping file: ../common/zstd_internal.h ****/
34807 
34808 
34809 /*-*******************************************************
34810  * Constants
34811  *********************************************************/
34812 static UNUSED_ATTR const U32 LL_base[MaxLL+1] = {
34813  0, 1, 2, 3, 4, 5, 6, 7,
34814  8, 9, 10, 11, 12, 13, 14, 15,
34815  16, 18, 20, 22, 24, 28, 32, 40,
34816  48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
34817  0x2000, 0x4000, 0x8000, 0x10000 };
34818 
34819 static UNUSED_ATTR const U32 OF_base[MaxOff+1] = {
34820  0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
34821  0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
34822  0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
34823  0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
34824 
34825 static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = {
34826  0, 1, 2, 3, 4, 5, 6, 7,
34827  8, 9, 10, 11, 12, 13, 14, 15,
34828  16, 17, 18, 19, 20, 21, 22, 23,
34829  24, 25, 26, 27, 28, 29, 30, 31 };
34830 
34831 static UNUSED_ATTR const U32 ML_base[MaxML+1] = {
34832  3, 4, 5, 6, 7, 8, 9, 10,
34833  11, 12, 13, 14, 15, 16, 17, 18,
34834  19, 20, 21, 22, 23, 24, 25, 26,
34835  27, 28, 29, 30, 31, 32, 33, 34,
34836  35, 37, 39, 41, 43, 47, 51, 59,
34837  67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
34838  0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
34841 /*-*******************************************************
34842  * Decompression types
34843  *********************************************************/
34844  typedef struct {
34845  U32 fastMode;
34846  U32 tableLog;
34848 
34849  typedef struct {
34850  U16 nextState;
34851  BYTE nbAdditionalBits;
34852  BYTE nbBits;
34853  U32 baseValue;
34855 
34856  #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log)))
34858 #define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64))
34859 #define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32))
34860 #define ZSTD_HUFFDTABLE_CAPACITY_LOG 12
34862 typedef struct {
34863  ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */
34864  ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */
34865  ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */
34866  HUF_DTable hufTable[HUF_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)]; /* can accommodate HUF_decompress4X */
34876 typedef enum { zdss_init=0, zdss_loadHeader,
34878 
34879 typedef enum {
34880  ZSTD_use_indefinitely = -1, /* Use the dictionary indefinitely */
34881  ZSTD_dont_use = 0, /* Do not use the dictionary (if one exists free it) */
34882  ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
34884 
34885 /* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */
34886 typedef struct {
34887  const ZSTD_DDict** ddictPtrTable;
34888  size_t ddictPtrTableSize;
34889  size_t ddictPtrCount;
34892 #ifndef ZSTD_DECODER_INTERNAL_BUFFER
34893 # define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16)
34894 #endif
34895 
34896 #define ZSTD_LBMIN 64
34897 #define ZSTD_LBMAX (128 << 10)
34899 /* extra buffer, compensates when dst is not large enough to store litBuffer */
34900 #define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX)
34901 
34902 typedef enum {
34903  ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */
34904  ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */
34905  ZSTD_split = 2 /* Split between litExtraBuffer and dst */
34915  U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */
34916  const void* previousDstEnd; /* detect continuity */
34917  const void* prefixStart; /* start of current segment */
34918  const void* virtualStart; /* virtual start of previous segment if it was just before current one */
34919  const void* dictEnd; /* end of previous segment */
34920  size_t expected;
34921  ZSTD_frameHeader fParams;
34924  blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
34929  size_t headerSize;
34930  ZSTD_format_e format;
34931  ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */
34932  U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */
34933  const BYTE* litPtr;
34934  ZSTD_customMem customMem;
34935  size_t litSize;
34936  size_t rleSize;
34937  size_t staticSize;
34938 #if DYNAMIC_BMI2 != 0
34939  int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
34940 #endif
34942  /* dictionary */
34944  const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */
34945  U32 dictID;
34946  int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */
34948  ZSTD_DDictHashSet* ddictSet; /* Hash set for multiple ddicts */
34949  ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */
34952  /* streaming */
34954  char* inBuff;
34955  size_t inBuffSize;
34956  size_t inPos;
34957  size_t maxWindowSize;
34958  char* outBuff;
34959  size_t outBuffSize;
34960  size_t outStart;
34961  size_t outEnd;
34962  size_t lhSize;
34963 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
34964  void* legacyContext;
34965  U32 previousLegacyVersion;
34966  U32 legacyVersion;
34967 #endif
34973  /* workspace */
34975  const BYTE* litBufferEnd;
34977  BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */
34978  BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
34979 
34980  size_t oversizedDuration;
34981 
34982 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
34983  void const* dictContentBeginForFuzzing;
34984  void const* dictContentEndForFuzzing;
34985 #endif
34986 
34987  /* Tracing */
34988 #if ZSTD_TRACE
34989  ZSTD_TraceCtx traceCtx;
34990 #endif
34991 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
34992 
34993 MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) {
34994 #if DYNAMIC_BMI2 != 0
34995  return dctx->bmi2;
34996 #else
34997  (void)dctx;
34998  return 0;
34999 #endif
35000 }
35001 
35002 /*-*******************************************************
35003  * Shared internal functions
35004  *********************************************************/
35005 
35010  const void* const dict, size_t const dictSize);
35011 
35017 void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize);
35018 
35019 
35020 #endif /* ZSTD_DECOMPRESS_INTERNAL_H */
35021 /**** ended inlining zstd_decompress_internal.h ****/
35022 /**** start inlining zstd_ddict.h ****/
35023 /*
35024  * Copyright (c) Meta Platforms, Inc. and affiliates.
35025  * All rights reserved.
35026  *
35027  * This source code is licensed under both the BSD-style license (found in the
35028  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
35029  * in the COPYING file in the root directory of this source tree).
35030  * You may select, at your option, one of the above-listed licenses.
35031  */
35032 
35033 
35034 #ifndef ZSTD_DDICT_H
35035 #define ZSTD_DDICT_H
35036 
35037 /*-*******************************************************
35038  * Dependencies
35039  *********************************************************/
35040 /**** skipping file: ../common/zstd_deps.h ****/
35041 /**** skipping file: ../zstd.h ****/
35042 
35043 
35044 /*-*******************************************************
35045  * Interface
35046  *********************************************************/
35047 
35048 /* note: several prototypes are already published in `zstd.h` :
35049  * ZSTD_createDDict()
35050  * ZSTD_createDDict_byReference()
35051  * ZSTD_createDDict_advanced()
35052  * ZSTD_freeDDict()
35053  * ZSTD_initStaticDDict()
35054  * ZSTD_sizeof_DDict()
35055  * ZSTD_estimateDDictSize()
35056  * ZSTD_getDictID_fromDict()
35057  */
35058 
35059 const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict);
35060 size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict);
35061 
35062 void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
35063 
35064 
35065 
35066 #endif /* ZSTD_DDICT_H */
35067 /**** ended inlining zstd_ddict.h ****/
35068 
35069 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
35070 #error Using excluded file: ../legacy/zstd_legacy.h (re-amalgamate source to fix)
35071 #endif
35075 /*-*******************************************************
35076 * Types
35077 *********************************************************/
35079  void* dictBuffer;
35080  const void* dictContent;
35081  size_t dictSize;
35083  U32 dictID;
35085  ZSTD_customMem cMem;
35086 }; /* typedef'd to ZSTD_DDict within "zstd.h" */
35087 
35088 const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict)
35089 {
35090  assert(ddict != NULL);
35091  return ddict->dictContent;
35092 }
35093 
35094 size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict)
35095 {
35096  assert(ddict != NULL);
35097  return ddict->dictSize;
35098 }
35099 
35100 void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
35101 {
35102  DEBUGLOG(4, "ZSTD_copyDDictParameters");
35103  assert(dctx != NULL);
35104  assert(ddict != NULL);
35105  dctx->dictID = ddict->dictID;
35106  dctx->prefixStart = ddict->dictContent;
35107  dctx->virtualStart = ddict->dictContent;
35108  dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
35109  dctx->previousDstEnd = dctx->dictEnd;
35110 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
35111  dctx->dictContentBeginForFuzzing = dctx->prefixStart;
35112  dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
35113 #endif
35114  if (ddict->entropyPresent) {
35115  dctx->litEntropy = 1;
35116  dctx->fseEntropy = 1;
35117  dctx->LLTptr = ddict->entropy.LLTable;
35118  dctx->MLTptr = ddict->entropy.MLTable;
35119  dctx->OFTptr = ddict->entropy.OFTable;
35120  dctx->HUFptr = ddict->entropy.hufTable;
35121  dctx->entropy.rep[0] = ddict->entropy.rep[0];
35122  dctx->entropy.rep[1] = ddict->entropy.rep[1];
35123  dctx->entropy.rep[2] = ddict->entropy.rep[2];
35124  } else {
35125  dctx->litEntropy = 0;
35126  dctx->fseEntropy = 0;
35127  }
35128 }
35129 
35130 
35131 static size_t
35133  ZSTD_dictContentType_e dictContentType)
35134 {
35135  ddict->dictID = 0;
35136  ddict->entropyPresent = 0;
35137  if (dictContentType == ZSTD_dct_rawContent) return 0;
35138 
35139  if (ddict->dictSize < 8) {
35140  if (dictContentType == ZSTD_dct_fullDict)
35141  return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
35142  return 0; /* pure content mode */
35143  }
35144  { U32 const magic = MEM_readLE32(ddict->dictContent);
35145  if (magic != ZSTD_MAGIC_DICTIONARY) {
35146  if (dictContentType == ZSTD_dct_fullDict)
35147  return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
35148  return 0; /* pure content mode */
35149  }
35150  }
35151  ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE);
35152 
35153  /* load entropy tables */
35155  &ddict->entropy, ddict->dictContent, ddict->dictSize)),
35156  dictionary_corrupted, "");
35157  ddict->entropyPresent = 1;
35158  return 0;
35159 }
35160 
35161 
35162 static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
35163  const void* dict, size_t dictSize,
35164  ZSTD_dictLoadMethod_e dictLoadMethod,
35165  ZSTD_dictContentType_e dictContentType)
35166 {
35167  if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
35168  ddict->dictBuffer = NULL;
35169  ddict->dictContent = dict;
35170  if (!dict) dictSize = 0;
35171  } else {
35172  void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem);
35173  ddict->dictBuffer = internalBuffer;
35174  ddict->dictContent = internalBuffer;
35175  if (!internalBuffer) return ERROR(memory_allocation);
35176  ZSTD_memcpy(internalBuffer, dict, dictSize);
35177  }
35178  ddict->dictSize = dictSize;
35179  ddict->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
35180 
35181  /* parse dictionary content */
35182  FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , "");
35183 
35184  return 0;
35185 }
35186 
35187 ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
35188  ZSTD_dictLoadMethod_e dictLoadMethod,
35189  ZSTD_dictContentType_e dictContentType,
35190  ZSTD_customMem customMem)
35191 {
35192  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
35193 
35194  { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem);
35195  if (ddict == NULL) return NULL;
35196  ddict->cMem = customMem;
35197  { size_t const initResult = ZSTD_initDDict_internal(ddict,
35198  dict, dictSize,
35199  dictLoadMethod, dictContentType);
35200  if (ZSTD_isError(initResult)) {
35201  ZSTD_freeDDict(ddict);
35202  return NULL;
35203  } }
35204  return ddict;
35205  }
35207 
35212 ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
35213 {
35214  ZSTD_customMem const allocator = { NULL, NULL, NULL };
35215  return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator);
35217 
35222 ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
35224  ZSTD_customMem const allocator = { NULL, NULL, NULL };
35225  return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator);
35226 }
35227 
35228 
35230  void* sBuffer, size_t sBufferSize,
35231  const void* dict, size_t dictSize,
35232  ZSTD_dictLoadMethod_e dictLoadMethod,
35233  ZSTD_dictContentType_e dictContentType)
35234 {
35235  size_t const neededSpace = sizeof(ZSTD_DDict)
35236  + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
35237  ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer;
35238  assert(sBuffer != NULL);
35239  assert(dict != NULL);
35240  if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */
35241  if (sBufferSize < neededSpace) return NULL;
35242  if (dictLoadMethod == ZSTD_dlm_byCopy) {
35243  ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */
35244  dict = ddict+1;
35245  }
35247  dict, dictSize,
35248  ZSTD_dlm_byRef, dictContentType) ))
35249  return NULL;
35250  return ddict;
35251 }
35252 
35253 
35254 size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
35255 {
35256  if (ddict==NULL) return 0; /* support free on NULL */
35257  { ZSTD_customMem const cMem = ddict->cMem;
35258  ZSTD_customFree(ddict->dictBuffer, cMem);
35259  ZSTD_customFree(ddict, cMem);
35260  return 0;
35261  }
35262 }
35263 
35267 size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
35268 {
35269  return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
35270 }
35271 
35272 size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
35273 {
35274  if (ddict==NULL) return 0; /* support sizeof on NULL */
35275  return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;
35277 
35282 unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
35283 {
35284  if (ddict==NULL) return 0;
35285  return ddict->dictID;
35286 }
35287 /**** ended inlining decompress/zstd_ddict.c ****/
35288 /**** start inlining decompress/zstd_decompress.c ****/
35289 /*
35290  * Copyright (c) Meta Platforms, Inc. and affiliates.
35291  * All rights reserved.
35292  *
35293  * This source code is licensed under both the BSD-style license (found in the
35294  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
35295  * in the COPYING file in the root directory of this source tree).
35296  * You may select, at your option, one of the above-listed licenses.
35297  */
35298 
35299 
35300 /* ***************************************************************
35301 * Tuning parameters
35302 *****************************************************************/
35309 #ifndef ZSTD_HEAPMODE
35310 # define ZSTD_HEAPMODE 1
35311 #endif
35312 
35317 #ifndef ZSTD_LEGACY_SUPPORT
35318 # define ZSTD_LEGACY_SUPPORT 0
35319 #endif
35320 
35327 #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
35328 # define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
35329 #endif
35330 
35338 #ifndef ZSTD_NO_FORWARD_PROGRESS_MAX
35339 # define ZSTD_NO_FORWARD_PROGRESS_MAX 16
35340 #endif
35341 
35342 
35343 /*-*******************************************************
35344 * Dependencies
35345 *********************************************************/
35346 /**** skipping file: ../common/allocations.h ****/
35347 /**** skipping file: ../common/zstd_deps.h ****/
35348 /**** skipping file: ../common/mem.h ****/
35349 #define FSE_STATIC_LINKING_ONLY
35350 /**** skipping file: ../common/fse.h ****/
35351 /**** skipping file: ../common/huf.h ****/
35352 /**** skipping file: ../common/xxhash.h ****/
35353 /**** skipping file: ../common/zstd_internal.h ****/
35354 /**** skipping file: zstd_decompress_internal.h ****/
35355 /**** skipping file: zstd_ddict.h ****/
35356 /**** start inlining zstd_decompress_block.h ****/
35357 /*
35358  * Copyright (c) Meta Platforms, Inc. and affiliates.
35359  * All rights reserved.
35360  *
35361  * This source code is licensed under both the BSD-style license (found in the
35362  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
35363  * in the COPYING file in the root directory of this source tree).
35364  * You may select, at your option, one of the above-listed licenses.
35365  */
35366 
35367 
35368 #ifndef ZSTD_DEC_BLOCK_H
35369 #define ZSTD_DEC_BLOCK_H
35370 
35371 /*-*******************************************************
35372  * Dependencies
35373  *********************************************************/
35374 /**** skipping file: ../common/zstd_deps.h ****/
35375 /**** skipping file: ../zstd.h ****/
35376 /**** skipping file: ../common/zstd_internal.h ****/
35377 /**** skipping file: zstd_decompress_internal.h ****/
35378 
35379 
35380 /* === Prototypes === */
35381 
35382 /* note: prototypes already published within `zstd.h` :
35383  * ZSTD_decompressBlock()
35384  */
35385 
35386 /* note: prototypes already published within `zstd_internal.h` :
35387  * ZSTD_getcBlockSize()
35388  * ZSTD_decodeSeqHeaders()
35389  */
35390 
35391 
35392  /* Streaming state is used to inform allocation of the literal buffer */
35393 typedef enum {
35394  not_streaming = 0,
35395  is_streaming = 1
35397 
35398 /* ZSTD_decompressBlock_internal() :
35399  * decompress block, starting at `src`,
35400  * into destination buffer `dst`.
35401  * @return : decompressed block size,
35402  * or an error code (which can be tested using ZSTD_isError())
35403  */
35405  void* dst, size_t dstCapacity,
35406  const void* src, size_t srcSize, const int frame, const streaming_operation streaming);
35407 
35408 /* ZSTD_buildFSETable() :
35409  * generate FSE decoding table for one symbol (ll, ml or off)
35410  * this function must be called with valid parameters only
35411  * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.)
35412  * in which case it cannot fail.
35413  * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is
35414  * defined in zstd_decompress_internal.h.
35415  * Internal use only.
35416  */
35418  const short* normalizedCounter, unsigned maxSymbolValue,
35419  const U32* baseValue, const U8* nbAdditionalBits,
35420  unsigned tableLog, void* wksp, size_t wkspSize,
35421  int bmi2);
35422 
35423 /* Internal definition of ZSTD_decompressBlock() to avoid deprecation warnings. */
35425  void* dst, size_t dstCapacity,
35426  const void* src, size_t srcSize);
35427 
35428 
35429 #endif /* ZSTD_DEC_BLOCK_H */
35430 /**** ended inlining zstd_decompress_block.h ****/
35431 /**** skipping file: ../common/bits.h ****/
35432 
35433 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
35434 #error Using excluded file: ../legacy/zstd_legacy.h (re-amalgamate source to fix)
35435 #endif
35436 
35439 /*************************************
35440  * Multiple DDicts Hashset internals *
35441  *************************************/
35442 
35443 #define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
35444 #define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
35445  * Currently, that means a 0.75 load factor.
35446  * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
35447  * the load factor of the ddict hash set.
35448  */
35449 
35450 #define DDICT_HASHSET_TABLE_BASE_SIZE 64
35451 #define DDICT_HASHSET_RESIZE_FACTOR 2
35452 
35453 /* Hash function to determine starting position of dict insertion within the table
35454  * Returns an index between [0, hashSet->ddictPtrTableSize]
35455  */
35456 static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) {
35457  const U64 hash = XXH64(&dictID, sizeof(U32), 0);
35458  /* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */
35459  return hash & (hashSet->ddictPtrTableSize - 1);
35460 }
35461 
35462 /* Adds DDict to a hashset without resizing it.
35463  * If inserting a DDict with a dictID that already exists in the set, replaces the one in the set.
35464  * Returns 0 if successful, or a zstd error code if something went wrong.
35465  */
35466 static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) {
35467  const U32 dictID = ZSTD_getDictID_fromDDict(ddict);
35468  size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
35469  const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
35470  RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!");
35471  DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
35472  while (hashSet->ddictPtrTable[idx] != NULL) {
35473  /* Replace existing ddict if inserting ddict with same dictID */
35474  if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) {
35475  DEBUGLOG(4, "DictID already exists, replacing rather than adding");
35476  hashSet->ddictPtrTable[idx] = ddict;
35477  return 0;
35478  }
35479  idx &= idxRangeMask;
35480  idx++;
35481  }
35482  DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
35483  hashSet->ddictPtrTable[idx] = ddict;
35484  hashSet->ddictPtrCount++;
35485  return 0;
35486 }
35487 
35488 /* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and
35489  * rehashes all values, allocates new table, frees old table.
35490  * Returns 0 on success, otherwise a zstd error code.
35491  */
35492 static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
35493  size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR;
35494  const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem);
35495  const ZSTD_DDict** oldTable = hashSet->ddictPtrTable;
35496  size_t oldTableSize = hashSet->ddictPtrTableSize;
35497  size_t i;
35498 
35499  DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize);
35500  RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!");
35501  hashSet->ddictPtrTable = newTable;
35502  hashSet->ddictPtrTableSize = newTableSize;
35503  hashSet->ddictPtrCount = 0;
35504  for (i = 0; i < oldTableSize; ++i) {
35505  if (oldTable[i] != NULL) {
35506  FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), "");
35507  }
35508  }
35509  ZSTD_customFree((void*)oldTable, customMem);
35510  DEBUGLOG(4, "Finished re-hash");
35511  return 0;
35512 }
35513 
35514 /* Fetches a DDict with the given dictID
35515  * Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL.
35516  */
35517 static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) {
35518  size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
35519  const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
35520  DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
35521  for (;;) {
35522  size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]);
35523  if (currDictID == dictID || currDictID == 0) {
35524  /* currDictID == 0 implies a NULL ddict entry */
35525  break;
35526  } else {
35527  idx &= idxRangeMask; /* Goes to start of table when we reach the end */
35528  idx++;
35529  }
35530  }
35531  DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
35532  return hashSet->ddictPtrTable[idx];
35533 }
35534 
35535 /* Allocates space for and returns a ddict hash set
35536  * The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with.
35537  * Returns NULL if allocation failed.
35538  */
35539 static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
35541  DEBUGLOG(4, "Allocating new hash set");
35542  if (!ret)
35543  return NULL;
35544  ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
35545  if (!ret->ddictPtrTable) {
35546  ZSTD_customFree(ret, customMem);
35547  return NULL;
35548  }
35549  ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
35550  ret->ddictPtrCount = 0;
35551  return ret;
35552 }
35553 
35554 /* Frees the table of ZSTD_DDict* within a hashset, then frees the hashset itself.
35555  * Note: The ZSTD_DDict* within the table are NOT freed.
35556  */
35557 static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
35558  DEBUGLOG(4, "Freeing ddict hash set");
35559  if (hashSet && hashSet->ddictPtrTable) {
35560  ZSTD_customFree((void*)hashSet->ddictPtrTable, customMem);
35561  }
35562  if (hashSet) {
35563  ZSTD_customFree(hashSet, customMem);
35564  }
35565 }
35566 
35567 /* Public function: Adds a DDict into the ZSTD_DDictHashSet, possibly triggering a resize of the hash set.
35568  * Returns 0 on success, or a ZSTD error.
35569  */
35570 static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict, ZSTD_customMem customMem) {
35571  DEBUGLOG(4, "Adding dict ID: %u to hashset with - Count: %zu Tablesize: %zu", ZSTD_getDictID_fromDDict(ddict), hashSet->ddictPtrCount, hashSet->ddictPtrTableSize);
35573  FORWARD_IF_ERROR(ZSTD_DDictHashSet_expand(hashSet, customMem), "");
35574  }
35575  FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, ddict), "");
35576  return 0;
35577 }
35578 
35579 /*-*************************************************************
35580 * Context management
35581 ***************************************************************/
35582 size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
35584  if (dctx==NULL) return 0; /* support sizeof NULL */
35585  return sizeof(*dctx)
35586  + ZSTD_sizeof_DDict(dctx->ddictLocal)
35587  + dctx->inBuffSize + dctx->outBuffSize;
35588 }
35589 
35590 size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
35592 
35593 static size_t ZSTD_startingInputLength(ZSTD_format_e format)
35594 {
35595  size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format);
35596  /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
35597  assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
35598  return startingInputLength;
35599 }
35600 
35601 static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
35603  assert(dctx->streamStage == zdss_init);
35604  dctx->format = ZSTD_f_zstd1;
35607  dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
35608  dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
35609  dctx->disableHufAsm = 0;
35610 }
35611 
35612 static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
35613 {
35614  dctx->staticSize = 0;
35615  dctx->ddict = NULL;
35616  dctx->ddictLocal = NULL;
35617  dctx->dictEnd = NULL;
35618  dctx->ddictIsCold = 0;
35619  dctx->dictUses = ZSTD_dont_use;
35620  dctx->inBuff = NULL;
35621  dctx->inBuffSize = 0;
35622  dctx->outBuffSize = 0;
35623  dctx->streamStage = zdss_init;
35624 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
35625  dctx->legacyContext = NULL;
35626  dctx->previousLegacyVersion = 0;
35627 #endif
35628  dctx->noForwardProgress = 0;
35629  dctx->oversizedDuration = 0;
35630 #if DYNAMIC_BMI2
35631  dctx->bmi2 = ZSTD_cpuSupportsBmi2();
35632 #endif
35633  dctx->ddictSet = NULL;
35635 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
35636  dctx->dictContentEndForFuzzing = NULL;
35637 #endif
35638 }
35639 
35640 ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
35641 {
35642  ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;
35644  if ((size_t)workspace & 7) return NULL; /* 8-aligned */
35645  if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
35646 
35647  ZSTD_initDCtx_internal(dctx);
35648  dctx->staticSize = workspaceSize;
35649  dctx->inBuff = (char*)(dctx+1);
35650  return dctx;
35651 }
35652 
35653 static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) {
35654  if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
35655 
35656  { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem);
35657  if (!dctx) return NULL;
35658  dctx->customMem = customMem;
35660  return dctx;
35661  }
35662 }
35663 
35664 ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
35666  return ZSTD_createDCtx_internal(customMem);
35667 }
35668 
35670 {
35671  DEBUGLOG(3, "ZSTD_createDCtx");
35672  return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
35674 
35675 static void ZSTD_clearDict(ZSTD_DCtx* dctx)
35676 {
35677  ZSTD_freeDDict(dctx->ddictLocal);
35678  dctx->ddictLocal = NULL;
35679  dctx->ddict = NULL;
35680  dctx->dictUses = ZSTD_dont_use;
35681 }
35682 
35683 size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
35684 {
35685  if (dctx==NULL) return 0; /* support free on NULL */
35686  RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
35687  { ZSTD_customMem const cMem = dctx->customMem;
35688  ZSTD_clearDict(dctx);
35689  ZSTD_customFree(dctx->inBuff, cMem);
35690  dctx->inBuff = NULL;
35691 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
35692  if (dctx->legacyContext)
35693  ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
35694 #endif
35695  if (dctx->ddictSet) {
35696  ZSTD_freeDDictHashSet(dctx->ddictSet, cMem);
35697  dctx->ddictSet = NULL;
35698  }
35699  ZSTD_customFree(dctx, cMem);
35700  return 0;
35701  }
35702 }
35703 
35704 /* no longer useful */
35705 void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
35706 {
35707  size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);
35708  ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */
35710 
35711 /* Given a dctx with a digested frame params, re-selects the correct ZSTD_DDict based on
35712  * the requested dict ID from the frame. If there exists a reference to the correct ZSTD_DDict, then
35713  * accordingly sets the ddict to be used to decompress the frame.
35714  *
35715  * If no DDict is found, then no action is taken, and the ZSTD_DCtx::ddict remains as-is.
35716  *
35717  * ZSTD_d_refMultipleDDicts must be enabled for this function to be called.
35718  */
35719 static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) {
35720  assert(dctx->refMultipleDDicts && dctx->ddictSet);
35721  DEBUGLOG(4, "Adjusting DDict based on requested dict ID from frame");
35722  if (dctx->ddict) {
35723  const ZSTD_DDict* frameDDict = ZSTD_DDictHashSet_getDDict(dctx->ddictSet, dctx->fParams.dictID);
35724  if (frameDDict) {
35725  DEBUGLOG(4, "DDict found!");
35726  ZSTD_clearDict(dctx);
35727  dctx->dictID = dctx->fParams.dictID;
35728  dctx->ddict = frameDDict;
35730  }
35731  }
35732 }
35733 
35735 /*-*************************************************************
35736  * Frame header decoding
35737  ***************************************************************/
35738 
35744 unsigned ZSTD_isFrame(const void* buffer, size_t size)
35745 {
35746  if (size < ZSTD_FRAMEIDSIZE) return 0;
35747  { U32 const magic = MEM_readLE32(buffer);
35748  if (magic == ZSTD_MAGICNUMBER) return 1;
35749  if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
35750  }
35751 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
35752  if (ZSTD_isLegacy(buffer, size)) return 1;
35753 #endif
35754  return 0;
35755 }
35756 
35761 unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size)
35762 {
35763  if (size < ZSTD_FRAMEIDSIZE) return 0;
35764  { U32 const magic = MEM_readLE32(buffer);
35766  }
35767  return 0;
35768 }
35769 
35775 static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
35776 {
35777  size_t const minInputSize = ZSTD_startingInputLength(format);
35778  RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, "");
35779 
35780  { BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
35781  U32 const dictID= fhd & 3;
35782  U32 const singleSegment = (fhd >> 5) & 1;
35783  U32 const fcsId = fhd >> 6;
35784  return minInputSize + !singleSegment
35785  + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
35786  + (singleSegment && !fcsId);
35787  }
35788 }
35789 
35794 size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
35795 {
35796  return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
35797 }
35798 
35799 
35806 size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
35807 {
35808  const BYTE* ip = (const BYTE*)src;
35809  size_t const minInputSize = ZSTD_startingInputLength(format);
35810 
35811  DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize);
35812 
35813  if (srcSize > 0) {
35814  /* note : technically could be considered an assert(), since it's an invalid entry */
35815  RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0");
35816  }
35817  if (srcSize < minInputSize) {
35818  if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) {
35819  /* when receiving less than @minInputSize bytes,
35820  * control these bytes at least correspond to a supported magic number
35821  * in order to error out early if they don't.
35822  **/
35823  size_t const toCopy = MIN(4, srcSize);
35824  unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER);
35825  assert(src != NULL);
35826  ZSTD_memcpy(hbuf, src, toCopy);
35827  if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) {
35828  /* not a zstd frame : let's check if it's a skippable frame */
35830  ZSTD_memcpy(hbuf, src, toCopy);
35832  RETURN_ERROR(prefix_unknown,
35833  "first bytes don't correspond to any supported magic number");
35834  } } }
35835  return minInputSize;
35836  }
35837 
35838  ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */
35839  if ( (format != ZSTD_f_zstd1_magicless)
35840  && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
35842  /* skippable frame */
35843  if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
35844  return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
35845  ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
35846  zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
35847  zfhPtr->frameType = ZSTD_skippableFrame;
35848  return 0;
35849  }
35850  RETURN_ERROR(prefix_unknown, "");
35851  }
35852 
35853  /* ensure there is enough `srcSize` to fully read/decode frame header */
35854  { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);
35855  if (srcSize < fhsize) return fhsize;
35856  zfhPtr->headerSize = (U32)fhsize;
35857  }
35858 
35859  { BYTE const fhdByte = ip[minInputSize-1];
35860  size_t pos = minInputSize;
35861  U32 const dictIDSizeCode = fhdByte&3;
35862  U32 const checksumFlag = (fhdByte>>2)&1;
35863  U32 const singleSegment = (fhdByte>>5)&1;
35864  U32 const fcsID = fhdByte>>6;
35865  U64 windowSize = 0;
35866  U32 dictID = 0;
35867  U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;
35868  RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,
35869  "reserved bits, must be zero");
35870 
35871  if (!singleSegment) {
35872  BYTE const wlByte = ip[pos++];
35873  U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
35874  RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, "");
35875  windowSize = (1ULL << windowLog);
35876  windowSize += (windowSize >> 3) * (wlByte&7);
35877  }
35878  switch(dictIDSizeCode)
35879  {
35880  default:
35881  assert(0); /* impossible */
35883  case 0 : break;
35884  case 1 : dictID = ip[pos]; pos++; break;
35885  case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
35886  case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
35887  }
35888  switch(fcsID)
35889  {
35890  default:
35891  assert(0); /* impossible */
35893  case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
35894  case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
35895  case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
35896  case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
35897  }
35898  if (singleSegment) windowSize = frameContentSize;
35899 
35900  zfhPtr->frameType = ZSTD_frame;
35901  zfhPtr->frameContentSize = frameContentSize;
35902  zfhPtr->windowSize = windowSize;
35903  zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
35904  zfhPtr->dictID = dictID;
35905  zfhPtr->checksumFlag = checksumFlag;
35906  }
35907  return 0;
35908 }
35909 
35916 size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
35917 {
35918  return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
35919 }
35920 
35926 unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
35927 {
35928 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
35929  if (ZSTD_isLegacy(src, srcSize)) {
35930  unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize);
35931  return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
35932  }
35933 #endif
35934  { ZSTD_frameHeader zfh;
35935  if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)
35936  return ZSTD_CONTENTSIZE_ERROR;
35937  if (zfh.frameType == ZSTD_skippableFrame) {
35938  return 0;
35939  } else {
35940  return zfh.frameContentSize;
35941  } }
35942 }
35943 
35944 static size_t readSkippableFrameSize(void const* src, size_t srcSize)
35945 {
35946  size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
35947  U32 sizeU32;
35948 
35949  RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
35950 
35951  sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
35952  RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
35953  frameParameter_unsupported, "");
35954  { size_t const skippableSize = skippableHeaderSize + sizeU32;
35955  RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
35956  return skippableSize;
35957  }
35958 }
35959 
35971 size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
35972  unsigned* magicVariant, /* optional, can be NULL */
35973  const void* src, size_t srcSize)
35974 {
35975  RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
35976 
35977  { U32 const magicNumber = MEM_readLE32(src);
35978  size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
35979  size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
35980 
35981  /* check input validity */
35982  RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
35983  RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
35984  RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
35985 
35986  /* deliver payload */
35987  if (skippableContentSize > 0 && dst != NULL)
35988  ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
35989  if (magicVariant != NULL)
35990  *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
35991  return skippableContentSize;
35992  }
35993 }
35994 
36000 unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
36001 {
36002  unsigned long long totalDstSize = 0;
36003 
36004  while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) {
36005  U32 const magicNumber = MEM_readLE32(src);
36006 
36007  if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
36008  size_t const skippableSize = readSkippableFrameSize(src, srcSize);
36009  if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR;
36010  assert(skippableSize <= srcSize);
36011 
36012  src = (const BYTE *)src + skippableSize;
36013  srcSize -= skippableSize;
36014  continue;
36015  }
36016 
36017  { unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize);
36018  if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs;
36019 
36020  if (totalDstSize + fcs < totalDstSize)
36021  return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */
36022  totalDstSize += fcs;
36023  }
36024  /* skip to next frame */
36025  { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
36026  if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR;
36027  assert(frameSrcSize <= srcSize);
36028 
36029  src = (const BYTE *)src + frameSrcSize;
36030  srcSize -= frameSrcSize;
36031  }
36032  } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
36033 
36034  if (srcSize) return ZSTD_CONTENTSIZE_ERROR;
36035 
36036  return totalDstSize;
36038 
36047 unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
36048 {
36049  unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
36051  return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;
36052 }
36053 
36054 
36059 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
36060 {
36061  size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
36062  if (ZSTD_isError(result)) return result; /* invalid header */
36063  RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
36064 
36065  /* Reference DDict requested by frame if dctx references multiple ddicts */
36066  if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts && dctx->ddictSet) {
36068  }
36069 
36070 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
36071  /* Skip the dictID check in fuzzing mode, because it makes the search
36072  * harder.
36073  */
36074  RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
36075  dictionary_wrong, "");
36076 #endif
36077  dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0;
36078  if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0);
36079  dctx->processedCSize += headerSize;
36080  return 0;
36082 
36084 {
36085  ZSTD_frameSizeInfo frameSizeInfo;
36086  frameSizeInfo.compressedSize = ret;
36087  frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
36088  return frameSizeInfo;
36089 }
36090 
36091 static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
36092 {
36093  ZSTD_frameSizeInfo frameSizeInfo;
36094  ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
36095 
36096 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
36097  if (ZSTD_isLegacy(src, srcSize))
36098  return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
36099 #endif
36100 
36101  if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
36103  frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
36104  assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
36105  frameSizeInfo.compressedSize <= srcSize);
36106  return frameSizeInfo;
36107  } else {
36108  const BYTE* ip = (const BYTE*)src;
36109  const BYTE* const ipstart = ip;
36110  size_t remainingSize = srcSize;
36111  size_t nbBlocks = 0;
36112  ZSTD_frameHeader zfh;
36113 
36114  /* Extract Frame Header */
36115  { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
36116  if (ZSTD_isError(ret))
36117  return ZSTD_errorFrameSizeInfo(ret);
36118  if (ret > 0)
36119  return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
36120  }
36121 
36122  ip += zfh.headerSize;
36123  remainingSize -= zfh.headerSize;
36124 
36125  /* Iterate over each block */
36126  while (1) {
36127  blockProperties_t blockProperties;
36128  size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
36129  if (ZSTD_isError(cBlockSize))
36130  return ZSTD_errorFrameSizeInfo(cBlockSize);
36131 
36132  if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
36133  return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
36134 
36135  ip += ZSTD_blockHeaderSize + cBlockSize;
36136  remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
36137  nbBlocks++;
36138 
36139  if (blockProperties.lastBlock) break;
36140  }
36141 
36142  /* Final frame content checksum */
36143  if (zfh.checksumFlag) {
36144  if (remainingSize < 4)
36145  return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
36146  ip += 4;
36147  }
36148 
36149  frameSizeInfo.nbBlocks = nbBlocks;
36150  frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
36151  frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
36152  ? zfh.frameContentSize
36153  : (unsigned long long)nbBlocks * zfh.blockSizeMax;
36154  return frameSizeInfo;
36155  }
36156 }
36157 
36163 size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
36164 {
36166  return frameSizeInfo.compressedSize;
36167 }
36168 
36175 unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
36176 {
36177  unsigned long long bound = 0;
36178  /* Iterate over each frame */
36179  while (srcSize > 0) {
36180  ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
36181  size_t const compressedSize = frameSizeInfo.compressedSize;
36182  unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
36184  return ZSTD_CONTENTSIZE_ERROR;
36186  src = (const BYTE*)src + compressedSize;
36188  bound += decompressedBound;
36189  }
36190  return bound;
36191 }
36192 
36193 size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
36194 {
36195  size_t margin = 0;
36196  unsigned maxBlockSize = 0;
36197 
36198  /* Iterate over each frame */
36199  while (srcSize > 0) {
36200  ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
36201  size_t const compressedSize = frameSizeInfo.compressedSize;
36202  unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
36203  ZSTD_frameHeader zfh;
36204 
36205  FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), "");
36206  if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
36207  return ERROR(corruption_detected);
36208 
36209  if (zfh.frameType == ZSTD_frame) {
36210  /* Add the frame header to our margin */
36211  margin += zfh.headerSize;
36212  /* Add the checksum to our margin */
36213  margin += zfh.checksumFlag ? 4 : 0;
36214  /* Add 3 bytes per block */
36215  margin += 3 * frameSizeInfo.nbBlocks;
36216 
36217  /* Compute the max block size */
36218  maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax);
36219  } else {
36220  assert(zfh.frameType == ZSTD_skippableFrame);
36221  /* Add the entire skippable frame size to our margin. */
36222  margin += compressedSize;
36223  }
36224 
36226  src = (const BYTE*)src + compressedSize;
36228  }
36229 
36230  /* Add the max block size back to the margin. */
36231  margin += maxBlockSize;
36233  return margin;
36234 }
36235 
36236 /*-*************************************************************
36237  * Frame decoding
36238  ***************************************************************/
36239 
36242 size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
36243 {
36244  DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize);
36245  ZSTD_checkContinuity(dctx, blockStart, blockSize);
36246  dctx->previousDstEnd = (const char*)blockStart + blockSize;
36247  return blockSize;
36248 }
36249 
36250 
36251 static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
36252  const void* src, size_t srcSize)
36253 {
36254  DEBUGLOG(5, "ZSTD_copyRawBlock");
36255  RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
36256  if (dst == NULL) {
36257  if (srcSize == 0) return 0;
36258  RETURN_ERROR(dstBuffer_null, "");
36259  }
36260  ZSTD_memmove(dst, src, srcSize);
36261  return srcSize;
36262 }
36263 
36264 static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
36265  BYTE b,
36266  size_t regenSize)
36268  RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
36269  if (dst == NULL) {
36270  if (regenSize == 0) return 0;
36271  RETURN_ERROR(dstBuffer_null, "");
36272  }
36273  ZSTD_memset(dst, b, regenSize);
36274  return regenSize;
36275 }
36276 
36277 static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
36278 {
36279 #if ZSTD_TRACE
36280  if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) {
36281  ZSTD_Trace trace;
36282  ZSTD_memset(&trace, 0, sizeof(trace));
36283  trace.version = ZSTD_VERSION_NUMBER;
36284  trace.streaming = streaming;
36285  if (dctx->ddict) {
36286  trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict);
36287  trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict);
36288  trace.dictionaryIsCold = dctx->ddictIsCold;
36289  }
36290  trace.uncompressedSize = (size_t)uncompressedSize;
36291  trace.compressedSize = (size_t)compressedSize;
36292  trace.dctx = dctx;
36293  ZSTD_trace_decompress_end(dctx->traceCtx, &trace);
36294  }
36295 #else
36296  (void)dctx;
36297  (void)uncompressedSize;
36299  (void)streaming;
36300 #endif
36301 }
36302 
36303 
36308 static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
36309  void* dst, size_t dstCapacity,
36310  const void** srcPtr, size_t *srcSizePtr)
36311 {
36312  const BYTE* const istart = (const BYTE*)(*srcPtr);
36313  const BYTE* ip = istart;
36314  BYTE* const ostart = (BYTE*)dst;
36315  BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart;
36316  BYTE* op = ostart;
36317  size_t remainingSrcSize = *srcSizePtr;
36318 
36319  DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr);
36320 
36321  /* check */
36323  remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize,
36324  srcSize_wrong, "");
36325 
36326  /* Frame Header */
36327  { size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal(
36328  ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format);
36329  if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
36330  RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
36331  srcSize_wrong, "");
36332  FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , "");
36333  ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
36334  }
36335 
36336  /* Loop on each block */
36337  while (1) {
36338  BYTE* oBlockEnd = oend;
36339  size_t decodedSize;
36340  blockProperties_t blockProperties;
36341  size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
36342  if (ZSTD_isError(cBlockSize)) return cBlockSize;
36343 
36345  remainingSrcSize -= ZSTD_blockHeaderSize;
36346  RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
36347 
36348  if (ip >= op && ip < oBlockEnd) {
36349  /* We are decompressing in-place. Limit the output pointer so that we
36350  * don't overwrite the block that we are currently reading. This will
36351  * fail decompression if the input & output pointers aren't spaced
36352  * far enough apart.
36353  *
36354  * This is important to set, even when the pointers are far enough
36355  * apart, because ZSTD_decompressBlock_internal() can decide to store
36356  * literals in the output buffer, after the block it is decompressing.
36357  * Since we don't want anything to overwrite our input, we have to tell
36358  * ZSTD_decompressBlock_internal to never write past ip.
36359  *
36360  * See ZSTD_allocateLiteralsBuffer() for reference.
36361  */
36362  oBlockEnd = op + (ip - op);
36363  }
36364 
36365  switch(blockProperties.blockType)
36366  {
36367  case bt_compressed:
36368  decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming);
36369  break;
36370  case bt_raw :
36371  /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
36372  decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
36373  break;
36374  case bt_rle :
36375  decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
36376  break;
36377  case bt_reserved :
36378  default:
36379  RETURN_ERROR(corruption_detected, "invalid block type");
36380  }
36381 
36382  if (ZSTD_isError(decodedSize)) return decodedSize;
36383  if (dctx->validateChecksum)
36384  XXH64_update(&dctx->xxhState, op, decodedSize);
36385  if (decodedSize != 0)
36386  op += decodedSize;
36387  assert(ip != NULL);
36388  ip += cBlockSize;
36389  remainingSrcSize -= cBlockSize;
36390  if (blockProperties.lastBlock) break;
36391  }
36392 
36393  if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
36394  RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
36395  corruption_detected, "");
36396  }
36397  if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
36398  RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, "");
36399  if (!dctx->forceIgnoreChecksum) {
36400  U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
36401  U32 checkRead;
36402  checkRead = MEM_readLE32(ip);
36403  RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
36404  }
36405  ip += 4;
36406  remainingSrcSize -= 4;
36407  }
36408  ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
36409  /* Allow caller to get size read */
36410  DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %zi, consuming %zi bytes of input", op-ostart, ip - (const BYTE*)*srcPtr);
36411  *srcPtr = ip;
36412  *srcSizePtr = remainingSrcSize;
36413  return (size_t)(op-ostart);
36414 }
36415 
36416 static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
36417  void* dst, size_t dstCapacity,
36418  const void* src, size_t srcSize,
36419  const void* dict, size_t dictSize,
36420  const ZSTD_DDict* ddict)
36421 {
36422  void* const dststart = dst;
36423  int moreThan1Frame = 0;
36424 
36425  DEBUGLOG(5, "ZSTD_decompressMultiFrame");
36426  assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */
36427 
36428  if (ddict) {
36429  dict = ZSTD_DDict_dictContent(ddict);
36430  dictSize = ZSTD_DDict_dictSize(ddict);
36431  }
36432 
36433  while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
36434 
36435 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
36436  if (ZSTD_isLegacy(src, srcSize)) {
36437  size_t decodedSize;
36438  size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
36439  if (ZSTD_isError(frameSize)) return frameSize;
36440  RETURN_ERROR_IF(dctx->staticSize, memory_allocation,
36441  "legacy support is not compatible with static dctx");
36442 
36443  decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
36444  if (ZSTD_isError(decodedSize)) return decodedSize;
36445 
36446  assert(decodedSize <= dstCapacity);
36447  dst = (BYTE*)dst + decodedSize;
36448  dstCapacity -= decodedSize;
36449 
36450  src = (const BYTE*)src + frameSize;
36451  srcSize -= frameSize;
36452 
36453  continue;
36454  }
36455 #endif
36456 
36457  if (srcSize >= 4) {
36458  U32 const magicNumber = MEM_readLE32(src);
36459  DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
36460  if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
36461  /* skippable frame detected : skip it */
36462  size_t const skippableSize = readSkippableFrameSize(src, srcSize);
36463  FORWARD_IF_ERROR(skippableSize, "invalid skippable frame");
36464  assert(skippableSize <= srcSize);
36465 
36466  src = (const BYTE *)src + skippableSize;
36467  srcSize -= skippableSize;
36468  continue; /* check next frame */
36469  } }
36470 
36471  if (ddict) {
36472  /* we were called from ZSTD_decompress_usingDDict */
36474  } else {
36475  /* this will initialize correctly with no dict if dict == NULL, so
36476  * use this in all cases but ddict */
36477  FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), "");
36478  }
36479  ZSTD_checkContinuity(dctx, dst, dstCapacity);
36480 
36481  { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
36482  &src, &srcSize);
36485  && (moreThan1Frame==1),
36486  srcSize_wrong,
36487  "At least one frame successfully completed, "
36488  "but following bytes are garbage: "
36489  "it's more likely to be a srcSize error, "
36490  "specifying more input bytes than size of frame(s). "
36491  "Note: one could be unlucky, it might be a corruption error instead, "
36492  "happening right at the place where we expect zstd magic bytes. "
36493  "But this is _much_ less likely than a srcSize field error.");
36494  if (ZSTD_isError(res)) return res;
36495  assert(res <= dstCapacity);
36496  if (res != 0)
36497  dst = (BYTE*)dst + res;
36498  dstCapacity -= res;
36499  }
36500  moreThan1Frame = 1;
36501  } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
36502 
36503  RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
36504 
36505  return (size_t)((BYTE*)dst - (BYTE*)dststart);
36506 }
36509  void* dst, size_t dstCapacity,
36510  const void* src, size_t srcSize,
36511  const void* dict, size_t dictSize)
36512 {
36513  return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
36514 }
36515 
36516 
36517 static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
36518 {
36519  switch (dctx->dictUses) {
36520  default:
36521  assert(0 /* Impossible */);
36523  case ZSTD_dont_use:
36525  return NULL;
36526  case ZSTD_use_indefinitely:
36527  return dctx->ddict;
36528  case ZSTD_use_once:
36529  dctx->dictUses = ZSTD_dont_use;
36530  return dctx->ddict;
36531  }
36532 }
36533 
36534 size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
36535 {
36536  return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));
36537 }
36538 
36539 
36540 size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
36541 {
36542 #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
36543  size_t regenSize;
36544  ZSTD_DCtx* const dctx = ZSTD_createDCtx_internal(ZSTD_defaultCMem);
36545  RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!");
36546  regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
36547  ZSTD_freeDCtx(dctx);
36548  return regenSize;
36549 #else /* stack mode */
36550  ZSTD_DCtx dctx;
36552  return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
36553 #endif
36554 }
36555 
36556 
36557 /*-**************************************
36558 * Advanced Streaming Decompression API
36559 * Bufferless and synchronous
36560 ****************************************/
36561 size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
36562 
36573 static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) {
36574  if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock))
36575  return dctx->expected;
36576  if (dctx->bType != bt_raw)
36577  return dctx->expected;
36578  return BOUNDED(1, inputSize, dctx->expected);
36579 }
36580 
36581 ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
36582  switch(dctx->stage)
36583  {
36584  default: /* should not happen */
36585  assert(0);
36590  return ZSTDnit_frameHeader;
36592  return ZSTDnit_blockHeader;
36594  return ZSTDnit_block;
36596  return ZSTDnit_lastBlock;
36597  case ZSTDds_checkChecksum:
36598  return ZSTDnit_checksum;
36601  case ZSTDds_skipFrame:
36602  return ZSTDnit_skippableFrame;
36603  }
36604 }
36605 
36606 static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }
36607 
36612 size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
36613 {
36614  DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
36615  /* Sanity check */
36616  RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed");
36617  ZSTD_checkContinuity(dctx, dst, dstCapacity);
36618 
36619  dctx->processedCSize += srcSize;
36620 
36621  switch (dctx->stage)
36622  {
36624  assert(src != NULL);
36625  if (dctx->format == ZSTD_f_zstd1) { /* allows header */
36626  assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */
36627  if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
36628  ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
36629  dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */
36631  return 0;
36632  } }
36634  if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
36635  ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
36636  dctx->expected = dctx->headerSize - srcSize;
36638  return 0;
36639 
36641  assert(src != NULL);
36642  ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
36646  return 0;
36647 
36649  { blockProperties_t bp;
36650  size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
36651  if (ZSTD_isError(cBlockSize)) return cBlockSize;
36652  RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, "Block Size Exceeds Maximum");
36653  dctx->expected = cBlockSize;
36654  dctx->bType = bp.blockType;
36655  dctx->rleSize = bp.origSize;
36656  if (cBlockSize) {
36658  return 0;
36659  }
36660  /* empty block */
36661  if (bp.lastBlock) {
36662  if (dctx->fParams.checksumFlag) {
36663  dctx->expected = 4;
36664  dctx->stage = ZSTDds_checkChecksum;
36665  } else {
36666  dctx->expected = 0; /* end of frame */
36668  }
36669  } else {
36670  dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */
36672  }
36673  return 0;
36674  }
36675 
36678  DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock");
36679  { size_t rSize;
36680  switch(dctx->bType)
36681  {
36682  case bt_compressed:
36683  DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
36684  rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming);
36685  dctx->expected = 0; /* Streaming not supported */
36686  break;
36687  case bt_raw :
36688  assert(srcSize <= dctx->expected);
36689  rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
36690  FORWARD_IF_ERROR(rSize, "ZSTD_copyRawBlock failed");
36691  assert(rSize == srcSize);
36692  dctx->expected -= rSize;
36693  break;
36694  case bt_rle :
36695  rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);
36696  dctx->expected = 0; /* Streaming not supported */
36697  break;
36698  case bt_reserved : /* should never happen */
36699  default:
36700  RETURN_ERROR(corruption_detected, "invalid block type");
36701  }
36702  FORWARD_IF_ERROR(rSize, "");
36703  RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
36704  DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
36705  dctx->decodedSize += rSize;
36706  if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize);
36707  dctx->previousDstEnd = (char*)dst + rSize;
36708 
36709  /* Stay on the same stage until we are finished streaming the block. */
36710  if (dctx->expected > 0) {
36711  return rSize;
36712  }
36713 
36714  if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
36715  DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
36717  dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
36718  && dctx->decodedSize != dctx->fParams.frameContentSize,
36719  corruption_detected, "");
36720  if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
36721  dctx->expected = 4;
36722  dctx->stage = ZSTDds_checkChecksum;
36723  } else {
36724  ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
36725  dctx->expected = 0; /* ends here */
36727  }
36728  } else {
36731  }
36732  return rSize;
36733  }
36734 
36735  case ZSTDds_checkChecksum:
36736  assert(srcSize == 4); /* guaranteed by dctx->expected */
36737  {
36738  if (dctx->validateChecksum) {
36739  U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
36740  U32 const check32 = MEM_readLE32(src);
36741  DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
36742  RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
36743  }
36744  ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
36745  dctx->expected = 0;
36747  return 0;
36748  }
36749 
36751  assert(src != NULL);
36752  assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
36753  ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
36754  dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
36755  dctx->stage = ZSTDds_skipFrame;
36756  return 0;
36757 
36758  case ZSTDds_skipFrame:
36759  dctx->expected = 0;
36761  return 0;
36762 
36763  default:
36764  assert(0); /* impossible */
36765  RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
36766  }
36767 }
36768 
36769 
36770 static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
36771 {
36772  dctx->dictEnd = dctx->previousDstEnd;
36773  dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
36774  dctx->prefixStart = dict;
36775  dctx->previousDstEnd = (const char*)dict + dictSize;
36776 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
36777  dctx->dictContentBeginForFuzzing = dctx->prefixStart;
36778  dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
36779 #endif
36780  return 0;
36781 }
36782 
36786 size_t
36788  const void* const dict, size_t const dictSize)
36789 {
36790  const BYTE* dictPtr = (const BYTE*)dict;
36791  const BYTE* const dictEnd = dictPtr + dictSize;
36792 
36793  RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small");
36794  assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */
36795  dictPtr += 8; /* skip header = magic + dictID */
36796 
36797  ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable));
36798  ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable));
36799  ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE);
36800  { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */
36801  size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable);
36802 #ifdef HUF_FORCE_DECOMPRESS_X1
36803  /* in minimal huffman, we always use X1 variants */
36804  size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
36805  dictPtr, dictEnd - dictPtr,
36806  workspace, workspaceSize, /* flags */ 0);
36807 #else
36808  size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
36809  dictPtr, (size_t)(dictEnd - dictPtr),
36810  workspace, workspaceSize, /* flags */ 0);
36811 #endif
36812  RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
36813  dictPtr += hSize;
36814  }
36815 
36816  { short offcodeNCount[MaxOff+1];
36817  unsigned offcodeMaxValue = MaxOff, offcodeLog;
36818  size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
36819  RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
36820  RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, "");
36821  RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
36822  ZSTD_buildFSETable( entropy->OFTable,
36823  offcodeNCount, offcodeMaxValue,
36824  OF_base, OF_bits,
36825  offcodeLog,
36826  entropy->workspace, sizeof(entropy->workspace),
36827  /* bmi2 */0);
36828  dictPtr += offcodeHeaderSize;
36829  }
36830 
36831  { short matchlengthNCount[MaxML+1];
36832  unsigned matchlengthMaxValue = MaxML, matchlengthLog;
36833  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
36834  RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
36835  RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, "");
36836  RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
36837  ZSTD_buildFSETable( entropy->MLTable,
36838  matchlengthNCount, matchlengthMaxValue,
36839  ML_base, ML_bits,
36840  matchlengthLog,
36841  entropy->workspace, sizeof(entropy->workspace),
36842  /* bmi2 */ 0);
36843  dictPtr += matchlengthHeaderSize;
36844  }
36845 
36846  { short litlengthNCount[MaxLL+1];
36847  unsigned litlengthMaxValue = MaxLL, litlengthLog;
36848  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
36849  RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
36850  RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, "");
36851  RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
36852  ZSTD_buildFSETable( entropy->LLTable,
36853  litlengthNCount, litlengthMaxValue,
36854  LL_base, LL_bits,
36855  litlengthLog,
36856  entropy->workspace, sizeof(entropy->workspace),
36857  /* bmi2 */ 0);
36858  dictPtr += litlengthHeaderSize;
36859  }
36860 
36861  RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
36862  { int i;
36863  size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
36864  for (i=0; i<3; i++) {
36865  U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
36866  RETURN_ERROR_IF(rep==0 || rep > dictContentSize,
36867  dictionary_corrupted, "");
36868  entropy->rep[i] = rep;
36869  } }
36870 
36871  return (size_t)(dictPtr - (const BYTE*)dict);
36872 }
36873 
36874 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
36875 {
36876  if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
36877  { U32 const magic = MEM_readLE32(dict);
36878  if (magic != ZSTD_MAGIC_DICTIONARY) {
36879  return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
36880  } }
36881  dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
36882 
36883  /* load entropy tables */
36884  { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
36885  RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, "");
36886  dict = (const char*)dict + eSize;
36887  dictSize -= eSize;
36888  }
36889  dctx->litEntropy = dctx->fseEntropy = 1;
36890 
36891  /* reference dictionary content */
36892  return ZSTD_refDictContent(dctx, dict, dictSize);
36893 }
36894 
36895 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
36896 {
36897  assert(dctx != NULL);
36898 #if ZSTD_TRACE
36899  dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0;
36900 #endif
36901  dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
36903  dctx->processedCSize = 0;
36904  dctx->decodedSize = 0;
36905  dctx->previousDstEnd = NULL;
36906  dctx->prefixStart = NULL;
36907  dctx->virtualStart = NULL;
36908  dctx->dictEnd = NULL;
36909  dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
36910  dctx->litEntropy = dctx->fseEntropy = 0;
36911  dctx->dictID = 0;
36913  ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
36914  ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
36915  dctx->LLTptr = dctx->entropy.LLTable;
36916  dctx->MLTptr = dctx->entropy.MLTable;
36917  dctx->OFTptr = dctx->entropy.OFTable;
36918  dctx->HUFptr = dctx->entropy.hufTable;
36919  return 0;
36920 }
36921 
36922 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
36923 {
36925  if (dict && dictSize)
36927  ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
36928  dictionary_corrupted, "");
36929  return 0;
36930 }
36931 
36932 
36933 /* ====== ZSTD_DDict ====== */
36934 
36935 size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
36936 {
36937  DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict");
36938  assert(dctx != NULL);
36939  if (ddict) {
36940  const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);
36941  size_t const dictSize = ZSTD_DDict_dictSize(ddict);
36942  const void* const dictEnd = dictStart + dictSize;
36943  dctx->ddictIsCold = (dctx->dictEnd != dictEnd);
36944  DEBUGLOG(4, "DDict is %s",
36945  dctx->ddictIsCold ? "~cold~" : "hot!");
36946  }
36948  if (ddict) { /* NULL ddict is equivalent to no dictionary */
36949  ZSTD_copyDDictParameters(dctx, ddict);
36950  }
36951  return 0;
36952 }
36953 
36958 unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
36959 {
36960  if (dictSize < 8) return 0;
36961  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
36962  return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
36963 }
36964 
36978 unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
36979 {
36980  ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
36981  size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
36982  if (ZSTD_isError(hError)) return 0;
36983  return zfp.dictID;
36984 }
36985 
36986 
36991  void* dst, size_t dstCapacity,
36992  const void* src, size_t srcSize,
36993  const ZSTD_DDict* ddict)
36994 {
36995  /* pass content and size in case legacy frames are encountered */
36996  return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
36997  NULL, 0,
36998  ddict);
36999 }
37000 
37001 
37002 /*=====================================
37003 * Streaming decompression
37004 *====================================*/
37005 
37008  DEBUGLOG(3, "ZSTD_createDStream");
37009  return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
37010 }
37011 
37012 ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
37013 {
37014  return ZSTD_initStaticDCtx(workspace, workspaceSize);
37015 }
37016 
37017 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
37018 {
37019  return ZSTD_createDCtx_internal(customMem);
37022 size_t ZSTD_freeDStream(ZSTD_DStream* zds)
37024  return ZSTD_freeDCtx(zds);
37025 }
37026 
37027 
37028 /* *** Initialization *** */
37029 
37031 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
37032 
37034  const void* dict, size_t dictSize,
37035  ZSTD_dictLoadMethod_e dictLoadMethod,
37036  ZSTD_dictContentType_e dictContentType)
37037 {
37038  RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
37040  if (dict && dictSize != 0) {
37041  dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
37042  RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation, "NULL pointer!");
37043  dctx->ddict = dctx->ddictLocal;
37045  }
37046  return 0;
37047 }
37048 
37049 size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
37050 {
37051  return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
37052 }
37053 
37054 size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
37055 {
37056  return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
37057 }
37058 
37059 size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
37060 {
37061  FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType), "");
37062  dctx->dictUses = ZSTD_use_once;
37063  return 0;
37064 }
37066 size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)
37067 {
37068  return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent);
37069 }
37070 
37071 
37072 /* ZSTD_initDStream_usingDict() :
37073  * return : expected size, aka ZSTD_startingInputLength().
37074  * this function cannot fail */
37075 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
37076 {
37077  DEBUGLOG(4, "ZSTD_initDStream_usingDict");
37079  FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) , "");
37080  return ZSTD_startingInputLength(zds->format);
37081 }
37082 
37083 /* note : this variant can't fail */
37084 size_t ZSTD_initDStream(ZSTD_DStream* zds)
37086  DEBUGLOG(4, "ZSTD_initDStream");
37088  FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), "");
37089  return ZSTD_startingInputLength(zds->format);
37090 }
37091 
37092 /* ZSTD_initDStream_usingDDict() :
37093  * ddict will just be referenced, and must outlive decompression session
37094  * this function cannot fail */
37095 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
37097  DEBUGLOG(4, "ZSTD_initDStream_usingDDict");
37099  FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
37100  return ZSTD_startingInputLength(dctx->format);
37101 }
37102 
37103 /* ZSTD_resetDStream() :
37104  * return : expected size, aka ZSTD_startingInputLength().
37105  * this function cannot fail */
37106 size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
37107 {
37108  DEBUGLOG(4, "ZSTD_resetDStream");
37110  return ZSTD_startingInputLength(dctx->format);
37111 }
37112 
37113 
37114 size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
37115 {
37116  RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
37117  ZSTD_clearDict(dctx);
37118  if (ddict) {
37119  dctx->ddict = ddict;
37121  if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts) {
37122  if (dctx->ddictSet == NULL) {
37124  if (!dctx->ddictSet) {
37125  RETURN_ERROR(memory_allocation, "Failed to allocate memory for hash set!");
37126  }
37127  }
37128  assert(!dctx->staticSize); /* Impossible: ddictSet cannot have been allocated if static dctx */
37130  }
37131  }
37132  return 0;
37133 }
37134 
37135 /* ZSTD_DCtx_setMaxWindowSize() :
37136  * note : no direct equivalence in ZSTD_DCtx_setParameter,
37137  * since this version sets windowSize, and the other sets windowLog */
37138 size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
37139 {
37141  size_t const min = (size_t)1 << bounds.lowerBound;
37142  size_t const max = (size_t)1 << bounds.upperBound;
37143  RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
37144  RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound, "");
37145  RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound, "");
37146  dctx->maxWindowSize = maxWindowSize;
37147  return 0;
37148 }
37149 
37150 size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
37151 {
37152  return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format);
37153 }
37154 
37156 {
37157  ZSTD_bounds bounds = { 0, 0, 0 };
37158  switch(dParam) {
37159  case ZSTD_d_windowLogMax:
37161  bounds.upperBound = ZSTD_WINDOWLOG_MAX;
37162  return bounds;
37163  case ZSTD_d_format:
37164  bounds.lowerBound = (int)ZSTD_f_zstd1;
37165  bounds.upperBound = (int)ZSTD_f_zstd1_magicless;
37166  ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
37167  return bounds;
37168  case ZSTD_d_stableOutBuffer:
37169  bounds.lowerBound = (int)ZSTD_bm_buffered;
37170  bounds.upperBound = (int)ZSTD_bm_stable;
37171  return bounds;
37172  case ZSTD_d_forceIgnoreChecksum:
37173  bounds.lowerBound = (int)ZSTD_d_validateChecksum;
37174  bounds.upperBound = (int)ZSTD_d_ignoreChecksum;
37175  return bounds;
37176  case ZSTD_d_refMultipleDDicts:
37177  bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
37178  bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
37179  return bounds;
37180  case ZSTD_d_disableHuffmanAssembly:
37181  bounds.lowerBound = 0;
37182  bounds.upperBound = 1;
37183  return bounds;
37185  default:;
37186  }
37187  bounds.error = ERROR(parameter_unsupported);
37188  return bounds;
37189 }
37190 
37191 /* ZSTD_dParam_withinBounds:
37192  * @return 1 if value is within dParam bounds,
37193  * 0 otherwise */
37194 static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
37195 {
37196  ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam);
37197  if (ZSTD_isError(bounds.error)) return 0;
37198  if (value < bounds.lowerBound) return 0;
37199  if (value > bounds.upperBound) return 0;
37200  return 1;
37201 }
37202 
37203 #define CHECK_DBOUNDS(p,v) { \
37204  RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \
37205 }
37206 
37207 size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value)
37208 {
37209  switch (param) {
37210  case ZSTD_d_windowLogMax:
37212  return 0;
37213  case ZSTD_d_format:
37214  *value = (int)dctx->format;
37215  return 0;
37216  case ZSTD_d_stableOutBuffer:
37217  *value = (int)dctx->outBufferMode;
37218  return 0;
37219  case ZSTD_d_forceIgnoreChecksum:
37220  *value = (int)dctx->forceIgnoreChecksum;
37221  return 0;
37222  case ZSTD_d_refMultipleDDicts:
37223  *value = (int)dctx->refMultipleDDicts;
37224  return 0;
37225  case ZSTD_d_disableHuffmanAssembly:
37226  *value = (int)dctx->disableHufAsm;
37227  return 0;
37228  default:;
37229  }
37230  RETURN_ERROR(parameter_unsupported, "");
37231 }
37232 
37233 size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
37234 {
37235  RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
37236  switch(dParam) {
37237  case ZSTD_d_windowLogMax:
37238  if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
37240  dctx->maxWindowSize = ((size_t)1) << value;
37241  return 0;
37242  case ZSTD_d_format:
37243  CHECK_DBOUNDS(ZSTD_d_format, value);
37244  dctx->format = (ZSTD_format_e)value;
37245  return 0;
37246  case ZSTD_d_stableOutBuffer:
37247  CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
37248  dctx->outBufferMode = (ZSTD_bufferMode_e)value;
37249  return 0;
37250  case ZSTD_d_forceIgnoreChecksum:
37251  CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
37252  dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value;
37253  return 0;
37254  case ZSTD_d_refMultipleDDicts:
37255  CHECK_DBOUNDS(ZSTD_d_refMultipleDDicts, value);
37256  if (dctx->staticSize != 0) {
37257  RETURN_ERROR(parameter_unsupported, "Static dctx does not support multiple DDicts!");
37258  }
37259  dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
37260  return 0;
37261  case ZSTD_d_disableHuffmanAssembly:
37262  CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
37263  dctx->disableHufAsm = value != 0;
37264  return 0;
37265  default:;
37266  }
37267  RETURN_ERROR(parameter_unsupported, "");
37268 }
37269 
37271 {
37272  if ( (reset == ZSTD_reset_session_only)
37274  dctx->streamStage = zdss_init;
37275  dctx->noForwardProgress = 0;
37276  }
37279  RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
37280  ZSTD_clearDict(dctx);
37282  }
37283  return 0;
37284 }
37285 
37286 
37287 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
37288 {
37289  return ZSTD_sizeof_DCtx(dctx);
37290 }
37291 
37292 size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
37293 {
37294  size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
37295  /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/
37296  unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2);
37297  unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
37298  size_t const minRBSize = (size_t) neededSize;
37299  RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
37300  frameParameter_windowTooLarge, "");
37301  return minRBSize;
37303 
37304 size_t ZSTD_estimateDStreamSize(size_t windowSize)
37305 {
37306  size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
37307  size_t const inBuffSize = blockSize; /* no block can be larger */
37308  size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);
37309  return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
37310 }
37311 
37312 size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
37313 {
37314  U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
37315  ZSTD_frameHeader zfh;
37316  size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
37317  if (ZSTD_isError(err)) return err;
37318  RETURN_ERROR_IF(err>0, srcSize_wrong, "");
37319  RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
37320  frameParameter_windowTooLarge, "");
37321  return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
37323 
37324 
37325 /* ***** Decompression ***** */
37326 
37327 static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
37328 {
37329  return (zds->inBuffSize + zds->outBuffSize) >= (neededInBuffSize + neededOutBuffSize) * ZSTD_WORKSPACETOOLARGE_FACTOR;
37331 
37332 static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
37333 {
37334  if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize))
37335  zds->oversizedDuration++;
37336  else
37337  zds->oversizedDuration = 0;
37338 }
37339 
37341 {
37343 }
37344 
37345 /* Checks that the output buffer hasn't changed if ZSTD_obm_stable is used. */
37346 static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* output)
37347 {
37349  /* No requirement when ZSTD_obm_stable is not enabled. */
37350  if (zds->outBufferMode != ZSTD_bm_stable)
37351  return 0;
37352  /* Any buffer is allowed in zdss_init, this must be the same for every other call until
37353  * the context is reset.
37354  */
37355  if (zds->streamStage == zdss_init)
37356  return 0;
37357  /* The buffer must match our expectation exactly. */
37358  if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
37359  return 0;
37360  RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!");
37361 }
37362 
37363 /* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
37364  * and updates the stage and the output buffer state. This call is extracted so it can be
37365  * used both when reading directly from the ZSTD_inBuffer, and in buffered input mode.
37366  * NOTE: You must break after calling this function since the streamStage is modified.
37367  */
37368 static size_t ZSTD_decompressContinueStream(
37369  ZSTD_DStream* zds, char** op, char* oend,
37370  void const* src, size_t srcSize) {
37371  int const isSkipFrame = ZSTD_isSkipFrame(zds);
37372  if (zds->outBufferMode == ZSTD_bm_buffered) {
37373  size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
37374  size_t const decodedSize = ZSTD_decompressContinue(zds,
37375  zds->outBuff + zds->outStart, dstSize, src, srcSize);
37376  FORWARD_IF_ERROR(decodedSize, "");
37377  if (!decodedSize && !isSkipFrame) {
37378  zds->streamStage = zdss_read;
37379  } else {
37380  zds->outEnd = zds->outStart + decodedSize;
37381  zds->streamStage = zdss_flush;
37382  }
37383  } else {
37384  /* Write directly into the output buffer */
37385  size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op);
37386  size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize);
37387  FORWARD_IF_ERROR(decodedSize, "");
37388  *op += decodedSize;
37389  /* Flushing is not needed. */
37390  zds->streamStage = zdss_read;
37391  assert(*op <= oend);
37393  }
37394  return 0;
37395 }
37396 
37398 {
37399  const char* const src = (const char*)input->src;
37400  const char* const istart = input->pos != 0 ? src + input->pos : src;
37401  const char* const iend = input->size != 0 ? src + input->size : src;
37402  const char* ip = istart;
37403  char* const dst = (char*)output->dst;
37404  char* const ostart = output->pos != 0 ? dst + output->pos : dst;
37405  char* const oend = output->size != 0 ? dst + output->size : dst;
37406  char* op = ostart;
37407  U32 someMoreWork = 1;
37408 
37409  DEBUGLOG(5, "ZSTD_decompressStream");
37411  input->pos > input->size,
37412  srcSize_wrong,
37413  "forbidden. in: pos: %u vs size: %u",
37414  (U32)input->pos, (U32)input->size);
37416  output->pos > output->size,
37417  dstSize_tooSmall,
37418  "forbidden. out: pos: %u vs size: %u",
37419  (U32)output->pos, (U32)output->size);
37420  DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
37422 
37423  while (someMoreWork) {
37424  switch(zds->streamStage)
37425  {
37426  case zdss_init :
37427  DEBUGLOG(5, "stage zdss_init => transparent reset ");
37429  zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
37430 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
37431  zds->legacyVersion = 0;
37432 #endif
37433  zds->hostageByte = 0;
37434  zds->expectedOutBuffer = *output;
37436 
37437  case zdss_loadHeader :
37438  DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
37439 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
37440  if (zds->legacyVersion) {
37441  RETURN_ERROR_IF(zds->staticSize, memory_allocation,
37442  "legacy support is incompatible with static dctx");
37443  { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
37444  if (hint==0) zds->streamStage = zdss_init;
37445  return hint;
37446  } }
37447 #endif
37448  { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
37449  if (zds->refMultipleDDicts && zds->ddictSet) {
37451  }
37452  if (ZSTD_isError(hSize)) {
37453 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
37454  U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
37455  if (legacyVersion) {
37456  ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);
37457  const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;
37458  size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;
37459  DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion);
37460  RETURN_ERROR_IF(zds->staticSize, memory_allocation,
37461  "legacy support is incompatible with static dctx");
37462  FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
37463  zds->previousLegacyVersion, legacyVersion,
37464  dict, dictSize), "");
37465  zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
37466  { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
37467  if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */
37468  return hint;
37469  } }
37470 #endif
37471  return hSize; /* error */
37472  }
37473  if (hSize != 0) { /* need more input */
37474  size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
37475  size_t const remainingInput = (size_t)(iend-ip);
37476  assert(iend >= ip);
37477  if (toLoad > remainingInput) { /* not enough input to load full header */
37478  if (remainingInput > 0) {
37479  ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);
37480  zds->lhSize += remainingInput;
37481  }
37482  input->pos = input->size;
37483  /* check first few bytes */
37486  "First few bytes detected incorrect" );
37487  /* return hint input size */
37488  return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
37489  }
37490  assert(ip != NULL);
37491  ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
37492  break;
37493  } }
37494 
37495  /* check for single-pass mode opportunity */
37496  if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
37497  && zds->fParams.frameType != ZSTD_skippableFrame
37498  && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
37499  size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart));
37500  if (cSize <= (size_t)(iend-istart)) {
37501  /* shortcut : using single-pass mode */
37502  size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
37503  if (ZSTD_isError(decompressedSize)) return decompressedSize;
37504  DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
37505  assert(istart != NULL);
37506  ip = istart + cSize;
37507  op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
37508  zds->expected = 0;
37509  zds->streamStage = zdss_init;
37510  someMoreWork = 0;
37511  break;
37512  } }
37513 
37514  /* Check output buffer is large enough for ZSTD_odm_stable. */
37515  if (zds->outBufferMode == ZSTD_bm_stable
37516  && zds->fParams.frameType != ZSTD_skippableFrame
37517  && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
37518  && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
37519  RETURN_ERROR(dstSize_tooSmall, "ZSTD_obm_stable passed but ZSTD_outBuffer is too small");
37520  }
37521 
37522  /* Consume header (see ZSTDds_decodeFrameHeader) */
37523  DEBUGLOG(4, "Consume header");
37525 
37526  if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
37528  zds->stage = ZSTDds_skipFrame;
37529  } else {
37533  }
37534 
37535  /* control buffer memory usage */
37536  DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)",
37537  (U32)(zds->fParams.windowSize >>10),
37538  (U32)(zds->maxWindowSize >> 10) );
37539  zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
37540  RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
37541  frameParameter_windowTooLarge, "");
37542 
37543  /* Adapt buffer sizes to frame header instructions */
37544  { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
37545  size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
37546  ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
37547  : 0;
37548 
37549  ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
37550 
37551  { int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize);
37552  int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds);
37553 
37554  if (tooSmall || tooLarge) {
37555  size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
37556  DEBUGLOG(4, "inBuff : from %u to %u",
37557  (U32)zds->inBuffSize, (U32)neededInBuffSize);
37558  DEBUGLOG(4, "outBuff : from %u to %u",
37559  (U32)zds->outBuffSize, (U32)neededOutBuffSize);
37560  if (zds->staticSize) { /* static DCtx */
37561  DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
37562  assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
37564  bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
37565  memory_allocation, "");
37566  } else {
37567  ZSTD_customFree(zds->inBuff, zds->customMem);
37568  zds->inBuffSize = 0;
37569  zds->outBuffSize = 0;
37570  zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem);
37571  RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, "");
37572  }
37573  zds->inBuffSize = neededInBuffSize;
37574  zds->outBuff = zds->inBuff + zds->inBuffSize;
37575  zds->outBuffSize = neededOutBuffSize;
37576  } } }
37577  zds->streamStage = zdss_read;
37579 
37580  case zdss_read:
37581  DEBUGLOG(5, "stage zdss_read");
37582  { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip));
37583  DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
37584  if (neededInSize==0) { /* end of frame */
37585  zds->streamStage = zdss_init;
37586  someMoreWork = 0;
37587  break;
37588  }
37589  if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
37590  FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
37591  assert(ip != NULL);
37592  ip += neededInSize;
37593  /* Function modifies the stage so we must break */
37594  break;
37595  } }
37596  if (ip==iend) { someMoreWork = 0; break; } /* no more input */
37597  zds->streamStage = zdss_load;
37599 
37600  case zdss_load:
37601  { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
37602  size_t const toLoad = neededInSize - zds->inPos;
37603  int const isSkipFrame = ZSTD_isSkipFrame(zds);
37604  size_t loadedSize;
37605  /* At this point we shouldn't be decompressing a block that we can stream. */
37606  assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)));
37607  if (isSkipFrame) {
37608  loadedSize = MIN(toLoad, (size_t)(iend-ip));
37609  } else {
37610  RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
37611  corruption_detected,
37612  "should never happen");
37613  loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
37614  }
37615  if (loadedSize != 0) {
37616  /* ip may be NULL */
37617  ip += loadedSize;
37618  zds->inPos += loadedSize;
37619  }
37620  if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
37621 
37622  /* decode loaded input */
37623  zds->inPos = 0; /* input is consumed */
37624  FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, zds->inBuff, neededInSize), "");
37625  /* Function modifies the stage so we must break */
37626  break;
37627  }
37628  case zdss_flush:
37629  {
37630  size_t const toFlushSize = zds->outEnd - zds->outStart;
37631  size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
37632 
37633  op = op ? op + flushedSize : op;
37634 
37635  zds->outStart += flushedSize;
37636  if (flushedSize == toFlushSize) { /* flush completed */
37637  zds->streamStage = zdss_read;
37638  if ( (zds->outBuffSize < zds->fParams.frameContentSize)
37639  && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
37640  DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
37641  (int)(zds->outBuffSize - zds->outStart),
37642  (U32)zds->fParams.blockSizeMax);
37643  zds->outStart = zds->outEnd = 0;
37644  }
37645  break;
37646  } }
37647  /* cannot complete flush */
37648  someMoreWork = 0;
37649  break;
37650 
37651  default:
37652  assert(0); /* impossible */
37653  RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
37654  } }
37655 
37656  /* result */
37657  input->pos = (size_t)(ip - (const char*)(input->src));
37658  output->pos = (size_t)(op - (char*)(output->dst));
37659 
37660  /* Update the expected output buffer for ZSTD_obm_stable. */
37661  zds->expectedOutBuffer = *output;
37662 
37663  if ((ip==istart) && (op==ostart)) { /* no forward progress */
37664  zds->noForwardProgress ++;
37666  RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, "");
37667  RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, "");
37668  assert(0);
37669  }
37670  } else {
37671  zds->noForwardProgress = 0;
37672  }
37673  { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
37674  if (!nextSrcSizeHint) { /* frame fully decoded */
37675  if (zds->outEnd == zds->outStart) { /* output fully flushed */
37676  if (zds->hostageByte) {
37677  if (input->pos >= input->size) {
37678  /* can't release hostage (not present) */
37679  zds->streamStage = zdss_read;
37680  return 1;
37681  }
37682  input->pos++; /* release hostage */
37683  } /* zds->hostageByte */
37684  return 0;
37685  } /* zds->outEnd == zds->outStart */
37686  if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
37687  input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
37688  zds->hostageByte=1;
37689  }
37690  return 1;
37691  } /* nextSrcSizeHint==0 */
37692  nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */
37693  assert(zds->inPos <= nextSrcSizeHint);
37694  nextSrcSizeHint -= zds->inPos; /* part already loaded*/
37695  return nextSrcSizeHint;
37696  }
37697 }
37698 
37700  ZSTD_DCtx* dctx,
37701  void* dst, size_t dstCapacity, size_t* dstPos,
37702  const void* src, size_t srcSize, size_t* srcPos)
37703 {
37705  ZSTD_inBuffer input;
37706  output.dst = dst;
37707  output.size = dstCapacity;
37708  output.pos = *dstPos;
37709  input.src = src;
37710  input.size = srcSize;
37711  input.pos = *srcPos;
37712  { size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
37713  *dstPos = output.pos;
37714  *srcPos = input.pos;
37715  return cErr;
37716  }
37717 }
37718 /**** ended inlining decompress/zstd_decompress.c ****/
37719 /**** start inlining decompress/zstd_decompress_block.c ****/
37720 /*
37721  * Copyright (c) Meta Platforms, Inc. and affiliates.
37722  * All rights reserved.
37723  *
37724  * This source code is licensed under both the BSD-style license (found in the
37725  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
37726  * in the COPYING file in the root directory of this source tree).
37727  * You may select, at your option, one of the above-listed licenses.
37728  */
37729 
37730 /* zstd_decompress_block :
37731  * this module takes care of decompressing _compressed_ block */
37732 
37733 /*-*******************************************************
37734 * Dependencies
37735 *********************************************************/
37736 /**** skipping file: ../common/zstd_deps.h ****/
37737 /**** skipping file: ../common/compiler.h ****/
37738 /**** skipping file: ../common/cpu.h ****/
37739 /**** skipping file: ../common/mem.h ****/
37740 #define FSE_STATIC_LINKING_ONLY
37741 /**** skipping file: ../common/fse.h ****/
37742 /**** skipping file: ../common/huf.h ****/
37743 /**** skipping file: ../common/zstd_internal.h ****/
37744 /**** skipping file: zstd_decompress_internal.h ****/
37745 /**** skipping file: zstd_ddict.h ****/
37746 /**** skipping file: zstd_decompress_block.h ****/
37747 /**** skipping file: ../common/bits.h ****/
37748 
37749 /*_*******************************************************
37750 * Macros
37751 **********************************************************/
37752 
37753 /* These two optional macros force the use one way or another of the two
37754  * ZSTD_decompressSequences implementations. You can't force in both directions
37755  * at the same time.
37756  */
37757 #if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
37758  defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
37759 #error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!"
37760 #endif
37761 
37762 
37763 /*_*******************************************************
37764 * Memory operations
37765 **********************************************************/
37766 static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); }
37767 
37768 
37769 /*-*************************************************************
37770  * Block decoding
37771  ***************************************************************/
37772 
37775 size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
37776  blockProperties_t* bpPtr)
37777 {
37778  RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, "");
37779 
37780  { U32 const cBlockHeader = MEM_readLE24(src);
37781  U32 const cSize = cBlockHeader >> 3;
37782  bpPtr->lastBlock = cBlockHeader & 1;
37783  bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
37784  bpPtr->origSize = cSize; /* only useful for RLE */
37785  if (bpPtr->blockType == bt_rle) return 1;
37786  RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, "");
37787  return cSize;
37788  }
37789 }
37790 
37791 /* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */
37792 static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,
37793  const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
37794 {
37795  if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH)
37796  {
37797  /* room for litbuffer to fit without read faulting */
37799  dctx->litBufferEnd = dctx->litBuffer + litSize;
37801  }
37802  else if (litSize > ZSTD_LITBUFFEREXTRASIZE)
37803  {
37804  /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
37805  if (splitImmediately) {
37806  /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
37807  dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
37808  dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;
37809  }
37810  else {
37811  /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */
37812  dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;
37813  dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;
37814  }
37815  dctx->litBufferLocation = ZSTD_split;
37816  }
37817  else
37818  {
37819  /* fits entirely within litExtraBuffer, so no split is necessary */
37820  dctx->litBuffer = dctx->litExtraBuffer;
37821  dctx->litBufferEnd = dctx->litBuffer + litSize;
37823  }
37824 }
37825 
37826 /* Hidden declaration for fullbench */
37827 size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
37828  const void* src, size_t srcSize,
37829  void* dst, size_t dstCapacity, const streaming_operation streaming);
37838 size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
37839  const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */
37840  void* dst, size_t dstCapacity, const streaming_operation streaming)
37841 {
37842  DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");
37843  RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
37844 
37845  { const BYTE* const istart = (const BYTE*) src;
37846  symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
37847 
37848  switch(litEncType)
37849  {
37850  case set_repeat:
37851  DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
37852  RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
37854 
37855  case set_compressed:
37856  RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3");
37857  { size_t lhSize, litSize, litCSize;
37858  U32 singleStream=0;
37859  U32 const lhlCode = (istart[0] >> 2) & 3;
37860  U32 const lhc = MEM_readLE32(istart);
37861  size_t hufSuccess;
37862  size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
37863  int const flags = 0
37864  | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)
37865  | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);
37866  switch(lhlCode)
37867  {
37868  case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
37869  /* 2 - 2 - 10 - 10 */
37870  singleStream = !lhlCode;
37871  lhSize = 3;
37872  litSize = (lhc >> 4) & 0x3FF;
37873  litCSize = (lhc >> 14) & 0x3FF;
37874  break;
37875  case 2:
37876  /* 2 - 2 - 14 - 14 */
37877  lhSize = 4;
37878  litSize = (lhc >> 4) & 0x3FFF;
37879  litCSize = lhc >> 18;
37880  break;
37881  case 3:
37882  /* 2 - 2 - 18 - 18 */
37883  lhSize = 5;
37884  litSize = (lhc >> 4) & 0x3FFFF;
37885  litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);
37886  break;
37887  }
37888  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
37889  RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
37890  if (!singleStream)
37891  RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
37892  "Not enough literals (%zu) for the 4-streams mode (min %u)",
37893  litSize, MIN_LITERALS_FOR_4_STREAMS);
37894  RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
37895  RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
37896  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
37897 
37898  /* prefetch huffman table if cold */
37899  if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {
37900  PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable));
37901  }
37902 
37903  if (litEncType==set_repeat) {
37904  if (singleStream) {
37905  hufSuccess = HUF_decompress1X_usingDTable(
37906  dctx->litBuffer, litSize, istart+lhSize, litCSize,
37907  dctx->HUFptr, flags);
37908  } else {
37909  assert(litSize >= MIN_LITERALS_FOR_4_STREAMS);
37910  hufSuccess = HUF_decompress4X_usingDTable(
37911  dctx->litBuffer, litSize, istart+lhSize, litCSize,
37912  dctx->HUFptr, flags);
37913  }
37914  } else {
37915  if (singleStream) {
37916 #if defined(HUF_FORCE_DECOMPRESS_X2)
37917  hufSuccess = HUF_decompress1X_DCtx_wksp(
37918  dctx->entropy.hufTable, dctx->litBuffer, litSize,
37919  istart+lhSize, litCSize, dctx->workspace,
37920  sizeof(dctx->workspace), flags);
37921 #else
37922  hufSuccess = HUF_decompress1X1_DCtx_wksp(
37923  dctx->entropy.hufTable, dctx->litBuffer, litSize,
37924  istart+lhSize, litCSize, dctx->workspace,
37925  sizeof(dctx->workspace), flags);
37926 #endif
37927  } else {
37928  hufSuccess = HUF_decompress4X_hufOnly_wksp(
37929  dctx->entropy.hufTable, dctx->litBuffer, litSize,
37930  istart+lhSize, litCSize, dctx->workspace,
37931  sizeof(dctx->workspace), flags);
37932  }
37933  }
37934  if (dctx->litBufferLocation == ZSTD_split)
37935  {
37936  ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
37937  ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
37938  dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
37939  dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
37940  }
37941 
37942  RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
37943 
37944  dctx->litPtr = dctx->litBuffer;
37945  dctx->litSize = litSize;
37946  dctx->litEntropy = 1;
37947  if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
37948  return litCSize + lhSize;
37949  }
37950 
37951  case set_basic:
37952  { size_t litSize, lhSize;
37953  U32 const lhlCode = ((istart[0]) >> 2) & 3;
37954  size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
37955  switch(lhlCode)
37956  {
37957  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
37958  lhSize = 1;
37959  litSize = istart[0] >> 3;
37960  break;
37961  case 1:
37962  lhSize = 2;
37963  litSize = MEM_readLE16(istart) >> 4;
37964  break;
37965  case 3:
37966  lhSize = 3;
37967  RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3");
37968  litSize = MEM_readLE24(istart) >> 4;
37969  break;
37970  }
37971 
37972  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
37973  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
37974  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
37975  if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
37976  RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");
37977  if (dctx->litBufferLocation == ZSTD_split)
37978  {
37979  ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE);
37980  ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
37981  }
37982  else
37983  {
37984  ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize);
37985  }
37986  dctx->litPtr = dctx->litBuffer;
37987  dctx->litSize = litSize;
37988  return lhSize+litSize;
37989  }
37990  /* direct reference into compressed stream */
37991  dctx->litPtr = istart+lhSize;
37992  dctx->litSize = litSize;
37993  dctx->litBufferEnd = dctx->litPtr + litSize;
37994  dctx->litBufferLocation = ZSTD_not_in_dst;
37995  return lhSize+litSize;
37996  }
37997 
37998  case set_rle:
37999  { U32 const lhlCode = ((istart[0]) >> 2) & 3;
38000  size_t litSize, lhSize;
38001  size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
38002  switch(lhlCode)
38003  {
38004  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
38005  lhSize = 1;
38006  litSize = istart[0] >> 3;
38007  break;
38008  case 1:
38009  lhSize = 2;
38010  RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3");
38011  litSize = MEM_readLE16(istart) >> 4;
38012  break;
38013  case 3:
38014  lhSize = 3;
38015  RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4");
38016  litSize = MEM_readLE24(istart) >> 4;
38017  break;
38018  }
38019  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
38020  RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
38021  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
38022  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
38023  if (dctx->litBufferLocation == ZSTD_split)
38024  {
38025  ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE);
38026  ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE);
38027  }
38028  else
38029  {
38030  ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize);
38031  }
38032  dctx->litPtr = dctx->litBuffer;
38033  dctx->litSize = litSize;
38034  return lhSize+1;
38035  }
38036  default:
38037  RETURN_ERROR(corruption_detected, "impossible");
38038  }
38039  }
38040 }
38041 
38042 /* Default FSE distribution tables.
38043  * These are pre-calculated FSE decoding tables using default distributions as defined in specification :
38044  * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
38045  * They were generated programmatically with following method :
38046  * - start from default distributions, present in /lib/common/zstd_internal.h
38047  * - generate tables normally, using ZSTD_buildFSETable()
38048  * - printout the content of tables
38049  * - pretify output, report below, test with fuzzer to ensure it's correct */
38050 
38051 /* Default FSE distribution table for Literal Lengths */
38052 static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
38053  { 1, 1, 1, LL_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
38054  /* nextState, nbAddBits, nbBits, baseVal */
38055  { 0, 0, 4, 0}, { 16, 0, 4, 0},
38056  { 32, 0, 5, 1}, { 0, 0, 5, 3},
38057  { 0, 0, 5, 4}, { 0, 0, 5, 6},
38058  { 0, 0, 5, 7}, { 0, 0, 5, 9},
38059  { 0, 0, 5, 10}, { 0, 0, 5, 12},
38060  { 0, 0, 6, 14}, { 0, 1, 5, 16},
38061  { 0, 1, 5, 20}, { 0, 1, 5, 22},
38062  { 0, 2, 5, 28}, { 0, 3, 5, 32},
38063  { 0, 4, 5, 48}, { 32, 6, 5, 64},
38064  { 0, 7, 5, 128}, { 0, 8, 6, 256},
38065  { 0, 10, 6, 1024}, { 0, 12, 6, 4096},
38066  { 32, 0, 4, 0}, { 0, 0, 4, 1},
38067  { 0, 0, 5, 2}, { 32, 0, 5, 4},
38068  { 0, 0, 5, 5}, { 32, 0, 5, 7},
38069  { 0, 0, 5, 8}, { 32, 0, 5, 10},
38070  { 0, 0, 5, 11}, { 0, 0, 6, 13},
38071  { 32, 1, 5, 16}, { 0, 1, 5, 18},
38072  { 32, 1, 5, 22}, { 0, 2, 5, 24},
38073  { 32, 3, 5, 32}, { 0, 3, 5, 40},
38074  { 0, 6, 4, 64}, { 16, 6, 4, 64},
38075  { 32, 7, 5, 128}, { 0, 9, 6, 512},
38076  { 0, 11, 6, 2048}, { 48, 0, 4, 0},
38077  { 16, 0, 4, 1}, { 32, 0, 5, 2},
38078  { 32, 0, 5, 3}, { 32, 0, 5, 5},
38079  { 32, 0, 5, 6}, { 32, 0, 5, 8},
38080  { 32, 0, 5, 9}, { 32, 0, 5, 11},
38081  { 32, 0, 5, 12}, { 0, 0, 6, 15},
38082  { 32, 1, 5, 18}, { 32, 1, 5, 20},
38083  { 32, 2, 5, 24}, { 32, 2, 5, 28},
38084  { 32, 3, 5, 40}, { 32, 4, 5, 48},
38085  { 0, 16, 6,65536}, { 0, 15, 6,32768},
38086  { 0, 14, 6,16384}, { 0, 13, 6, 8192},
38087 }; /* LL_defaultDTable */
38088 
38089 /* Default FSE distribution table for Offset Codes */
38090 static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
38091  { 1, 1, 1, OF_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
38092  /* nextState, nbAddBits, nbBits, baseVal */
38093  { 0, 0, 5, 0}, { 0, 6, 4, 61},
38094  { 0, 9, 5, 509}, { 0, 15, 5,32765},
38095  { 0, 21, 5,2097149}, { 0, 3, 5, 5},
38096  { 0, 7, 4, 125}, { 0, 12, 5, 4093},
38097  { 0, 18, 5,262141}, { 0, 23, 5,8388605},
38098  { 0, 5, 5, 29}, { 0, 8, 4, 253},
38099  { 0, 14, 5,16381}, { 0, 20, 5,1048573},
38100  { 0, 2, 5, 1}, { 16, 7, 4, 125},
38101  { 0, 11, 5, 2045}, { 0, 17, 5,131069},
38102  { 0, 22, 5,4194301}, { 0, 4, 5, 13},
38103  { 16, 8, 4, 253}, { 0, 13, 5, 8189},
38104  { 0, 19, 5,524285}, { 0, 1, 5, 1},
38105  { 16, 6, 4, 61}, { 0, 10, 5, 1021},
38106  { 0, 16, 5,65533}, { 0, 28, 5,268435453},
38107  { 0, 27, 5,134217725}, { 0, 26, 5,67108861},
38108  { 0, 25, 5,33554429}, { 0, 24, 5,16777213},
38109 }; /* OF_defaultDTable */
38110 
38111 
38112 /* Default FSE distribution table for Match Lengths */
38113 static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
38114  { 1, 1, 1, ML_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
38115  /* nextState, nbAddBits, nbBits, baseVal */
38116  { 0, 0, 6, 3}, { 0, 0, 4, 4},
38117  { 32, 0, 5, 5}, { 0, 0, 5, 6},
38118  { 0, 0, 5, 8}, { 0, 0, 5, 9},
38119  { 0, 0, 5, 11}, { 0, 0, 6, 13},
38120  { 0, 0, 6, 16}, { 0, 0, 6, 19},
38121  { 0, 0, 6, 22}, { 0, 0, 6, 25},
38122  { 0, 0, 6, 28}, { 0, 0, 6, 31},
38123  { 0, 0, 6, 34}, { 0, 1, 6, 37},
38124  { 0, 1, 6, 41}, { 0, 2, 6, 47},
38125  { 0, 3, 6, 59}, { 0, 4, 6, 83},
38126  { 0, 7, 6, 131}, { 0, 9, 6, 515},
38127  { 16, 0, 4, 4}, { 0, 0, 4, 5},
38128  { 32, 0, 5, 6}, { 0, 0, 5, 7},
38129  { 32, 0, 5, 9}, { 0, 0, 5, 10},
38130  { 0, 0, 6, 12}, { 0, 0, 6, 15},
38131  { 0, 0, 6, 18}, { 0, 0, 6, 21},
38132  { 0, 0, 6, 24}, { 0, 0, 6, 27},
38133  { 0, 0, 6, 30}, { 0, 0, 6, 33},
38134  { 0, 1, 6, 35}, { 0, 1, 6, 39},
38135  { 0, 2, 6, 43}, { 0, 3, 6, 51},
38136  { 0, 4, 6, 67}, { 0, 5, 6, 99},
38137  { 0, 8, 6, 259}, { 32, 0, 4, 4},
38138  { 48, 0, 4, 4}, { 16, 0, 4, 5},
38139  { 32, 0, 5, 7}, { 32, 0, 5, 8},
38140  { 32, 0, 5, 10}, { 32, 0, 5, 11},
38141  { 0, 0, 6, 14}, { 0, 0, 6, 17},
38142  { 0, 0, 6, 20}, { 0, 0, 6, 23},
38143  { 0, 0, 6, 26}, { 0, 0, 6, 29},
38144  { 0, 0, 6, 32}, { 0, 16, 6,65539},
38145  { 0, 15, 6,32771}, { 0, 14, 6,16387},
38146  { 0, 13, 6, 8195}, { 0, 12, 6, 4099},
38147  { 0, 11, 6, 2051}, { 0, 10, 6, 1027},
38148 }; /* ML_defaultDTable */
38149 
38150 
38151 static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBits)
38152 {
38153  void* ptr = dt;
38154  ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;
38155  ZSTD_seqSymbol* const cell = dt + 1;
38156 
38157  DTableH->tableLog = 0;
38158  DTableH->fastMode = 0;
38159 
38160  cell->nbBits = 0;
38161  cell->nextState = 0;
38162  assert(nbAddBits < 255);
38163  cell->nbAdditionalBits = nbAddBits;
38164  cell->baseValue = baseValue;
38165 }
38166 
38167 
38168 /* ZSTD_buildFSETable() :
38169  * generate FSE decoding table for one symbol (ll, ml or off)
38170  * cannot fail if input is valid =>
38171  * all inputs are presumed validated at this stage */
38172 FORCE_INLINE_TEMPLATE
38173 void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
38174  const short* normalizedCounter, unsigned maxSymbolValue,
38175  const U32* baseValue, const U8* nbAdditionalBits,
38176  unsigned tableLog, void* wksp, size_t wkspSize)
38177 {
38178  ZSTD_seqSymbol* const tableDecode = dt+1;
38179  U32 const maxSV1 = maxSymbolValue + 1;
38180  U32 const tableSize = 1 << tableLog;
38181 
38182  U16* symbolNext = (U16*)wksp;
38183  BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);
38184  U32 highThreshold = tableSize - 1;
38185 
38186 
38187  /* Sanity Checks */
38188  assert(maxSymbolValue <= MaxSeq);
38189  assert(tableLog <= MaxFSELog);
38190  assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE);
38191  (void)wkspSize;
38192  /* Init, lay down lowprob symbols */
38193  { ZSTD_seqSymbol_header DTableH;
38194  DTableH.tableLog = tableLog;
38195  DTableH.fastMode = 1;
38196  { S16 const largeLimit= (S16)(1 << (tableLog-1));
38197  U32 s;
38198  for (s=0; s<maxSV1; s++) {
38199  if (normalizedCounter[s]==-1) {
38200  tableDecode[highThreshold--].baseValue = s;
38201  symbolNext[s] = 1;
38202  } else {
38203  if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
38204  assert(normalizedCounter[s]>=0);
38205  symbolNext[s] = (U16)normalizedCounter[s];
38206  } } }
38207  ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
38208  }
38209 
38210  /* Spread symbols */
38211  assert(tableSize <= 512);
38212  /* Specialized symbol spreading for the case when there are
38213  * no low probability (-1 count) symbols. When compressing
38214  * small blocks we avoid low probability symbols to hit this
38215  * case, since header decoding speed matters more.
38216  */
38217  if (highThreshold == tableSize - 1) {
38218  size_t const tableMask = tableSize-1;
38219  size_t const step = FSE_TABLESTEP(tableSize);
38220  /* First lay down the symbols in order.
38221  * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
38222  * misses since small blocks generally have small table logs, so nearly
38223  * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
38224  * our buffer to handle the over-write.
38225  */
38226  {
38227  U64 const add = 0x0101010101010101ull;
38228  size_t pos = 0;
38229  U64 sv = 0;
38230  U32 s;
38231  for (s=0; s<maxSV1; ++s, sv += add) {
38232  int i;
38233  int const n = normalizedCounter[s];
38234  MEM_write64(spread + pos, sv);
38235  for (i = 8; i < n; i += 8) {
38236  MEM_write64(spread + pos + i, sv);
38237  }
38238  assert(n>=0);
38239  pos += (size_t)n;
38240  }
38241  }
38242  /* Now we spread those positions across the table.
38243  * The benefit of doing it in two stages is that we avoid the
38244  * variable size inner loop, which caused lots of branch misses.
38245  * Now we can run through all the positions without any branch misses.
38246  * We unroll the loop twice, since that is what empirically worked best.
38247  */
38248  {
38249  size_t position = 0;
38250  size_t s;
38251  size_t const unroll = 2;
38252  assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
38253  for (s = 0; s < (size_t)tableSize; s += unroll) {
38254  size_t u;
38255  for (u = 0; u < unroll; ++u) {
38256  size_t const uPosition = (position + (u * step)) & tableMask;
38257  tableDecode[uPosition].baseValue = spread[s + u];
38258  }
38259  position = (position + (unroll * step)) & tableMask;
38260  }
38261  assert(position == 0);
38262  }
38263  } else {
38264  U32 const tableMask = tableSize-1;
38265  U32 const step = FSE_TABLESTEP(tableSize);
38266  U32 s, position = 0;
38267  for (s=0; s<maxSV1; s++) {
38268  int i;
38269  int const n = normalizedCounter[s];
38270  for (i=0; i<n; i++) {
38271  tableDecode[position].baseValue = s;
38272  position = (position + step) & tableMask;
38273  while (UNLIKELY(position > highThreshold)) position = (position + step) & tableMask; /* lowprob area */
38274  } }
38275  assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
38276  }
38277 
38278  /* Build Decoding table */
38279  {
38280  U32 u;
38281  for (u=0; u<tableSize; u++) {
38282  U32 const symbol = tableDecode[u].baseValue;
38283  U32 const nextState = symbolNext[symbol]++;
38284  tableDecode[u].nbBits = (BYTE) (tableLog - ZSTD_highbit32(nextState) );
38285  tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
38286  assert(nbAdditionalBits[symbol] < 255);
38287  tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol];
38288  tableDecode[u].baseValue = baseValue[symbol];
38289  }
38290  }
38291 }
38292 
38293 /* Avoids the FORCE_INLINE of the _body() function. */
38294 static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt,
38295  const short* normalizedCounter, unsigned maxSymbolValue,
38296  const U32* baseValue, const U8* nbAdditionalBits,
38297  unsigned tableLog, void* wksp, size_t wkspSize)
38298 {
38299  ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
38300  baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
38301 }
38302 
38303 #if DYNAMIC_BMI2
38304 BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt,
38305  const short* normalizedCounter, unsigned maxSymbolValue,
38306  const U32* baseValue, const U8* nbAdditionalBits,
38307  unsigned tableLog, void* wksp, size_t wkspSize)
38308 {
38309  ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
38310  baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
38311 }
38312 #endif
38313 
38314 void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
38315  const short* normalizedCounter, unsigned maxSymbolValue,
38316  const U32* baseValue, const U8* nbAdditionalBits,
38317  unsigned tableLog, void* wksp, size_t wkspSize, int bmi2)
38318 {
38319 #if DYNAMIC_BMI2
38320  if (bmi2) {
38321  ZSTD_buildFSETable_body_bmi2(dt, normalizedCounter, maxSymbolValue,
38322  baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
38323  return;
38324  }
38325 #endif
38326  (void)bmi2;
38327  ZSTD_buildFSETable_body_default(dt, normalizedCounter, maxSymbolValue,
38328  baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
38329 }
38330 
38331 
38335 static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
38336  symbolEncodingType_e type, unsigned max, U32 maxLog,
38337  const void* src, size_t srcSize,
38338  const U32* baseValue, const U8* nbAdditionalBits,
38339  const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
38340  int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize,
38341  int bmi2)
38342 {
38343  switch(type)
38344  {
38345  case set_rle :
38346  RETURN_ERROR_IF(!srcSize, srcSize_wrong, "");
38347  RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected, "");
38348  { U32 const symbol = *(const BYTE*)src;
38349  U32 const baseline = baseValue[symbol];
38350  U8 const nbBits = nbAdditionalBits[symbol];
38351  ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits);
38352  }
38353  *DTablePtr = DTableSpace;
38354  return 1;
38355  case set_basic :
38356  *DTablePtr = defaultTable;
38357  return 0;
38358  case set_repeat:
38359  RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, "");
38360  /* prefetch FSE table if used */
38361  if (ddictIsCold && (nbSeq > 24 /* heuristic */)) {
38362  const void* const pStart = *DTablePtr;
38363  size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog));
38364  PREFETCH_AREA(pStart, pSize);
38365  }
38366  return 0;
38367  case set_compressed :
38368  { unsigned tableLog;
38369  S16 norm[MaxSeq+1];
38370  size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
38371  RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, "");
38372  RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, "");
38373  ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2);
38374  *DTablePtr = DTableSpace;
38375  return headerSize;
38376  }
38377  default :
38378  assert(0);
38379  RETURN_ERROR(GENERIC, "impossible");
38380  }
38381 }
38382 
38383 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
38384  const void* src, size_t srcSize)
38385 {
38386  const BYTE* const istart = (const BYTE*)src;
38387  const BYTE* const iend = istart + srcSize;
38388  const BYTE* ip = istart;
38389  int nbSeq;
38390  DEBUGLOG(5, "ZSTD_decodeSeqHeaders");
38391 
38392  /* check */
38393  RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, "");
38394 
38395  /* SeqHead */
38396  nbSeq = *ip++;
38397  if (!nbSeq) {
38398  *nbSeqPtr=0;
38399  RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
38400  return 1;
38401  }
38402  if (nbSeq > 0x7F) {
38403  if (nbSeq == 0xFF) {
38404  RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
38405  nbSeq = MEM_readLE16(ip) + LONGNBSEQ;
38406  ip+=2;
38407  } else {
38408  RETURN_ERROR_IF(ip >= iend, srcSize_wrong, "");
38409  nbSeq = ((nbSeq-0x80)<<8) + *ip++;
38410  }
38411  }
38412  *nbSeqPtr = nbSeq;
38413 
38414  /* FSE table descriptors */
38415  RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
38416  { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
38417  symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
38418  symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
38419  ip++;
38420 
38421  /* Build DTables */
38422  { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
38423  LLtype, MaxLL, LLFSELog,
38424  ip, iend-ip,
38425  LL_base, LL_bits,
38426  LL_defaultDTable, dctx->fseEntropy,
38427  dctx->ddictIsCold, nbSeq,
38428  dctx->workspace, sizeof(dctx->workspace),
38429  ZSTD_DCtx_get_bmi2(dctx));
38430  RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed");
38431  ip += llhSize;
38432  }
38433 
38434  { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
38435  OFtype, MaxOff, OffFSELog,
38436  ip, iend-ip,
38437  OF_base, OF_bits,
38438  OF_defaultDTable, dctx->fseEntropy,
38439  dctx->ddictIsCold, nbSeq,
38440  dctx->workspace, sizeof(dctx->workspace),
38441  ZSTD_DCtx_get_bmi2(dctx));
38442  RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed");
38443  ip += ofhSize;
38444  }
38445 
38446  { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
38447  MLtype, MaxML, MLFSELog,
38448  ip, iend-ip,
38449  ML_base, ML_bits,
38450  ML_defaultDTable, dctx->fseEntropy,
38451  dctx->ddictIsCold, nbSeq,
38452  dctx->workspace, sizeof(dctx->workspace),
38453  ZSTD_DCtx_get_bmi2(dctx));
38454  RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed");
38455  ip += mlhSize;
38456  }
38457  }
38458 
38459  return ip-istart;
38462 
38463 typedef struct {
38464  size_t litLength;
38465  size_t matchLength;
38466  size_t offset;
38467 } seq_t;
38469 typedef struct {
38470  size_t state;
38471  const ZSTD_seqSymbol* table;
38472 } ZSTD_fseState;
38473 
38474 typedef struct {
38475  BIT_DStream_t DStream;
38476  ZSTD_fseState stateLL;
38477  ZSTD_fseState stateOffb;
38478  ZSTD_fseState stateML;
38479  size_t prevOffset[ZSTD_REP_NUM];
38480 } seqState_t;
38481 
38489 HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
38490  assert(*ip <= *op);
38491  if (offset < 8) {
38492  /* close range match, overlap */
38493  static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
38494  static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
38495  int const sub2 = dec64table[offset];
38496  (*op)[0] = (*ip)[0];
38497  (*op)[1] = (*ip)[1];
38498  (*op)[2] = (*ip)[2];
38499  (*op)[3] = (*ip)[3];
38500  *ip += dec32table[offset];
38501  ZSTD_copy4(*op+4, *ip);
38502  *ip -= sub2;
38503  } else {
38504  ZSTD_copy8(*op, *ip);
38505  }
38506  *ip += 8;
38507  *op += 8;
38508  assert(*op - *ip >= 8);
38509 }
38510 
38522 static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {
38523  ptrdiff_t const diff = op - ip;
38524  BYTE* const oend = op + length;
38525 
38526  assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) ||
38527  (ovtype == ZSTD_overlap_src_before_dst && diff >= 0));
38528 
38529  if (length < 8) {
38530  /* Handle short lengths. */
38531  while (op < oend) *op++ = *ip++;
38532  return;
38533  }
38534  if (ovtype == ZSTD_overlap_src_before_dst) {
38535  /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
38536  assert(length >= 8);
38537  ZSTD_overlapCopy8(&op, &ip, diff);
38538  length -= 8;
38539  assert(op - ip >= 8);
38540  assert(op <= oend);
38541  }
38542 
38543  if (oend <= oend_w) {
38544  /* No risk of overwrite. */
38545  ZSTD_wildcopy(op, ip, length, ovtype);
38546  return;
38547  }
38548  if (op <= oend_w) {
38549  /* Wildcopy until we get close to the end. */
38550  assert(oend > oend_w);
38551  ZSTD_wildcopy(op, ip, oend_w - op, ovtype);
38552  ip += oend_w - op;
38553  op += oend_w - op;
38554  }
38555  /* Handle the leftovers. */
38556  while (op < oend) *op++ = *ip++;
38557 }
38558 
38559 /* ZSTD_safecopyDstBeforeSrc():
38560  * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
38561  * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
38562 static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) {
38563  ptrdiff_t const diff = op - ip;
38564  BYTE* const oend = op + length;
38565 
38566  if (length < 8 || diff > -8) {
38567  /* Handle short lengths, close overlaps, and dst not before src. */
38568  while (op < oend) *op++ = *ip++;
38569  return;
38570  }
38571 
38572  if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) {
38573  ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap);
38574  ip += oend - WILDCOPY_OVERLENGTH - op;
38575  op += oend - WILDCOPY_OVERLENGTH - op;
38576  }
38577 
38578  /* Handle the leftovers. */
38579  while (op < oend) *op++ = *ip++;
38580 }
38582 /* ZSTD_execSequenceEnd():
38583  * This version handles cases that are near the end of the output buffer. It requires
38584  * more careful checks to make sure there is no overflow. By separating out these hard
38585  * and unlikely cases, we can speed up the common cases.
38586  *
38587  * NOTE: This function needs to be fast for a single long sequence, but doesn't need
38588  * to be optimized for many small sequences, since those fall into ZSTD_execSequence().
38589  */
38590 FORCE_NOINLINE
38591 size_t ZSTD_execSequenceEnd(BYTE* op,
38592  BYTE* const oend, seq_t sequence,
38593  const BYTE** litPtr, const BYTE* const litLimit,
38594  const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
38595 {
38596  BYTE* const oLitEnd = op + sequence.litLength;
38597  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
38598  const BYTE* const iLitEnd = *litPtr + sequence.litLength;
38599  const BYTE* match = oLitEnd - sequence.offset;
38600  BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
38601 
38602  /* bounds checks : careful of address space overflow in 32-bit mode */
38603  RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
38604  RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
38605  assert(op < op + sequenceLength);
38606  assert(oLitEnd < op + sequenceLength);
38607 
38608  /* copy literals */
38609  ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);
38610  op = oLitEnd;
38611  *litPtr = iLitEnd;
38612 
38613  /* copy Match */
38614  if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
38615  /* offset beyond prefix */
38616  RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
38617  match = dictEnd - (prefixStart - match);
38618  if (match + sequence.matchLength <= dictEnd) {
38619  ZSTD_memmove(oLitEnd, match, sequence.matchLength);
38620  return sequenceLength;
38621  }
38622  /* span extDict & currentPrefixSegment */
38623  { size_t const length1 = dictEnd - match;
38624  ZSTD_memmove(oLitEnd, match, length1);
38625  op = oLitEnd + length1;
38626  sequence.matchLength -= length1;
38627  match = prefixStart;
38628  }
38629  }
38630  ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
38631  return sequenceLength;
38632 }
38633 
38634 /* ZSTD_execSequenceEndSplitLitBuffer():
38635  * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case.
38636  */
38637 FORCE_NOINLINE
38638 size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
38639  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
38640  const BYTE** litPtr, const BYTE* const litLimit,
38641  const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
38642 {
38643  BYTE* const oLitEnd = op + sequence.litLength;
38644  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
38645  const BYTE* const iLitEnd = *litPtr + sequence.litLength;
38646  const BYTE* match = oLitEnd - sequence.offset;
38647 
38648 
38649  /* bounds checks : careful of address space overflow in 32-bit mode */
38650  RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
38651  RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
38652  assert(op < op + sequenceLength);
38653  assert(oLitEnd < op + sequenceLength);
38654 
38655  /* copy literals */
38656  RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer");
38657  ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength);
38658  op = oLitEnd;
38659  *litPtr = iLitEnd;
38660 
38661  /* copy Match */
38662  if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
38663  /* offset beyond prefix */
38664  RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
38665  match = dictEnd - (prefixStart - match);
38666  if (match + sequence.matchLength <= dictEnd) {
38667  ZSTD_memmove(oLitEnd, match, sequence.matchLength);
38668  return sequenceLength;
38669  }
38670  /* span extDict & currentPrefixSegment */
38671  { size_t const length1 = dictEnd - match;
38672  ZSTD_memmove(oLitEnd, match, length1);
38673  op = oLitEnd + length1;
38674  sequence.matchLength -= length1;
38675  match = prefixStart;
38676  }
38677  }
38678  ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
38679  return sequenceLength;
38680 }
38681 
38682 HINT_INLINE
38683 size_t ZSTD_execSequence(BYTE* op,
38684  BYTE* const oend, seq_t sequence,
38685  const BYTE** litPtr, const BYTE* const litLimit,
38686  const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
38687 {
38688  BYTE* const oLitEnd = op + sequence.litLength;
38689  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
38690  BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
38691  BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */
38692  const BYTE* const iLitEnd = *litPtr + sequence.litLength;
38693  const BYTE* match = oLitEnd - sequence.offset;
38694 
38695  assert(op != NULL /* Precondition */);
38696  assert(oend_w < oend /* No underflow */);
38697 
38698 #if defined(__aarch64__)
38699  /* prefetch sequence starting from match that will be used for copy later */
38700  PREFETCH_L1(match);
38701 #endif
38702  /* Handle edge cases in a slow path:
38703  * - Read beyond end of literals
38704  * - Match end is within WILDCOPY_OVERLIMIT of oend
38705  * - 32-bit mode and the match length overflows
38706  */
38707  if (UNLIKELY(
38708  iLitEnd > litLimit ||
38709  oMatchEnd > oend_w ||
38710  (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
38711  return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
38712 
38713  /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
38714  assert(op <= oLitEnd /* No overflow */);
38715  assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
38716  assert(oMatchEnd <= oend /* No underflow */);
38717  assert(iLitEnd <= litLimit /* Literal length is in bounds */);
38718  assert(oLitEnd <= oend_w /* Can wildcopy literals */);
38719  assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
38720 
38721  /* Copy Literals:
38722  * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.
38723  * We likely don't need the full 32-byte wildcopy.
38724  */
38725  assert(WILDCOPY_OVERLENGTH >= 16);
38726  ZSTD_copy16(op, (*litPtr));
38727  if (UNLIKELY(sequence.litLength > 16)) {
38728  ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap);
38729  }
38730  op = oLitEnd;
38731  *litPtr = iLitEnd; /* update for next sequence */
38732 
38733  /* Copy Match */
38734  if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
38735  /* offset beyond prefix -> go into extDict */
38736  RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
38737  match = dictEnd + (match - prefixStart);
38738  if (match + sequence.matchLength <= dictEnd) {
38739  ZSTD_memmove(oLitEnd, match, sequence.matchLength);
38740  return sequenceLength;
38741  }
38742  /* span extDict & currentPrefixSegment */
38743  { size_t const length1 = dictEnd - match;
38744  ZSTD_memmove(oLitEnd, match, length1);
38745  op = oLitEnd + length1;
38746  sequence.matchLength -= length1;
38747  match = prefixStart;
38748  }
38749  }
38750  /* Match within prefix of 1 or more bytes */
38751  assert(op <= oMatchEnd);
38752  assert(oMatchEnd <= oend_w);
38753  assert(match >= prefixStart);
38754  assert(sequence.matchLength >= 1);
38755 
38756  /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
38757  * without overlap checking.
38758  */
38759  if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
38760  /* We bet on a full wildcopy for matches, since we expect matches to be
38761  * longer than literals (in general). In silesia, ~10% of matches are longer
38762  * than 16 bytes.
38763  */
38764  ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
38765  return sequenceLength;
38766  }
38767  assert(sequence.offset < WILDCOPY_VECLEN);
38768 
38769  /* Copy 8 bytes and spread the offset to be >= 8. */
38770  ZSTD_overlapCopy8(&op, &match, sequence.offset);
38772  /* If the match length is > 8 bytes, then continue with the wildcopy. */
38773  if (sequence.matchLength > 8) {
38774  assert(op < oMatchEnd);
38775  ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst);
38776  }
38777  return sequenceLength;
38778 }
38779 
38780 HINT_INLINE
38781 size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
38782  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
38783  const BYTE** litPtr, const BYTE* const litLimit,
38784  const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
38785 {
38786  BYTE* const oLitEnd = op + sequence.litLength;
38787  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
38788  BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
38789  const BYTE* const iLitEnd = *litPtr + sequence.litLength;
38790  const BYTE* match = oLitEnd - sequence.offset;
38791 
38792  assert(op != NULL /* Precondition */);
38793  assert(oend_w < oend /* No underflow */);
38794  /* Handle edge cases in a slow path:
38795  * - Read beyond end of literals
38796  * - Match end is within WILDCOPY_OVERLIMIT of oend
38797  * - 32-bit mode and the match length overflows
38798  */
38799  if (UNLIKELY(
38800  iLitEnd > litLimit ||
38801  oMatchEnd > oend_w ||
38802  (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
38803  return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
38804 
38805  /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
38806  assert(op <= oLitEnd /* No overflow */);
38807  assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
38808  assert(oMatchEnd <= oend /* No underflow */);
38809  assert(iLitEnd <= litLimit /* Literal length is in bounds */);
38810  assert(oLitEnd <= oend_w /* Can wildcopy literals */);
38811  assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
38812 
38813  /* Copy Literals:
38814  * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.
38815  * We likely don't need the full 32-byte wildcopy.
38816  */
38817  assert(WILDCOPY_OVERLENGTH >= 16);
38818  ZSTD_copy16(op, (*litPtr));
38819  if (UNLIKELY(sequence.litLength > 16)) {
38820  ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap);
38821  }
38822  op = oLitEnd;
38823  *litPtr = iLitEnd; /* update for next sequence */
38824 
38825  /* Copy Match */
38826  if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
38827  /* offset beyond prefix -> go into extDict */
38828  RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
38829  match = dictEnd + (match - prefixStart);
38830  if (match + sequence.matchLength <= dictEnd) {
38831  ZSTD_memmove(oLitEnd, match, sequence.matchLength);
38832  return sequenceLength;
38833  }
38834  /* span extDict & currentPrefixSegment */
38835  { size_t const length1 = dictEnd - match;
38836  ZSTD_memmove(oLitEnd, match, length1);
38837  op = oLitEnd + length1;
38838  sequence.matchLength -= length1;
38839  match = prefixStart;
38840  } }
38841  /* Match within prefix of 1 or more bytes */
38842  assert(op <= oMatchEnd);
38843  assert(oMatchEnd <= oend_w);
38844  assert(match >= prefixStart);
38845  assert(sequence.matchLength >= 1);
38846 
38847  /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
38848  * without overlap checking.
38849  */
38850  if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
38851  /* We bet on a full wildcopy for matches, since we expect matches to be
38852  * longer than literals (in general). In silesia, ~10% of matches are longer
38853  * than 16 bytes.
38854  */
38855  ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
38856  return sequenceLength;
38857  }
38858  assert(sequence.offset < WILDCOPY_VECLEN);
38859 
38860  /* Copy 8 bytes and spread the offset to be >= 8. */
38861  ZSTD_overlapCopy8(&op, &match, sequence.offset);
38862 
38863  /* If the match length is > 8 bytes, then continue with the wildcopy. */
38864  if (sequence.matchLength > 8) {
38865  assert(op < oMatchEnd);
38866  ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst);
38867  }
38868  return sequenceLength;
38869 }
38870 
38871 
38872 static void
38873 ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
38874 {
38875  const void* ptr = dt;
38876  const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr;
38877  DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
38878  DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits",
38879  (U32)DStatePtr->state, DTableH->tableLog);
38880  BIT_reloadDStream(bitD);
38881  DStatePtr->table = dt + 1;
38882 }
38883 
38884 FORCE_INLINE_TEMPLATE void
38885 ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits)
38887  size_t const lowBits = BIT_readBits(bitD, nbBits);
38888  DStatePtr->state = nextState + lowBits;
38889 }
38890 
38891 /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
38892  * offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32
38893  * bits before reloading. This value is the maximum number of bytes we read
38894  * after reloading when we are decoding long offsets.
38895  */
38896 #define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
38897  (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
38898  ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
38899  : 0)
38900 
38901 typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
38902 
38903 FORCE_INLINE_TEMPLATE seq_t
38904 ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
38905 {
38906  seq_t seq;
38907  /*
38908  * ZSTD_seqSymbol is a structure with a total of 64 bits wide. So it can be
38909  * loaded in one operation and extracted its fields by simply shifting or
38910  * bit-extracting on aarch64.
38911  * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh
38912  * operations that cause performance drop. This can be avoided by using this
38913  * ZSTD_memcpy hack.
38914  */
38915 #if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__))
38916  ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
38917  ZSTD_seqSymbol* const llDInfo = &llDInfoS;
38918  ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
38919  ZSTD_seqSymbol* const ofDInfo = &ofDInfoS;
38920  ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol));
38921  ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol));
38922  ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol));
38923 #else
38924  const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
38925  const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
38926  const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
38927 #endif
38928  seq.matchLength = mlDInfo->baseValue;
38929  seq.litLength = llDInfo->baseValue;
38930  { U32 const ofBase = ofDInfo->baseValue;
38931  BYTE const llBits = llDInfo->nbAdditionalBits;
38932  BYTE const mlBits = mlDInfo->nbAdditionalBits;
38933  BYTE const ofBits = ofDInfo->nbAdditionalBits;
38934  BYTE const totalBits = llBits+mlBits+ofBits;
38935 
38936  U16 const llNext = llDInfo->nextState;
38937  U16 const mlNext = mlDInfo->nextState;
38938  U16 const ofNext = ofDInfo->nextState;
38939  U32 const llnbBits = llDInfo->nbBits;
38940  U32 const mlnbBits = mlDInfo->nbBits;
38941  U32 const ofnbBits = ofDInfo->nbBits;
38942 
38943  assert(llBits <= MaxLLBits);
38944  assert(mlBits <= MaxMLBits);
38945  assert(ofBits <= MaxOff);
38946  /*
38947  * As gcc has better branch and block analyzers, sometimes it is only
38948  * valuable to mark likeliness for clang, it gives around 3-4% of
38949  * performance.
38950  */
38951 
38952  /* sequence */
38953  { size_t offset;
38954  if (ofBits > 1) {
38955  ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
38956  ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
38957  ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32);
38958  ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits);
38959  if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
38960  /* Always read extra bits, this keeps the logic simple,
38961  * avoids branches, and avoids accidentally reading 0 bits.
38962  */
38963  U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32;
38964  offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
38965  BIT_reloadDStream(&seqState->DStream);
38966  offset += BIT_readBitsFast(&seqState->DStream, extraBits);
38967  } else {
38968  offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
38969  if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
38970  }
38971  seqState->prevOffset[2] = seqState->prevOffset[1];
38972  seqState->prevOffset[1] = seqState->prevOffset[0];
38973  seqState->prevOffset[0] = offset;
38974  } else {
38975  U32 const ll0 = (llDInfo->baseValue == 0);
38976  if (LIKELY((ofBits == 0))) {
38977  offset = seqState->prevOffset[ll0];
38978  seqState->prevOffset[1] = seqState->prevOffset[!ll0];
38979  seqState->prevOffset[0] = offset;
38980  } else {
38981  offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
38982  { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
38983  temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
38984  if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
38985  seqState->prevOffset[1] = seqState->prevOffset[0];
38986  seqState->prevOffset[0] = offset = temp;
38987  } } }
38988  seq.offset = offset;
38989  }
38990 
38991  if (mlBits > 0)
38992  seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
38993 
38994  if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
38995  BIT_reloadDStream(&seqState->DStream);
38996  if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
38997  BIT_reloadDStream(&seqState->DStream);
38998  /* Ensure there are enough bits to read the rest of data in 64-bit mode. */
38999  ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
39000 
39001  if (llBits > 0)
39002  seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
39003 
39004  if (MEM_32bits())
39005  BIT_reloadDStream(&seqState->DStream);
39006 
39007  DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
39008  (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
39009 
39010  ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
39011  ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
39012  if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
39013  ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
39014  }
39015 
39016  return seq;
39017 }
39018 
39019 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
39020 MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
39021 {
39022  size_t const windowSize = dctx->fParams.windowSize;
39023  /* No dictionary used. */
39024  if (dctx->dictContentEndForFuzzing == NULL) return 0;
39025  /* Dictionary is our prefix. */
39026  if (prefixStart == dctx->dictContentBeginForFuzzing) return 1;
39027  /* Dictionary is not our ext-dict. */
39028  if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0;
39029  /* Dictionary is not within our window size. */
39030  if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0;
39031  /* Dictionary is active. */
39032  return 1;
39033 }
39034 
39035 MEM_STATIC void ZSTD_assertValidSequence(
39036  ZSTD_DCtx const* dctx,
39037  BYTE const* op, BYTE const* oend,
39038  seq_t const seq,
39039  BYTE const* prefixStart, BYTE const* virtualStart)
39040 {
39041 #if DEBUGLEVEL >= 1
39042  size_t const windowSize = dctx->fParams.windowSize;
39043  size_t const sequenceSize = seq.litLength + seq.matchLength;
39044  BYTE const* const oLitEnd = op + seq.litLength;
39045  DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
39046  (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
39047  assert(op <= oend);
39048  assert((size_t)(oend - op) >= sequenceSize);
39049  assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
39050  if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
39051  size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
39052  /* Offset must be within the dictionary. */
39053  assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
39054  assert(seq.offset <= windowSize + dictSize);
39055  } else {
39056  /* Offset must be within our window. */
39057  assert(seq.offset <= windowSize);
39058  }
39059 #else
39060  (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
39061 #endif
39062 }
39063 #endif
39064 
39065 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
39066 
39067 
39068 FORCE_INLINE_TEMPLATE size_t
39069 DONT_VECTORIZE
39070 ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
39071  void* dst, size_t maxDstSize,
39072  const void* seqStart, size_t seqSize, int nbSeq,
39073  const ZSTD_longOffset_e isLongOffset,
39074  const int frame)
39075 {
39076  const BYTE* ip = (const BYTE*)seqStart;
39077  const BYTE* const iend = ip + seqSize;
39078  BYTE* const ostart = (BYTE*)dst;
39079  BYTE* const oend = ostart + maxDstSize;
39080  BYTE* op = ostart;
39081  const BYTE* litPtr = dctx->litPtr;
39082  const BYTE* litBufferEnd = dctx->litBufferEnd;
39083  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
39084  const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
39085  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
39087  (void)frame;
39088 
39089  /* Regen sequences */
39090  if (nbSeq) {
39091  seqState_t seqState;
39092  dctx->fseEntropy = 1;
39093  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
39094  RETURN_ERROR_IF(
39095  ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
39096  corruption_detected, "");
39097  ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
39098  ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
39099  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
39100  assert(dst != NULL);
39101 
39102  ZSTD_STATIC_ASSERT(
39103  BIT_DStream_unfinished < BIT_DStream_completed &&
39104  BIT_DStream_endOfBuffer < BIT_DStream_completed &&
39105  BIT_DStream_completed < BIT_DStream_overflow);
39106 
39107  /* decompress without overrunning litPtr begins */
39108  {
39109  seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39110  /* Align the decompression loop to 32 + 16 bytes.
39111  *
39112  * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
39113  * speed swings based on the alignment of the decompression loop. This
39114  * performance swing is caused by parts of the decompression loop falling
39115  * out of the DSB. The entire decompression loop should fit in the DSB,
39116  * when it can't we get much worse performance. You can measure if you've
39117  * hit the good case or the bad case with this perf command for some
39118  * compressed file test.zst:
39119  *
39120  * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \
39121  * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst
39122  *
39123  * If you see most cycles served out of the MITE you've hit the bad case.
39124  * If you see most cycles served out of the DSB you've hit the good case.
39125  * If it is pretty even then you may be in an okay case.
39126  *
39127  * This issue has been reproduced on the following CPUs:
39128  * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
39129  * Use Instruments->Counters to get DSB/MITE cycles.
39130  * I never got performance swings, but I was able to
39131  * go from the good case of mostly DSB to half of the
39132  * cycles served from MITE.
39133  * - Coffeelake: Intel i9-9900k
39134  * - Coffeelake: Intel i7-9700k
39135  *
39136  * I haven't been able to reproduce the instability or DSB misses on any
39137  * of the following CPUS:
39138  * - Haswell
39139  * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH
39140  * - Skylake
39141  *
39142  * Alignment is done for each of the three major decompression loops:
39143  * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer
39144  * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer
39145  * - ZSTD_decompressSequences_body
39146  * Alignment choices are made to minimize large swings on bad cases and influence on performance
39147  * from changes external to this code, rather than to overoptimize on the current commit.
39148  *
39149  * If you are seeing performance stability this script can help test.
39150  * It tests on 4 commits in zstd where I saw performance change.
39151  *
39152  * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
39153  */
39154 #if defined(__GNUC__) && defined(__x86_64__)
39155  __asm__(".p2align 6");
39156 # if __GNUC__ >= 7
39157  /* good for gcc-7, gcc-9, and gcc-11 */
39158  __asm__("nop");
39159  __asm__(".p2align 5");
39160  __asm__("nop");
39161  __asm__(".p2align 4");
39162 # if __GNUC__ == 8 || __GNUC__ == 10
39163  /* good for gcc-8 and gcc-10 */
39164  __asm__("nop");
39165  __asm__(".p2align 3");
39166 # endif
39167 # endif
39168 #endif
39169 
39170  /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
39171  for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) {
39172  size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
39173 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39174  assert(!ZSTD_isError(oneSeqSize));
39175  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
39176 #endif
39177  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
39178  return oneSeqSize;
39179  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
39180  op += oneSeqSize;
39181  if (UNLIKELY(!--nbSeq))
39182  break;
39183  BIT_reloadDStream(&(seqState.DStream));
39184  sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39185  }
39186 
39187  /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
39188  if (nbSeq > 0) {
39189  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
39190  if (leftoverLit)
39191  {
39192  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
39193  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
39194  sequence.litLength -= leftoverLit;
39195  op += leftoverLit;
39196  }
39197  litPtr = dctx->litExtraBuffer;
39198  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
39199  dctx->litBufferLocation = ZSTD_not_in_dst;
39200  {
39201  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
39202 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39203  assert(!ZSTD_isError(oneSeqSize));
39204  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
39205 #endif
39206  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
39207  return oneSeqSize;
39208  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
39209  op += oneSeqSize;
39210  if (--nbSeq)
39211  BIT_reloadDStream(&(seqState.DStream));
39212  }
39213  }
39214  }
39215 
39216  if (nbSeq > 0) /* there is remaining lit from extra buffer */
39217  {
39218 
39219 #if defined(__GNUC__) && defined(__x86_64__)
39220  __asm__(".p2align 6");
39221  __asm__("nop");
39222 # if __GNUC__ != 7
39223  /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */
39224  __asm__(".p2align 4");
39225  __asm__("nop");
39226  __asm__(".p2align 3");
39227 # elif __GNUC__ >= 11
39228  __asm__(".p2align 3");
39229 # else
39230  __asm__(".p2align 5");
39231  __asm__("nop");
39232  __asm__(".p2align 3");
39233 # endif
39234 #endif
39235 
39236  for (; ; ) {
39237  seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39238  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
39239 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39240  assert(!ZSTD_isError(oneSeqSize));
39241  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
39242 #endif
39243  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
39244  return oneSeqSize;
39245  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
39246  op += oneSeqSize;
39247  if (UNLIKELY(!--nbSeq))
39248  break;
39249  BIT_reloadDStream(&(seqState.DStream));
39250  }
39251  }
39252 
39253  /* check if reached exact end */
39254  DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
39255  RETURN_ERROR_IF(nbSeq, corruption_detected, "");
39256  RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
39257  /* save reps for next block */
39258  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
39259  }
39260 
39261  /* last literal segment */
39262  if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
39263  {
39264  size_t const lastLLSize = litBufferEnd - litPtr;
39265  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
39266  if (op != NULL) {
39267  ZSTD_memmove(op, litPtr, lastLLSize);
39268  op += lastLLSize;
39269  }
39270  litPtr = dctx->litExtraBuffer;
39271  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
39272  dctx->litBufferLocation = ZSTD_not_in_dst;
39273  }
39274  { size_t const lastLLSize = litBufferEnd - litPtr;
39275  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
39276  if (op != NULL) {
39277  ZSTD_memcpy(op, litPtr, lastLLSize);
39278  op += lastLLSize;
39279  }
39280  }
39281 
39282  return op-ostart;
39283 }
39284 
39285 FORCE_INLINE_TEMPLATE size_t
39286 DONT_VECTORIZE
39287 ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
39288  void* dst, size_t maxDstSize,
39289  const void* seqStart, size_t seqSize, int nbSeq,
39290  const ZSTD_longOffset_e isLongOffset,
39291  const int frame)
39292 {
39293  const BYTE* ip = (const BYTE*)seqStart;
39294  const BYTE* const iend = ip + seqSize;
39295  BYTE* const ostart = (BYTE*)dst;
39296  BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer;
39297  BYTE* op = ostart;
39298  const BYTE* litPtr = dctx->litPtr;
39299  const BYTE* const litEnd = litPtr + dctx->litSize;
39300  const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart);
39301  const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
39302  const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
39303  DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq);
39304  (void)frame;
39305 
39306  /* Regen sequences */
39307  if (nbSeq) {
39308  seqState_t seqState;
39309  dctx->fseEntropy = 1;
39310  { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
39311  RETURN_ERROR_IF(
39312  ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)),
39313  corruption_detected, "");
39314  ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
39315  ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
39316  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
39317  assert(dst != NULL);
39318 
39319  ZSTD_STATIC_ASSERT(
39320  BIT_DStream_unfinished < BIT_DStream_completed &&
39321  BIT_DStream_endOfBuffer < BIT_DStream_completed &&
39322  BIT_DStream_completed < BIT_DStream_overflow);
39323 
39324 #if defined(__GNUC__) && defined(__x86_64__)
39325  __asm__(".p2align 6");
39326  __asm__("nop");
39327 # if __GNUC__ >= 7
39328  __asm__(".p2align 5");
39329  __asm__("nop");
39330  __asm__(".p2align 3");
39331 # else
39332  __asm__(".p2align 4");
39333  __asm__("nop");
39334  __asm__(".p2align 3");
39335 # endif
39336 #endif
39337 
39338  for ( ; ; ) {
39339  seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39340  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
39341 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39342  assert(!ZSTD_isError(oneSeqSize));
39343  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
39344 #endif
39345  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
39346  return oneSeqSize;
39347  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
39348  op += oneSeqSize;
39349  if (UNLIKELY(!--nbSeq))
39350  break;
39351  BIT_reloadDStream(&(seqState.DStream));
39352  }
39353 
39354  /* check if reached exact end */
39355  DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
39356  RETURN_ERROR_IF(nbSeq, corruption_detected, "");
39357  RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
39358  /* save reps for next block */
39359  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
39360  }
39361 
39362  /* last literal segment */
39363  { size_t const lastLLSize = litEnd - litPtr;
39364  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
39365  if (op != NULL) {
39366  ZSTD_memcpy(op, litPtr, lastLLSize);
39367  op += lastLLSize;
39368  }
39369  }
39370 
39371  return op-ostart;
39372 }
39373 
39374 static size_t
39375 ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
39376  void* dst, size_t maxDstSize,
39377  const void* seqStart, size_t seqSize, int nbSeq,
39378  const ZSTD_longOffset_e isLongOffset,
39379  const int frame)
39380 {
39381  return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39382 }
39383 
39384 static size_t
39385 ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
39386  void* dst, size_t maxDstSize,
39387  const void* seqStart, size_t seqSize, int nbSeq,
39388  const ZSTD_longOffset_e isLongOffset,
39389  const int frame)
39390 {
39391  return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39392 }
39393 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
39394 
39395 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
39396 
39397 FORCE_INLINE_TEMPLATE size_t
39398 ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
39399  const BYTE* const prefixStart, const BYTE* const dictEnd)
39400 {
39401  prefetchPos += sequence.litLength;
39402  { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
39403  const BYTE* const match = matchBase + prefetchPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
39404  * No consequence though : memory address is only used for prefetching, not for dereferencing */
39405  PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
39406  }
39407  return prefetchPos + sequence.matchLength;
39408 }
39409 
39410 /* This decoding function employs prefetching
39411  * to reduce latency impact of cache misses.
39412  * It's generally employed when block contains a significant portion of long-distance matches
39413  * or when coupled with a "cold" dictionary */
39414 FORCE_INLINE_TEMPLATE size_t
39415 ZSTD_decompressSequencesLong_body(
39416  ZSTD_DCtx* dctx,
39417  void* dst, size_t maxDstSize,
39418  const void* seqStart, size_t seqSize, int nbSeq,
39419  const ZSTD_longOffset_e isLongOffset,
39420  const int frame)
39421 {
39422  const BYTE* ip = (const BYTE*)seqStart;
39423  const BYTE* const iend = ip + seqSize;
39424  BYTE* const ostart = (BYTE*)dst;
39425  BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize;
39426  BYTE* op = ostart;
39427  const BYTE* litPtr = dctx->litPtr;
39428  const BYTE* litBufferEnd = dctx->litBufferEnd;
39429  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
39430  const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
39431  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
39432  (void)frame;
39433 
39434  /* Regen sequences */
39435  if (nbSeq) {
39436 #define STORED_SEQS 8
39437 #define STORED_SEQS_MASK (STORED_SEQS-1)
39438 #define ADVANCED_SEQS STORED_SEQS
39439  seq_t sequences[STORED_SEQS];
39440  int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
39441  seqState_t seqState;
39442  int seqNb;
39443  size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */
39444 
39445  dctx->fseEntropy = 1;
39446  { int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
39447  assert(dst != NULL);
39448  assert(iend >= ip);
39449  RETURN_ERROR_IF(
39450  ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
39451  corruption_detected, "");
39452  ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
39453  ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
39454  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
39455 
39456  /* prepare in advance */
39457  for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
39458  seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39459  prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
39460  sequences[seqNb] = sequence;
39461  }
39462  RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
39463 
39464  /* decompress without stomping litBuffer */
39465  for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb < nbSeq); seqNb++) {
39466  seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
39467  size_t oneSeqSize;
39468 
39469  if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
39470  {
39471  /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
39472  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
39473  if (leftoverLit)
39474  {
39475  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
39476  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
39477  sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
39478  op += leftoverLit;
39479  }
39480  litPtr = dctx->litExtraBuffer;
39481  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
39482  dctx->litBufferLocation = ZSTD_not_in_dst;
39483  oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
39484 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39485  assert(!ZSTD_isError(oneSeqSize));
39486  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
39487 #endif
39488  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
39489 
39490  prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
39491  sequences[seqNb & STORED_SEQS_MASK] = sequence;
39492  op += oneSeqSize;
39493  }
39494  else
39495  {
39496  /* lit buffer is either wholly contained in first or second split, or not split at all*/
39497  oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
39498  ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
39499  ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
39500 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39501  assert(!ZSTD_isError(oneSeqSize));
39502  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
39503 #endif
39504  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
39505 
39506  prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
39507  sequences[seqNb & STORED_SEQS_MASK] = sequence;
39508  op += oneSeqSize;
39509  }
39510  }
39511  RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
39512 
39513  /* finish queue */
39514  seqNb -= seqAdvance;
39515  for ( ; seqNb<nbSeq ; seqNb++) {
39516  seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
39517  if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
39518  {
39519  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
39520  if (leftoverLit)
39521  {
39522  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
39523  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
39524  sequence->litLength -= leftoverLit;
39525  op += leftoverLit;
39526  }
39527  litPtr = dctx->litExtraBuffer;
39528  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
39529  dctx->litBufferLocation = ZSTD_not_in_dst;
39530  {
39531  size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
39532 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39533  assert(!ZSTD_isError(oneSeqSize));
39534  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
39535 #endif
39536  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
39537  op += oneSeqSize;
39538  }
39539  }
39540  else
39541  {
39542  size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
39543  ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
39544  ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
39545 #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
39546  assert(!ZSTD_isError(oneSeqSize));
39547  if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
39548 #endif
39549  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
39550  op += oneSeqSize;
39551  }
39552  }
39553 
39554  /* save reps for next block */
39555  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
39556  }
39557 
39558  /* last literal segment */
39559  if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */
39560  {
39561  size_t const lastLLSize = litBufferEnd - litPtr;
39562  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
39563  if (op != NULL) {
39564  ZSTD_memmove(op, litPtr, lastLLSize);
39565  op += lastLLSize;
39566  }
39567  litPtr = dctx->litExtraBuffer;
39568  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
39569  }
39570  { size_t const lastLLSize = litBufferEnd - litPtr;
39571  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
39572  if (op != NULL) {
39573  ZSTD_memmove(op, litPtr, lastLLSize);
39574  op += lastLLSize;
39575  }
39576  }
39577 
39578  return op-ostart;
39579 }
39580 
39581 static size_t
39582 ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
39583  void* dst, size_t maxDstSize,
39584  const void* seqStart, size_t seqSize, int nbSeq,
39585  const ZSTD_longOffset_e isLongOffset,
39586  const int frame)
39587 {
39588  return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39589 }
39590 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
39591 
39592 
39593 
39594 #if DYNAMIC_BMI2
39595 
39596 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
39597 static BMI2_TARGET_ATTRIBUTE size_t
39598 DONT_VECTORIZE
39599 ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
39600  void* dst, size_t maxDstSize,
39601  const void* seqStart, size_t seqSize, int nbSeq,
39602  const ZSTD_longOffset_e isLongOffset,
39603  const int frame)
39604 {
39605  return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39606 }
39607 static BMI2_TARGET_ATTRIBUTE size_t
39608 DONT_VECTORIZE
39609 ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
39610  void* dst, size_t maxDstSize,
39611  const void* seqStart, size_t seqSize, int nbSeq,
39612  const ZSTD_longOffset_e isLongOffset,
39613  const int frame)
39614 {
39615  return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39616 }
39617 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
39618 
39619 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
39620 static BMI2_TARGET_ATTRIBUTE size_t
39621 ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
39622  void* dst, size_t maxDstSize,
39623  const void* seqStart, size_t seqSize, int nbSeq,
39624  const ZSTD_longOffset_e isLongOffset,
39625  const int frame)
39626 {
39627  return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39628 }
39629 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
39630 
39631 #endif /* DYNAMIC_BMI2 */
39633 typedef size_t (*ZSTD_decompressSequences_t)(
39634  ZSTD_DCtx* dctx,
39635  void* dst, size_t maxDstSize,
39636  const void* seqStart, size_t seqSize, int nbSeq,
39637  const ZSTD_longOffset_e isLongOffset,
39638  const int frame);
39639 
39640 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
39641 static size_t
39642 ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
39643  const void* seqStart, size_t seqSize, int nbSeq,
39644  const ZSTD_longOffset_e isLongOffset,
39645  const int frame)
39647  DEBUGLOG(5, "ZSTD_decompressSequences");
39648 #if DYNAMIC_BMI2
39649  if (ZSTD_DCtx_get_bmi2(dctx)) {
39650  return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39651  }
39652 #endif
39653  return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39654 }
39655 static size_t
39656 ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
39657  const void* seqStart, size_t seqSize, int nbSeq,
39658  const ZSTD_longOffset_e isLongOffset,
39659  const int frame)
39660 {
39662 #if DYNAMIC_BMI2
39663  if (ZSTD_DCtx_get_bmi2(dctx)) {
39664  return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39665  }
39666 #endif
39667  return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39668 }
39669 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
39670 
39671 
39672 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
39673 /* ZSTD_decompressSequencesLong() :
39674  * decompression function triggered when a minimum share of offsets is considered "long",
39675  * aka out of cache.
39676  * note : "long" definition seems overloaded here, sometimes meaning "wider than bitstream register", and sometimes meaning "farther than memory cache distance".
39677  * This function will try to mitigate main memory latency through the use of prefetching */
39678 static size_t
39679 ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
39680  void* dst, size_t maxDstSize,
39681  const void* seqStart, size_t seqSize, int nbSeq,
39682  const ZSTD_longOffset_e isLongOffset,
39683  const int frame)
39684 {
39685  DEBUGLOG(5, "ZSTD_decompressSequencesLong");
39686 #if DYNAMIC_BMI2
39687  if (ZSTD_DCtx_get_bmi2(dctx)) {
39688  return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39689  }
39690 #endif
39691  return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
39692 }
39693 #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
39694 
39695 
39701 static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart)
39702 {
39703  return (size_t)(op - virtualStart);
39704 }
39705 
39706 typedef struct {
39707  unsigned longOffsetShare;
39708  unsigned maxNbAdditionalBits;
39709 } ZSTD_OffsetInfo;
39710 
39711 /* ZSTD_getOffsetInfo() :
39712  * condition : offTable must be valid
39713  * @return : "share" of long offsets (arbitrarily defined as > (1<<23))
39714  * compared to maximum possible of (1<<OffFSELog),
39715  * as well as the maximum number additional bits required.
39716  */
39717 static ZSTD_OffsetInfo
39718 ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable, int nbSeq)
39719 {
39720  ZSTD_OffsetInfo info = {0, 0};
39721  /* If nbSeq == 0, then the offTable is uninitialized, but we have
39722  * no sequences, so both values should be 0.
39723  */
39724  if (nbSeq != 0) {
39725  const void* ptr = offTable;
39726  U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
39727  const ZSTD_seqSymbol* table = offTable + 1;
39728  U32 const max = 1 << tableLog;
39729  U32 u;
39730  DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
39731 
39732  assert(max <= (1 << OffFSELog)); /* max not too large */
39733  for (u=0; u<max; u++) {
39734  info.maxNbAdditionalBits = MAX(info.maxNbAdditionalBits, table[u].nbAdditionalBits);
39735  if (table[u].nbAdditionalBits > 22) info.longOffsetShare += 1;
39736  }
39737 
39738  assert(tableLog <= OffFSELog);
39739  info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */
39740  }
39741 
39742  return info;
39743 }
39744 
39750 static size_t ZSTD_maxShortOffset(void)
39751 {
39752  if (MEM_64bits()) {
39753  /* We can decode any offset without reloading bits.
39754  * This might change if the max window size grows.
39755  */
39756  ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
39757  return (size_t)-1;
39758  } else {
39759  /* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1.
39760  * This offBase would require STREAM_ACCUMULATOR_MIN extra bits.
39761  * Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset.
39762  */
39763  size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1;
39764  size_t const maxOffset = maxOffbase - ZSTD_REP_NUM;
39765  assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN);
39766  return maxOffset;
39767  }
39768 }
39769 
39770 size_t
39771 ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
39772  void* dst, size_t dstCapacity,
39773  const void* src, size_t srcSize, const int frame, const streaming_operation streaming)
39774 { /* blockType == blockCompressed */
39775  const BYTE* ip = (const BYTE*)src;
39776  DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
39777 
39778  /* Note : the wording of the specification
39779  * allows compressed block to be sized exactly ZSTD_BLOCKSIZE_MAX.
39780  * This generally does not happen, as it makes little sense,
39781  * since an uncompressed block would feature same size and have no decompression cost.
39782  * Also, note that decoder from reference libzstd before < v1.5.4
39783  * would consider this edge case as an error.
39784  * As a consequence, avoid generating compressed blocks of size ZSTD_BLOCKSIZE_MAX
39785  * for broader compatibility with the deployed ecosystem of zstd decoders */
39786  RETURN_ERROR_IF(srcSize > ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
39787 
39788  /* Decode literals section */
39789  { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
39790  DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize);
39791  if (ZSTD_isError(litCSize)) return litCSize;
39792  ip += litCSize;
39793  srcSize -= litCSize;
39794  }
39795 
39796  /* Build Decoding Tables */
39797  {
39798  /* Compute the maximum block size, which must also work when !frame and fParams are unset.
39799  * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
39800  */
39801  size_t const blockSizeMax = MIN(dstCapacity, (frame ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX));
39802  size_t const totalHistorySize = ZSTD_totalHistorySize((BYTE*)dst + blockSizeMax, (BYTE const*)dctx->virtualStart);
39803  /* isLongOffset must be true if there are long offsets.
39804  * Offsets are long if they are larger than ZSTD_maxShortOffset().
39805  * We don't expect that to be the case in 64-bit mode.
39806  *
39807  * We check here to see if our history is large enough to allow long offsets.
39808  * If it isn't, then we can't possible have (valid) long offsets. If the offset
39809  * is invalid, then it is okay to read it incorrectly.
39810  *
39811  * If isLongOffsets is true, then we will later check our decoding table to see
39812  * if it is even possible to generate long offsets.
39813  */
39814  ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset()));
39815  /* These macros control at build-time which decompressor implementation
39816  * we use. If neither is defined, we do some inspection and dispatch at
39817  * runtime.
39818  */
39819 #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
39820  !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
39821  int usePrefetchDecoder = dctx->ddictIsCold;
39822 #else
39823  /* Set to 1 to avoid computing offset info if we don't need to.
39824  * Otherwise this value is ignored.
39825  */
39826  int usePrefetchDecoder = 1;
39827 #endif
39828  int nbSeq;
39829  size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);
39830  if (ZSTD_isError(seqHSize)) return seqHSize;
39831  ip += seqHSize;
39832  srcSize -= seqHSize;
39833 
39834  RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
39835  RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall,
39836  "invalid dst");
39837 
39838  /* If we could potentially have long offsets, or we might want to use the prefetch decoder,
39839  * compute information about the share of long offsets, and the maximum nbAdditionalBits.
39840  * NOTE: could probably use a larger nbSeq limit
39841  */
39842  if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) {
39843  ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq);
39844  if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) {
39845  /* If isLongOffset, but the maximum number of additional bits that we see in our table is small
39846  * enough, then we know it is impossible to have too long an offset in this block, so we can
39847  * use the regular offset decoder.
39848  */
39849  isLongOffset = ZSTD_lo_isRegularOffset;
39850  }
39851  if (!usePrefetchDecoder) {
39852  U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
39853  usePrefetchDecoder = (info.longOffsetShare >= minShare);
39854  }
39855  }
39856 
39857  dctx->ddictIsCold = 0;
39858 
39859 #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
39860  !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
39861  if (usePrefetchDecoder) {
39862 #else
39863  (void)usePrefetchDecoder;
39864  {
39865 #endif
39866 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
39867  return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
39868 #endif
39869  }
39870 
39871 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
39872  /* else */
39873  if (dctx->litBufferLocation == ZSTD_split)
39874  return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
39875  else
39876  return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
39877 #endif
39878  }
39879 }
39880 
39881 
39882 void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
39884  if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
39885  dctx->dictEnd = dctx->previousDstEnd;
39886  dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
39887  dctx->prefixStart = dst;
39888  dctx->previousDstEnd = dst;
39889  }
39890 }
39891 
39892 
39893 size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
39894  void* dst, size_t dstCapacity,
39895  const void* src, size_t srcSize)
39897  size_t dSize;
39898  ZSTD_checkContinuity(dctx, dst, dstCapacity);
39899  dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming);
39900  dctx->previousDstEnd = (char*)dst + dSize;
39901  return dSize;
39902 }
39903 
39904 
39905 /* NOTE: Must just wrap ZSTD_decompressBlock_deprecated() */
39906 size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
39907  void* dst, size_t dstCapacity,
39908  const void* src, size_t srcSize)
39909 {
39910  return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize);
39911 }
39912 /**** ended inlining decompress/zstd_decompress_block.c ****/
39913 
39914 /**** start inlining dictBuilder/cover.c ****/
39915 /*
39916  * Copyright (c) Meta Platforms, Inc. and affiliates.
39917  * All rights reserved.
39918  *
39919  * This source code is licensed under both the BSD-style license (found in the
39920  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
39921  * in the COPYING file in the root directory of this source tree).
39922  * You may select, at your option, one of the above-listed licenses.
39923  */
39924 
39925 /* *****************************************************************************
39926  * Constructs a dictionary using a heuristic based on the following paper:
39927  *
39928  * Liao, Petri, Moffat, Wirth
39929  * Effective Construction of Relative Lempel-Ziv Dictionaries
39930  * Published in WWW 2016.
39931  *
39932  * Adapted from code originally written by @ot (Giuseppe Ottaviano).
39933  ******************************************************************************/
39935 /*-*************************************
39936 * Dependencies
39937 ***************************************/
39938 #include <stdio.h> /* fprintf */
39939 #include <stdlib.h> /* malloc, free, qsort */
39940 #include <string.h> /* memset */
39941 #include <time.h> /* clock */
39942 
39943 #ifndef ZDICT_STATIC_LINKING_ONLY
39944 # define ZDICT_STATIC_LINKING_ONLY
39945 #endif
39946 
39947 /**** skipping file: ../common/mem.h ****/
39948 /**** skipping file: ../common/pool.h ****/
39949 /**** skipping file: ../common/threading.h ****/
39950 /**** skipping file: ../common/zstd_internal.h ****/
39951 /**** skipping file: ../common/bits.h ****/
39952 /**** start inlining ../zdict.h ****/
39953 /*
39954  * Copyright (c) Meta Platforms, Inc. and affiliates.
39955  * All rights reserved.
39956  *
39957  * This source code is licensed under both the BSD-style license (found in the
39958  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
39959  * in the COPYING file in the root directory of this source tree).
39960  * You may select, at your option, one of the above-listed licenses.
39961  */
39962 
39963 #if defined (__cplusplus)
39964 extern "C" {
39965 #endif
39966 
39967 #ifndef ZSTD_ZDICT_H
39968 #define ZSTD_ZDICT_H
39969 
39970 /*====== Dependencies ======*/
39971 #include <stddef.h> /* size_t */
39973 
39974 /* ===== ZDICTLIB_API : control library symbols visibility ===== */
39975 #ifndef ZDICTLIB_VISIBLE
39976  /* Backwards compatibility with old macro name */
39977 # ifdef ZDICTLIB_VISIBILITY
39978 # define ZDICTLIB_VISIBLE ZDICTLIB_VISIBILITY
39979 # elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
39980 # define ZDICTLIB_VISIBLE __attribute__ ((visibility ("default")))
39981 # else
39982 # define ZDICTLIB_VISIBLE
39983 # endif
39984 #endif
39985 
39986 #ifndef ZDICTLIB_HIDDEN
39987 # if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
39988 # define ZDICTLIB_HIDDEN __attribute__ ((visibility ("hidden")))
39989 # else
39990 # define ZDICTLIB_HIDDEN
39991 # endif
39992 #endif
39993 
39994 #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
39995 # define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBLE
39996 #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
39997 # define ZDICTLIB_API __declspec(dllimport) ZDICTLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
39998 #else
39999 # define ZDICTLIB_API ZDICTLIB_VISIBLE
40000 #endif
40001 
40002 /*******************************************************************************
40003  * Zstd dictionary builder
40004  *
40005  * FAQ
40006  * ===
40007  * Why should I use a dictionary?
40008  * ------------------------------
40009  *
40010  * Zstd can use dictionaries to improve compression ratio of small data.
40011  * Traditionally small files don't compress well because there is very little
40012  * repetition in a single sample, since it is small. But, if you are compressing
40013  * many similar files, like a bunch of JSON records that share the same
40014  * structure, you can train a dictionary on ahead of time on some samples of
40015  * these files. Then, zstd can use the dictionary to find repetitions that are
40016  * present across samples. This can vastly improve compression ratio.
40017  *
40018  * When is a dictionary useful?
40019  * ----------------------------
40020  *
40021  * Dictionaries are useful when compressing many small files that are similar.
40022  * The larger a file is, the less benefit a dictionary will have. Generally,
40023  * we don't expect dictionary compression to be effective past 100KB. And the
40024  * smaller a file is, the more we would expect the dictionary to help.
40025  *
40026  * How do I use a dictionary?
40027  * --------------------------
40028  *
40029  * Simply pass the dictionary to the zstd compressor with
40030  * `ZSTD_CCtx_loadDictionary()`. The same dictionary must then be passed to
40031  * the decompressor, using `ZSTD_DCtx_loadDictionary()`. There are other
40032  * more advanced functions that allow selecting some options, see zstd.h for
40033  * complete documentation.
40034  *
40035  * What is a zstd dictionary?
40036  * --------------------------
40037  *
40038  * A zstd dictionary has two pieces: Its header, and its content. The header
40039  * contains a magic number, the dictionary ID, and entropy tables. These
40040  * entropy tables allow zstd to save on header costs in the compressed file,
40041  * which really matters for small data. The content is just bytes, which are
40042  * repeated content that is common across many samples.
40043  *
40044  * What is a raw content dictionary?
40045  * ---------------------------------
40046  *
40047  * A raw content dictionary is just bytes. It doesn't have a zstd dictionary
40048  * header, a dictionary ID, or entropy tables. Any buffer is a valid raw
40049  * content dictionary.
40050  *
40051  * How do I train a dictionary?
40052  * ----------------------------
40053  *
40054  * Gather samples from your use case. These samples should be similar to each
40055  * other. If you have several use cases, you could try to train one dictionary
40056  * per use case.
40057  *
40058  * Pass those samples to `ZDICT_trainFromBuffer()` and that will train your
40059  * dictionary. There are a few advanced versions of this function, but this
40060  * is a great starting point. If you want to further tune your dictionary
40061  * you could try `ZDICT_optimizeTrainFromBuffer_cover()`. If that is too slow
40062  * you can try `ZDICT_optimizeTrainFromBuffer_fastCover()`.
40063  *
40064  * If the dictionary training function fails, that is likely because you
40065  * either passed too few samples, or a dictionary would not be effective
40066  * for your data. Look at the messages that the dictionary trainer printed,
40067  * if it doesn't say too few samples, then a dictionary would not be effective.
40068  *
40069  * How large should my dictionary be?
40070  * ----------------------------------
40071  *
40072  * A reasonable dictionary size, the `dictBufferCapacity`, is about 100KB.
40073  * The zstd CLI defaults to a 110KB dictionary. You likely don't need a
40074  * dictionary larger than that. But, most use cases can get away with a
40075  * smaller dictionary. The advanced dictionary builders can automatically
40076  * shrink the dictionary for you, and select the smallest size that doesn't
40077  * hurt compression ratio too much. See the `shrinkDict` parameter.
40078  * A smaller dictionary can save memory, and potentially speed up
40079  * compression.
40080  *
40081  * How many samples should I provide to the dictionary builder?
40082  * ------------------------------------------------------------
40083  *
40084  * We generally recommend passing ~100x the size of the dictionary
40085  * in samples. A few thousand should suffice. Having too few samples
40086  * can hurt the dictionaries effectiveness. Having more samples will
40087  * only improve the dictionaries effectiveness. But having too many
40088  * samples can slow down the dictionary builder.
40089  *
40090  * How do I determine if a dictionary will be effective?
40091  * -----------------------------------------------------
40092  *
40093  * Simply train a dictionary and try it out. You can use zstd's built in
40094  * benchmarking tool to test the dictionary effectiveness.
40095  *
40096  * # Benchmark levels 1-3 without a dictionary
40097  * zstd -b1e3 -r /path/to/my/files
40098  * # Benchmark levels 1-3 with a dictionary
40099  * zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary
40100  *
40101  * When should I retrain a dictionary?
40102  * -----------------------------------
40103  *
40104  * You should retrain a dictionary when its effectiveness drops. Dictionary
40105  * effectiveness drops as the data you are compressing changes. Generally, we do
40106  * expect dictionaries to "decay" over time, as your data changes, but the rate
40107  * at which they decay depends on your use case. Internally, we regularly
40108  * retrain dictionaries, and if the new dictionary performs significantly
40109  * better than the old dictionary, we will ship the new dictionary.
40110  *
40111  * I have a raw content dictionary, how do I turn it into a zstd dictionary?
40112  * -------------------------------------------------------------------------
40113  *
40114  * If you have a raw content dictionary, e.g. by manually constructing it, or
40115  * using a third-party dictionary builder, you can turn it into a zstd
40116  * dictionary by using `ZDICT_finalizeDictionary()`. You'll also have to
40117  * provide some samples of the data. It will add the zstd header to the
40118  * raw content, which contains a dictionary ID and entropy tables, which
40119  * will improve compression ratio, and allow zstd to write the dictionary ID
40120  * into the frame, if you so choose.
40121  *
40122  * Do I have to use zstd's dictionary builder?
40123  * -------------------------------------------
40124  *
40125  * No! You can construct dictionary content however you please, it is just
40126  * bytes. It will always be valid as a raw content dictionary. If you want
40127  * a zstd dictionary, which can improve compression ratio, use
40128  * `ZDICT_finalizeDictionary()`.
40129  *
40130  * What is the attack surface of a zstd dictionary?
40131  * ------------------------------------------------
40132  *
40133  * Zstd is heavily fuzz tested, including loading fuzzed dictionaries, so
40134  * zstd should never crash, or access out-of-bounds memory no matter what
40135  * the dictionary is. However, if an attacker can control the dictionary
40136  * during decompression, they can cause zstd to generate arbitrary bytes,
40137  * just like if they controlled the compressed data.
40138  *
40139  ******************************************************************************/
40140 
40141 
40162 ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
40163  const void* samplesBuffer,
40164  const size_t* samplesSizes, unsigned nbSamples);
40165 
40166 typedef struct {
40167  int compressionLevel; /**< optimize for a specific zstd compression level; 0 means default */
40168  unsigned notificationLevel; /**< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
40169  unsigned dictID; /**< force dictID value; 0 means auto mode (32-bits random value)
40170  * NOTE: The zstd format reserves some dictionary IDs for future use.
40171  * You may use them in private settings, but be warned that they
40172  * may be used by zstd in a public dictionary registry in the future.
40173  * These dictionary IDs are:
40174  * - low range : <= 32767
40175  * - high range : >= (2^31)
40176  */
40177 } ZDICT_params_t;
40178 
40214 ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dstDictBuffer, size_t maxDictSize,
40215  const void* dictContent, size_t dictContentSize,
40216  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
40217  ZDICT_params_t parameters);
40218 
40220 /*====== Helper functions ======*/
40221 ZDICTLIB_API unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize); /**< extracts dictID; @return zero if error (not a valid dictionary) */
40222 ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize); /* returns dict header size; returns a ZSTD error code on failure */
40223 ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode);
40224 ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
40225 
40226 #endif /* ZSTD_ZDICT_H */
40227 
40228 #if defined(ZDICT_STATIC_LINKING_ONLY) && !defined(ZSTD_ZDICT_H_STATIC)
40229 #define ZSTD_ZDICT_H_STATIC
40230 
40231 /* This can be overridden externally to hide static symbols. */
40232 #ifndef ZDICTLIB_STATIC_API
40233 # if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
40234 # define ZDICTLIB_STATIC_API __declspec(dllexport) ZDICTLIB_VISIBLE
40235 # elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
40236 # define ZDICTLIB_STATIC_API __declspec(dllimport) ZDICTLIB_VISIBLE
40237 # else
40238 # define ZDICTLIB_STATIC_API ZDICTLIB_VISIBLE
40239 # endif
40240 #endif
40242 /* ====================================================================================
40243  * The definitions in this section are considered experimental.
40244  * They should never be used with a dynamic library, as they may change in the future.
40245  * They are provided for advanced usages.
40246  * Use them only in association with static linking.
40247  * ==================================================================================== */
40249 #define ZDICT_DICTSIZE_MIN 256
40250 /* Deprecated: Remove in v1.6.0 */
40251 #define ZDICT_CONTENTSIZE_MIN 128
40257 typedef struct {
40258  unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */
40259  unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */
40260  unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */
40261  unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */
40262  double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (1.0), 1.0 when all samples are used for both training and testing */
40263  unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */
40264  unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */
40265  ZDICT_params_t zParams;
40266 } ZDICT_cover_params_t;
40268 typedef struct {
40269  unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */
40270  unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */
40271  unsigned f; /* log of size of frequency array : constraint: 0 < f <= 31 : 1 means default(20)*/
40272  unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */
40273  unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */
40274  double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (0.75), 1.0 when all samples are used for both training and testing */
40275  unsigned accel; /* Acceleration level: constraint: 0 < accel <= 10, higher means faster and less accurate, 0 means default(1) */
40276  unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */
40277  unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */
40278 
40279  ZDICT_params_t zParams;
40280 } ZDICT_fastCover_params_t;
40281 
40296 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
40297  void *dictBuffer, size_t dictBufferCapacity,
40298  const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
40299  ZDICT_cover_params_t parameters);
40300 
40318 ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
40319  void* dictBuffer, size_t dictBufferCapacity,
40320  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
40321  ZDICT_cover_params_t* parameters);
40322 
40339 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer,
40340  size_t dictBufferCapacity, const void *samplesBuffer,
40341  const size_t *samplesSizes, unsigned nbSamples,
40342  ZDICT_fastCover_params_t parameters);
40343 
40362 ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer,
40363  size_t dictBufferCapacity, const void* samplesBuffer,
40364  const size_t* samplesSizes, unsigned nbSamples,
40365  ZDICT_fastCover_params_t* parameters);
40366 
40367 typedef struct {
40368  unsigned selectivityLevel; /* 0 means default; larger => select more => larger dictionary */
40369  ZDICT_params_t zParams;
40370 } ZDICT_legacy_params_t;
40371 
40387 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy(
40388  void* dictBuffer, size_t dictBufferCapacity,
40389  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
40390  ZDICT_legacy_params_t parameters);
40392 
40393 /* Deprecation warnings */
40394 /* It is generally possible to disable deprecation warnings from compiler,
40395  for example with -Wno-deprecated-declarations for gcc
40396  or _CRT_SECURE_NO_WARNINGS in Visual.
40397  Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */
40398 #ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS
40399 # define ZDICT_DEPRECATED(message) /* disable deprecation warnings */
40400 #else
40401 # define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
40402 # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
40403 # define ZDICT_DEPRECATED(message) [[deprecated(message)]]
40404 # elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405)
40405 # define ZDICT_DEPRECATED(message) __attribute__((deprecated(message)))
40406 # elif (ZDICT_GCC_VERSION >= 301)
40407 # define ZDICT_DEPRECATED(message) __attribute__((deprecated))
40408 # elif defined(_MSC_VER)
40409 # define ZDICT_DEPRECATED(message) __declspec(deprecated(message))
40410 # else
40411 # pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler")
40412 # define ZDICT_DEPRECATED(message)
40413 # endif
40414 #endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */
40415 
40416 ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead")
40418 size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
40419  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
40420 
40421 
40422 #endif /* ZSTD_ZDICT_H_STATIC */
40423 
40424 #if defined (__cplusplus)
40425 }
40426 #endif
40427 /**** ended inlining ../zdict.h ****/
40428 /**** start inlining cover.h ****/
40429 /*
40430  * Copyright (c) Meta Platforms, Inc. and affiliates.
40431  * All rights reserved.
40432  *
40433  * This source code is licensed under both the BSD-style license (found in the
40434  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
40435  * in the COPYING file in the root directory of this source tree).
40436  * You may select, at your option, one of the above-listed licenses.
40437  */
40438 
40439 #ifndef ZDICT_STATIC_LINKING_ONLY
40440 # define ZDICT_STATIC_LINKING_ONLY
40441 #endif
40442 
40443 #include <stdio.h> /* fprintf */
40444 #include <stdlib.h> /* malloc, free, qsort */
40445 #include <string.h> /* memset */
40446 #include <time.h> /* clock */
40447 /**** skipping file: ../common/mem.h ****/
40448 /**** skipping file: ../common/pool.h ****/
40449 /**** skipping file: ../common/threading.h ****/
40450 /**** skipping file: ../common/zstd_internal.h ****/
40451 /**** skipping file: ../zdict.h ****/
40461 typedef struct COVER_best_s {
40464  size_t liveJobs;
40465  void *dict;
40466  size_t dictSize;
40468  size_t compressedSize;
40469 } COVER_best_t;
40470 
40474 typedef struct {
40475  U32 begin;
40476  U32 end;
40477  U32 score;
40478 } COVER_segment_t;
40479 
40483 typedef struct {
40484  U32 num;
40485  U32 size;
40487 
40491 typedef struct COVER_dictSelection {
40492  BYTE* dictContent;
40493  size_t dictSize;
40494  size_t totalCompressedSize;
40496 
40510 COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize, U32 nbDmers,
40511  U32 k, U32 passes);
40512 
40516 void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel);
40517 
40522  const size_t *samplesSizes, const BYTE *samples,
40523  size_t *offsets,
40524  size_t nbTrainSamples, size_t nbSamples,
40525  BYTE *const dict, size_t dictBufferCapacity);
40526 
40530 size_t COVER_sum(const size_t *samplesSizes, unsigned nbSamples) ;
40531 
40535 void COVER_best_init(COVER_best_t *best);
40536 
40540 void COVER_best_wait(COVER_best_t *best);
40541 
40545 void COVER_best_destroy(COVER_best_t *best);
40546 
40551 void COVER_best_start(COVER_best_t *best);
40552 
40558 void COVER_best_finish(COVER_best_t *best, ZDICT_cover_params_t parameters,
40559  COVER_dictSelection_t selection);
40565 
40571 
40577 
40584  COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBufferCapacity,
40585  size_t dictContentSize, const BYTE* samplesBuffer, const size_t* samplesSizes, unsigned nbFinalizeSamples,
40586  size_t nbCheckSamples, size_t nbSamples, ZDICT_cover_params_t params, size_t* offsets, size_t totalCompressedSize);
40587 /**** ended inlining cover.h ****/
40588 
40589 /*-*************************************
40590 * Constants
40591 ***************************************/
40599 #define COVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB))
40600 #define COVER_DEFAULT_SPLITPOINT 1.0
40601 
40602 /*-*************************************
40603 * Console display
40604 ***************************************/
40605 #ifndef LOCALDISPLAYLEVEL
40606 static int g_displayLevel = 0;
40607 #endif
40608 #undef DISPLAY
40609 #define DISPLAY(...) \
40610  { \
40611  fprintf(stderr, __VA_ARGS__); \
40612  fflush(stderr); \
40613  }
40614 #undef LOCALDISPLAYLEVEL
40615 #define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
40616  if (displayLevel >= l) { \
40617  DISPLAY(__VA_ARGS__); \
40618  } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
40619 #undef DISPLAYLEVEL
40620 #define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
40621 
40622 #ifndef LOCALDISPLAYUPDATE
40623 static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
40624 static clock_t g_time = 0;
40625 #endif
40626 #undef LOCALDISPLAYUPDATE
40627 #define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
40628  if (displayLevel >= l) { \
40629  if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
40630  g_time = clock(); \
40631  DISPLAY(__VA_ARGS__); \
40632  } \
40633  }
40634 #undef DISPLAYUPDATE
40635 #define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
40637 /*-*************************************
40638 * Hash table
40639 ***************************************
40640 * A small specialized hash map for storing activeDmers.
40641 * The map does not resize, so if it becomes full it will loop forever.
40642 * Thus, the map must be large enough to store every value.
40643 * The map implements linear probing and keeps its load less than 0.5.
40644 */
40646 #define MAP_EMPTY_VALUE ((U32)-1)
40647 typedef struct COVER_map_pair_t_s {
40648  U32 key;
40649  U32 value;
40651 
40652 typedef struct COVER_map_s {
40654  U32 sizeLog;
40655  U32 size;
40656  U32 sizeMask;
40657 } COVER_map_t;
40658 
40662 static void COVER_map_clear(COVER_map_t *map) {
40663  memset(map->data, MAP_EMPTY_VALUE, map->size * sizeof(COVER_map_pair_t));
40664 }
40665 
40672 static int COVER_map_init(COVER_map_t *map, U32 size) {
40673  map->sizeLog = ZSTD_highbit32(size) + 2;
40674  map->size = (U32)1 << map->sizeLog;
40675  map->sizeMask = map->size - 1;
40676  map->data = (COVER_map_pair_t *)malloc(map->size * sizeof(COVER_map_pair_t));
40677  if (!map->data) {
40678  map->sizeLog = 0;
40679  map->size = 0;
40680  return 0;
40681  }
40682  COVER_map_clear(map);
40683  return 1;
40684 }
40685 
40689 static const U32 COVER_prime4bytes = 2654435761U;
40690 static U32 COVER_map_hash(COVER_map_t *map, U32 key) {
40691  return (key * COVER_prime4bytes) >> (32 - map->sizeLog);
40692 }
40693 
40697 static U32 COVER_map_index(COVER_map_t *map, U32 key) {
40698  const U32 hash = COVER_map_hash(map, key);
40699  U32 i;
40700  for (i = hash;; i = (i + 1) & map->sizeMask) {
40701  COVER_map_pair_t *pos = &map->data[i];
40702  if (pos->value == MAP_EMPTY_VALUE) {
40703  return i;
40704  }
40705  if (pos->key == key) {
40706  return i;
40707  }
40708  }
40709 }
40710 
40716 static U32 *COVER_map_at(COVER_map_t *map, U32 key) {
40717  COVER_map_pair_t *pos = &map->data[COVER_map_index(map, key)];
40718  if (pos->value == MAP_EMPTY_VALUE) {
40719  pos->key = key;
40720  pos->value = 0;
40721  }
40722  return &pos->value;
40723 }
40724 
40728 static void COVER_map_remove(COVER_map_t *map, U32 key) {
40729  U32 i = COVER_map_index(map, key);
40730  COVER_map_pair_t *del = &map->data[i];
40731  U32 shift = 1;
40732  if (del->value == MAP_EMPTY_VALUE) {
40733  return;
40734  }
40735  for (i = (i + 1) & map->sizeMask;; i = (i + 1) & map->sizeMask) {
40736  COVER_map_pair_t *const pos = &map->data[i];
40737  /* If the position is empty we are done */
40738  if (pos->value == MAP_EMPTY_VALUE) {
40739  del->value = MAP_EMPTY_VALUE;
40740  return;
40741  }
40742  /* If pos can be moved to del do so */
40743  if (((i - COVER_map_hash(map, pos->key)) & map->sizeMask) >= shift) {
40744  del->key = pos->key;
40745  del->value = pos->value;
40746  del = pos;
40747  shift = 1;
40748  } else {
40749  ++shift;
40750  }
40751  }
40752 }
40753 
40757 static void COVER_map_destroy(COVER_map_t *map) {
40758  if (map->data) {
40759  free(map->data);
40760  }
40761  map->data = NULL;
40762  map->size = 0;
40765 /*-*************************************
40766 * Context
40767 ***************************************/
40769 typedef struct {
40770  const BYTE *samples;
40771  size_t *offsets;
40772  const size_t *samplesSizes;
40773  size_t nbSamples;
40774  size_t nbTrainSamples;
40775  size_t nbTestSamples;
40776  U32 *suffix;
40777  size_t suffixSize;
40778  U32 *freqs;
40779  U32 *dmerAt;
40780  unsigned d;
40781 } COVER_ctx_t;
40782 
40783 /* We need a global context for qsort... */
40784 static COVER_ctx_t *g_coverCtx = NULL;
40785 
40786 /*-*************************************
40787 * Helper functions
40788 ***************************************/
40789 
40793 size_t COVER_sum(const size_t *samplesSizes, unsigned nbSamples) {
40794  size_t sum = 0;
40795  unsigned i;
40796  for (i = 0; i < nbSamples; ++i) {
40797  sum += samplesSizes[i];
40798  }
40799  return sum;
40800 }
40801 
40807 static int COVER_cmp(COVER_ctx_t *ctx, const void *lp, const void *rp) {
40808  U32 const lhs = *(U32 const *)lp;
40809  U32 const rhs = *(U32 const *)rp;
40810  return memcmp(ctx->samples + lhs, ctx->samples + rhs, ctx->d);
40811 }
40815 static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp) {
40816  U64 const mask = (ctx->d == 8) ? (U64)-1 : (((U64)1 << (8 * ctx->d)) - 1);
40817  U64 const lhs = MEM_readLE64(ctx->samples + *(U32 const *)lp) & mask;
40818  U64 const rhs = MEM_readLE64(ctx->samples + *(U32 const *)rp) & mask;
40819  if (lhs < rhs) {
40820  return -1;
40821  }
40822  return (lhs > rhs);
40823 }
40824 
40830 static int WIN_CDECL COVER_strict_cmp(const void *lp, const void *rp) {
40831  int result = COVER_cmp(g_coverCtx, lp, rp);
40832  if (result == 0) {
40833  result = lp < rp ? -1 : 1;
40834  }
40835  return result;
40836 }
40840 static int WIN_CDECL COVER_strict_cmp8(const void *lp, const void *rp) {
40841  int result = COVER_cmp8(g_coverCtx, lp, rp);
40842  if (result == 0) {
40843  result = lp < rp ? -1 : 1;
40844  }
40845  return result;
40846 }
40847 
40852 static const size_t *COVER_lower_bound(const size_t *first, const size_t *last,
40853  size_t value) {
40854  size_t count = last - first;
40855  while (count != 0) {
40856  size_t step = count / 2;
40857  const size_t *ptr = first;
40858  ptr += step;
40859  if (*ptr < value) {
40860  first = ++ptr;
40861  count -= step + 1;
40862  } else {
40863  count = step;
40864  }
40865  }
40866  return first;
40867 }
40868 
40874 static void
40875 COVER_groupBy(const void *data, size_t count, size_t size, COVER_ctx_t *ctx,
40876  int (*cmp)(COVER_ctx_t *, const void *, const void *),
40877  void (*grp)(COVER_ctx_t *, const void *, const void *)) {
40878  const BYTE *ptr = (const BYTE *)data;
40879  size_t num = 0;
40880  while (num < count) {
40881  const BYTE *grpEnd = ptr + size;
40882  ++num;
40883  while (num < count && cmp(ctx, ptr, grpEnd) == 0) {
40884  grpEnd += size;
40885  ++num;
40886  }
40887  grp(ctx, ptr, grpEnd);
40888  ptr = grpEnd;
40889  }
40890 }
40892 /*-*************************************
40893 * Cover functions
40894 ***************************************/
40895 
40901 static void COVER_group(COVER_ctx_t *ctx, const void *group,
40902  const void *groupEnd) {
40903  /* The group consists of all the positions with the same first d bytes. */
40904  const U32 *grpPtr = (const U32 *)group;
40905  const U32 *grpEnd = (const U32 *)groupEnd;
40906  /* The dmerId is how we will reference this dmer.
40907  * This allows us to map the whole dmer space to a much smaller space, the
40908  * size of the suffix array.
40909  */
40910  const U32 dmerId = (U32)(grpPtr - ctx->suffix);
40911  /* Count the number of samples this dmer shows up in */
40912  U32 freq = 0;
40913  /* Details */
40914  const size_t *curOffsetPtr = ctx->offsets;
40915  const size_t *offsetsEnd = ctx->offsets + ctx->nbSamples;
40916  /* Once *grpPtr >= curSampleEnd this occurrence of the dmer is in a
40917  * different sample than the last.
40918  */
40919  size_t curSampleEnd = ctx->offsets[0];
40920  for (; grpPtr != grpEnd; ++grpPtr) {
40921  /* Save the dmerId for this position so we can get back to it. */
40922  ctx->dmerAt[*grpPtr] = dmerId;
40923  /* Dictionaries only help for the first reference to the dmer.
40924  * After that zstd can reference the match from the previous reference.
40925  * So only count each dmer once for each sample it is in.
40926  */
40927  if (*grpPtr < curSampleEnd) {
40928  continue;
40929  }
40930  freq += 1;
40931  /* Binary search to find the end of the sample *grpPtr is in.
40932  * In the common case that grpPtr + 1 == grpEnd we can skip the binary
40933  * search because the loop is over.
40934  */
40935  if (grpPtr + 1 != grpEnd) {
40936  const size_t *sampleEndPtr =
40937  COVER_lower_bound(curOffsetPtr, offsetsEnd, *grpPtr);
40938  curSampleEnd = *sampleEndPtr;
40939  curOffsetPtr = sampleEndPtr + 1;
40940  }
40941  }
40942  /* At this point we are never going to look at this segment of the suffix
40943  * array again. We take advantage of this fact to save memory.
40944  * We store the frequency of the dmer in the first position of the group,
40945  * which is dmerId.
40946  */
40947  ctx->suffix[dmerId] = freq;
40948 }
40949 
40950 
40962 static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs,
40963  COVER_map_t *activeDmers, U32 begin,
40964  U32 end,
40965  ZDICT_cover_params_t parameters) {
40966  /* Constants */
40967  const U32 k = parameters.k;
40968  const U32 d = parameters.d;
40969  const U32 dmersInK = k - d + 1;
40970  /* Try each segment (activeSegment) and save the best (bestSegment) */
40971  COVER_segment_t bestSegment = {0, 0, 0};
40972  COVER_segment_t activeSegment;
40973  /* Reset the activeDmers in the segment */
40974  COVER_map_clear(activeDmers);
40975  /* The activeSegment starts at the beginning of the epoch. */
40976  activeSegment.begin = begin;
40977  activeSegment.end = begin;
40978  activeSegment.score = 0;
40979  /* Slide the activeSegment through the whole epoch.
40980  * Save the best segment in bestSegment.
40981  */
40982  while (activeSegment.end < end) {
40983  /* The dmerId for the dmer at the next position */
40984  U32 newDmer = ctx->dmerAt[activeSegment.end];
40985  /* The entry in activeDmers for this dmerId */
40986  U32 *newDmerOcc = COVER_map_at(activeDmers, newDmer);
40987  /* If the dmer isn't already present in the segment add its score. */
40988  if (*newDmerOcc == 0) {
40989  /* The paper suggest using the L-0.5 norm, but experiments show that it
40990  * doesn't help.
40991  */
40992  activeSegment.score += freqs[newDmer];
40993  }
40994  /* Add the dmer to the segment */
40995  activeSegment.end += 1;
40996  *newDmerOcc += 1;
40997 
40998  /* If the window is now too large, drop the first position */
40999  if (activeSegment.end - activeSegment.begin == dmersInK + 1) {
41000  U32 delDmer = ctx->dmerAt[activeSegment.begin];
41001  U32 *delDmerOcc = COVER_map_at(activeDmers, delDmer);
41002  activeSegment.begin += 1;
41003  *delDmerOcc -= 1;
41004  /* If this is the last occurrence of the dmer, subtract its score */
41005  if (*delDmerOcc == 0) {
41006  COVER_map_remove(activeDmers, delDmer);
41007  activeSegment.score -= freqs[delDmer];
41008  }
41009  }
41010 
41011  /* If this segment is the best so far save it */
41012  if (activeSegment.score > bestSegment.score) {
41013  bestSegment = activeSegment;
41014  }
41015  }
41016  {
41017  /* Trim off the zero frequency head and tail from the segment. */
41018  U32 newBegin = bestSegment.end;
41019  U32 newEnd = bestSegment.begin;
41020  U32 pos;
41021  for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) {
41022  U32 freq = freqs[ctx->dmerAt[pos]];
41023  if (freq != 0) {
41024  newBegin = MIN(newBegin, pos);
41025  newEnd = pos + 1;
41026  }
41027  }
41028  bestSegment.begin = newBegin;
41029  bestSegment.end = newEnd;
41030  }
41031  {
41032  /* Zero out the frequency of each dmer covered by the chosen segment. */
41033  U32 pos;
41034  for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) {
41035  freqs[ctx->dmerAt[pos]] = 0;
41036  }
41037  }
41038  return bestSegment;
41039 }
41040 
41045 static int COVER_checkParameters(ZDICT_cover_params_t parameters,
41046  size_t maxDictSize) {
41047  /* k and d are required parameters */
41048  if (parameters.d == 0 || parameters.k == 0) {
41049  return 0;
41050  }
41051  /* k <= maxDictSize */
41052  if (parameters.k > maxDictSize) {
41053  return 0;
41054  }
41055  /* d <= k */
41056  if (parameters.d > parameters.k) {
41057  return 0;
41058  }
41059  /* 0 < splitPoint <= 1 */
41060  if (parameters.splitPoint <= 0 || parameters.splitPoint > 1){
41061  return 0;
41062  }
41063  return 1;
41064 }
41065 
41069 static void COVER_ctx_destroy(COVER_ctx_t *ctx) {
41070  if (!ctx) {
41071  return;
41072  }
41073  if (ctx->suffix) {
41074  free(ctx->suffix);
41075  ctx->suffix = NULL;
41076  }
41077  if (ctx->freqs) {
41078  free(ctx->freqs);
41079  ctx->freqs = NULL;
41080  }
41081  if (ctx->dmerAt) {
41082  free(ctx->dmerAt);
41083  ctx->dmerAt = NULL;
41084  }
41085  if (ctx->offsets) {
41086  free(ctx->offsets);
41087  ctx->offsets = NULL;
41088  }
41089 }
41090 
41098 static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
41099  const size_t *samplesSizes, unsigned nbSamples,
41100  unsigned d, double splitPoint) {
41101  const BYTE *const samples = (const BYTE *)samplesBuffer;
41102  const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
41103  /* Split samples into testing and training sets */
41104  const unsigned nbTrainSamples = splitPoint < 1.0 ? (unsigned)((double)nbSamples * splitPoint) : nbSamples;
41105  const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
41106  const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
41107  const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
41108  /* Checks */
41109  if (totalSamplesSize < MAX(d, sizeof(U64)) ||
41110  totalSamplesSize >= (size_t)COVER_MAX_SAMPLES_SIZE) {
41111  DISPLAYLEVEL(1, "Total samples size is too large (%u MB), maximum size is %u MB\n",
41112  (unsigned)(totalSamplesSize>>20), (COVER_MAX_SAMPLES_SIZE >> 20));
41113  return ERROR(srcSize_wrong);
41114  }
41115  /* Check if there are at least 5 training samples */
41116  if (nbTrainSamples < 5) {
41117  DISPLAYLEVEL(1, "Total number of training samples is %u and is invalid.", nbTrainSamples);
41118  return ERROR(srcSize_wrong);
41119  }
41120  /* Check if there's testing sample */
41121  if (nbTestSamples < 1) {
41122  DISPLAYLEVEL(1, "Total number of testing samples is %u and is invalid.", nbTestSamples);
41123  return ERROR(srcSize_wrong);
41124  }
41125  /* Zero the context */
41126  memset(ctx, 0, sizeof(*ctx));
41127  DISPLAYLEVEL(2, "Training on %u samples of total size %u\n", nbTrainSamples,
41128  (unsigned)trainingSamplesSize);
41129  DISPLAYLEVEL(2, "Testing on %u samples of total size %u\n", nbTestSamples,
41130  (unsigned)testSamplesSize);
41131  ctx->samples = samples;
41132  ctx->samplesSizes = samplesSizes;
41133  ctx->nbSamples = nbSamples;
41134  ctx->nbTrainSamples = nbTrainSamples;
41135  ctx->nbTestSamples = nbTestSamples;
41136  /* Partial suffix array */
41137  ctx->suffixSize = trainingSamplesSize - MAX(d, sizeof(U64)) + 1;
41138  ctx->suffix = (U32 *)malloc(ctx->suffixSize * sizeof(U32));
41139  /* Maps index to the dmerID */
41140  ctx->dmerAt = (U32 *)malloc(ctx->suffixSize * sizeof(U32));
41141  /* The offsets of each file */
41142  ctx->offsets = (size_t *)malloc((nbSamples + 1) * sizeof(size_t));
41143  if (!ctx->suffix || !ctx->dmerAt || !ctx->offsets) {
41144  DISPLAYLEVEL(1, "Failed to allocate scratch buffers\n");
41145  COVER_ctx_destroy(ctx);
41146  return ERROR(memory_allocation);
41147  }
41148  ctx->freqs = NULL;
41149  ctx->d = d;
41150 
41151  /* Fill offsets from the samplesSizes */
41152  {
41153  U32 i;
41154  ctx->offsets[0] = 0;
41155  for (i = 1; i <= nbSamples; ++i) {
41156  ctx->offsets[i] = ctx->offsets[i - 1] + samplesSizes[i - 1];
41157  }
41158  }
41159  DISPLAYLEVEL(2, "Constructing partial suffix array\n");
41160  {
41161  /* suffix is a partial suffix array.
41162  * It only sorts suffixes by their first parameters.d bytes.
41163  * The sort is stable, so each dmer group is sorted by position in input.
41164  */
41165  U32 i;
41166  for (i = 0; i < ctx->suffixSize; ++i) {
41167  ctx->suffix[i] = i;
41168  }
41169  /* qsort doesn't take an opaque pointer, so pass as a global.
41170  * On OpenBSD qsort() is not guaranteed to be stable, their mergesort() is.
41171  */
41172  g_coverCtx = ctx;
41173 #if defined(__OpenBSD__)
41174  mergesort(ctx->suffix, ctx->suffixSize, sizeof(U32),
41175  (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
41176 #else
41177  qsort(ctx->suffix, ctx->suffixSize, sizeof(U32),
41178  (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
41179 #endif
41180  }
41181  DISPLAYLEVEL(2, "Computing frequencies\n");
41182  /* For each dmer group (group of positions with the same first d bytes):
41183  * 1. For each position we set dmerAt[position] = dmerID. The dmerID is
41184  * (groupBeginPtr - suffix). This allows us to go from position to
41185  * dmerID so we can look up values in freq.
41186  * 2. We calculate how many samples the dmer occurs in and save it in
41187  * freqs[dmerId].
41188  */
41189  COVER_groupBy(ctx->suffix, ctx->suffixSize, sizeof(U32), ctx,
41190  (ctx->d <= 8 ? &COVER_cmp8 : &COVER_cmp), &COVER_group);
41191  ctx->freqs = ctx->suffix;
41192  ctx->suffix = NULL;
41193  return 0;
41194 }
41195 
41196 void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel)
41197 {
41198  const double ratio = (double)nbDmers / (double)maxDictSize;
41199  if (ratio >= 10) {
41200  return;
41201  }
41202  LOCALDISPLAYLEVEL(displayLevel, 1,
41203  "WARNING: The maximum dictionary size %u is too large "
41204  "compared to the source size %u! "
41205  "size(source)/size(dictionary) = %f, but it should be >= "
41206  "10! This may lead to a subpar dictionary! We recommend "
41207  "training on sources at least 10x, and preferably 100x "
41208  "the size of the dictionary! \n", (U32)maxDictSize,
41209  (U32)nbDmers, ratio);
41210 }
41211 
41213  U32 nbDmers, U32 k, U32 passes)
41214 {
41215  const U32 minEpochSize = k * 10;
41216  COVER_epoch_info_t epochs;
41217  epochs.num = MAX(1, maxDictSize / k / passes);
41218  epochs.size = nbDmers / epochs.num;
41219  if (epochs.size >= minEpochSize) {
41220  assert(epochs.size * epochs.num <= nbDmers);
41221  return epochs;
41222  }
41223  epochs.size = MIN(minEpochSize, nbDmers);
41224  epochs.num = nbDmers / epochs.size;
41225  assert(epochs.size * epochs.num <= nbDmers);
41226  return epochs;
41227 }
41228 
41232 static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
41233  COVER_map_t *activeDmers, void *dictBuffer,
41234  size_t dictBufferCapacity,
41235  ZDICT_cover_params_t parameters) {
41236  BYTE *const dict = (BYTE *)dictBuffer;
41237  size_t tail = dictBufferCapacity;
41238  /* Divide the data into epochs. We will select one segment from each epoch. */
41239  const COVER_epoch_info_t epochs = COVER_computeEpochs(
41240  (U32)dictBufferCapacity, (U32)ctx->suffixSize, parameters.k, 4);
41241  const size_t maxZeroScoreRun = MAX(10, MIN(100, epochs.num >> 3));
41242  size_t zeroScoreRun = 0;
41243  size_t epoch;
41244  DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
41245  (U32)epochs.num, (U32)epochs.size);
41246  /* Loop through the epochs until there are no more segments or the dictionary
41247  * is full.
41248  */
41249  for (epoch = 0; tail > 0; epoch = (epoch + 1) % epochs.num) {
41250  const U32 epochBegin = (U32)(epoch * epochs.size);
41251  const U32 epochEnd = epochBegin + epochs.size;
41252  size_t segmentSize;
41253  /* Select a segment */
41255  ctx, freqs, activeDmers, epochBegin, epochEnd, parameters);
41256  /* If the segment covers no dmers, then we are out of content.
41257  * There may be new content in other epochs, for continue for some time.
41258  */
41259  if (segment.score == 0) {
41260  if (++zeroScoreRun >= maxZeroScoreRun) {
41261  break;
41262  }
41263  continue;
41264  }
41265  zeroScoreRun = 0;
41266  /* Trim the segment if necessary and if it is too small then we are done */
41267  segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail);
41268  if (segmentSize < parameters.d) {
41269  break;
41270  }
41271  /* We fill the dictionary from the back to allow the best segments to be
41272  * referenced with the smallest offsets.
41273  */
41274  tail -= segmentSize;
41275  memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
41276  DISPLAYUPDATE(
41277  2, "\r%u%% ",
41278  (unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
41279  }
41280  DISPLAYLEVEL(2, "\r%79s\r", "");
41281  return tail;
41282 }
41283 
41285  void *dictBuffer, size_t dictBufferCapacity,
41286  const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
41287  ZDICT_cover_params_t parameters)
41288 {
41289  BYTE* const dict = (BYTE*)dictBuffer;
41290  COVER_ctx_t ctx;
41291  COVER_map_t activeDmers;
41292  parameters.splitPoint = 1.0;
41293  /* Initialize global data */
41295  /* Checks */
41296  if (!COVER_checkParameters(parameters, dictBufferCapacity)) {
41297  DISPLAYLEVEL(1, "Cover parameters incorrect\n");
41298  return ERROR(parameter_outOfBound);
41299  }
41300  if (nbSamples == 0) {
41301  DISPLAYLEVEL(1, "Cover must have at least one input file\n");
41302  return ERROR(srcSize_wrong);
41303  }
41304  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
41305  DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n",
41307  return ERROR(dstSize_tooSmall);
41308  }
41309  /* Initialize context and activeDmers */
41310  {
41311  size_t const initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
41312  parameters.d, parameters.splitPoint);
41313  if (ZSTD_isError(initVal)) {
41314  return initVal;
41315  }
41316  }
41317  COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, g_displayLevel);
41318  if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
41319  DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
41320  COVER_ctx_destroy(&ctx);
41321  return ERROR(memory_allocation);
41322  }
41323 
41324  DISPLAYLEVEL(2, "Building dictionary\n");
41325  {
41326  const size_t tail =
41327  COVER_buildDictionary(&ctx, ctx.freqs, &activeDmers, dictBuffer,
41328  dictBufferCapacity, parameters);
41329  const size_t dictionarySize = ZDICT_finalizeDictionary(
41330  dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail,
41331  samplesBuffer, samplesSizes, nbSamples, parameters.zParams);
41332  if (!ZSTD_isError(dictionarySize)) {
41333  DISPLAYLEVEL(2, "Constructed dictionary of size %u\n",
41334  (unsigned)dictionarySize);
41335  }
41336  COVER_ctx_destroy(&ctx);
41337  COVER_map_destroy(&activeDmers);
41338  return dictionarySize;
41339  }
41340 }
41341 
41342 
41343 
41345  const size_t *samplesSizes, const BYTE *samples,
41346  size_t *offsets,
41347  size_t nbTrainSamples, size_t nbSamples,
41348  BYTE *const dict, size_t dictBufferCapacity) {
41349  size_t totalCompressedSize = ERROR(GENERIC);
41350  /* Pointers */
41351  ZSTD_CCtx *cctx;
41352  ZSTD_CDict *cdict;
41353  void *dst;
41354  /* Local variables */
41355  size_t dstCapacity;
41356  size_t i;
41357  /* Allocate dst with enough space to compress the maximum sized sample */
41358  {
41359  size_t maxSampleSize = 0;
41360  i = parameters.splitPoint < 1.0 ? nbTrainSamples : 0;
41361  for (; i < nbSamples; ++i) {
41362  maxSampleSize = MAX(samplesSizes[i], maxSampleSize);
41363  }
41364  dstCapacity = ZSTD_compressBound(maxSampleSize);
41365  dst = malloc(dstCapacity);
41366  }
41367  /* Create the cctx and cdict */
41368  cctx = ZSTD_createCCtx();
41369  cdict = ZSTD_createCDict(dict, dictBufferCapacity,
41370  parameters.zParams.compressionLevel);
41371  if (!dst || !cctx || !cdict) {
41372  goto _compressCleanup;
41373  }
41374  /* Compress each sample and sum their sizes (or error) */
41375  totalCompressedSize = dictBufferCapacity;
41376  i = parameters.splitPoint < 1.0 ? nbTrainSamples : 0;
41377  for (; i < nbSamples; ++i) {
41378  const size_t size = ZSTD_compress_usingCDict(
41379  cctx, dst, dstCapacity, samples + offsets[i],
41380  samplesSizes[i], cdict);
41381  if (ZSTD_isError(size)) {
41382  totalCompressedSize = size;
41383  goto _compressCleanup;
41384  }
41385  totalCompressedSize += size;
41386  }
41387 _compressCleanup:
41388  ZSTD_freeCCtx(cctx);
41389  ZSTD_freeCDict(cdict);
41390  if (dst) {
41391  free(dst);
41392  }
41393  return totalCompressedSize;
41394 }
41395 
41396 
41400 void COVER_best_init(COVER_best_t *best) {
41401  if (best==NULL) return; /* compatible with init on NULL */
41402  (void)ZSTD_pthread_mutex_init(&best->mutex, NULL);
41403  (void)ZSTD_pthread_cond_init(&best->cond, NULL);
41404  best->liveJobs = 0;
41405  best->dict = NULL;
41406  best->dictSize = 0;
41407  best->compressedSize = (size_t)-1;
41408  memset(&best->parameters, 0, sizeof(best->parameters));
41409 }
41410 
41414 void COVER_best_wait(COVER_best_t *best) {
41415  if (!best) {
41416  return;
41417  }
41419  while (best->liveJobs != 0) {
41420  ZSTD_pthread_cond_wait(&best->cond, &best->mutex);
41421  }
41423 }
41424 
41428 void COVER_best_destroy(COVER_best_t *best) {
41429  if (!best) {
41430  return;
41431  }
41432  COVER_best_wait(best);
41433  if (best->dict) {
41434  free(best->dict);
41435  }
41438 }
41439 
41444 void COVER_best_start(COVER_best_t *best) {
41445  if (!best) {
41446  return;
41447  }
41449  ++best->liveJobs;
41451 }
41452 
41458 void COVER_best_finish(COVER_best_t *best, ZDICT_cover_params_t parameters,
41459  COVER_dictSelection_t selection) {
41460  void* dict = selection.dictContent;
41461  size_t compressedSize = selection.totalCompressedSize;
41462  size_t dictSize = selection.dictSize;
41463  if (!best) {
41464  return;
41465  }
41466  {
41467  size_t liveJobs;
41469  --best->liveJobs;
41470  liveJobs = best->liveJobs;
41471  /* If the new dictionary is better */
41472  if (compressedSize < best->compressedSize) {
41473  /* Allocate space if necessary */
41474  if (!best->dict || best->dictSize < dictSize) {
41475  if (best->dict) {
41476  free(best->dict);
41477  }
41478  best->dict = malloc(dictSize);
41479  if (!best->dict) {
41480  best->compressedSize = ERROR(GENERIC);
41481  best->dictSize = 0;
41484  return;
41485  }
41486  }
41487  /* Save the dictionary, parameters, and size */
41488  if (dict) {
41489  memcpy(best->dict, dict, dictSize);
41490  best->dictSize = dictSize;
41491  best->parameters = parameters;
41493  }
41494  }
41495  if (liveJobs == 0) {
41497  }
41499  }
41500 }
41502 static COVER_dictSelection_t setDictSelection(BYTE* buf, size_t s, size_t csz)
41503 {
41505  ds.dictContent = buf;
41506  ds.dictSize = s;
41507  ds.totalCompressedSize = csz;
41508  return ds;
41510 
41512  return setDictSelection(NULL, 0, error);
41514 
41516  return (ZSTD_isError(selection.totalCompressedSize) || !selection.dictContent);
41517 }
41518 
41520  free(selection.dictContent);
41521 }
41522 
41523 COVER_dictSelection_t COVER_selectDict(BYTE* customDictContent, size_t dictBufferCapacity,
41524  size_t dictContentSize, const BYTE* samplesBuffer, const size_t* samplesSizes, unsigned nbFinalizeSamples,
41525  size_t nbCheckSamples, size_t nbSamples, ZDICT_cover_params_t params, size_t* offsets, size_t totalCompressedSize) {
41526 
41527  size_t largestDict = 0;
41528  size_t largestCompressed = 0;
41529  BYTE* customDictContentEnd = customDictContent + dictContentSize;
41530 
41531  BYTE * largestDictbuffer = (BYTE *)malloc(dictBufferCapacity);
41532  BYTE * candidateDictBuffer = (BYTE *)malloc(dictBufferCapacity);
41533  double regressionTolerance = ((double)params.shrinkDictMaxRegression / 100.0) + 1.00;
41534 
41535  if (!largestDictbuffer || !candidateDictBuffer) {
41536  free(largestDictbuffer);
41537  free(candidateDictBuffer);
41538  return COVER_dictSelectionError(dictContentSize);
41539  }
41540 
41541  /* Initial dictionary size and compressed size */
41542  memcpy(largestDictbuffer, customDictContent, dictContentSize);
41543  dictContentSize = ZDICT_finalizeDictionary(
41544  largestDictbuffer, dictBufferCapacity, customDictContent, dictContentSize,
41545  samplesBuffer, samplesSizes, nbFinalizeSamples, params.zParams);
41546 
41547  if (ZDICT_isError(dictContentSize)) {
41548  free(largestDictbuffer);
41549  free(candidateDictBuffer);
41550  return COVER_dictSelectionError(dictContentSize);
41551  }
41552 
41553  totalCompressedSize = COVER_checkTotalCompressedSize(params, samplesSizes,
41554  samplesBuffer, offsets,
41555  nbCheckSamples, nbSamples,
41556  largestDictbuffer, dictContentSize);
41557 
41558  if (ZSTD_isError(totalCompressedSize)) {
41559  free(largestDictbuffer);
41560  free(candidateDictBuffer);
41561  return COVER_dictSelectionError(totalCompressedSize);
41562  }
41563 
41564  if (params.shrinkDict == 0) {
41565  free(candidateDictBuffer);
41566  return setDictSelection(largestDictbuffer, dictContentSize, totalCompressedSize);
41567  }
41568 
41569  largestDict = dictContentSize;
41570  largestCompressed = totalCompressedSize;
41571  dictContentSize = ZDICT_DICTSIZE_MIN;
41572 
41573  /* Largest dict is initially at least ZDICT_DICTSIZE_MIN */
41574  while (dictContentSize < largestDict) {
41575  memcpy(candidateDictBuffer, largestDictbuffer, largestDict);
41576  dictContentSize = ZDICT_finalizeDictionary(
41577  candidateDictBuffer, dictBufferCapacity, customDictContentEnd - dictContentSize, dictContentSize,
41578  samplesBuffer, samplesSizes, nbFinalizeSamples, params.zParams);
41579 
41580  if (ZDICT_isError(dictContentSize)) {
41581  free(largestDictbuffer);
41582  free(candidateDictBuffer);
41583  return COVER_dictSelectionError(dictContentSize);
41584 
41585  }
41586 
41587  totalCompressedSize = COVER_checkTotalCompressedSize(params, samplesSizes,
41588  samplesBuffer, offsets,
41589  nbCheckSamples, nbSamples,
41590  candidateDictBuffer, dictContentSize);
41591 
41592  if (ZSTD_isError(totalCompressedSize)) {
41593  free(largestDictbuffer);
41594  free(candidateDictBuffer);
41595  return COVER_dictSelectionError(totalCompressedSize);
41596  }
41597 
41598  if ((double)totalCompressedSize <= (double)largestCompressed * regressionTolerance) {
41599  free(largestDictbuffer);
41600  return setDictSelection( candidateDictBuffer, dictContentSize, totalCompressedSize );
41601  }
41602  dictContentSize *= 2;
41603  }
41604  dictContentSize = largestDict;
41605  totalCompressedSize = largestCompressed;
41606  free(candidateDictBuffer);
41607  return setDictSelection( largestDictbuffer, dictContentSize, totalCompressedSize );
41608 }
41609 
41613 typedef struct COVER_tryParameters_data_s {
41614  const COVER_ctx_t *ctx;
41616  size_t dictBufferCapacity;
41619 
41625 static void COVER_tryParameters(void *opaque)
41626 {
41627  /* Save parameters as local variables */
41629  const COVER_ctx_t *const ctx = data->ctx;
41630  const ZDICT_cover_params_t parameters = data->parameters;
41631  size_t dictBufferCapacity = data->dictBufferCapacity;
41632  size_t totalCompressedSize = ERROR(GENERIC);
41633  /* Allocate space for hash table, dict, and freqs */
41634  COVER_map_t activeDmers;
41635  BYTE* const dict = (BYTE*)malloc(dictBufferCapacity);
41637  U32* const freqs = (U32*)malloc(ctx->suffixSize * sizeof(U32));
41638  if (!COVER_map_init(&activeDmers, parameters.k - parameters.d + 1)) {
41639  DISPLAYLEVEL(1, "Failed to allocate dmer map: out of memory\n");
41640  goto _cleanup;
41641  }
41642  if (!dict || !freqs) {
41643  DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
41644  goto _cleanup;
41645  }
41646  /* Copy the frequencies because we need to modify them */
41647  memcpy(freqs, ctx->freqs, ctx->suffixSize * sizeof(U32));
41648  /* Build the dictionary */
41649  {
41650  const size_t tail = COVER_buildDictionary(ctx, freqs, &activeDmers, dict,
41651  dictBufferCapacity, parameters);
41652  selection = COVER_selectDict(dict + tail, dictBufferCapacity, dictBufferCapacity - tail,
41653  ctx->samples, ctx->samplesSizes, (unsigned)ctx->nbTrainSamples, ctx->nbTrainSamples, ctx->nbSamples, parameters, ctx->offsets,
41654  totalCompressedSize);
41655 
41656  if (COVER_dictSelectionIsError(selection)) {
41657  DISPLAYLEVEL(1, "Failed to select dictionary\n");
41658  goto _cleanup;
41659  }
41660  }
41661 _cleanup:
41662  free(dict);
41663  COVER_best_finish(data->best, parameters, selection);
41664  free(data);
41665  COVER_map_destroy(&activeDmers);
41666  COVER_dictSelectionFree(selection);
41667  free(freqs);
41668 }
41669 
41671  void* dictBuffer, size_t dictBufferCapacity, const void* samplesBuffer,
41672  const size_t* samplesSizes, unsigned nbSamples,
41673  ZDICT_cover_params_t* parameters)
41674 {
41675  /* constants */
41676  const unsigned nbThreads = parameters->nbThreads;
41677  const double splitPoint =
41678  parameters->splitPoint <= 0.0 ? COVER_DEFAULT_SPLITPOINT : parameters->splitPoint;
41679  const unsigned kMinD = parameters->d == 0 ? 6 : parameters->d;
41680  const unsigned kMaxD = parameters->d == 0 ? 8 : parameters->d;
41681  const unsigned kMinK = parameters->k == 0 ? 50 : parameters->k;
41682  const unsigned kMaxK = parameters->k == 0 ? 2000 : parameters->k;
41683  const unsigned kSteps = parameters->steps == 0 ? 40 : parameters->steps;
41684  const unsigned kStepSize = MAX((kMaxK - kMinK) / kSteps, 1);
41685  const unsigned kIterations =
41686  (1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
41687  const unsigned shrinkDict = 0;
41688  /* Local variables */
41689  const int displayLevel = parameters->zParams.notificationLevel;
41690  unsigned iteration = 1;
41691  unsigned d;
41692  unsigned k;
41693  COVER_best_t best;
41694  POOL_ctx *pool = NULL;
41695  int warned = 0;
41696 
41697  /* Checks */
41698  if (splitPoint <= 0 || splitPoint > 1) {
41699  LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
41700  return ERROR(parameter_outOfBound);
41701  }
41702  if (kMinK < kMaxD || kMaxK < kMinK) {
41703  LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect parameters\n");
41704  return ERROR(parameter_outOfBound);
41705  }
41706  if (nbSamples == 0) {
41707  DISPLAYLEVEL(1, "Cover must have at least one input file\n");
41708  return ERROR(srcSize_wrong);
41709  }
41710  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
41711  DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n",
41713  return ERROR(dstSize_tooSmall);
41714  }
41715  if (nbThreads > 1) {
41716  pool = POOL_create(nbThreads, 1);
41717  if (!pool) {
41718  return ERROR(memory_allocation);
41719  }
41720  }
41721  /* Initialization */
41722  COVER_best_init(&best);
41723  /* Turn down global display level to clean up display at level 2 and below */
41724  g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
41725  /* Loop through d first because each new value needs a new context */
41726  LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
41727  kIterations);
41728  for (d = kMinD; d <= kMaxD; d += 2) {
41729  /* Initialize the context for this value of d */
41730  COVER_ctx_t ctx;
41731  LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d);
41732  {
41733  const size_t initVal = COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint);
41734  if (ZSTD_isError(initVal)) {
41735  LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
41736  COVER_best_destroy(&best);
41737  POOL_free(pool);
41738  return initVal;
41739  }
41740  }
41741  if (!warned) {
41742  COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.suffixSize, displayLevel);
41743  warned = 1;
41744  }
41745  /* Loop through k reusing the same context */
41746  for (k = kMinK; k <= kMaxK; k += kStepSize) {
41747  /* Prepare the arguments */
41749  sizeof(COVER_tryParameters_data_t));
41750  LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
41751  if (!data) {
41752  LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
41753  COVER_best_destroy(&best);
41754  COVER_ctx_destroy(&ctx);
41755  POOL_free(pool);
41756  return ERROR(memory_allocation);
41757  }
41758  data->ctx = &ctx;
41759  data->best = &best;
41760  data->dictBufferCapacity = dictBufferCapacity;
41761  data->parameters = *parameters;
41762  data->parameters.k = k;
41763  data->parameters.d = d;
41764  data->parameters.splitPoint = splitPoint;
41765  data->parameters.steps = kSteps;
41766  data->parameters.shrinkDict = shrinkDict;
41767  data->parameters.zParams.notificationLevel = g_displayLevel;
41768  /* Check the parameters */
41769  if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) {
41770  DISPLAYLEVEL(1, "Cover parameters incorrect\n");
41771  free(data);
41772  continue;
41773  }
41774  /* Call the function and pass ownership of data to it */
41775  COVER_best_start(&best);
41776  if (pool) {
41778  } else {
41780  }
41781  /* Print status */
41782  LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
41783  (unsigned)((iteration * 100) / kIterations));
41784  ++iteration;
41785  }
41786  COVER_best_wait(&best);
41787  COVER_ctx_destroy(&ctx);
41788  }
41789  LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", "");
41790  /* Fill the output buffer and parameters with output of the best parameters */
41791  {
41792  const size_t dictSize = best.dictSize;
41793  if (ZSTD_isError(best.compressedSize)) {
41794  const size_t compressedSize = best.compressedSize;
41795  COVER_best_destroy(&best);
41796  POOL_free(pool);
41797  return compressedSize;
41798  }
41799  *parameters = best.parameters;
41800  memcpy(dictBuffer, best.dict, dictSize);
41801  COVER_best_destroy(&best);
41802  POOL_free(pool);
41803  return dictSize;
41804  }
41805 }
41806 /**** ended inlining dictBuilder/cover.c ****/
41807 /**** start inlining dictBuilder/divsufsort.c ****/
41808 /*
41809  * divsufsort.c for libdivsufsort-lite
41810  * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
41811  *
41812  * Permission is hereby granted, free of charge, to any person
41813  * obtaining a copy of this software and associated documentation
41814  * files (the "Software"), to deal in the Software without
41815  * restriction, including without limitation the rights to use,
41816  * copy, modify, merge, publish, distribute, sublicense, and/or sell
41817  * copies of the Software, and to permit persons to whom the
41818  * Software is furnished to do so, subject to the following
41819  * conditions:
41820  *
41821  * The above copyright notice and this permission notice shall be
41822  * included in all copies or substantial portions of the Software.
41823  *
41824  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
41825  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
41826  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
41827  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41828  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41829  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41830  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41831  * OTHER DEALINGS IN THE SOFTWARE.
41832  */
41833 
41834 /*- Compiler specifics -*/
41835 #ifdef __clang__
41836 #pragma clang diagnostic ignored "-Wshorten-64-to-32"
41837 #endif
41838 
41839 #if defined(_MSC_VER)
41840 # pragma warning(disable : 4244)
41841 # pragma warning(disable : 4127) /* C4127 : Condition expression is constant */
41842 #endif
41843 
41844 
41845 /*- Dependencies -*/
41846 #include <assert.h>
41847 #include <stdio.h>
41848 #include <stdlib.h>
41849 
41850 /**** start inlining divsufsort.h ****/
41851 /*
41852  * divsufsort.h for libdivsufsort-lite
41853  * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
41854  *
41855  * Permission is hereby granted, free of charge, to any person
41856  * obtaining a copy of this software and associated documentation
41857  * files (the "Software"), to deal in the Software without
41858  * restriction, including without limitation the rights to use,
41859  * copy, modify, merge, publish, distribute, sublicense, and/or sell
41860  * copies of the Software, and to permit persons to whom the
41861  * Software is furnished to do so, subject to the following
41862  * conditions:
41863  *
41864  * The above copyright notice and this permission notice shall be
41865  * included in all copies or substantial portions of the Software.
41866  *
41867  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
41868  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
41869  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
41870  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
41871  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41872  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
41873  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41874  * OTHER DEALINGS IN THE SOFTWARE.
41875  */
41876 
41877 #ifndef _DIVSUFSORT_H
41878 #define _DIVSUFSORT_H 1
41879 
41880 #ifdef __cplusplus
41881 extern "C" {
41882 #endif /* __cplusplus */
41883 
41884 
41885 /*- Prototypes -*/
41886 
41895 int
41896 divsufsort(const unsigned char *T, int *SA, int n, int openMP);
41897 
41909 int
41910 divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char * num_indexes, int * indexes, int openMP);
41911 
41912 
41913 #ifdef __cplusplus
41914 } /* extern "C" */
41915 #endif /* __cplusplus */
41916 
41917 #endif /* _DIVSUFSORT_H */
41918 /**** ended inlining divsufsort.h ****/
41919 
41920 /*- Constants -*/
41921 #if defined(INLINE)
41922 # undef INLINE
41923 #endif
41924 #if !defined(INLINE)
41925 # define INLINE __inline
41926 #endif
41927 #if defined(ALPHABET_SIZE) && (ALPHABET_SIZE < 1)
41928 # undef ALPHABET_SIZE
41929 #endif
41930 #if !defined(ALPHABET_SIZE)
41931 # define ALPHABET_SIZE (256)
41932 #endif
41933 #define BUCKET_A_SIZE (ALPHABET_SIZE)
41934 #define BUCKET_B_SIZE (ALPHABET_SIZE * ALPHABET_SIZE)
41935 #if defined(SS_INSERTIONSORT_THRESHOLD)
41936 # if SS_INSERTIONSORT_THRESHOLD < 1
41937 # undef SS_INSERTIONSORT_THRESHOLD
41938 # define SS_INSERTIONSORT_THRESHOLD (1)
41939 # endif
41940 #else
41941 # define SS_INSERTIONSORT_THRESHOLD (8)
41942 #endif
41943 #if defined(SS_BLOCKSIZE)
41944 # if SS_BLOCKSIZE < 0
41945 # undef SS_BLOCKSIZE
41946 # define SS_BLOCKSIZE (0)
41947 # elif 32768 <= SS_BLOCKSIZE
41948 # undef SS_BLOCKSIZE
41949 # define SS_BLOCKSIZE (32767)
41950 # endif
41951 #else
41952 # define SS_BLOCKSIZE (1024)
41953 #endif
41954 /* minstacksize = log(SS_BLOCKSIZE) / log(3) * 2 */
41955 #if SS_BLOCKSIZE == 0
41956 # define SS_MISORT_STACKSIZE (96)
41957 #elif SS_BLOCKSIZE <= 4096
41958 # define SS_MISORT_STACKSIZE (16)
41959 #else
41960 # define SS_MISORT_STACKSIZE (24)
41961 #endif
41962 #define SS_SMERGE_STACKSIZE (32)
41963 #define TR_INSERTIONSORT_THRESHOLD (8)
41964 #define TR_STACKSIZE (64)
41965 
41966 
41967 /*- Macros -*/
41968 #ifndef SWAP
41969 # define SWAP(_a, _b) do { t = (_a); (_a) = (_b); (_b) = t; } while(0)
41970 #endif /* SWAP */
41971 #ifndef MIN
41972 # define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
41973 #endif /* MIN */
41974 #ifndef MAX
41975 # define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
41976 #endif /* MAX */
41977 #define STACK_PUSH(_a, _b, _c, _d)\
41978  do {\
41979  assert(ssize < STACK_SIZE);\
41980  stack[ssize].a = (_a), stack[ssize].b = (_b),\
41981  stack[ssize].c = (_c), stack[ssize++].d = (_d);\
41982  } while(0)
41983 #define STACK_PUSH5(_a, _b, _c, _d, _e)\
41984  do {\
41985  assert(ssize < STACK_SIZE);\
41986  stack[ssize].a = (_a), stack[ssize].b = (_b),\
41987  stack[ssize].c = (_c), stack[ssize].d = (_d), stack[ssize++].e = (_e);\
41988  } while(0)
41989 #define STACK_POP(_a, _b, _c, _d)\
41990  do {\
41991  assert(0 <= ssize);\
41992  if(ssize == 0) { return; }\
41993  (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
41994  (_c) = stack[ssize].c, (_d) = stack[ssize].d;\
41995  } while(0)
41996 #define STACK_POP5(_a, _b, _c, _d, _e)\
41997  do {\
41998  assert(0 <= ssize);\
41999  if(ssize == 0) { return; }\
42000  (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
42001  (_c) = stack[ssize].c, (_d) = stack[ssize].d, (_e) = stack[ssize].e;\
42002  } while(0)
42003 #define BUCKET_A(_c0) bucket_A[(_c0)]
42004 #if ALPHABET_SIZE == 256
42005 #define BUCKET_B(_c0, _c1) (bucket_B[((_c1) << 8) | (_c0)])
42006 #define BUCKET_BSTAR(_c0, _c1) (bucket_B[((_c0) << 8) | (_c1)])
42007 #else
42008 #define BUCKET_B(_c0, _c1) (bucket_B[(_c1) * ALPHABET_SIZE + (_c0)])
42009 #define BUCKET_BSTAR(_c0, _c1) (bucket_B[(_c0) * ALPHABET_SIZE + (_c1)])
42010 #endif
42011 
42012 
42013 /*- Private Functions -*/
42014 
42015 static const int lg_table[256]= {
42016  -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
42017  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
42018  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
42019  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
42020  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
42021  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
42022  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
42023  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
42024 };
42025 
42026 #if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE)
42027 
42028 static INLINE
42029 int
42030 ss_ilg(int n) {
42031 #if SS_BLOCKSIZE == 0
42032  return (n & 0xffff0000) ?
42033  ((n & 0xff000000) ?
42034  24 + lg_table[(n >> 24) & 0xff] :
42035  16 + lg_table[(n >> 16) & 0xff]) :
42036  ((n & 0x0000ff00) ?
42037  8 + lg_table[(n >> 8) & 0xff] :
42038  0 + lg_table[(n >> 0) & 0xff]);
42039 #elif SS_BLOCKSIZE < 256
42040  return lg_table[n];
42041 #else
42042  return (n & 0xff00) ?
42043  8 + lg_table[(n >> 8) & 0xff] :
42044  0 + lg_table[(n >> 0) & 0xff];
42045 #endif
42046 }
42047 
42048 #endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */
42049 
42050 #if SS_BLOCKSIZE != 0
42051 
42052 static const int sqq_table[256] = {
42053  0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61,
42054  64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89,
42055  90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109,
42056 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
42057 128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
42058 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155,
42059 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
42060 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180,
42061 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191,
42062 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201,
42063 202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211,
42064 212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221,
42065 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230,
42066 230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
42067 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247,
42068 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255
42069 };
42070 
42071 static INLINE
42072 int
42073 ss_isqrt(int x) {
42074  int y, e;
42075 
42076  if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; }
42077  e = (x & 0xffff0000) ?
42078  ((x & 0xff000000) ?
42079  24 + lg_table[(x >> 24) & 0xff] :
42080  16 + lg_table[(x >> 16) & 0xff]) :
42081  ((x & 0x0000ff00) ?
42082  8 + lg_table[(x >> 8) & 0xff] :
42083  0 + lg_table[(x >> 0) & 0xff]);
42084 
42085  if(e >= 16) {
42086  y = sqq_table[x >> ((e - 6) - (e & 1))] << ((e >> 1) - 7);
42087  if(e >= 24) { y = (y + 1 + x / y) >> 1; }
42088  y = (y + 1 + x / y) >> 1;
42089  } else if(e >= 8) {
42090  y = (sqq_table[x >> ((e - 6) - (e & 1))] >> (7 - (e >> 1))) + 1;
42091  } else {
42092  return sqq_table[x] >> 4;
42093  }
42094 
42095  return (x < (y * y)) ? y - 1 : y;
42097 
42098 #endif /* SS_BLOCKSIZE != 0 */
42099 
42100 
42101 /*---------------------------------------------------------------------------*/
42102 
42103 /* Compares two suffixes. */
42104 static INLINE
42105 int
42106 ss_compare(const unsigned char *T,
42107  const int *p1, const int *p2,
42108  int depth) {
42109  const unsigned char *U1, *U2, *U1n, *U2n;
42110 
42111  for(U1 = T + depth + *p1,
42112  U2 = T + depth + *p2,
42113  U1n = T + *(p1 + 1) + 2,
42114  U2n = T + *(p2 + 1) + 2;
42115  (U1 < U1n) && (U2 < U2n) && (*U1 == *U2);
42116  ++U1, ++U2) {
42117  }
42118 
42119  return U1 < U1n ?
42120  (U2 < U2n ? *U1 - *U2 : 1) :
42121  (U2 < U2n ? -1 : 0);
42123 
42124 
42125 /*---------------------------------------------------------------------------*/
42126 
42127 #if (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1)
42128 
42129 /* Insertionsort for small size groups */
42130 static
42131 void
42132 ss_insertionsort(const unsigned char *T, const int *PA,
42133  int *first, int *last, int depth) {
42134  int *i, *j;
42135  int t;
42136  int r;
42137 
42138  for(i = last - 2; first <= i; --i) {
42139  for(t = *i, j = i + 1; 0 < (r = ss_compare(T, PA + t, PA + *j, depth));) {
42140  do { *(j - 1) = *j; } while((++j < last) && (*j < 0));
42141  if(last <= j) { break; }
42142  }
42143  if(r == 0) { *j = ~*j; }
42144  *(j - 1) = t;
42145  }
42146 }
42147 
42148 #endif /* (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1) */
42149 
42150 
42151 /*---------------------------------------------------------------------------*/
42152 
42153 #if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE)
42154 
42155 static INLINE
42156 void
42157 ss_fixdown(const unsigned char *Td, const int *PA,
42158  int *SA, int i, int size) {
42159  int j, k;
42160  int v;
42161  int c, d, e;
42162 
42163  for(v = SA[i], c = Td[PA[v]]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) {
42164  d = Td[PA[SA[k = j++]]];
42165  if(d < (e = Td[PA[SA[j]]])) { k = j; d = e; }
42166  if(d <= c) { break; }
42167  }
42168  SA[i] = v;
42169 }
42170 
42171 /* Simple top-down heapsort. */
42172 static
42173 void
42174 ss_heapsort(const unsigned char *Td, const int *PA, int *SA, int size) {
42175  int i, m;
42176  int t;
42177 
42178  m = size;
42179  if((size % 2) == 0) {
42180  m--;
42181  if(Td[PA[SA[m / 2]]] < Td[PA[SA[m]]]) { SWAP(SA[m], SA[m / 2]); }
42182  }
42183 
42184  for(i = m / 2 - 1; 0 <= i; --i) { ss_fixdown(Td, PA, SA, i, m); }
42185  if((size % 2) == 0) { SWAP(SA[0], SA[m]); ss_fixdown(Td, PA, SA, 0, m); }
42186  for(i = m - 1; 0 < i; --i) {
42187  t = SA[0], SA[0] = SA[i];
42188  ss_fixdown(Td, PA, SA, 0, i);
42189  SA[i] = t;
42190  }
42191 }
42192 
42193 
42194 /*---------------------------------------------------------------------------*/
42195 
42196 /* Returns the median of three elements. */
42197 static INLINE
42198 int *
42199 ss_median3(const unsigned char *Td, const int *PA,
42200  int *v1, int *v2, int *v3) {
42201  int *t;
42202  if(Td[PA[*v1]] > Td[PA[*v2]]) { SWAP(v1, v2); }
42203  if(Td[PA[*v2]] > Td[PA[*v3]]) {
42204  if(Td[PA[*v1]] > Td[PA[*v3]]) { return v1; }
42205  else { return v3; }
42206  }
42207  return v2;
42208 }
42209 
42210 /* Returns the median of five elements. */
42211 static INLINE
42212 int *
42213 ss_median5(const unsigned char *Td, const int *PA,
42214  int *v1, int *v2, int *v3, int *v4, int *v5) {
42215  int *t;
42216  if(Td[PA[*v2]] > Td[PA[*v3]]) { SWAP(v2, v3); }
42217  if(Td[PA[*v4]] > Td[PA[*v5]]) { SWAP(v4, v5); }
42218  if(Td[PA[*v2]] > Td[PA[*v4]]) { SWAP(v2, v4); SWAP(v3, v5); }
42219  if(Td[PA[*v1]] > Td[PA[*v3]]) { SWAP(v1, v3); }
42220  if(Td[PA[*v1]] > Td[PA[*v4]]) { SWAP(v1, v4); SWAP(v3, v5); }
42221  if(Td[PA[*v3]] > Td[PA[*v4]]) { return v4; }
42222  return v3;
42223 }
42224 
42225 /* Returns the pivot element. */
42226 static INLINE
42227 int *
42228 ss_pivot(const unsigned char *Td, const int *PA, int *first, int *last) {
42229  int *middle;
42230  int t;
42231 
42232  t = last - first;
42233  middle = first + t / 2;
42234 
42235  if(t <= 512) {
42236  if(t <= 32) {
42237  return ss_median3(Td, PA, first, middle, last - 1);
42238  } else {
42239  t >>= 2;
42240  return ss_median5(Td, PA, first, first + t, middle, last - 1 - t, last - 1);
42241  }
42242  }
42243  t >>= 3;
42244  first = ss_median3(Td, PA, first, first + t, first + (t << 1));
42245  middle = ss_median3(Td, PA, middle - t, middle, middle + t);
42246  last = ss_median3(Td, PA, last - 1 - (t << 1), last - 1 - t, last - 1);
42247  return ss_median3(Td, PA, first, middle, last);
42248 }
42249 
42250 
42251 /*---------------------------------------------------------------------------*/
42252 
42253 /* Binary partition for substrings. */
42254 static INLINE
42255 int *
42256 ss_partition(const int *PA,
42257  int *first, int *last, int depth) {
42258  int *a, *b;
42259  int t;
42260  for(a = first - 1, b = last;;) {
42261  for(; (++a < b) && ((PA[*a] + depth) >= (PA[*a + 1] + 1));) { *a = ~*a; }
42262  for(; (a < --b) && ((PA[*b] + depth) < (PA[*b + 1] + 1));) { }
42263  if(b <= a) { break; }
42264  t = ~*b;
42265  *b = *a;
42266  *a = t;
42267  }
42268  if(first < a) { *first = ~*first; }
42269  return a;
42270 }
42271 
42272 /* Multikey introsort for medium size groups. */
42273 static
42274 void
42275 ss_mintrosort(const unsigned char *T, const int *PA,
42276  int *first, int *last,
42277  int depth) {
42278 #define STACK_SIZE SS_MISORT_STACKSIZE
42279  struct { int *a, *b, c; int d; } stack[STACK_SIZE];
42280  const unsigned char *Td;
42281  int *a, *b, *c, *d, *e, *f;
42282  int s, t;
42283  int ssize;
42284  int limit;
42285  int v, x = 0;
42286 
42287  for(ssize = 0, limit = ss_ilg(last - first);;) {
42288 
42289  if((last - first) <= SS_INSERTIONSORT_THRESHOLD) {
42290 #if 1 < SS_INSERTIONSORT_THRESHOLD
42291  if(1 < (last - first)) { ss_insertionsort(T, PA, first, last, depth); }
42292 #endif
42293  STACK_POP(first, last, depth, limit);
42294  continue;
42295  }
42296 
42297  Td = T + depth;
42298  if(limit-- == 0) { ss_heapsort(Td, PA, first, last - first); }
42299  if(limit < 0) {
42300  for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) {
42301  if((x = Td[PA[*a]]) != v) {
42302  if(1 < (a - first)) { break; }
42303  v = x;
42304  first = a;
42305  }
42306  }
42307  if(Td[PA[*first] - 1] < v) {
42308  first = ss_partition(PA, first, a, depth);
42309  }
42310  if((a - first) <= (last - a)) {
42311  if(1 < (a - first)) {
42312  STACK_PUSH(a, last, depth, -1);
42313  last = a, depth += 1, limit = ss_ilg(a - first);
42314  } else {
42315  first = a, limit = -1;
42316  }
42317  } else {
42318  if(1 < (last - a)) {
42319  STACK_PUSH(first, a, depth + 1, ss_ilg(a - first));
42320  first = a, limit = -1;
42321  } else {
42322  last = a, depth += 1, limit = ss_ilg(a - first);
42323  }
42324  }
42325  continue;
42326  }
42327 
42328  /* choose pivot */
42329  a = ss_pivot(Td, PA, first, last);
42330  v = Td[PA[*a]];
42331  SWAP(*first, *a);
42332 
42333  /* partition */
42334  for(b = first; (++b < last) && ((x = Td[PA[*b]]) == v);) { }
42335  if(((a = b) < last) && (x < v)) {
42336  for(; (++b < last) && ((x = Td[PA[*b]]) <= v);) {
42337  if(x == v) { SWAP(*b, *a); ++a; }
42338  }
42339  }
42340  for(c = last; (b < --c) && ((x = Td[PA[*c]]) == v);) { }
42341  if((b < (d = c)) && (x > v)) {
42342  for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) {
42343  if(x == v) { SWAP(*c, *d); --d; }
42344  }
42345  }
42346  for(; b < c;) {
42347  SWAP(*b, *c);
42348  for(; (++b < c) && ((x = Td[PA[*b]]) <= v);) {
42349  if(x == v) { SWAP(*b, *a); ++a; }
42350  }
42351  for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) {
42352  if(x == v) { SWAP(*c, *d); --d; }
42353  }
42354  }
42355 
42356  if(a <= d) {
42357  c = b - 1;
42358 
42359  if((s = a - first) > (t = b - a)) { s = t; }
42360  for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
42361  if((s = d - c) > (t = last - d - 1)) { s = t; }
42362  for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
42363 
42364  a = first + (b - a), c = last - (d - c);
42365  b = (v <= Td[PA[*a] - 1]) ? a : ss_partition(PA, a, c, depth);
42366 
42367  if((a - first) <= (last - c)) {
42368  if((last - c) <= (c - b)) {
42369  STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
42370  STACK_PUSH(c, last, depth, limit);
42371  last = a;
42372  } else if((a - first) <= (c - b)) {
42373  STACK_PUSH(c, last, depth, limit);
42374  STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
42375  last = a;
42376  } else {
42377  STACK_PUSH(c, last, depth, limit);
42378  STACK_PUSH(first, a, depth, limit);
42379  first = b, last = c, depth += 1, limit = ss_ilg(c - b);
42380  }
42381  } else {
42382  if((a - first) <= (c - b)) {
42383  STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
42384  STACK_PUSH(first, a, depth, limit);
42385  first = c;
42386  } else if((last - c) <= (c - b)) {
42387  STACK_PUSH(first, a, depth, limit);
42388  STACK_PUSH(b, c, depth + 1, ss_ilg(c - b));
42389  first = c;
42390  } else {
42391  STACK_PUSH(first, a, depth, limit);
42392  STACK_PUSH(c, last, depth, limit);
42393  first = b, last = c, depth += 1, limit = ss_ilg(c - b);
42394  }
42395  }
42396  } else {
42397  limit += 1;
42398  if(Td[PA[*first] - 1] < v) {
42399  first = ss_partition(PA, first, last, depth);
42400  limit = ss_ilg(last - first);
42401  }
42402  depth += 1;
42403  }
42404  }
42405 #undef STACK_SIZE
42406 }
42408 #endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */
42409 
42410 
42411 /*---------------------------------------------------------------------------*/
42412 
42413 #if SS_BLOCKSIZE != 0
42414 
42415 static INLINE
42416 void
42417 ss_blockswap(int *a, int *b, int n) {
42418  int t;
42419  for(; 0 < n; --n, ++a, ++b) {
42420  t = *a, *a = *b, *b = t;
42421  }
42422 }
42423 
42424 static INLINE
42425 void
42426 ss_rotate(int *first, int *middle, int *last) {
42427  int *a, *b, t;
42428  int l, r;
42429  l = middle - first, r = last - middle;
42430  for(; (0 < l) && (0 < r);) {
42431  if(l == r) { ss_blockswap(first, middle, l); break; }
42432  if(l < r) {
42433  a = last - 1, b = middle - 1;
42434  t = *a;
42435  do {
42436  *a-- = *b, *b-- = *a;
42437  if(b < first) {
42438  *a = t;
42439  last = a;
42440  if((r -= l + 1) <= l) { break; }
42441  a -= 1, b = middle - 1;
42442  t = *a;
42443  }
42444  } while(1);
42445  } else {
42446  a = first, b = middle;
42447  t = *a;
42448  do {
42449  *a++ = *b, *b++ = *a;
42450  if(last <= b) {
42451  *a = t;
42452  first = a + 1;
42453  if((l -= r + 1) <= r) { break; }
42454  a += 1, b = middle;
42455  t = *a;
42456  }
42457  } while(1);
42458  }
42459  }
42460 }
42461 
42462 
42463 /*---------------------------------------------------------------------------*/
42464 
42465 static
42466 void
42467 ss_inplacemerge(const unsigned char *T, const int *PA,
42468  int *first, int *middle, int *last,
42469  int depth) {
42470  const int *p;
42471  int *a, *b;
42472  int len, half;
42473  int q, r;
42474  int x;
42475 
42476  for(;;) {
42477  if(*(last - 1) < 0) { x = 1; p = PA + ~*(last - 1); }
42478  else { x = 0; p = PA + *(last - 1); }
42479  for(a = first, len = middle - first, half = len >> 1, r = -1;
42480  0 < len;
42481  len = half, half >>= 1) {
42482  b = a + half;
42483  q = ss_compare(T, PA + ((0 <= *b) ? *b : ~*b), p, depth);
42484  if(q < 0) {
42485  a = b + 1;
42486  half -= (len & 1) ^ 1;
42487  } else {
42488  r = q;
42489  }
42490  }
42491  if(a < middle) {
42492  if(r == 0) { *a = ~*a; }
42493  ss_rotate(a, middle, last);
42494  last -= middle - a;
42495  middle = a;
42496  if(first == middle) { break; }
42497  }
42498  --last;
42499  if(x != 0) { while(*--last < 0) { } }
42500  if(middle == last) { break; }
42501  }
42502 }
42503 
42504 
42505 /*---------------------------------------------------------------------------*/
42506 
42507 /* Merge-forward with internal buffer. */
42508 static
42509 void
42510 ss_mergeforward(const unsigned char *T, const int *PA,
42511  int *first, int *middle, int *last,
42512  int *buf, int depth) {
42513  int *a, *b, *c, *bufend;
42514  int t;
42515  int r;
42516 
42517  bufend = buf + (middle - first) - 1;
42518  ss_blockswap(buf, first, middle - first);
42519 
42520  for(t = *(a = first), b = buf, c = middle;;) {
42521  r = ss_compare(T, PA + *b, PA + *c, depth);
42522  if(r < 0) {
42523  do {
42524  *a++ = *b;
42525  if(bufend <= b) { *bufend = t; return; }
42526  *b++ = *a;
42527  } while(*b < 0);
42528  } else if(r > 0) {
42529  do {
42530  *a++ = *c, *c++ = *a;
42531  if(last <= c) {
42532  while(b < bufend) { *a++ = *b, *b++ = *a; }
42533  *a = *b, *b = t;
42534  return;
42535  }
42536  } while(*c < 0);
42537  } else {
42538  *c = ~*c;
42539  do {
42540  *a++ = *b;
42541  if(bufend <= b) { *bufend = t; return; }
42542  *b++ = *a;
42543  } while(*b < 0);
42544 
42545  do {
42546  *a++ = *c, *c++ = *a;
42547  if(last <= c) {
42548  while(b < bufend) { *a++ = *b, *b++ = *a; }
42549  *a = *b, *b = t;
42550  return;
42551  }
42552  } while(*c < 0);
42553  }
42554  }
42555 }
42556 
42557 /* Merge-backward with internal buffer. */
42558 static
42559 void
42560 ss_mergebackward(const unsigned char *T, const int *PA,
42561  int *first, int *middle, int *last,
42562  int *buf, int depth) {
42563  const int *p1, *p2;
42564  int *a, *b, *c, *bufend;
42565  int t;
42566  int r;
42567  int x;
42568 
42569  bufend = buf + (last - middle) - 1;
42570  ss_blockswap(buf, middle, last - middle);
42571 
42572  x = 0;
42573  if(*bufend < 0) { p1 = PA + ~*bufend; x |= 1; }
42574  else { p1 = PA + *bufend; }
42575  if(*(middle - 1) < 0) { p2 = PA + ~*(middle - 1); x |= 2; }
42576  else { p2 = PA + *(middle - 1); }
42577  for(t = *(a = last - 1), b = bufend, c = middle - 1;;) {
42578  r = ss_compare(T, p1, p2, depth);
42579  if(0 < r) {
42580  if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; }
42581  *a-- = *b;
42582  if(b <= buf) { *buf = t; break; }
42583  *b-- = *a;
42584  if(*b < 0) { p1 = PA + ~*b; x |= 1; }
42585  else { p1 = PA + *b; }
42586  } else if(r < 0) {
42587  if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; }
42588  *a-- = *c, *c-- = *a;
42589  if(c < first) {
42590  while(buf < b) { *a-- = *b, *b-- = *a; }
42591  *a = *b, *b = t;
42592  break;
42593  }
42594  if(*c < 0) { p2 = PA + ~*c; x |= 2; }
42595  else { p2 = PA + *c; }
42596  } else {
42597  if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; }
42598  *a-- = ~*b;
42599  if(b <= buf) { *buf = t; break; }
42600  *b-- = *a;
42601  if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; }
42602  *a-- = *c, *c-- = *a;
42603  if(c < first) {
42604  while(buf < b) { *a-- = *b, *b-- = *a; }
42605  *a = *b, *b = t;
42606  break;
42607  }
42608  if(*b < 0) { p1 = PA + ~*b; x |= 1; }
42609  else { p1 = PA + *b; }
42610  if(*c < 0) { p2 = PA + ~*c; x |= 2; }
42611  else { p2 = PA + *c; }
42612  }
42613  }
42614 }
42615 
42616 /* D&C based merge. */
42617 static
42618 void
42619 ss_swapmerge(const unsigned char *T, const int *PA,
42620  int *first, int *middle, int *last,
42621  int *buf, int bufsize, int depth) {
42622 #define STACK_SIZE SS_SMERGE_STACKSIZE
42623 #define GETIDX(a) ((0 <= (a)) ? (a) : (~(a)))
42624 #define MERGE_CHECK(a, b, c)\
42625  do {\
42626  if(((c) & 1) ||\
42627  (((c) & 2) && (ss_compare(T, PA + GETIDX(*((a) - 1)), PA + *(a), depth) == 0))) {\
42628  *(a) = ~*(a);\
42629  }\
42630  if(((c) & 4) && ((ss_compare(T, PA + GETIDX(*((b) - 1)), PA + *(b), depth) == 0))) {\
42631  *(b) = ~*(b);\
42632  }\
42633  } while(0)
42634  struct { int *a, *b, *c; int d; } stack[STACK_SIZE];
42635  int *l, *r, *lm, *rm;
42636  int m, len, half;
42637  int ssize;
42638  int check, next;
42639 
42640  for(check = 0, ssize = 0;;) {
42641  if((last - middle) <= bufsize) {
42642  if((first < middle) && (middle < last)) {
42643  ss_mergebackward(T, PA, first, middle, last, buf, depth);
42644  }
42645  MERGE_CHECK(first, last, check);
42646  STACK_POP(first, middle, last, check);
42647  continue;
42648  }
42649 
42650  if((middle - first) <= bufsize) {
42651  if(first < middle) {
42652  ss_mergeforward(T, PA, first, middle, last, buf, depth);
42653  }
42654  MERGE_CHECK(first, last, check);
42655  STACK_POP(first, middle, last, check);
42656  continue;
42657  }
42658 
42659  for(m = 0, len = MIN(middle - first, last - middle), half = len >> 1;
42660  0 < len;
42661  len = half, half >>= 1) {
42662  if(ss_compare(T, PA + GETIDX(*(middle + m + half)),
42663  PA + GETIDX(*(middle - m - half - 1)), depth) < 0) {
42664  m += half + 1;
42665  half -= (len & 1) ^ 1;
42666  }
42667  }
42668 
42669  if(0 < m) {
42670  lm = middle - m, rm = middle + m;
42671  ss_blockswap(lm, middle, m);
42672  l = r = middle, next = 0;
42673  if(rm < last) {
42674  if(*rm < 0) {
42675  *rm = ~*rm;
42676  if(first < lm) { for(; *--l < 0;) { } next |= 4; }
42677  next |= 1;
42678  } else if(first < lm) {
42679  for(; *r < 0; ++r) { }
42680  next |= 2;
42681  }
42682  }
42683 
42684  if((l - first) <= (last - r)) {
42685  STACK_PUSH(r, rm, last, (next & 3) | (check & 4));
42686  middle = lm, last = l, check = (check & 3) | (next & 4);
42687  } else {
42688  if((next & 2) && (r == middle)) { next ^= 6; }
42689  STACK_PUSH(first, lm, l, (check & 3) | (next & 4));
42690  first = r, middle = rm, check = (next & 3) | (check & 4);
42691  }
42692  } else {
42693  if(ss_compare(T, PA + GETIDX(*(middle - 1)), PA + *middle, depth) == 0) {
42694  *middle = ~*middle;
42695  }
42696  MERGE_CHECK(first, last, check);
42697  STACK_POP(first, middle, last, check);
42698  }
42699  }
42700 #undef STACK_SIZE
42702 
42703 #endif /* SS_BLOCKSIZE != 0 */
42704 
42705 
42706 /*---------------------------------------------------------------------------*/
42707 
42708 /* Substring sort */
42709 static
42710 void
42711 sssort(const unsigned char *T, const int *PA,
42712  int *first, int *last,
42713  int *buf, int bufsize,
42714  int depth, int n, int lastsuffix) {
42715  int *a;
42716 #if SS_BLOCKSIZE != 0
42717  int *b, *middle, *curbuf;
42718  int j, k, curbufsize, limit;
42719 #endif
42720  int i;
42721 
42722  if(lastsuffix != 0) { ++first; }
42723 
42724 #if SS_BLOCKSIZE == 0
42725  ss_mintrosort(T, PA, first, last, depth);
42726 #else
42727  if((bufsize < SS_BLOCKSIZE) &&
42728  (bufsize < (last - first)) &&
42729  (bufsize < (limit = ss_isqrt(last - first)))) {
42730  if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; }
42731  buf = middle = last - limit, bufsize = limit;
42732  } else {
42733  middle = last, limit = 0;
42734  }
42735  for(a = first, i = 0; SS_BLOCKSIZE < (middle - a); a += SS_BLOCKSIZE, ++i) {
42736 #if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
42737  ss_mintrosort(T, PA, a, a + SS_BLOCKSIZE, depth);
42738 #elif 1 < SS_BLOCKSIZE
42739  ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth);
42740 #endif
42741  curbufsize = last - (a + SS_BLOCKSIZE);
42742  curbuf = a + SS_BLOCKSIZE;
42743  if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; }
42744  for(b = a, k = SS_BLOCKSIZE, j = i; j & 1; b -= k, k <<= 1, j >>= 1) {
42745  ss_swapmerge(T, PA, b - k, b, b + k, curbuf, curbufsize, depth);
42746  }
42747  }
42748 #if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
42749  ss_mintrosort(T, PA, a, middle, depth);
42750 #elif 1 < SS_BLOCKSIZE
42751  ss_insertionsort(T, PA, a, middle, depth);
42752 #endif
42753  for(k = SS_BLOCKSIZE; i != 0; k <<= 1, i >>= 1) {
42754  if(i & 1) {
42755  ss_swapmerge(T, PA, a - k, a, middle, buf, bufsize, depth);
42756  a -= k;
42757  }
42758  }
42759  if(limit != 0) {
42760 #if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
42761  ss_mintrosort(T, PA, middle, last, depth);
42762 #elif 1 < SS_BLOCKSIZE
42763  ss_insertionsort(T, PA, middle, last, depth);
42764 #endif
42765  ss_inplacemerge(T, PA, first, middle, last, depth);
42766  }
42767 #endif
42768 
42769  if(lastsuffix != 0) {
42770  /* Insert last type B* suffix. */
42771  int PAi[2]; PAi[0] = PA[*(first - 1)], PAi[1] = n - 2;
42772  for(a = first, i = *(first - 1);
42773  (a < last) && ((*a < 0) || (0 < ss_compare(T, &(PAi[0]), PA + *a, depth)));
42774  ++a) {
42775  *(a - 1) = *a;
42776  }
42777  *(a - 1) = i;
42778  }
42779 }
42780 
42781 
42782 /*---------------------------------------------------------------------------*/
42783 
42784 static INLINE
42785 int
42786 tr_ilg(int n) {
42787  return (n & 0xffff0000) ?
42788  ((n & 0xff000000) ?
42789  24 + lg_table[(n >> 24) & 0xff] :
42790  16 + lg_table[(n >> 16) & 0xff]) :
42791  ((n & 0x0000ff00) ?
42792  8 + lg_table[(n >> 8) & 0xff] :
42793  0 + lg_table[(n >> 0) & 0xff]);
42794 }
42795 
42796 
42797 /*---------------------------------------------------------------------------*/
42798 
42799 /* Simple insertionsort for small size groups. */
42800 static
42801 void
42802 tr_insertionsort(const int *ISAd, int *first, int *last) {
42803  int *a, *b;
42804  int t, r;
42805 
42806  for(a = first + 1; a < last; ++a) {
42807  for(t = *a, b = a - 1; 0 > (r = ISAd[t] - ISAd[*b]);) {
42808  do { *(b + 1) = *b; } while((first <= --b) && (*b < 0));
42809  if(b < first) { break; }
42810  }
42811  if(r == 0) { *b = ~*b; }
42812  *(b + 1) = t;
42813  }
42814 }
42815 
42816 
42817 /*---------------------------------------------------------------------------*/
42818 
42819 static INLINE
42820 void
42821 tr_fixdown(const int *ISAd, int *SA, int i, int size) {
42822  int j, k;
42823  int v;
42824  int c, d, e;
42825 
42826  for(v = SA[i], c = ISAd[v]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) {
42827  d = ISAd[SA[k = j++]];
42828  if(d < (e = ISAd[SA[j]])) { k = j; d = e; }
42829  if(d <= c) { break; }
42830  }
42831  SA[i] = v;
42832 }
42833 
42834 /* Simple top-down heapsort. */
42835 static
42836 void
42837 tr_heapsort(const int *ISAd, int *SA, int size) {
42838  int i, m;
42839  int t;
42840 
42841  m = size;
42842  if((size % 2) == 0) {
42843  m--;
42844  if(ISAd[SA[m / 2]] < ISAd[SA[m]]) { SWAP(SA[m], SA[m / 2]); }
42845  }
42846 
42847  for(i = m / 2 - 1; 0 <= i; --i) { tr_fixdown(ISAd, SA, i, m); }
42848  if((size % 2) == 0) { SWAP(SA[0], SA[m]); tr_fixdown(ISAd, SA, 0, m); }
42849  for(i = m - 1; 0 < i; --i) {
42850  t = SA[0], SA[0] = SA[i];
42851  tr_fixdown(ISAd, SA, 0, i);
42852  SA[i] = t;
42853  }
42854 }
42855 
42856 
42857 /*---------------------------------------------------------------------------*/
42858 
42859 /* Returns the median of three elements. */
42860 static INLINE
42861 int *
42862 tr_median3(const int *ISAd, int *v1, int *v2, int *v3) {
42863  int *t;
42864  if(ISAd[*v1] > ISAd[*v2]) { SWAP(v1, v2); }
42865  if(ISAd[*v2] > ISAd[*v3]) {
42866  if(ISAd[*v1] > ISAd[*v3]) { return v1; }
42867  else { return v3; }
42868  }
42869  return v2;
42870 }
42871 
42872 /* Returns the median of five elements. */
42873 static INLINE
42874 int *
42875 tr_median5(const int *ISAd,
42876  int *v1, int *v2, int *v3, int *v4, int *v5) {
42877  int *t;
42878  if(ISAd[*v2] > ISAd[*v3]) { SWAP(v2, v3); }
42879  if(ISAd[*v4] > ISAd[*v5]) { SWAP(v4, v5); }
42880  if(ISAd[*v2] > ISAd[*v4]) { SWAP(v2, v4); SWAP(v3, v5); }
42881  if(ISAd[*v1] > ISAd[*v3]) { SWAP(v1, v3); }
42882  if(ISAd[*v1] > ISAd[*v4]) { SWAP(v1, v4); SWAP(v3, v5); }
42883  if(ISAd[*v3] > ISAd[*v4]) { return v4; }
42884  return v3;
42885 }
42886 
42887 /* Returns the pivot element. */
42888 static INLINE
42889 int *
42890 tr_pivot(const int *ISAd, int *first, int *last) {
42891  int *middle;
42892  int t;
42893 
42894  t = last - first;
42895  middle = first + t / 2;
42896 
42897  if(t <= 512) {
42898  if(t <= 32) {
42899  return tr_median3(ISAd, first, middle, last - 1);
42900  } else {
42901  t >>= 2;
42902  return tr_median5(ISAd, first, first + t, middle, last - 1 - t, last - 1);
42903  }
42904  }
42905  t >>= 3;
42906  first = tr_median3(ISAd, first, first + t, first + (t << 1));
42907  middle = tr_median3(ISAd, middle - t, middle, middle + t);
42908  last = tr_median3(ISAd, last - 1 - (t << 1), last - 1 - t, last - 1);
42909  return tr_median3(ISAd, first, middle, last);
42911 
42912 
42913 /*---------------------------------------------------------------------------*/
42914 
42915 typedef struct _trbudget_t trbudget_t;
42916 struct _trbudget_t {
42917  int chance;
42918  int remain;
42919  int incval;
42920  int count;
42921 };
42923 static INLINE
42924 void
42925 trbudget_init(trbudget_t *budget, int chance, int incval) {
42926  budget->chance = chance;
42927  budget->remain = budget->incval = incval;
42928 }
42929 
42930 static INLINE
42931 int
42932 trbudget_check(trbudget_t *budget, int size) {
42933  if(size <= budget->remain) { budget->remain -= size; return 1; }
42934  if(budget->chance == 0) { budget->count += size; return 0; }
42935  budget->remain += budget->incval - size;
42936  budget->chance -= 1;
42937  return 1;
42938 }
42939 
42940 
42941 /*---------------------------------------------------------------------------*/
42942 
42943 static INLINE
42944 void
42945 tr_partition(const int *ISAd,
42946  int *first, int *middle, int *last,
42947  int **pa, int **pb, int v) {
42948  int *a, *b, *c, *d, *e, *f;
42949  int t, s;
42950  int x = 0;
42951 
42952  for(b = middle - 1; (++b < last) && ((x = ISAd[*b]) == v);) { }
42953  if(((a = b) < last) && (x < v)) {
42954  for(; (++b < last) && ((x = ISAd[*b]) <= v);) {
42955  if(x == v) { SWAP(*b, *a); ++a; }
42956  }
42957  }
42958  for(c = last; (b < --c) && ((x = ISAd[*c]) == v);) { }
42959  if((b < (d = c)) && (x > v)) {
42960  for(; (b < --c) && ((x = ISAd[*c]) >= v);) {
42961  if(x == v) { SWAP(*c, *d); --d; }
42962  }
42963  }
42964  for(; b < c;) {
42965  SWAP(*b, *c);
42966  for(; (++b < c) && ((x = ISAd[*b]) <= v);) {
42967  if(x == v) { SWAP(*b, *a); ++a; }
42968  }
42969  for(; (b < --c) && ((x = ISAd[*c]) >= v);) {
42970  if(x == v) { SWAP(*c, *d); --d; }
42971  }
42972  }
42973 
42974  if(a <= d) {
42975  c = b - 1;
42976  if((s = a - first) > (t = b - a)) { s = t; }
42977  for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
42978  if((s = d - c) > (t = last - d - 1)) { s = t; }
42979  for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
42980  first += (b - a), last -= (d - c);
42981  }
42982  *pa = first, *pb = last;
42983 }
42984 
42985 static
42986 void
42987 tr_copy(int *ISA, const int *SA,
42988  int *first, int *a, int *b, int *last,
42989  int depth) {
42990  /* sort suffixes of middle partition
42991  by using sorted order of suffixes of left and right partition. */
42992  int *c, *d, *e;
42993  int s, v;
42994 
42995  v = b - SA - 1;
42996  for(c = first, d = a - 1; c <= d; ++c) {
42997  if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
42998  *++d = s;
42999  ISA[s] = d - SA;
43000  }
43001  }
43002  for(c = last - 1, e = d + 1, d = b; e < d; --c) {
43003  if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
43004  *--d = s;
43005  ISA[s] = d - SA;
43006  }
43007  }
43008 }
43009 
43010 static
43011 void
43012 tr_partialcopy(int *ISA, const int *SA,
43013  int *first, int *a, int *b, int *last,
43014  int depth) {
43015  int *c, *d, *e;
43016  int s, v;
43017  int rank, lastrank, newrank = -1;
43018 
43019  v = b - SA - 1;
43020  lastrank = -1;
43021  for(c = first, d = a - 1; c <= d; ++c) {
43022  if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
43023  *++d = s;
43024  rank = ISA[s + depth];
43025  if(lastrank != rank) { lastrank = rank; newrank = d - SA; }
43026  ISA[s] = newrank;
43027  }
43028  }
43029 
43030  lastrank = -1;
43031  for(e = d; first <= e; --e) {
43032  rank = ISA[*e];
43033  if(lastrank != rank) { lastrank = rank; newrank = e - SA; }
43034  if(newrank != rank) { ISA[*e] = newrank; }
43035  }
43036 
43037  lastrank = -1;
43038  for(c = last - 1, e = d + 1, d = b; e < d; --c) {
43039  if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
43040  *--d = s;
43041  rank = ISA[s + depth];
43042  if(lastrank != rank) { lastrank = rank; newrank = d - SA; }
43043  ISA[s] = newrank;
43044  }
43045  }
43046 }
43047 
43048 static
43049 void
43050 tr_introsort(int *ISA, const int *ISAd,
43051  int *SA, int *first, int *last,
43052  trbudget_t *budget) {
43053 #define STACK_SIZE TR_STACKSIZE
43054  struct { const int *a; int *b, *c; int d, e; }stack[STACK_SIZE];
43055  int *a, *b, *c;
43056  int t;
43057  int v, x = 0;
43058  int incr = ISAd - ISA;
43059  int limit, next;
43060  int ssize, trlink = -1;
43061 
43062  for(ssize = 0, limit = tr_ilg(last - first);;) {
43063 
43064  if(limit < 0) {
43065  if(limit == -1) {
43066  /* tandem repeat partition */
43067  tr_partition(ISAd - incr, first, first, last, &a, &b, last - SA - 1);
43068 
43069  /* update ranks */
43070  if(a < last) {
43071  for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; }
43072  }
43073  if(b < last) {
43074  for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; }
43075  }
43076 
43077  /* push */
43078  if(1 < (b - a)) {
43079  STACK_PUSH5(NULL, a, b, 0, 0);
43080  STACK_PUSH5(ISAd - incr, first, last, -2, trlink);
43081  trlink = ssize - 2;
43082  }
43083  if((a - first) <= (last - b)) {
43084  if(1 < (a - first)) {
43085  STACK_PUSH5(ISAd, b, last, tr_ilg(last - b), trlink);
43086  last = a, limit = tr_ilg(a - first);
43087  } else if(1 < (last - b)) {
43088  first = b, limit = tr_ilg(last - b);
43089  } else {
43090  STACK_POP5(ISAd, first, last, limit, trlink);
43091  }
43092  } else {
43093  if(1 < (last - b)) {
43094  STACK_PUSH5(ISAd, first, a, tr_ilg(a - first), trlink);
43095  first = b, limit = tr_ilg(last - b);
43096  } else if(1 < (a - first)) {
43097  last = a, limit = tr_ilg(a - first);
43098  } else {
43099  STACK_POP5(ISAd, first, last, limit, trlink);
43100  }
43101  }
43102  } else if(limit == -2) {
43103  /* tandem repeat copy */
43104  a = stack[--ssize].b, b = stack[ssize].c;
43105  if(stack[ssize].d == 0) {
43106  tr_copy(ISA, SA, first, a, b, last, ISAd - ISA);
43107  } else {
43108  if(0 <= trlink) { stack[trlink].d = -1; }
43109  tr_partialcopy(ISA, SA, first, a, b, last, ISAd - ISA);
43110  }
43111  STACK_POP5(ISAd, first, last, limit, trlink);
43112  } else {
43113  /* sorted partition */
43114  if(0 <= *first) {
43115  a = first;
43116  do { ISA[*a] = a - SA; } while((++a < last) && (0 <= *a));
43117  first = a;
43118  }
43119  if(first < last) {
43120  a = first; do { *a = ~*a; } while(*++a < 0);
43121  next = (ISA[*a] != ISAd[*a]) ? tr_ilg(a - first + 1) : -1;
43122  if(++a < last) { for(b = first, v = a - SA - 1; b < a; ++b) { ISA[*b] = v; } }
43123 
43124  /* push */
43125  if(trbudget_check(budget, a - first)) {
43126  if((a - first) <= (last - a)) {
43127  STACK_PUSH5(ISAd, a, last, -3, trlink);
43128  ISAd += incr, last = a, limit = next;
43129  } else {
43130  if(1 < (last - a)) {
43131  STACK_PUSH5(ISAd + incr, first, a, next, trlink);
43132  first = a, limit = -3;
43133  } else {
43134  ISAd += incr, last = a, limit = next;
43135  }
43136  }
43137  } else {
43138  if(0 <= trlink) { stack[trlink].d = -1; }
43139  if(1 < (last - a)) {
43140  first = a, limit = -3;
43141  } else {
43142  STACK_POP5(ISAd, first, last, limit, trlink);
43143  }
43144  }
43145  } else {
43146  STACK_POP5(ISAd, first, last, limit, trlink);
43147  }
43148  }
43149  continue;
43150  }
43151 
43152  if((last - first) <= TR_INSERTIONSORT_THRESHOLD) {
43153  tr_insertionsort(ISAd, first, last);
43154  limit = -3;
43155  continue;
43156  }
43157 
43158  if(limit-- == 0) {
43159  tr_heapsort(ISAd, first, last - first);
43160  for(a = last - 1; first < a; a = b) {
43161  for(x = ISAd[*a], b = a - 1; (first <= b) && (ISAd[*b] == x); --b) { *b = ~*b; }
43162  }
43163  limit = -3;
43164  continue;
43165  }
43166 
43167  /* choose pivot */
43168  a = tr_pivot(ISAd, first, last);
43169  SWAP(*first, *a);
43170  v = ISAd[*first];
43171 
43172  /* partition */
43173  tr_partition(ISAd, first, first + 1, last, &a, &b, v);
43174  if((last - first) != (b - a)) {
43175  next = (ISA[*a] != v) ? tr_ilg(b - a) : -1;
43176 
43177  /* update ranks */
43178  for(c = first, v = a - SA - 1; c < a; ++c) { ISA[*c] = v; }
43179  if(b < last) { for(c = a, v = b - SA - 1; c < b; ++c) { ISA[*c] = v; } }
43180 
43181  /* push */
43182  if((1 < (b - a)) && (trbudget_check(budget, b - a))) {
43183  if((a - first) <= (last - b)) {
43184  if((last - b) <= (b - a)) {
43185  if(1 < (a - first)) {
43186  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43187  STACK_PUSH5(ISAd, b, last, limit, trlink);
43188  last = a;
43189  } else if(1 < (last - b)) {
43190  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43191  first = b;
43192  } else {
43193  ISAd += incr, first = a, last = b, limit = next;
43194  }
43195  } else if((a - first) <= (b - a)) {
43196  if(1 < (a - first)) {
43197  STACK_PUSH5(ISAd, b, last, limit, trlink);
43198  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43199  last = a;
43200  } else {
43201  STACK_PUSH5(ISAd, b, last, limit, trlink);
43202  ISAd += incr, first = a, last = b, limit = next;
43203  }
43204  } else {
43205  STACK_PUSH5(ISAd, b, last, limit, trlink);
43206  STACK_PUSH5(ISAd, first, a, limit, trlink);
43207  ISAd += incr, first = a, last = b, limit = next;
43208  }
43209  } else {
43210  if((a - first) <= (b - a)) {
43211  if(1 < (last - b)) {
43212  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43213  STACK_PUSH5(ISAd, first, a, limit, trlink);
43214  first = b;
43215  } else if(1 < (a - first)) {
43216  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43217  last = a;
43218  } else {
43219  ISAd += incr, first = a, last = b, limit = next;
43220  }
43221  } else if((last - b) <= (b - a)) {
43222  if(1 < (last - b)) {
43223  STACK_PUSH5(ISAd, first, a, limit, trlink);
43224  STACK_PUSH5(ISAd + incr, a, b, next, trlink);
43225  first = b;
43226  } else {
43227  STACK_PUSH5(ISAd, first, a, limit, trlink);
43228  ISAd += incr, first = a, last = b, limit = next;
43229  }
43230  } else {
43231  STACK_PUSH5(ISAd, first, a, limit, trlink);
43232  STACK_PUSH5(ISAd, b, last, limit, trlink);
43233  ISAd += incr, first = a, last = b, limit = next;
43234  }
43235  }
43236  } else {
43237  if((1 < (b - a)) && (0 <= trlink)) { stack[trlink].d = -1; }
43238  if((a - first) <= (last - b)) {
43239  if(1 < (a - first)) {
43240  STACK_PUSH5(ISAd, b, last, limit, trlink);
43241  last = a;
43242  } else if(1 < (last - b)) {
43243  first = b;
43244  } else {
43245  STACK_POP5(ISAd, first, last, limit, trlink);
43246  }
43247  } else {
43248  if(1 < (last - b)) {
43249  STACK_PUSH5(ISAd, first, a, limit, trlink);
43250  first = b;
43251  } else if(1 < (a - first)) {
43252  last = a;
43253  } else {
43254  STACK_POP5(ISAd, first, last, limit, trlink);
43255  }
43256  }
43257  }
43258  } else {
43259  if(trbudget_check(budget, last - first)) {
43260  limit = tr_ilg(last - first), ISAd += incr;
43261  } else {
43262  if(0 <= trlink) { stack[trlink].d = -1; }
43263  STACK_POP5(ISAd, first, last, limit, trlink);
43264  }
43265  }
43266  }
43267 #undef STACK_SIZE
43268 }
43269 
43270 
43271 
43272 /*---------------------------------------------------------------------------*/
43273 
43274 /* Tandem repeat sort */
43275 static
43276 void
43277 trsort(int *ISA, int *SA, int n, int depth) {
43278  int *ISAd;
43279  int *first, *last;
43280  trbudget_t budget;
43281  int t, skip, unsorted;
43282 
43283  trbudget_init(&budget, tr_ilg(n) * 2 / 3, n);
43284 /* trbudget_init(&budget, tr_ilg(n) * 3 / 4, n); */
43285  for(ISAd = ISA + depth; -n < *SA; ISAd += ISAd - ISA) {
43286  first = SA;
43287  skip = 0;
43288  unsorted = 0;
43289  do {
43290  if((t = *first) < 0) { first -= t; skip += t; }
43291  else {
43292  if(skip != 0) { *(first + skip) = skip; skip = 0; }
43293  last = SA + ISA[t] + 1;
43294  if(1 < (last - first)) {
43295  budget.count = 0;
43296  tr_introsort(ISA, ISAd, SA, first, last, &budget);
43297  if(budget.count != 0) { unsorted += budget.count; }
43298  else { skip = first - last; }
43299  } else if((last - first) == 1) {
43300  skip = -1;
43301  }
43302  first = last;
43303  }
43304  } while(first < (SA + n));
43305  if(skip != 0) { *(first + skip) = skip; }
43306  if(unsorted == 0) { break; }
43307  }
43308 }
43309 
43310 
43311 /*---------------------------------------------------------------------------*/
43312 
43313 /* Sorts suffixes of type B*. */
43314 static
43315 int
43316 sort_typeBstar(const unsigned char *T, int *SA,
43317  int *bucket_A, int *bucket_B,
43318  int n, int openMP) {
43319  int *PAb, *ISAb, *buf;
43320 #ifdef LIBBSC_OPENMP
43321  int *curbuf;
43322  int l;
43323 #endif
43324  int i, j, k, t, m, bufsize;
43325  int c0, c1;
43326 #ifdef LIBBSC_OPENMP
43327  int d0, d1;
43328 #endif
43329  (void)openMP;
43330 
43331  /* Initialize bucket arrays. */
43332  for(i = 0; i < BUCKET_A_SIZE; ++i) { bucket_A[i] = 0; }
43333  for(i = 0; i < BUCKET_B_SIZE; ++i) { bucket_B[i] = 0; }
43334 
43335  /* Count the number of occurrences of the first one or two characters of each
43336  type A, B and B* suffix. Moreover, store the beginning position of all
43337  type B* suffixes into the array SA. */
43338  for(i = n - 1, m = n, c0 = T[n - 1]; 0 <= i;) {
43339  /* type A suffix. */
43340  do { ++BUCKET_A(c1 = c0); } while((0 <= --i) && ((c0 = T[i]) >= c1));
43341  if(0 <= i) {
43342  /* type B* suffix. */
43343  ++BUCKET_BSTAR(c0, c1);
43344  SA[--m] = i;
43345  /* type B suffix. */
43346  for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) {
43347  ++BUCKET_B(c0, c1);
43348  }
43349  }
43350  }
43351  m = n - m;
43352 /*
43353 note:
43354  A type B* suffix is lexicographically smaller than a type B suffix that
43355  begins with the same first two characters.
43356 */
43357 
43358  /* Calculate the index of start/end point of each bucket. */
43359  for(c0 = 0, i = 0, j = 0; c0 < ALPHABET_SIZE; ++c0) {
43360  t = i + BUCKET_A(c0);
43361  BUCKET_A(c0) = i + j; /* start point */
43362  i = t + BUCKET_B(c0, c0);
43363  for(c1 = c0 + 1; c1 < ALPHABET_SIZE; ++c1) {
43364  j += BUCKET_BSTAR(c0, c1);
43365  BUCKET_BSTAR(c0, c1) = j; /* end point */
43366  i += BUCKET_B(c0, c1);
43367  }
43368  }
43369 
43370  if(0 < m) {
43371  /* Sort the type B* suffixes by their first two characters. */
43372  PAb = SA + n - m; ISAb = SA + m;
43373  for(i = m - 2; 0 <= i; --i) {
43374  t = PAb[i], c0 = T[t], c1 = T[t + 1];
43375  SA[--BUCKET_BSTAR(c0, c1)] = i;
43376  }
43377  t = PAb[m - 1], c0 = T[t], c1 = T[t + 1];
43378  SA[--BUCKET_BSTAR(c0, c1)] = m - 1;
43379 
43380  /* Sort the type B* substrings using sssort. */
43381 #ifdef LIBBSC_OPENMP
43382  if (openMP)
43383  {
43384  buf = SA + m;
43385  c0 = ALPHABET_SIZE - 2, c1 = ALPHABET_SIZE - 1, j = m;
43386 #pragma omp parallel default(shared) private(bufsize, curbuf, k, l, d0, d1)
43387  {
43388  bufsize = (n - (2 * m)) / omp_get_num_threads();
43389  curbuf = buf + omp_get_thread_num() * bufsize;
43390  k = 0;
43391  for(;;) {
43392  #pragma omp critical(sssort_lock)
43393  {
43394  if(0 < (l = j)) {
43395  d0 = c0, d1 = c1;
43396  do {
43397  k = BUCKET_BSTAR(d0, d1);
43398  if(--d1 <= d0) {
43399  d1 = ALPHABET_SIZE - 1;
43400  if(--d0 < 0) { break; }
43401  }
43402  } while(((l - k) <= 1) && (0 < (l = k)));
43403  c0 = d0, c1 = d1, j = k;
43404  }
43405  }
43406  if(l == 0) { break; }
43407  sssort(T, PAb, SA + k, SA + l,
43408  curbuf, bufsize, 2, n, *(SA + k) == (m - 1));
43409  }
43410  }
43411  }
43412  else
43413  {
43414  buf = SA + m, bufsize = n - (2 * m);
43415  for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) {
43416  for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) {
43417  i = BUCKET_BSTAR(c0, c1);
43418  if(1 < (j - i)) {
43419  sssort(T, PAb, SA + i, SA + j,
43420  buf, bufsize, 2, n, *(SA + i) == (m - 1));
43421  }
43422  }
43423  }
43424  }
43425 #else
43426  buf = SA + m, bufsize = n - (2 * m);
43427  for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) {
43428  for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) {
43429  i = BUCKET_BSTAR(c0, c1);
43430  if(1 < (j - i)) {
43431  sssort(T, PAb, SA + i, SA + j,
43432  buf, bufsize, 2, n, *(SA + i) == (m - 1));
43433  }
43434  }
43435  }
43436 #endif
43437 
43438  /* Compute ranks of type B* substrings. */
43439  for(i = m - 1; 0 <= i; --i) {
43440  if(0 <= SA[i]) {
43441  j = i;
43442  do { ISAb[SA[i]] = i; } while((0 <= --i) && (0 <= SA[i]));
43443  SA[i + 1] = i - j;
43444  if(i <= 0) { break; }
43445  }
43446  j = i;
43447  do { ISAb[SA[i] = ~SA[i]] = j; } while(SA[--i] < 0);
43448  ISAb[SA[i]] = j;
43449  }
43450 
43451  /* Construct the inverse suffix array of type B* suffixes using trsort. */
43452  trsort(ISAb, SA, m, 1);
43453 
43454  /* Set the sorted order of type B* suffixes. */
43455  for(i = n - 1, j = m, c0 = T[n - 1]; 0 <= i;) {
43456  for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) >= c1); --i, c1 = c0) { }
43457  if(0 <= i) {
43458  t = i;
43459  for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) { }
43460  SA[ISAb[--j]] = ((t == 0) || (1 < (t - i))) ? t : ~t;
43461  }
43462  }
43463 
43464  /* Calculate the index of start/end point of each bucket. */
43465  BUCKET_B(ALPHABET_SIZE - 1, ALPHABET_SIZE - 1) = n; /* end point */
43466  for(c0 = ALPHABET_SIZE - 2, k = m - 1; 0 <= c0; --c0) {
43467  i = BUCKET_A(c0 + 1) - 1;
43468  for(c1 = ALPHABET_SIZE - 1; c0 < c1; --c1) {
43469  t = i - BUCKET_B(c0, c1);
43470  BUCKET_B(c0, c1) = i; /* end point */
43471 
43472  /* Move all type B* suffixes to the correct position. */
43473  for(i = t, j = BUCKET_BSTAR(c0, c1);
43474  j <= k;
43475  --i, --k) { SA[i] = SA[k]; }
43476  }
43477  BUCKET_BSTAR(c0, c0 + 1) = i - BUCKET_B(c0, c0) + 1; /* start point */
43478  BUCKET_B(c0, c0) = i; /* end point */
43479  }
43480  }
43481 
43482  return m;
43483 }
43484 
43485 /* Constructs the suffix array by using the sorted order of type B* suffixes. */
43486 static
43487 void
43488 construct_SA(const unsigned char *T, int *SA,
43489  int *bucket_A, int *bucket_B,
43490  int n, int m) {
43491  int *i, *j, *k;
43492  int s;
43493  int c0, c1, c2;
43494 
43495  if(0 < m) {
43496  /* Construct the sorted order of type B suffixes by using
43497  the sorted order of type B* suffixes. */
43498  for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
43499  /* Scan the suffix array from right to left. */
43500  for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
43501  j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
43502  i <= j;
43503  --j) {
43504  if(0 < (s = *j)) {
43505  assert(T[s] == c1);
43506  assert(((s + 1) < n) && (T[s] <= T[s + 1]));
43507  assert(T[s - 1] <= T[s]);
43508  *j = ~s;
43509  c0 = T[--s];
43510  if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
43511  if(c0 != c2) {
43512  if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
43513  k = SA + BUCKET_B(c2 = c0, c1);
43514  }
43515  assert(k < j); assert(k != NULL);
43516  *k-- = s;
43517  } else {
43518  assert(((s == 0) && (T[s] == c1)) || (s < 0));
43519  *j = ~s;
43520  }
43521  }
43522  }
43523  }
43524 
43525  /* Construct the suffix array by using
43526  the sorted order of type B suffixes. */
43527  k = SA + BUCKET_A(c2 = T[n - 1]);
43528  *k++ = (T[n - 2] < c2) ? ~(n - 1) : (n - 1);
43529  /* Scan the suffix array from left to right. */
43530  for(i = SA, j = SA + n; i < j; ++i) {
43531  if(0 < (s = *i)) {
43532  assert(T[s - 1] >= T[s]);
43533  c0 = T[--s];
43534  if((s == 0) || (T[s - 1] < c0)) { s = ~s; }
43535  if(c0 != c2) {
43536  BUCKET_A(c2) = k - SA;
43537  k = SA + BUCKET_A(c2 = c0);
43538  }
43539  assert(i < k);
43540  *k++ = s;
43541  } else {
43542  assert(s < 0);
43543  *i = ~s;
43544  }
43545  }
43546 }
43547 
43548 /* Constructs the burrows-wheeler transformed string directly
43549  by using the sorted order of type B* suffixes. */
43550 static
43551 int
43552 construct_BWT(const unsigned char *T, int *SA,
43553  int *bucket_A, int *bucket_B,
43554  int n, int m) {
43555  int *i, *j, *k, *orig;
43556  int s;
43557  int c0, c1, c2;
43558 
43559  if(0 < m) {
43560  /* Construct the sorted order of type B suffixes by using
43561  the sorted order of type B* suffixes. */
43562  for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
43563  /* Scan the suffix array from right to left. */
43564  for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
43565  j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
43566  i <= j;
43567  --j) {
43568  if(0 < (s = *j)) {
43569  assert(T[s] == c1);
43570  assert(((s + 1) < n) && (T[s] <= T[s + 1]));
43571  assert(T[s - 1] <= T[s]);
43572  c0 = T[--s];
43573  *j = ~((int)c0);
43574  if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
43575  if(c0 != c2) {
43576  if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
43577  k = SA + BUCKET_B(c2 = c0, c1);
43578  }
43579  assert(k < j); assert(k != NULL);
43580  *k-- = s;
43581  } else if(s != 0) {
43582  *j = ~s;
43583 #ifndef NDEBUG
43584  } else {
43585  assert(T[s] == c1);
43586 #endif
43587  }
43588  }
43589  }
43590  }
43591 
43592  /* Construct the BWTed string by using
43593  the sorted order of type B suffixes. */
43594  k = SA + BUCKET_A(c2 = T[n - 1]);
43595  *k++ = (T[n - 2] < c2) ? ~((int)T[n - 2]) : (n - 1);
43596  /* Scan the suffix array from left to right. */
43597  for(i = SA, j = SA + n, orig = SA; i < j; ++i) {
43598  if(0 < (s = *i)) {
43599  assert(T[s - 1] >= T[s]);
43600  c0 = T[--s];
43601  *i = c0;
43602  if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); }
43603  if(c0 != c2) {
43604  BUCKET_A(c2) = k - SA;
43605  k = SA + BUCKET_A(c2 = c0);
43606  }
43607  assert(i < k);
43608  *k++ = s;
43609  } else if(s != 0) {
43610  *i = ~s;
43611  } else {
43612  orig = i;
43613  }
43614  }
43615 
43616  return orig - SA;
43617 }
43618 
43619 /* Constructs the burrows-wheeler transformed string directly
43620  by using the sorted order of type B* suffixes. */
43621 static
43622 int
43623 construct_BWT_indexes(const unsigned char *T, int *SA,
43624  int *bucket_A, int *bucket_B,
43625  int n, int m,
43626  unsigned char * num_indexes, int * indexes) {
43627  int *i, *j, *k, *orig;
43628  int s;
43629  int c0, c1, c2;
43630 
43631  int mod = n / 8;
43632  {
43633  mod |= mod >> 1; mod |= mod >> 2;
43634  mod |= mod >> 4; mod |= mod >> 8;
43635  mod |= mod >> 16; mod >>= 1;
43636 
43637  *num_indexes = (unsigned char)((n - 1) / (mod + 1));
43638  }
43639 
43640  if(0 < m) {
43641  /* Construct the sorted order of type B suffixes by using
43642  the sorted order of type B* suffixes. */
43643  for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
43644  /* Scan the suffix array from right to left. */
43645  for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
43646  j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
43647  i <= j;
43648  --j) {
43649  if(0 < (s = *j)) {
43650  assert(T[s] == c1);
43651  assert(((s + 1) < n) && (T[s] <= T[s + 1]));
43652  assert(T[s - 1] <= T[s]);
43653 
43654  if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = j - SA;
43655 
43656  c0 = T[--s];
43657  *j = ~((int)c0);
43658  if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
43659  if(c0 != c2) {
43660  if(0 <= c2) { BUCKET_B(c2, c1) = k - SA; }
43661  k = SA + BUCKET_B(c2 = c0, c1);
43662  }
43663  assert(k < j); assert(k != NULL);
43664  *k-- = s;
43665  } else if(s != 0) {
43666  *j = ~s;
43667 #ifndef NDEBUG
43668  } else {
43669  assert(T[s] == c1);
43670 #endif
43671  }
43672  }
43673  }
43674  }
43675 
43676  /* Construct the BWTed string by using
43677  the sorted order of type B suffixes. */
43678  k = SA + BUCKET_A(c2 = T[n - 1]);
43679  if (T[n - 2] < c2) {
43680  if (((n - 1) & mod) == 0) indexes[(n - 1) / (mod + 1) - 1] = k - SA;
43681  *k++ = ~((int)T[n - 2]);
43682  }
43683  else {
43684  *k++ = n - 1;
43685  }
43686 
43687  /* Scan the suffix array from left to right. */
43688  for(i = SA, j = SA + n, orig = SA; i < j; ++i) {
43689  if(0 < (s = *i)) {
43690  assert(T[s - 1] >= T[s]);
43691 
43692  if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = i - SA;
43693 
43694  c0 = T[--s];
43695  *i = c0;
43696  if(c0 != c2) {
43697  BUCKET_A(c2) = k - SA;
43698  k = SA + BUCKET_A(c2 = c0);
43699  }
43700  assert(i < k);
43701  if((0 < s) && (T[s - 1] < c0)) {
43702  if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = k - SA;
43703  *k++ = ~((int)T[s - 1]);
43704  } else
43705  *k++ = s;
43706  } else if(s != 0) {
43707  *i = ~s;
43708  } else {
43709  orig = i;
43710  }
43711  }
43713  return orig - SA;
43714 }
43715 
43716 
43717 /*---------------------------------------------------------------------------*/
43718 
43719 /*- Function -*/
43720 
43721 int
43722 divsufsort(const unsigned char *T, int *SA, int n, int openMP) {
43723  int *bucket_A, *bucket_B;
43724  int m;
43725  int err = 0;
43726 
43727  /* Check arguments. */
43728  if((T == NULL) || (SA == NULL) || (n < 0)) { return -1; }
43729  else if(n == 0) { return 0; }
43730  else if(n == 1) { SA[0] = 0; return 0; }
43731  else if(n == 2) { m = (T[0] < T[1]); SA[m ^ 1] = 0, SA[m] = 1; return 0; }
43732 
43733  bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int));
43734  bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int));
43735 
43736  /* Suffixsort. */
43737  if((bucket_A != NULL) && (bucket_B != NULL)) {
43738  m = sort_typeBstar(T, SA, bucket_A, bucket_B, n, openMP);
43739  construct_SA(T, SA, bucket_A, bucket_B, n, m);
43740  } else {
43741  err = -2;
43742  }
43743 
43744  free(bucket_B);
43745  free(bucket_A);
43746 
43747  return err;
43748 }
43749 
43750 int
43751 divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char * num_indexes, int * indexes, int openMP) {
43752  int *B;
43753  int *bucket_A, *bucket_B;
43754  int m, pidx, i;
43755 
43756  /* Check arguments. */
43757  if((T == NULL) || (U == NULL) || (n < 0)) { return -1; }
43758  else if(n <= 1) { if(n == 1) { U[0] = T[0]; } return n; }
43759 
43760  if((B = A) == NULL) { B = (int *)malloc((size_t)(n + 1) * sizeof(int)); }
43761  bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int));
43762  bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int));
43763 
43764  /* Burrows-Wheeler Transform. */
43765  if((B != NULL) && (bucket_A != NULL) && (bucket_B != NULL)) {
43766  m = sort_typeBstar(T, B, bucket_A, bucket_B, n, openMP);
43767 
43768  if (num_indexes == NULL || indexes == NULL) {
43769  pidx = construct_BWT(T, B, bucket_A, bucket_B, n, m);
43770  } else {
43771  pidx = construct_BWT_indexes(T, B, bucket_A, bucket_B, n, m, num_indexes, indexes);
43772  }
43773 
43774  /* Copy to output string. */
43775  U[0] = T[n - 1];
43776  for(i = 0; i < pidx; ++i) { U[i + 1] = (unsigned char)B[i]; }
43777  for(i += 1; i < n; ++i) { U[i] = (unsigned char)B[i]; }
43778  pidx += 1;
43779  } else {
43780  pidx = -2;
43781  }
43782 
43783  free(bucket_B);
43784  free(bucket_A);
43785  if(A == NULL) { free(B); }
43786 
43787  return pidx;
43788 }
43789 /**** ended inlining dictBuilder/divsufsort.c ****/
43790 /**** start inlining dictBuilder/fastcover.c ****/
43791 /*
43792  * Copyright (c) Meta Platforms, Inc. and affiliates.
43793  * All rights reserved.
43794  *
43795  * This source code is licensed under both the BSD-style license (found in the
43796  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
43797  * in the COPYING file in the root directory of this source tree).
43798  * You may select, at your option, one of the above-listed licenses.
43799  */
43800 
43801 /*-*************************************
43802 * Dependencies
43803 ***************************************/
43804 #include <stdio.h> /* fprintf */
43805 #include <stdlib.h> /* malloc, free, qsort */
43806 #include <string.h> /* memset */
43807 #include <time.h> /* clock */
43808 
43809 #ifndef ZDICT_STATIC_LINKING_ONLY
43810 # define ZDICT_STATIC_LINKING_ONLY
43811 #endif
43812 
43813 /**** skipping file: ../common/mem.h ****/
43814 /**** skipping file: ../common/pool.h ****/
43815 /**** skipping file: ../common/threading.h ****/
43816 /**** skipping file: ../common/zstd_internal.h ****/
43817 /**** skipping file: ../compress/zstd_compress_internal.h ****/
43818 /**** skipping file: ../zdict.h ****/
43819 /**** skipping file: cover.h ****/
43820 
43821 
43822 /*-*************************************
43823 * Constants
43824 ***************************************/
43832 #define FASTCOVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB))
43833 #define FASTCOVER_MAX_F 31
43834 #define FASTCOVER_MAX_ACCEL 10
43835 #define FASTCOVER_DEFAULT_SPLITPOINT 0.75
43836 #define DEFAULT_F 20
43837 #define DEFAULT_ACCEL 1
43838 
43839 
43840 /*-*************************************
43841 * Console display
43842 ***************************************/
43843 #ifndef LOCALDISPLAYLEVEL
43844 static int g_displayLevel = 0;
43845 #endif
43846 #undef DISPLAY
43847 #define DISPLAY(...) \
43848  { \
43849  fprintf(stderr, __VA_ARGS__); \
43850  fflush(stderr); \
43851  }
43852 #undef LOCALDISPLAYLEVEL
43853 #define LOCALDISPLAYLEVEL(displayLevel, l, ...) \
43854  if (displayLevel >= l) { \
43855  DISPLAY(__VA_ARGS__); \
43856  } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
43857 #undef DISPLAYLEVEL
43858 #define DISPLAYLEVEL(l, ...) LOCALDISPLAYLEVEL(g_displayLevel, l, __VA_ARGS__)
43859 
43860 #ifndef LOCALDISPLAYUPDATE
43861 static const clock_t g_refreshRate = CLOCKS_PER_SEC * 15 / 100;
43862 static clock_t g_time = 0;
43863 #endif
43864 #undef LOCALDISPLAYUPDATE
43865 #define LOCALDISPLAYUPDATE(displayLevel, l, ...) \
43866  if (displayLevel >= l) { \
43867  if ((clock() - g_time > g_refreshRate) || (displayLevel >= 4)) { \
43868  g_time = clock(); \
43869  DISPLAY(__VA_ARGS__); \
43870  } \
43871  }
43872 #undef DISPLAYUPDATE
43873 #define DISPLAYUPDATE(l, ...) LOCALDISPLAYUPDATE(g_displayLevel, l, __VA_ARGS__)
43874 
43875 
43876 /*-*************************************
43877 * Hash Functions
43878 ***************************************/
43882 static size_t FASTCOVER_hashPtrToIndex(const void* p, U32 f, unsigned d) {
43883  if (d == 6) {
43884  return ZSTD_hash6Ptr(p, f);
43885  }
43886  return ZSTD_hash8Ptr(p, f);
43887 }
43888 
43890 /*-*************************************
43891 * Acceleration
43892 ***************************************/
43893 typedef struct {
43894  unsigned finalize; /* Percentage of training samples used for ZDICT_finalizeDictionary */
43895  unsigned skip; /* Number of dmer skipped between each dmer counted in computeFrequency */
43897 
43898 
43900  { 100, 0 }, /* accel = 0, should not happen because accel = 0 defaults to accel = 1 */
43901  { 100, 0 }, /* accel = 1 */
43902  { 50, 1 }, /* accel = 2 */
43903  { 34, 2 }, /* accel = 3 */
43904  { 25, 3 }, /* accel = 4 */
43905  { 20, 4 }, /* accel = 5 */
43906  { 17, 5 }, /* accel = 6 */
43907  { 14, 6 }, /* accel = 7 */
43908  { 13, 7 }, /* accel = 8 */
43909  { 11, 8 }, /* accel = 9 */
43910  { 10, 9 }, /* accel = 10 */
43911 };
43914 /*-*************************************
43915 * Context
43916 ***************************************/
43917 typedef struct {
43918  const BYTE *samples;
43919  size_t *offsets;
43920  const size_t *samplesSizes;
43921  size_t nbSamples;
43922  size_t nbTrainSamples;
43923  size_t nbTestSamples;
43924  size_t nbDmers;
43925  U32 *freqs;
43926  unsigned d;
43927  unsigned f;
43928  FASTCOVER_accel_t accelParams;
43929 } FASTCOVER_ctx_t;
43930 
43931 
43932 /*-*************************************
43933 * Helper functions
43934 ***************************************/
43947  U32 *freqs, U32 begin, U32 end,
43948  ZDICT_cover_params_t parameters,
43949  U16* segmentFreqs) {
43950  /* Constants */
43951  const U32 k = parameters.k;
43952  const U32 d = parameters.d;
43953  const U32 f = ctx->f;
43954  const U32 dmersInK = k - d + 1;
43955 
43956  /* Try each segment (activeSegment) and save the best (bestSegment) */
43957  COVER_segment_t bestSegment = {0, 0, 0};
43958  COVER_segment_t activeSegment;
43959 
43960  /* Reset the activeDmers in the segment */
43961  /* The activeSegment starts at the beginning of the epoch. */
43962  activeSegment.begin = begin;
43963  activeSegment.end = begin;
43964  activeSegment.score = 0;
43965 
43966  /* Slide the activeSegment through the whole epoch.
43967  * Save the best segment in bestSegment.
43968  */
43969  while (activeSegment.end < end) {
43970  /* Get hash value of current dmer */
43971  const size_t idx = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.end, f, d);
43972 
43973  /* Add frequency of this index to score if this is the first occurrence of index in active segment */
43974  if (segmentFreqs[idx] == 0) {
43975  activeSegment.score += freqs[idx];
43976  }
43977  /* Increment end of segment and segmentFreqs*/
43978  activeSegment.end += 1;
43979  segmentFreqs[idx] += 1;
43980  /* If the window is now too large, drop the first position */
43981  if (activeSegment.end - activeSegment.begin == dmersInK + 1) {
43982  /* Get hash value of the dmer to be eliminated from active segment */
43983  const size_t delIndex = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.begin, f, d);
43984  segmentFreqs[delIndex] -= 1;
43985  /* Subtract frequency of this index from score if this is the last occurrence of this index in active segment */
43986  if (segmentFreqs[delIndex] == 0) {
43987  activeSegment.score -= freqs[delIndex];
43988  }
43989  /* Increment start of segment */
43990  activeSegment.begin += 1;
43991  }
43992 
43993  /* If this segment is the best so far save it */
43994  if (activeSegment.score > bestSegment.score) {
43995  bestSegment = activeSegment;
43996  }
43997  }
43998 
43999  /* Zero out rest of segmentFreqs array */
44000  while (activeSegment.begin < end) {
44001  const size_t delIndex = FASTCOVER_hashPtrToIndex(ctx->samples + activeSegment.begin, f, d);
44002  segmentFreqs[delIndex] -= 1;
44003  activeSegment.begin += 1;
44004  }
44005 
44006  {
44007  /* Zero the frequency of hash value of each dmer covered by the chosen segment. */
44008  U32 pos;
44009  for (pos = bestSegment.begin; pos != bestSegment.end; ++pos) {
44010  const size_t i = FASTCOVER_hashPtrToIndex(ctx->samples + pos, f, d);
44011  freqs[i] = 0;
44012  }
44013  }
44014 
44015  return bestSegment;
44016 }
44017 
44018 
44019 static int FASTCOVER_checkParameters(ZDICT_cover_params_t parameters,
44020  size_t maxDictSize, unsigned f,
44021  unsigned accel) {
44022  /* k, d, and f are required parameters */
44023  if (parameters.d == 0 || parameters.k == 0) {
44024  return 0;
44025  }
44026  /* d has to be 6 or 8 */
44027  if (parameters.d != 6 && parameters.d != 8) {
44028  return 0;
44029  }
44030  /* k <= maxDictSize */
44031  if (parameters.k > maxDictSize) {
44032  return 0;
44033  }
44034  /* d <= k */
44035  if (parameters.d > parameters.k) {
44036  return 0;
44037  }
44038  /* 0 < f <= FASTCOVER_MAX_F*/
44039  if (f > FASTCOVER_MAX_F || f == 0) {
44040  return 0;
44041  }
44042  /* 0 < splitPoint <= 1 */
44043  if (parameters.splitPoint <= 0 || parameters.splitPoint > 1) {
44044  return 0;
44045  }
44046  /* 0 < accel <= 10 */
44047  if (accel > 10 || accel == 0) {
44048  return 0;
44049  }
44050  return 1;
44051 }
44052 
44053 
44057 static void
44059 {
44060  if (!ctx) return;
44061 
44062  free(ctx->freqs);
44063  ctx->freqs = NULL;
44065  free(ctx->offsets);
44066  ctx->offsets = NULL;
44067 }
44068 
44069 
44073 static void
44075 {
44076  const unsigned f = ctx->f;
44077  const unsigned d = ctx->d;
44078  const unsigned skip = ctx->accelParams.skip;
44079  const unsigned readLength = MAX(d, 8);
44080  size_t i;
44081  assert(ctx->nbTrainSamples >= 5);
44082  assert(ctx->nbTrainSamples <= ctx->nbSamples);
44083  for (i = 0; i < ctx->nbTrainSamples; i++) {
44084  size_t start = ctx->offsets[i]; /* start of current dmer */
44085  size_t const currSampleEnd = ctx->offsets[i+1];
44086  while (start + readLength <= currSampleEnd) {
44087  const size_t dmerIndex = FASTCOVER_hashPtrToIndex(ctx->samples + start, f, d);
44088  freqs[dmerIndex]++;
44089  start = start + skip + 1;
44090  }
44091  }
44092 }
44094 
44102 static size_t
44104  const void* samplesBuffer,
44105  const size_t* samplesSizes, unsigned nbSamples,
44106  unsigned d, double splitPoint, unsigned f,
44107  FASTCOVER_accel_t accelParams)
44108 {
44109  const BYTE* const samples = (const BYTE*)samplesBuffer;
44110  const size_t totalSamplesSize = COVER_sum(samplesSizes, nbSamples);
44111  /* Split samples into testing and training sets */
44112  const unsigned nbTrainSamples = splitPoint < 1.0 ? (unsigned)((double)nbSamples * splitPoint) : nbSamples;
44113  const unsigned nbTestSamples = splitPoint < 1.0 ? nbSamples - nbTrainSamples : nbSamples;
44114  const size_t trainingSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes, nbTrainSamples) : totalSamplesSize;
44115  const size_t testSamplesSize = splitPoint < 1.0 ? COVER_sum(samplesSizes + nbTrainSamples, nbTestSamples) : totalSamplesSize;
44116 
44117  /* Checks */
44118  if (totalSamplesSize < MAX(d, sizeof(U64)) ||
44119  totalSamplesSize >= (size_t)FASTCOVER_MAX_SAMPLES_SIZE) {
44120  DISPLAYLEVEL(1, "Total samples size is too large (%u MB), maximum size is %u MB\n",
44121  (unsigned)(totalSamplesSize >> 20), (FASTCOVER_MAX_SAMPLES_SIZE >> 20));
44122  return ERROR(srcSize_wrong);
44123  }
44124 
44125  /* Check if there are at least 5 training samples */
44126  if (nbTrainSamples < 5) {
44127  DISPLAYLEVEL(1, "Total number of training samples is %u and is invalid\n", nbTrainSamples);
44128  return ERROR(srcSize_wrong);
44129  }
44130 
44131  /* Check if there's testing sample */
44132  if (nbTestSamples < 1) {
44133  DISPLAYLEVEL(1, "Total number of testing samples is %u and is invalid.\n", nbTestSamples);
44134  return ERROR(srcSize_wrong);
44135  }
44136 
44137  /* Zero the context */
44138  memset(ctx, 0, sizeof(*ctx));
44139  DISPLAYLEVEL(2, "Training on %u samples of total size %u\n", nbTrainSamples,
44140  (unsigned)trainingSamplesSize);
44141  DISPLAYLEVEL(2, "Testing on %u samples of total size %u\n", nbTestSamples,
44142  (unsigned)testSamplesSize);
44143 
44144  ctx->samples = samples;
44145  ctx->samplesSizes = samplesSizes;
44146  ctx->nbSamples = nbSamples;
44147  ctx->nbTrainSamples = nbTrainSamples;
44148  ctx->nbTestSamples = nbTestSamples;
44149  ctx->nbDmers = trainingSamplesSize - MAX(d, sizeof(U64)) + 1;
44150  ctx->d = d;
44151  ctx->f = f;
44152  ctx->accelParams = accelParams;
44153 
44154  /* The offsets of each file */
44155  ctx->offsets = (size_t*)calloc((nbSamples + 1), sizeof(size_t));
44156  if (ctx->offsets == NULL) {
44157  DISPLAYLEVEL(1, "Failed to allocate scratch buffers \n");
44158  FASTCOVER_ctx_destroy(ctx);
44159  return ERROR(memory_allocation);
44160  }
44161 
44162  /* Fill offsets from the samplesSizes */
44163  { U32 i;
44164  ctx->offsets[0] = 0;
44165  assert(nbSamples >= 5);
44166  for (i = 1; i <= nbSamples; ++i) {
44167  ctx->offsets[i] = ctx->offsets[i - 1] + samplesSizes[i - 1];
44168  }
44169  }
44170 
44171  /* Initialize frequency array of size 2^f */
44172  ctx->freqs = (U32*)calloc(((U64)1 << f), sizeof(U32));
44173  if (ctx->freqs == NULL) {
44174  DISPLAYLEVEL(1, "Failed to allocate frequency table \n");
44175  FASTCOVER_ctx_destroy(ctx);
44176  return ERROR(memory_allocation);
44177  }
44178 
44179  DISPLAYLEVEL(2, "Computing frequencies\n");
44181 
44182  return 0;
44183 }
44184 
44185 
44189 static size_t
44191  U32* freqs,
44192  void* dictBuffer, size_t dictBufferCapacity,
44193  ZDICT_cover_params_t parameters,
44194  U16* segmentFreqs)
44195 {
44196  BYTE *const dict = (BYTE *)dictBuffer;
44197  size_t tail = dictBufferCapacity;
44198  /* Divide the data into epochs. We will select one segment from each epoch. */
44199  const COVER_epoch_info_t epochs = COVER_computeEpochs(
44200  (U32)dictBufferCapacity, (U32)ctx->nbDmers, parameters.k, 1);
44201  const size_t maxZeroScoreRun = 10;
44202  size_t zeroScoreRun = 0;
44203  size_t epoch;
44204  DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n",
44205  (U32)epochs.num, (U32)epochs.size);
44206  /* Loop through the epochs until there are no more segments or the dictionary
44207  * is full.
44208  */
44209  for (epoch = 0; tail > 0; epoch = (epoch + 1) % epochs.num) {
44210  const U32 epochBegin = (U32)(epoch * epochs.size);
44211  const U32 epochEnd = epochBegin + epochs.size;
44212  size_t segmentSize;
44213  /* Select a segment */
44215  ctx, freqs, epochBegin, epochEnd, parameters, segmentFreqs);
44216 
44217  /* If the segment covers no dmers, then we are out of content.
44218  * There may be new content in other epochs, for continue for some time.
44219  */
44220  if (segment.score == 0) {
44221  if (++zeroScoreRun >= maxZeroScoreRun) {
44222  break;
44223  }
44224  continue;
44225  }
44226  zeroScoreRun = 0;
44227 
44228  /* Trim the segment if necessary and if it is too small then we are done */
44229  segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail);
44230  if (segmentSize < parameters.d) {
44231  break;
44232  }
44233 
44234  /* We fill the dictionary from the back to allow the best segments to be
44235  * referenced with the smallest offsets.
44236  */
44237  tail -= segmentSize;
44238  memcpy(dict + tail, ctx->samples + segment.begin, segmentSize);
44239  DISPLAYUPDATE(
44240  2, "\r%u%% ",
44241  (unsigned)(((dictBufferCapacity - tail) * 100) / dictBufferCapacity));
44242  }
44243  DISPLAYLEVEL(2, "\r%79s\r", "");
44244  return tail;
44245 }
44246 
44250 typedef struct FASTCOVER_tryParameters_data_s {
44251  const FASTCOVER_ctx_t* ctx;
44252  COVER_best_t* best;
44256 
44257 
44263 static void FASTCOVER_tryParameters(void* opaque)
44264 {
44265  /* Save parameters as local variables */
44267  const FASTCOVER_ctx_t *const ctx = data->ctx;
44268  const ZDICT_cover_params_t parameters = data->parameters;
44269  size_t dictBufferCapacity = data->dictBufferCapacity;
44270  size_t totalCompressedSize = ERROR(GENERIC);
44271  /* Initialize array to keep track of frequency of dmer within activeSegment */
44272  U16* segmentFreqs = (U16*)calloc(((U64)1 << ctx->f), sizeof(U16));
44273  /* Allocate space for hash table, dict, and freqs */
44274  BYTE *const dict = (BYTE*)malloc(dictBufferCapacity);
44276  U32* freqs = (U32*) malloc(((U64)1 << ctx->f) * sizeof(U32));
44277  if (!segmentFreqs || !dict || !freqs) {
44278  DISPLAYLEVEL(1, "Failed to allocate buffers: out of memory\n");
44279  goto _cleanup;
44280  }
44281  /* Copy the frequencies because we need to modify them */
44282  memcpy(freqs, ctx->freqs, ((U64)1 << ctx->f) * sizeof(U32));
44283  /* Build the dictionary */
44284  { const size_t tail = FASTCOVER_buildDictionary(ctx, freqs, dict, dictBufferCapacity,
44285  parameters, segmentFreqs);
44286 
44287  const unsigned nbFinalizeSamples = (unsigned)(ctx->nbTrainSamples * ctx->accelParams.finalize / 100);
44288  selection = COVER_selectDict(dict + tail, dictBufferCapacity, dictBufferCapacity - tail,
44289  ctx->samples, ctx->samplesSizes, nbFinalizeSamples, ctx->nbTrainSamples, ctx->nbSamples, parameters, ctx->offsets,
44290  totalCompressedSize);
44291 
44292  if (COVER_dictSelectionIsError(selection)) {
44293  DISPLAYLEVEL(1, "Failed to select dictionary\n");
44294  goto _cleanup;
44295  }
44296  }
44297 _cleanup:
44298  free(dict);
44299  COVER_best_finish(data->best, parameters, selection);
44300  free(data);
44301  free(segmentFreqs);
44302  COVER_dictSelectionFree(selection);
44303  free(freqs);
44304 }
44305 
44306 
44307 static void
44309  ZDICT_cover_params_t* coverParams)
44310 {
44311  coverParams->k = fastCoverParams.k;
44312  coverParams->d = fastCoverParams.d;
44313  coverParams->steps = fastCoverParams.steps;
44314  coverParams->nbThreads = fastCoverParams.nbThreads;
44315  coverParams->splitPoint = fastCoverParams.splitPoint;
44316  coverParams->zParams = fastCoverParams.zParams;
44317  coverParams->shrinkDict = fastCoverParams.shrinkDict;
44318 }
44319 
44320 
44321 static void
44323  ZDICT_fastCover_params_t* fastCoverParams,
44324  unsigned f, unsigned accel)
44325 {
44326  fastCoverParams->k = coverParams.k;
44327  fastCoverParams->d = coverParams.d;
44328  fastCoverParams->steps = coverParams.steps;
44329  fastCoverParams->nbThreads = coverParams.nbThreads;
44330  fastCoverParams->splitPoint = coverParams.splitPoint;
44331  fastCoverParams->f = f;
44332  fastCoverParams->accel = accel;
44333  fastCoverParams->zParams = coverParams.zParams;
44334  fastCoverParams->shrinkDict = coverParams.shrinkDict;
44335 }
44336 
44337 
44338 ZDICTLIB_API size_t
44339 ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity,
44340  const void* samplesBuffer,
44341  const size_t* samplesSizes, unsigned nbSamples,
44342  ZDICT_fastCover_params_t parameters)
44343 {
44344  BYTE* const dict = (BYTE*)dictBuffer;
44345  FASTCOVER_ctx_t ctx;
44346  ZDICT_cover_params_t coverParams;
44347  FASTCOVER_accel_t accelParams;
44348  /* Initialize global data */
44350  /* Assign splitPoint and f if not provided */
44351  parameters.splitPoint = 1.0;
44352  parameters.f = parameters.f == 0 ? DEFAULT_F : parameters.f;
44353  parameters.accel = parameters.accel == 0 ? DEFAULT_ACCEL : parameters.accel;
44354  /* Convert to cover parameter */
44355  memset(&coverParams, 0 , sizeof(coverParams));
44356  FASTCOVER_convertToCoverParams(parameters, &coverParams);
44357  /* Checks */
44358  if (!FASTCOVER_checkParameters(coverParams, dictBufferCapacity, parameters.f,
44359  parameters.accel)) {
44360  DISPLAYLEVEL(1, "FASTCOVER parameters incorrect\n");
44361  return ERROR(parameter_outOfBound);
44362  }
44363  if (nbSamples == 0) {
44364  DISPLAYLEVEL(1, "FASTCOVER must have at least one input file\n");
44365  return ERROR(srcSize_wrong);
44366  }
44367  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
44368  DISPLAYLEVEL(1, "dictBufferCapacity must be at least %u\n",
44370  return ERROR(dstSize_tooSmall);
44371  }
44372  /* Assign corresponding FASTCOVER_accel_t to accelParams*/
44373  accelParams = FASTCOVER_defaultAccelParameters[parameters.accel];
44374  /* Initialize context */
44375  {
44376  size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
44377  coverParams.d, parameters.splitPoint, parameters.f,
44378  accelParams);
44379  if (ZSTD_isError(initVal)) {
44380  DISPLAYLEVEL(1, "Failed to initialize context\n");
44381  return initVal;
44382  }
44383  }
44384  COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, g_displayLevel);
44385  /* Build the dictionary */
44386  DISPLAYLEVEL(2, "Building dictionary\n");
44387  {
44388  /* Initialize array to keep track of frequency of dmer within activeSegment */
44389  U16* segmentFreqs = (U16 *)calloc(((U64)1 << parameters.f), sizeof(U16));
44390  const size_t tail = FASTCOVER_buildDictionary(&ctx, ctx.freqs, dictBuffer,
44391  dictBufferCapacity, coverParams, segmentFreqs);
44392  const unsigned nbFinalizeSamples = (unsigned)(ctx.nbTrainSamples * ctx.accelParams.finalize / 100);
44393  const size_t dictionarySize = ZDICT_finalizeDictionary(
44394  dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail,
44395  samplesBuffer, samplesSizes, nbFinalizeSamples, coverParams.zParams);
44396  if (!ZSTD_isError(dictionarySize)) {
44397  DISPLAYLEVEL(2, "Constructed dictionary of size %u\n",
44398  (unsigned)dictionarySize);
44399  }
44400  FASTCOVER_ctx_destroy(&ctx);
44401  free(segmentFreqs);
44402  return dictionarySize;
44403  }
44404 }
44405 
44406 
44407 ZDICTLIB_API size_t
44409  void* dictBuffer, size_t dictBufferCapacity,
44410  const void* samplesBuffer,
44411  const size_t* samplesSizes, unsigned nbSamples,
44412  ZDICT_fastCover_params_t* parameters)
44413 {
44414  ZDICT_cover_params_t coverParams;
44415  FASTCOVER_accel_t accelParams;
44416  /* constants */
44417  const unsigned nbThreads = parameters->nbThreads;
44418  const double splitPoint =
44419  parameters->splitPoint <= 0.0 ? FASTCOVER_DEFAULT_SPLITPOINT : parameters->splitPoint;
44420  const unsigned kMinD = parameters->d == 0 ? 6 : parameters->d;
44421  const unsigned kMaxD = parameters->d == 0 ? 8 : parameters->d;
44422  const unsigned kMinK = parameters->k == 0 ? 50 : parameters->k;
44423  const unsigned kMaxK = parameters->k == 0 ? 2000 : parameters->k;
44424  const unsigned kSteps = parameters->steps == 0 ? 40 : parameters->steps;
44425  const unsigned kStepSize = MAX((kMaxK - kMinK) / kSteps, 1);
44426  const unsigned kIterations =
44427  (1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
44428  const unsigned f = parameters->f == 0 ? DEFAULT_F : parameters->f;
44429  const unsigned accel = parameters->accel == 0 ? DEFAULT_ACCEL : parameters->accel;
44430  const unsigned shrinkDict = 0;
44431  /* Local variables */
44432  const int displayLevel = (int)parameters->zParams.notificationLevel;
44433  unsigned iteration = 1;
44434  unsigned d;
44435  unsigned k;
44436  COVER_best_t best;
44437  POOL_ctx *pool = NULL;
44438  int warned = 0;
44439  /* Checks */
44440  if (splitPoint <= 0 || splitPoint > 1) {
44441  LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect splitPoint\n");
44442  return ERROR(parameter_outOfBound);
44443  }
44444  if (accel == 0 || accel > FASTCOVER_MAX_ACCEL) {
44445  LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect accel\n");
44446  return ERROR(parameter_outOfBound);
44447  }
44448  if (kMinK < kMaxD || kMaxK < kMinK) {
44449  LOCALDISPLAYLEVEL(displayLevel, 1, "Incorrect k\n");
44450  return ERROR(parameter_outOfBound);
44451  }
44452  if (nbSamples == 0) {
44453  LOCALDISPLAYLEVEL(displayLevel, 1, "FASTCOVER must have at least one input file\n");
44454  return ERROR(srcSize_wrong);
44455  }
44456  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) {
44457  LOCALDISPLAYLEVEL(displayLevel, 1, "dictBufferCapacity must be at least %u\n",
44459  return ERROR(dstSize_tooSmall);
44460  }
44461  if (nbThreads > 1) {
44462  pool = POOL_create(nbThreads, 1);
44463  if (!pool) {
44464  return ERROR(memory_allocation);
44465  }
44466  }
44467  /* Initialization */
44468  COVER_best_init(&best);
44469  memset(&coverParams, 0 , sizeof(coverParams));
44470  FASTCOVER_convertToCoverParams(*parameters, &coverParams);
44471  accelParams = FASTCOVER_defaultAccelParameters[accel];
44472  /* Turn down global display level to clean up display at level 2 and below */
44473  g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
44474  /* Loop through d first because each new value needs a new context */
44475  LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
44476  kIterations);
44477  for (d = kMinD; d <= kMaxD; d += 2) {
44478  /* Initialize the context for this value of d */
44479  FASTCOVER_ctx_t ctx;
44480  LOCALDISPLAYLEVEL(displayLevel, 3, "d=%u\n", d);
44481  {
44482  size_t const initVal = FASTCOVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples, d, splitPoint, f, accelParams);
44483  if (ZSTD_isError(initVal)) {
44484  LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to initialize context\n");
44485  COVER_best_destroy(&best);
44486  POOL_free(pool);
44487  return initVal;
44488  }
44489  }
44490  if (!warned) {
44491  COVER_warnOnSmallCorpus(dictBufferCapacity, ctx.nbDmers, displayLevel);
44492  warned = 1;
44493  }
44494  /* Loop through k reusing the same context */
44495  for (k = kMinK; k <= kMaxK; k += kStepSize) {
44496  /* Prepare the arguments */
44499  LOCALDISPLAYLEVEL(displayLevel, 3, "k=%u\n", k);
44500  if (!data) {
44501  LOCALDISPLAYLEVEL(displayLevel, 1, "Failed to allocate parameters\n");
44502  COVER_best_destroy(&best);
44503  FASTCOVER_ctx_destroy(&ctx);
44504  POOL_free(pool);
44505  return ERROR(memory_allocation);
44506  }
44507  data->ctx = &ctx;
44508  data->best = &best;
44509  data->dictBufferCapacity = dictBufferCapacity;
44510  data->parameters = coverParams;
44511  data->parameters.k = k;
44512  data->parameters.d = d;
44513  data->parameters.splitPoint = splitPoint;
44514  data->parameters.steps = kSteps;
44515  data->parameters.shrinkDict = shrinkDict;
44516  data->parameters.zParams.notificationLevel = (unsigned)g_displayLevel;
44517  /* Check the parameters */
44518  if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity,
44519  data->ctx->f, accel)) {
44520  DISPLAYLEVEL(1, "FASTCOVER parameters incorrect\n");
44521  free(data);
44522  continue;
44523  }
44524  /* Call the function and pass ownership of data to it */
44525  COVER_best_start(&best);
44526  if (pool) {
44528  } else {
44530  }
44531  /* Print status */
44532  LOCALDISPLAYUPDATE(displayLevel, 2, "\r%u%% ",
44533  (unsigned)((iteration * 100) / kIterations));
44534  ++iteration;
44535  }
44536  COVER_best_wait(&best);
44537  FASTCOVER_ctx_destroy(&ctx);
44538  }
44539  LOCALDISPLAYLEVEL(displayLevel, 2, "\r%79s\r", "");
44540  /* Fill the output buffer and parameters with output of the best parameters */
44541  {
44542  const size_t dictSize = best.dictSize;
44543  if (ZSTD_isError(best.compressedSize)) {
44544  const size_t compressedSize = best.compressedSize;
44545  COVER_best_destroy(&best);
44546  POOL_free(pool);
44547  return compressedSize;
44548  }
44549  FASTCOVER_convertToFastCoverParams(best.parameters, parameters, f, accel);
44550  memcpy(dictBuffer, best.dict, dictSize);
44551  COVER_best_destroy(&best);
44552  POOL_free(pool);
44553  return dictSize;
44554  }
44555 
44556 }
44557 /**** ended inlining dictBuilder/fastcover.c ****/
44558 /**** start inlining dictBuilder/zdict.c ****/
44559 /*
44560  * Copyright (c) Meta Platforms, Inc. and affiliates.
44561  * All rights reserved.
44562  *
44563  * This source code is licensed under both the BSD-style license (found in the
44564  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
44565  * in the COPYING file in the root directory of this source tree).
44566  * You may select, at your option, one of the above-listed licenses.
44567  */
44568 
44569 
44570 /*-**************************************
44571 * Tuning parameters
44572 ****************************************/
44573 #define MINRATIO 4 /* minimum nb of apparition to be selected in dictionary */
44574 #define ZDICT_MAX_SAMPLES_SIZE (2000U << 20)
44575 #define ZDICT_MIN_SAMPLES_SIZE (ZDICT_CONTENTSIZE_MIN * MINRATIO)
44576 
44577 
44578 /*-**************************************
44579 * Compiler Options
44580 ****************************************/
44581 /* Unix Large Files support (>4GB) */
44582 #define _FILE_OFFSET_BITS 64
44583 #if (defined(__sun__) && (!defined(__LP64__))) /* Sun Solaris 32-bits requires specific definitions */
44584 # ifndef _LARGEFILE_SOURCE
44585 # define _LARGEFILE_SOURCE
44586 # endif
44587 #elif ! defined(__LP64__) /* No point defining Large file for 64 bit */
44588 # ifndef _LARGEFILE64_SOURCE
44589 # define _LARGEFILE64_SOURCE
44590 # endif
44591 #endif
44592 
44593 
44594 /*-*************************************
44595 * Dependencies
44596 ***************************************/
44597 #include <stdlib.h> /* malloc, free */
44598 #include <string.h> /* memset */
44599 #include <stdio.h> /* fprintf, fopen, ftello64 */
44600 #include <time.h> /* clock */
44601 
44602 #ifndef ZDICT_STATIC_LINKING_ONLY
44603 # define ZDICT_STATIC_LINKING_ONLY
44604 #endif
44605 
44606 /**** skipping file: ../common/mem.h ****/
44607 /**** skipping file: ../common/fse.h ****/
44608 /**** skipping file: ../common/huf.h ****/
44609 /**** skipping file: ../common/zstd_internal.h ****/
44610 /**** skipping file: ../common/xxhash.h ****/
44611 /**** skipping file: ../compress/zstd_compress_internal.h ****/
44612 /**** skipping file: ../zdict.h ****/
44613 /**** skipping file: divsufsort.h ****/
44614 /**** skipping file: ../common/bits.h ****/
44615 
44617 /*-*************************************
44618 * Constants
44619 ***************************************/
44620 #define KB *(1 <<10)
44621 #define MB *(1 <<20)
44622 #define GB *(1U<<30)
44623 
44624 #define DICTLISTSIZE_DEFAULT 10000
44626 #define NOISELENGTH 32
44628 static const U32 g_selectivity_default = 9;
44630 
44631 /*-*************************************
44632 * Console display
44633 ***************************************/
44634 #undef DISPLAY
44635 #define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush( stderr ); }
44636 #undef DISPLAYLEVEL
44637 #define DISPLAYLEVEL(l, ...) if (notificationLevel>=l) { DISPLAY(__VA_ARGS__); } /* 0 : no display; 1: errors; 2: default; 3: details; 4: debug */
44638 
44639 static clock_t ZDICT_clockSpan(clock_t nPrevious) { return clock() - nPrevious; }
44640 
44641 static void ZDICT_printHex(const void* ptr, size_t length)
44642 {
44643  const BYTE* const b = (const BYTE*)ptr;
44644  size_t u;
44645  for (u=0; u<length; u++) {
44646  BYTE c = b[u];
44647  if (c<32 || c>126) c = '.'; /* non-printable char */
44648  DISPLAY("%c", c);
44649  }
44651 
44652 
44653 /*-********************************************************
44654 * Helper functions
44655 **********************************************************/
44656 unsigned ZDICT_isError(size_t errorCode) { return ERR_isError(errorCode); }
44658 const char* ZDICT_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); }
44659 
44660 unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize)
44661 {
44662  if (dictSize < 8) return 0;
44663  if (MEM_readLE32(dictBuffer) != ZSTD_MAGIC_DICTIONARY) return 0;
44664  return MEM_readLE32((const char*)dictBuffer + 4);
44665 }
44666 
44667 size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize)
44668 {
44669  size_t headerSize;
44670  if (dictSize <= 8 || MEM_readLE32(dictBuffer) != ZSTD_MAGIC_DICTIONARY) return ERROR(dictionary_corrupted);
44671 
44673  U32* wksp = (U32*)malloc(HUF_WORKSPACE_SIZE);
44674  if (!bs || !wksp) {
44675  headerSize = ERROR(memory_allocation);
44676  } else {
44678  headerSize = ZSTD_loadCEntropy(bs, wksp, dictBuffer, dictSize);
44679  }
44680 
44681  free(bs);
44682  free(wksp);
44683  }
44684 
44685  return headerSize;
44686 }
44687 
44688 /*-********************************************************
44689 * Dictionary training functions
44690 **********************************************************/
44695 static size_t ZDICT_count(const void* pIn, const void* pMatch)
44696 {
44697  const char* const pStart = (const char*)pIn;
44698  for (;;) {
44699  size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
44700  if (!diff) {
44701  pIn = (const char*)pIn+sizeof(size_t);
44702  pMatch = (const char*)pMatch+sizeof(size_t);
44703  continue;
44704  }
44705  pIn = (const char*)pIn+ZSTD_NbCommonBytes(diff);
44706  return (size_t)((const char*)pIn - pStart);
44707  }
44708 }
44709 
44710 
44711 typedef struct {
44712  U32 pos;
44713  U32 length;
44714  U32 savings;
44718 {
44719  d->pos = 1;
44720  d->length = 0;
44721  d->savings = (U32)(-1);
44722 }
44723 
44724 
44725 #define LLIMIT 64 /* heuristic determined experimentally */
44726 #define MINMATCHLENGTH 7 /* heuristic determined experimentally */
44727 static dictItem ZDICT_analyzePos(
44728  BYTE* doneMarks,
44729  const int* suffix, U32 start,
44730  const void* buffer, U32 minRatio, U32 notificationLevel)
44731 {
44732  U32 lengthList[LLIMIT] = {0};
44733  U32 cumulLength[LLIMIT] = {0};
44734  U32 savings[LLIMIT] = {0};
44735  const BYTE* b = (const BYTE*)buffer;
44736  size_t maxLength = LLIMIT;
44737  size_t pos = (size_t)suffix[start];
44738  U32 end = start;
44739  dictItem solution;
44740 
44741  /* init */
44742  memset(&solution, 0, sizeof(solution));
44743  doneMarks[pos] = 1;
44744 
44745  /* trivial repetition cases */
44746  if ( (MEM_read16(b+pos+0) == MEM_read16(b+pos+2))
44747  ||(MEM_read16(b+pos+1) == MEM_read16(b+pos+3))
44748  ||(MEM_read16(b+pos+2) == MEM_read16(b+pos+4)) ) {
44749  /* skip and mark segment */
44750  U16 const pattern16 = MEM_read16(b+pos+4);
44751  U32 u, patternEnd = 6;
44752  while (MEM_read16(b+pos+patternEnd) == pattern16) patternEnd+=2 ;
44753  if (b[pos+patternEnd] == b[pos+patternEnd-1]) patternEnd++;
44754  for (u=1; u<patternEnd; u++)
44755  doneMarks[pos+u] = 1;
44756  return solution;
44757  }
44758 
44759  /* look forward */
44760  { size_t length;
44761  do {
44762  end++;
44763  length = ZDICT_count(b + pos, b + suffix[end]);
44764  } while (length >= MINMATCHLENGTH);
44765  }
44766 
44767  /* look backward */
44768  { size_t length;
44769  do {
44770  length = ZDICT_count(b + pos, b + *(suffix+start-1));
44771  if (length >=MINMATCHLENGTH) start--;
44772  } while(length >= MINMATCHLENGTH);
44773  }
44774 
44775  /* exit if not found a minimum nb of repetitions */
44776  if (end-start < minRatio) {
44777  U32 idx;
44778  for(idx=start; idx<end; idx++)
44779  doneMarks[suffix[idx]] = 1;
44780  return solution;
44781  }
44782 
44783  { int i;
44784  U32 mml;
44785  U32 refinedStart = start;
44786  U32 refinedEnd = end;
44787 
44788  DISPLAYLEVEL(4, "\n");
44789  DISPLAYLEVEL(4, "found %3u matches of length >= %i at pos %7u ", (unsigned)(end-start), MINMATCHLENGTH, (unsigned)pos);
44790  DISPLAYLEVEL(4, "\n");
44791 
44792  for (mml = MINMATCHLENGTH ; ; mml++) {
44793  BYTE currentChar = 0;
44794  U32 currentCount = 0;
44795  U32 currentID = refinedStart;
44796  U32 id;
44797  U32 selectedCount = 0;
44798  U32 selectedID = currentID;
44799  for (id =refinedStart; id < refinedEnd; id++) {
44800  if (b[suffix[id] + mml] != currentChar) {
44801  if (currentCount > selectedCount) {
44802  selectedCount = currentCount;
44803  selectedID = currentID;
44804  }
44805  currentID = id;
44806  currentChar = b[ suffix[id] + mml];
44807  currentCount = 0;
44808  }
44809  currentCount ++;
44810  }
44811  if (currentCount > selectedCount) { /* for last */
44812  selectedCount = currentCount;
44813  selectedID = currentID;
44814  }
44815 
44816  if (selectedCount < minRatio)
44817  break;
44818  refinedStart = selectedID;
44819  refinedEnd = refinedStart + selectedCount;
44820  }
44821 
44822  /* evaluate gain based on new dict */
44823  start = refinedStart;
44824  pos = suffix[refinedStart];
44825  end = start;
44826  memset(lengthList, 0, sizeof(lengthList));
44827 
44828  /* look forward */
44829  { size_t length;
44830  do {
44831  end++;
44832  length = ZDICT_count(b + pos, b + suffix[end]);
44833  if (length >= LLIMIT) length = LLIMIT-1;
44834  lengthList[length]++;
44835  } while (length >=MINMATCHLENGTH);
44836  }
44837 
44838  /* look backward */
44839  { size_t length = MINMATCHLENGTH;
44840  while ((length >= MINMATCHLENGTH) & (start > 0)) {
44841  length = ZDICT_count(b + pos, b + suffix[start - 1]);
44842  if (length >= LLIMIT) length = LLIMIT - 1;
44843  lengthList[length]++;
44844  if (length >= MINMATCHLENGTH) start--;
44845  }
44846  }
44847 
44848  /* largest useful length */
44849  memset(cumulLength, 0, sizeof(cumulLength));
44850  cumulLength[maxLength-1] = lengthList[maxLength-1];
44851  for (i=(int)(maxLength-2); i>=0; i--)
44852  cumulLength[i] = cumulLength[i+1] + lengthList[i];
44853 
44854  for (i=LLIMIT-1; i>=MINMATCHLENGTH; i--) if (cumulLength[i]>=minRatio) break;
44855  maxLength = i;
44856 
44857  /* reduce maxLength in case of final into repetitive data */
44858  { U32 l = (U32)maxLength;
44859  BYTE const c = b[pos + maxLength-1];
44860  while (b[pos+l-2]==c) l--;
44861  maxLength = l;
44862  }
44863  if (maxLength < MINMATCHLENGTH) return solution; /* skip : no long-enough solution */
44864 
44865  /* calculate savings */
44866  savings[5] = 0;
44867  for (i=MINMATCHLENGTH; i<=(int)maxLength; i++)
44868  savings[i] = savings[i-1] + (lengthList[i] * (i-3));
44869 
44870  DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n",
44871  (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength);
44872 
44873  solution.pos = (U32)pos;
44874  solution.length = (U32)maxLength;
44875  solution.savings = savings[maxLength];
44876 
44877  /* mark positions done */
44878  { U32 id;
44879  for (id=start; id<end; id++) {
44880  U32 p, pEnd, length;
44881  U32 const testedPos = (U32)suffix[id];
44882  if (testedPos == pos)
44883  length = solution.length;
44884  else {
44885  length = (U32)ZDICT_count(b+pos, b+testedPos);
44886  if (length > solution.length) length = solution.length;
44887  }
44888  pEnd = (U32)(testedPos + length);
44889  for (p=testedPos; p<pEnd; p++)
44890  doneMarks[p] = 1;
44891  } } }
44892 
44893  return solution;
44894 }
44895 
44896 
44897 static int isIncluded(const void* in, const void* container, size_t length)
44898 {
44899  const char* const ip = (const char*) in;
44900  const char* const into = (const char*) container;
44901  size_t u;
44902 
44903  for (u=0; u<length; u++) { /* works because end of buffer is a noisy guard band */
44904  if (ip[u] != into[u]) break;
44905  }
44906 
44907  return u==length;
44908 }
44909 
44914 static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const void* buffer)
44915 {
44916  const U32 tableSize = table->pos;
44917  const U32 eltEnd = elt.pos + elt.length;
44918  const char* const buf = (const char*) buffer;
44919 
44920  /* tail overlap */
44921  U32 u; for (u=1; u<tableSize; u++) {
44922  if (u==eltNbToSkip) continue;
44923  if ((table[u].pos > elt.pos) && (table[u].pos <= eltEnd)) { /* overlap, existing > new */
44924  /* append */
44925  U32 const addedLength = table[u].pos - elt.pos;
44926  table[u].length += addedLength;
44927  table[u].pos = elt.pos;
44928  table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */
44929  table[u].savings += elt.length / 8; /* rough approx bonus */
44930  elt = table[u];
44931  /* sort : improve rank */
44932  while ((u>1) && (table[u-1].savings < elt.savings))
44933  table[u] = table[u-1], u--;
44934  table[u] = elt;
44935  return u;
44936  } }
44937 
44938  /* front overlap */
44939  for (u=1; u<tableSize; u++) {
44940  if (u==eltNbToSkip) continue;
44941 
44942  if ((table[u].pos + table[u].length >= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */
44943  /* append */
44944  int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length);
44945  table[u].savings += elt.length / 8; /* rough approx bonus */
44946  if (addedLength > 0) { /* otherwise, elt fully included into existing */
44947  table[u].length += addedLength;
44948  table[u].savings += elt.savings * addedLength / elt.length; /* rough approx */
44949  }
44950  /* sort : improve rank */
44951  elt = table[u];
44952  while ((u>1) && (table[u-1].savings < elt.savings))
44953  table[u] = table[u-1], u--;
44954  table[u] = elt;
44955  return u;
44956  }
44957 
44958  if (MEM_read64(buf + table[u].pos) == MEM_read64(buf + elt.pos + 1)) {
44959  if (isIncluded(buf + table[u].pos, buf + elt.pos + 1, table[u].length)) {
44960  size_t const addedLength = MAX( (int)elt.length - (int)table[u].length , 1 );
44961  table[u].pos = elt.pos;
44962  table[u].savings += (U32)(elt.savings * addedLength / elt.length);
44963  table[u].length = MIN(elt.length, table[u].length + 1);
44964  return u;
44965  }
44966  }
44967  }
44968 
44969  return 0;
44970 }
44971 
44972 
44973 static void ZDICT_removeDictItem(dictItem* table, U32 id)
44974 {
44975  /* convention : table[0].pos stores nb of elts */
44976  U32 const max = table[0].pos;
44977  U32 u;
44978  if (!id) return; /* protection, should never happen */
44979  for (u=id; u<max-1; u++)
44980  table[u] = table[u+1];
44981  table->pos--;
44982 }
44983 
44984 
44985 static void ZDICT_insertDictItem(dictItem* table, U32 maxSize, dictItem elt, const void* buffer)
44986 {
44987  /* merge if possible */
44988  U32 mergeId = ZDICT_tryMerge(table, elt, 0, buffer);
44989  if (mergeId) {
44990  U32 newMerge = 1;
44991  while (newMerge) {
44992  newMerge = ZDICT_tryMerge(table, table[mergeId], mergeId, buffer);
44993  if (newMerge) ZDICT_removeDictItem(table, mergeId);
44994  mergeId = newMerge;
44995  }
44996  return;
44997  }
44998 
44999  /* insert */
45000  { U32 current;
45001  U32 nextElt = table->pos;
45002  if (nextElt >= maxSize) nextElt = maxSize-1;
45003  current = nextElt-1;
45004  while (table[current].savings < elt.savings) {
45005  table[current+1] = table[current];
45006  current--;
45007  }
45008  table[current+1] = elt;
45009  table->pos = nextElt+1;
45010  }
45011 }
45012 
45014 static U32 ZDICT_dictSize(const dictItem* dictList)
45015 {
45016  U32 u, dictSize = 0;
45017  for (u=1; u<dictList[0].pos; u++)
45018  dictSize += dictList[u].length;
45019  return dictSize;
45020 }
45021 
45022 
45023 static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
45024  const void* const buffer, size_t bufferSize, /* buffer must end with noisy guard band */
45025  const size_t* fileSizes, unsigned nbFiles,
45026  unsigned minRatio, U32 notificationLevel)
45027 {
45028  int* const suffix0 = (int*)malloc((bufferSize+2)*sizeof(*suffix0));
45029  int* const suffix = suffix0+1;
45030  U32* reverseSuffix = (U32*)malloc((bufferSize)*sizeof(*reverseSuffix));
45031  BYTE* doneMarks = (BYTE*)malloc((bufferSize+16)*sizeof(*doneMarks)); /* +16 for overflow security */
45032  U32* filePos = (U32*)malloc(nbFiles * sizeof(*filePos));
45033  size_t result = 0;
45034  clock_t displayClock = 0;
45035  clock_t const refreshRate = CLOCKS_PER_SEC * 3 / 10;
45036 
45037 # undef DISPLAYUPDATE
45038 # define DISPLAYUPDATE(l, ...) if (notificationLevel>=l) { \
45039  if (ZDICT_clockSpan(displayClock) > refreshRate) \
45040  { displayClock = clock(); DISPLAY(__VA_ARGS__); \
45041  if (notificationLevel>=4) fflush(stderr); } }
45042 
45043  /* init */
45044  DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
45045  if (!suffix0 || !reverseSuffix || !doneMarks || !filePos) {
45046  result = ERROR(memory_allocation);
45047  goto _cleanup;
45048  }
45049  if (minRatio < MINRATIO) minRatio = MINRATIO;
45050  memset(doneMarks, 0, bufferSize+16);
45051 
45052  /* limit sample set size (divsufsort limitation)*/
45053  if (bufferSize > ZDICT_MAX_SAMPLES_SIZE) DISPLAYLEVEL(3, "sample set too large : reduced to %u MB ...\n", (unsigned)(ZDICT_MAX_SAMPLES_SIZE>>20));
45054  while (bufferSize > ZDICT_MAX_SAMPLES_SIZE) bufferSize -= fileSizes[--nbFiles];
45055 
45056  /* sort */
45057  DISPLAYLEVEL(2, "sorting %u files of total size %u MB ...\n", nbFiles, (unsigned)(bufferSize>>20));
45058  { int const divSuftSortResult = divsufsort((const unsigned char*)buffer, suffix, (int)bufferSize, 0);
45059  if (divSuftSortResult != 0) { result = ERROR(GENERIC); goto _cleanup; }
45060  }
45061  suffix[bufferSize] = (int)bufferSize; /* leads into noise */
45062  suffix0[0] = (int)bufferSize; /* leads into noise */
45063  /* build reverse suffix sort */
45064  { size_t pos;
45065  for (pos=0; pos < bufferSize; pos++)
45066  reverseSuffix[suffix[pos]] = (U32)pos;
45067  /* note filePos tracks borders between samples.
45068  It's not used at this stage, but planned to become useful in a later update */
45069  filePos[0] = 0;
45070  for (pos=1; pos<nbFiles; pos++)
45071  filePos[pos] = (U32)(filePos[pos-1] + fileSizes[pos-1]);
45072  }
45073 
45074  DISPLAYLEVEL(2, "finding patterns ... \n");
45075  DISPLAYLEVEL(3, "minimum ratio : %u \n", minRatio);
45076 
45077  { U32 cursor; for (cursor=0; cursor < bufferSize; ) {
45078  dictItem solution;
45079  if (doneMarks[cursor]) { cursor++; continue; }
45080  solution = ZDICT_analyzePos(doneMarks, suffix, reverseSuffix[cursor], buffer, minRatio, notificationLevel);
45081  if (solution.length==0) { cursor++; continue; }
45082  ZDICT_insertDictItem(dictList, dictListSize, solution, buffer);
45083  cursor += solution.length;
45084  DISPLAYUPDATE(2, "\r%4.2f %% \r", (double)cursor / (double)bufferSize * 100.0);
45085  } }
45087 _cleanup:
45088  free(suffix0);
45089  free(reverseSuffix);
45090  free(doneMarks);
45091  free(filePos);
45092  return result;
45093 }
45094 
45095 
45096 static void ZDICT_fillNoise(void* buffer, size_t length)
45097 {
45098  unsigned const prime1 = 2654435761U;
45099  unsigned const prime2 = 2246822519U;
45100  unsigned acc = prime1;
45101  size_t p=0;
45102  for (p=0; p<length; p++) {
45103  acc *= prime2;
45104  ((unsigned char*)buffer)[p] = (unsigned char)(acc >> 21);
45105  }
45107 
45109 typedef struct
45110 {
45111  ZSTD_CDict* dict; /* dictionary */
45112  ZSTD_CCtx* zc; /* working context */
45113  void* workPlace; /* must be ZSTD_BLOCKSIZE_MAX allocated */
45114 } EStats_ress_t;
45115 
45116 #define MAXREPOFFSET 1024
45117 
45118 static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters* params,
45119  unsigned* countLit, unsigned* offsetcodeCount, unsigned* matchlengthCount, unsigned* litlengthCount, U32* repOffsets,
45120  const void* src, size_t srcSize,
45121  U32 notificationLevel)
45122 {
45123  size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_MAX, 1 << params->cParams.windowLog);
45124  size_t cSize;
45125 
45126  if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */
45127  { size_t const errorCode = ZSTD_compressBegin_usingCDict_deprecated(esr.zc, esr.dict);
45128  if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_compressBegin_usingCDict failed \n"); return; }
45129 
45130  }
45132  if (ZSTD_isError(cSize)) { DISPLAYLEVEL(3, "warning : could not compress sample size %u \n", (unsigned)srcSize); return; }
45133 
45134  if (cSize) { /* if == 0; block is not compressible */
45135  const seqStore_t* const seqStorePtr = ZSTD_getSeqStore(esr.zc);
45136 
45137  /* literals stats */
45138  { const BYTE* bytePtr;
45139  for(bytePtr = seqStorePtr->litStart; bytePtr < seqStorePtr->lit; bytePtr++)
45140  countLit[*bytePtr]++;
45141  }
45142 
45143  /* seqStats */
45144  { U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
45145  ZSTD_seqToCodes(seqStorePtr);
45146 
45147  { const BYTE* codePtr = seqStorePtr->ofCode;
45148  U32 u;
45149  for (u=0; u<nbSeq; u++) offsetcodeCount[codePtr[u]]++;
45150  }
45151 
45152  { const BYTE* codePtr = seqStorePtr->mlCode;
45153  U32 u;
45154  for (u=0; u<nbSeq; u++) matchlengthCount[codePtr[u]]++;
45155  }
45156 
45157  { const BYTE* codePtr = seqStorePtr->llCode;
45158  U32 u;
45159  for (u=0; u<nbSeq; u++) litlengthCount[codePtr[u]]++;
45160  }
45161 
45162  if (nbSeq >= 2) { /* rep offsets */
45163  const seqDef* const seq = seqStorePtr->sequencesStart;
45164  U32 offset1 = seq[0].offBase - ZSTD_REP_NUM;
45165  U32 offset2 = seq[1].offBase - ZSTD_REP_NUM;
45166  if (offset1 >= MAXREPOFFSET) offset1 = 0;
45167  if (offset2 >= MAXREPOFFSET) offset2 = 0;
45168  repOffsets[offset1] += 3;
45169  repOffsets[offset2] += 1;
45170  } } }
45172 
45173 static size_t ZDICT_totalSampleSize(const size_t* fileSizes, unsigned nbFiles)
45174 {
45175  size_t total=0;
45176  unsigned u;
45177  for (u=0; u<nbFiles; u++) total += fileSizes[u];
45178  return total;
45179 }
45180 
45181 typedef struct { U32 offset; U32 count; } offsetCount_t;
45182 
45184 {
45185  U32 u;
45186  table[ZSTD_REP_NUM].offset = val;
45187  table[ZSTD_REP_NUM].count = count;
45188  for (u=ZSTD_REP_NUM; u>0; u--) {
45189  offsetCount_t tmp;
45190  if (table[u-1].count >= table[u].count) break;
45191  tmp = table[u-1];
45192  table[u-1] = table[u];
45193  table[u] = tmp;
45194  }
45195 }
45196 
45197 /* ZDICT_flatLit() :
45198  * rewrite `countLit` to contain a mostly flat but still compressible distribution of literals.
45199  * necessary to avoid generating a non-compressible distribution that HUF_writeCTable() cannot encode.
45200  */
45201 static void ZDICT_flatLit(unsigned* countLit)
45202 {
45203  int u;
45204  for (u=1; u<256; u++) countLit[u] = 2;
45205  countLit[0] = 4;
45206  countLit[253] = 1;
45207  countLit[254] = 1;
45208 }
45209 
45210 #define OFFCODE_MAX 30 /* only applicable to first block */
45211 static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
45212  int compressionLevel,
45213  const void* srcBuffer, const size_t* fileSizes, unsigned nbFiles,
45214  const void* dictBuffer, size_t dictBufferSize,
45215  unsigned notificationLevel)
45216 {
45217  unsigned countLit[256];
45218  HUF_CREATE_STATIC_CTABLE(hufTable, 255);
45219  unsigned offcodeCount[OFFCODE_MAX+1];
45220  short offcodeNCount[OFFCODE_MAX+1];
45221  U32 offcodeMax = ZSTD_highbit32((U32)(dictBufferSize + 128 KB));
45222  unsigned matchLengthCount[MaxML+1];
45223  short matchLengthNCount[MaxML+1];
45224  unsigned litLengthCount[MaxLL+1];
45225  short litLengthNCount[MaxLL+1];
45226  U32 repOffset[MAXREPOFFSET];
45227  offsetCount_t bestRepOffset[ZSTD_REP_NUM+1];
45228  EStats_ress_t esr = { NULL, NULL, NULL };
45229  ZSTD_parameters params;
45230  U32 u, huffLog = 11, Offlog = OffFSELog, mlLog = MLFSELog, llLog = LLFSELog, total;
45231  size_t pos = 0, errorCode;
45232  size_t eSize = 0;
45233  size_t const totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles);
45234  size_t const averageSampleSize = totalSrcSize / (nbFiles + !nbFiles);
45235  BYTE* dstPtr = (BYTE*)dstBuffer;
45237 
45238  /* init */
45239  DEBUGLOG(4, "ZDICT_analyzeEntropy");
45240  if (offcodeMax>OFFCODE_MAX) { eSize = ERROR(dictionaryCreation_failed); goto _cleanup; } /* too large dictionary */
45241  for (u=0; u<256; u++) countLit[u] = 1; /* any character must be described */
45242  for (u=0; u<=offcodeMax; u++) offcodeCount[u] = 1;
45243  for (u=0; u<=MaxML; u++) matchLengthCount[u] = 1;
45244  for (u=0; u<=MaxLL; u++) litLengthCount[u] = 1;
45245  memset(repOffset, 0, sizeof(repOffset));
45246  repOffset[1] = repOffset[4] = repOffset[8] = 1;
45247  memset(bestRepOffset, 0, sizeof(bestRepOffset));
45249  params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize);
45250 
45251  esr.dict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, ZSTD_dlm_byRef, ZSTD_dct_rawContent, params.cParams, ZSTD_defaultCMem);
45252  esr.zc = ZSTD_createCCtx();
45253  esr.workPlace = malloc(ZSTD_BLOCKSIZE_MAX);
45254  if (!esr.dict || !esr.zc || !esr.workPlace) {
45255  eSize = ERROR(memory_allocation);
45256  DISPLAYLEVEL(1, "Not enough memory \n");
45257  goto _cleanup;
45258  }
45259 
45260  /* collect stats on all samples */
45261  for (u=0; u<nbFiles; u++) {
45262  ZDICT_countEStats(esr, &params,
45263  countLit, offcodeCount, matchLengthCount, litLengthCount, repOffset,
45264  (const char*)srcBuffer + pos, fileSizes[u],
45265  notificationLevel);
45266  pos += fileSizes[u];
45267  }
45268 
45269  if (notificationLevel >= 4) {
45270  /* writeStats */
45271  DISPLAYLEVEL(4, "Offset Code Frequencies : \n");
45272  for (u=0; u<=offcodeMax; u++) {
45273  DISPLAYLEVEL(4, "%2u :%7u \n", u, offcodeCount[u]);
45274  } }
45275 
45276  /* analyze, build stats, starting with literals */
45277  { size_t maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp));
45278  if (HUF_isError(maxNbBits)) {
45279  eSize = maxNbBits;
45280  DISPLAYLEVEL(1, " HUF_buildCTable error \n");
45281  goto _cleanup;
45282  }
45283  if (maxNbBits==8) { /* not compressible : will fail on HUF_writeCTable() */
45284  DISPLAYLEVEL(2, "warning : pathological dataset : literals are not compressible : samples are noisy or too regular \n");
45285  ZDICT_flatLit(countLit); /* replace distribution by a fake "mostly flat but still compressible" distribution, that HUF_writeCTable() can encode */
45286  maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp));
45287  assert(maxNbBits==9);
45288  }
45289  huffLog = (U32)maxNbBits;
45290  }
45291 
45292  /* looking for most common first offsets */
45293  { U32 offset;
45294  for (offset=1; offset<MAXREPOFFSET; offset++)
45295  ZDICT_insertSortCount(bestRepOffset, offset, repOffset[offset]);
45296  }
45297  /* note : the result of this phase should be used to better appreciate the impact on statistics */
45298 
45299  total=0; for (u=0; u<=offcodeMax; u++) total+=offcodeCount[u];
45300  errorCode = FSE_normalizeCount(offcodeNCount, Offlog, offcodeCount, total, offcodeMax, /* useLowProbCount */ 1);
45301  if (FSE_isError(errorCode)) {
45302  eSize = errorCode;
45303  DISPLAYLEVEL(1, "FSE_normalizeCount error with offcodeCount \n");
45304  goto _cleanup;
45305  }
45306  Offlog = (U32)errorCode;
45307 
45308  total=0; for (u=0; u<=MaxML; u++) total+=matchLengthCount[u];
45309  errorCode = FSE_normalizeCount(matchLengthNCount, mlLog, matchLengthCount, total, MaxML, /* useLowProbCount */ 1);
45310  if (FSE_isError(errorCode)) {
45311  eSize = errorCode;
45312  DISPLAYLEVEL(1, "FSE_normalizeCount error with matchLengthCount \n");
45313  goto _cleanup;
45314  }
45315  mlLog = (U32)errorCode;
45316 
45317  total=0; for (u=0; u<=MaxLL; u++) total+=litLengthCount[u];
45318  errorCode = FSE_normalizeCount(litLengthNCount, llLog, litLengthCount, total, MaxLL, /* useLowProbCount */ 1);
45319  if (FSE_isError(errorCode)) {
45320  eSize = errorCode;
45321  DISPLAYLEVEL(1, "FSE_normalizeCount error with litLengthCount \n");
45322  goto _cleanup;
45323  }
45324  llLog = (U32)errorCode;
45325 
45326  /* write result to buffer */
45327  { size_t const hhSize = HUF_writeCTable_wksp(dstPtr, maxDstSize, hufTable, 255, huffLog, wksp, sizeof(wksp));
45328  if (HUF_isError(hhSize)) {
45329  eSize = hhSize;
45330  DISPLAYLEVEL(1, "HUF_writeCTable error \n");
45331  goto _cleanup;
45332  }
45333  dstPtr += hhSize;
45334  maxDstSize -= hhSize;
45335  eSize += hhSize;
45336  }
45337 
45338  { size_t const ohSize = FSE_writeNCount(dstPtr, maxDstSize, offcodeNCount, OFFCODE_MAX, Offlog);
45339  if (FSE_isError(ohSize)) {
45340  eSize = ohSize;
45341  DISPLAYLEVEL(1, "FSE_writeNCount error with offcodeNCount \n");
45342  goto _cleanup;
45343  }
45344  dstPtr += ohSize;
45345  maxDstSize -= ohSize;
45346  eSize += ohSize;
45347  }
45348 
45349  { size_t const mhSize = FSE_writeNCount(dstPtr, maxDstSize, matchLengthNCount, MaxML, mlLog);
45350  if (FSE_isError(mhSize)) {
45351  eSize = mhSize;
45352  DISPLAYLEVEL(1, "FSE_writeNCount error with matchLengthNCount \n");
45353  goto _cleanup;
45354  }
45355  dstPtr += mhSize;
45356  maxDstSize -= mhSize;
45357  eSize += mhSize;
45358  }
45359 
45360  { size_t const lhSize = FSE_writeNCount(dstPtr, maxDstSize, litLengthNCount, MaxLL, llLog);
45361  if (FSE_isError(lhSize)) {
45362  eSize = lhSize;
45363  DISPLAYLEVEL(1, "FSE_writeNCount error with litlengthNCount \n");
45364  goto _cleanup;
45365  }
45366  dstPtr += lhSize;
45367  maxDstSize -= lhSize;
45368  eSize += lhSize;
45369  }
45370 
45371  if (maxDstSize<12) {
45372  eSize = ERROR(dstSize_tooSmall);
45373  DISPLAYLEVEL(1, "not enough space to write RepOffsets \n");
45374  goto _cleanup;
45375  }
45376 # if 0
45377  MEM_writeLE32(dstPtr+0, bestRepOffset[0].offset);
45378  MEM_writeLE32(dstPtr+4, bestRepOffset[1].offset);
45379  MEM_writeLE32(dstPtr+8, bestRepOffset[2].offset);
45380 #else
45381  /* at this stage, we don't use the result of "most common first offset",
45382  * as the impact of statistics is not properly evaluated */
45383  MEM_writeLE32(dstPtr+0, repStartValue[0]);
45384  MEM_writeLE32(dstPtr+4, repStartValue[1]);
45385  MEM_writeLE32(dstPtr+8, repStartValue[2]);
45386 #endif
45387  eSize += 12;
45388 
45389 _cleanup:
45390  ZSTD_freeCDict(esr.dict);
45392  free(esr.workPlace);
45393 
45394  return eSize;
45395 }
45396 
45397 
45401 static U32 ZDICT_maxRep(U32 const reps[ZSTD_REP_NUM])
45402 {
45403  U32 maxRep = reps[0];
45404  int r;
45405  for (r = 1; r < ZSTD_REP_NUM; ++r)
45406  maxRep = MAX(maxRep, reps[r]);
45407  return maxRep;
45408 }
45409 
45410 size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
45411  const void* customDictContent, size_t dictContentSize,
45412  const void* samplesBuffer, const size_t* samplesSizes,
45413  unsigned nbSamples, ZDICT_params_t params)
45414 {
45415  size_t hSize;
45416 #define HBUFFSIZE 256 /* should prove large enough for all entropy headers */
45418  int const compressionLevel = (params.compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : params.compressionLevel;
45419  U32 const notificationLevel = params.notificationLevel;
45420  /* The final dictionary content must be at least as large as the largest repcode */
45421  size_t const minContentSize = (size_t)ZDICT_maxRep(repStartValue);
45422  size_t paddingSize;
45423 
45424  /* check conditions */
45425  DEBUGLOG(4, "ZDICT_finalizeDictionary");
45426  if (dictBufferCapacity < dictContentSize) return ERROR(dstSize_tooSmall);
45427  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) return ERROR(dstSize_tooSmall);
45428 
45429  /* dictionary header */
45431  { U64 const randomID = XXH64(customDictContent, dictContentSize, 0);
45432  U32 const compliantID = (randomID % ((1U<<31)-32768)) + 32768;
45433  U32 const dictID = params.dictID ? params.dictID : compliantID;
45434  MEM_writeLE32(header+4, dictID);
45435  }
45436  hSize = 8;
45437 
45438  /* entropy tables */
45439  DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
45440  DISPLAYLEVEL(2, "statistics ... \n");
45441  { size_t const eSize = ZDICT_analyzeEntropy(header+hSize, HBUFFSIZE-hSize,
45443  samplesBuffer, samplesSizes, nbSamples,
45444  customDictContent, dictContentSize,
45445  notificationLevel);
45446  if (ZDICT_isError(eSize)) return eSize;
45447  hSize += eSize;
45448  }
45449 
45450  /* Shrink the content size if it doesn't fit in the buffer */
45451  if (hSize + dictContentSize > dictBufferCapacity) {
45452  dictContentSize = dictBufferCapacity - hSize;
45453  }
45454 
45455  /* Pad the dictionary content with zeros if it is too small */
45456  if (dictContentSize < minContentSize) {
45457  RETURN_ERROR_IF(hSize + minContentSize > dictBufferCapacity, dstSize_tooSmall,
45458  "dictBufferCapacity too small to fit max repcode");
45459  paddingSize = minContentSize - dictContentSize;
45460  } else {
45461  paddingSize = 0;
45462  }
45463 
45464  {
45465  size_t const dictSize = hSize + paddingSize + dictContentSize;
45466 
45467  /* The dictionary consists of the header, optional padding, and the content.
45468  * The padding comes before the content because the "best" position in the
45469  * dictionary is the last byte.
45470  */
45471  BYTE* const outDictHeader = (BYTE*)dictBuffer;
45472  BYTE* const outDictPadding = outDictHeader + hSize;
45473  BYTE* const outDictContent = outDictPadding + paddingSize;
45474 
45475  assert(dictSize <= dictBufferCapacity);
45476  assert(outDictContent + dictContentSize == (BYTE*)dictBuffer + dictSize);
45477 
45478  /* First copy the customDictContent into its final location.
45479  * `customDictContent` and `dictBuffer` may overlap, so we must
45480  * do this before any other writes into the output buffer.
45481  * Then copy the header & padding into the output buffer.
45482  */
45483  memmove(outDictContent, customDictContent, dictContentSize);
45484  memcpy(outDictHeader, header, hSize);
45485  memset(outDictPadding, 0, paddingSize);
45486 
45487  return dictSize;
45488  }
45489 }
45490 
45491 
45493  void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
45494  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
45495  ZDICT_params_t params)
45496 {
45497  int const compressionLevel = (params.compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : params.compressionLevel;
45498  U32 const notificationLevel = params.notificationLevel;
45499  size_t hSize = 8;
45500 
45501  /* calculate entropy tables */
45502  DISPLAYLEVEL(2, "\r%70s\r", ""); /* clean display line */
45503  DISPLAYLEVEL(2, "statistics ... \n");
45504  { size_t const eSize = ZDICT_analyzeEntropy((char*)dictBuffer+hSize, dictBufferCapacity-hSize,
45506  samplesBuffer, samplesSizes, nbSamples,
45507  (char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize,
45508  notificationLevel);
45509  if (ZDICT_isError(eSize)) return eSize;
45510  hSize += eSize;
45511  }
45512 
45513  /* add dictionary header (after entropy tables) */
45514  MEM_writeLE32(dictBuffer, ZSTD_MAGIC_DICTIONARY);
45515  { U64 const randomID = XXH64((char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, 0);
45516  U32 const compliantID = (randomID % ((1U<<31)-32768)) + 32768;
45517  U32 const dictID = params.dictID ? params.dictID : compliantID;
45518  MEM_writeLE32((char*)dictBuffer+4, dictID);
45519  }
45521  if (hSize + dictContentSize < dictBufferCapacity)
45522  memmove((char*)dictBuffer + hSize, (char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize);
45523  return MIN(dictBufferCapacity, hSize+dictContentSize);
45524 }
45525 
45531  void* dictBuffer, size_t maxDictSize,
45532  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
45533  ZDICT_legacy_params_t params)
45534 {
45535  U32 const dictListSize = MAX(MAX(DICTLISTSIZE_DEFAULT, nbSamples), (U32)(maxDictSize/16));
45536  dictItem* const dictList = (dictItem*)malloc(dictListSize * sizeof(*dictList));
45537  unsigned const selectivity = params.selectivityLevel == 0 ? g_selectivity_default : params.selectivityLevel;
45538  unsigned const minRep = (selectivity > 30) ? MINRATIO : nbSamples >> selectivity;
45539  size_t const targetDictSize = maxDictSize;
45540  size_t const samplesBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
45541  size_t dictSize = 0;
45542  U32 const notificationLevel = params.zParams.notificationLevel;
45543 
45544  /* checks */
45545  if (!dictList) return ERROR(memory_allocation);
45546  if (maxDictSize < ZDICT_DICTSIZE_MIN) { free(dictList); return ERROR(dstSize_tooSmall); } /* requested dictionary size is too small */
45547  if (samplesBuffSize < ZDICT_MIN_SAMPLES_SIZE) { free(dictList); return ERROR(dictionaryCreation_failed); } /* not enough source to create dictionary */
45548 
45549  /* init */
45550  ZDICT_initDictItem(dictList);
45551 
45552  /* build dictionary */
45553  ZDICT_trainBuffer_legacy(dictList, dictListSize,
45554  samplesBuffer, samplesBuffSize,
45555  samplesSizes, nbSamples,
45556  minRep, notificationLevel);
45557 
45558  /* display best matches */
45559  if (params.zParams.notificationLevel>= 3) {
45560  unsigned const nb = MIN(25, dictList[0].pos);
45561  unsigned const dictContentSize = ZDICT_dictSize(dictList);
45562  unsigned u;
45563  DISPLAYLEVEL(3, "\n %u segments found, of total size %u \n", (unsigned)dictList[0].pos-1, dictContentSize);
45564  DISPLAYLEVEL(3, "list %u best segments \n", nb-1);
45565  for (u=1; u<nb; u++) {
45566  unsigned const pos = dictList[u].pos;
45567  unsigned const length = dictList[u].length;
45568  U32 const printedLength = MIN(40, length);
45569  if ((pos > samplesBuffSize) || ((pos + length) > samplesBuffSize)) {
45570  free(dictList);
45571  return ERROR(GENERIC); /* should never happen */
45572  }
45573  DISPLAYLEVEL(3, "%3u:%3u bytes at pos %8u, savings %7u bytes |",
45574  u, length, pos, (unsigned)dictList[u].savings);
45575  ZDICT_printHex((const char*)samplesBuffer+pos, printedLength);
45576  DISPLAYLEVEL(3, "| \n");
45577  } }
45578 
45579 
45580  /* create dictionary */
45581  { unsigned dictContentSize = ZDICT_dictSize(dictList);
45582  if (dictContentSize < ZDICT_CONTENTSIZE_MIN) { free(dictList); return ERROR(dictionaryCreation_failed); } /* dictionary content too small */
45583  if (dictContentSize < targetDictSize/4) {
45584  DISPLAYLEVEL(2, "! warning : selected content significantly smaller than requested (%u < %u) \n", dictContentSize, (unsigned)maxDictSize);
45585  if (samplesBuffSize < 10 * targetDictSize)
45586  DISPLAYLEVEL(2, "! consider increasing the number of samples (total size : %u MB)\n", (unsigned)(samplesBuffSize>>20));
45587  if (minRep > MINRATIO) {
45588  DISPLAYLEVEL(2, "! consider increasing selectivity to produce larger dictionary (-s%u) \n", selectivity+1);
45589  DISPLAYLEVEL(2, "! note : larger dictionaries are not necessarily better, test its efficiency on samples \n");
45590  }
45591  }
45592 
45593  if ((dictContentSize > targetDictSize*3) && (nbSamples > 2*MINRATIO) && (selectivity>1)) {
45594  unsigned proposedSelectivity = selectivity-1;
45595  while ((nbSamples >> proposedSelectivity) <= MINRATIO) { proposedSelectivity--; }
45596  DISPLAYLEVEL(2, "! note : calculated dictionary significantly larger than requested (%u > %u) \n", dictContentSize, (unsigned)maxDictSize);
45597  DISPLAYLEVEL(2, "! consider increasing dictionary size, or produce denser dictionary (-s%u) \n", proposedSelectivity);
45598  DISPLAYLEVEL(2, "! always test dictionary efficiency on real samples \n");
45599  }
45600 
45601  /* limit dictionary size */
45602  { U32 const max = dictList->pos; /* convention : nb of useful elts within dictList */
45603  U32 currentSize = 0;
45604  U32 n; for (n=1; n<max; n++) {
45605  currentSize += dictList[n].length;
45606  if (currentSize > targetDictSize) { currentSize -= dictList[n].length; break; }
45607  }
45608  dictList->pos = n;
45609  dictContentSize = currentSize;
45610  }
45611 
45612  /* build dict content */
45613  { U32 u;
45614  BYTE* ptr = (BYTE*)dictBuffer + maxDictSize;
45615  for (u=1; u<dictList->pos; u++) {
45616  U32 l = dictList[u].length;
45617  ptr -= l;
45618  if (ptr<(BYTE*)dictBuffer) { free(dictList); return ERROR(GENERIC); } /* should not happen */
45619  memcpy(ptr, (const char*)samplesBuffer+dictList[u].pos, l);
45620  } }
45621 
45622  dictSize = ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, maxDictSize,
45623  samplesBuffer, samplesSizes, nbSamples,
45624  params.zParams);
45625  }
45627  /* clean up */
45628  free(dictList);
45629  return dictSize;
45630 }
45631 
45632 
45633 /* ZDICT_trainFromBuffer_legacy() :
45634  * issue : samplesBuffer need to be followed by a noisy guard band.
45635  * work around : duplicate the buffer, and add the noise */
45636 size_t ZDICT_trainFromBuffer_legacy(void* dictBuffer, size_t dictBufferCapacity,
45637  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
45638  ZDICT_legacy_params_t params)
45639 {
45640  size_t result;
45641  void* newBuff;
45642  size_t const sBuffSize = ZDICT_totalSampleSize(samplesSizes, nbSamples);
45643  if (sBuffSize < ZDICT_MIN_SAMPLES_SIZE) return 0; /* not enough content => no dictionary */
45644 
45645  newBuff = malloc(sBuffSize + NOISELENGTH);
45646  if (!newBuff) return ERROR(memory_allocation);
45647 
45648  memcpy(newBuff, samplesBuffer, sBuffSize);
45649  ZDICT_fillNoise((char*)newBuff + sBuffSize, NOISELENGTH); /* guard band, for end of buffer condition */
45650 
45651  result =
45652  ZDICT_trainFromBuffer_unsafe_legacy(dictBuffer, dictBufferCapacity, newBuff,
45653  samplesSizes, nbSamples, params);
45654  free(newBuff);
45655  return result;
45656 }
45657 
45658 
45659 size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
45660  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples)
45661 {
45662  ZDICT_fastCover_params_t params;
45663  DEBUGLOG(3, "ZDICT_trainFromBuffer");
45664  memset(&params, 0, sizeof(params));
45665  params.d = 8;
45666  params.steps = 4;
45667  /* Use default level since no compression level information is available */
45669 #if defined(DEBUGLEVEL) && (DEBUGLEVEL>=1)
45671 #endif
45672  return ZDICT_optimizeTrainFromBuffer_fastCover(dictBuffer, dictBufferCapacity,
45673  samplesBuffer, samplesSizes, nbSamples,
45674  &params);
45675 }
45676 
45677 size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
45678  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples)
45679 {
45680  ZDICT_params_t params;
45681  memset(&params, 0, sizeof(params));
45682  return ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, dictBufferCapacity,
45683  samplesBuffer, samplesSizes, nbSamples,
45684  params);
45685 }
45686 /**** ended inlining dictBuilder/zdict.c ****/
COVER_best_s::liveJobs
size_t liveJobs
Definition: zstd.c:40454
COVER_tryParameters_data_s::parameters
ZDICT_cover_params_t parameters
Definition: zstd.c:41607
LitHufLog
#define LitHufLog
Definition: zstd.c:10842
ZSTD_noCompressLiterals
size_t ZSTD_noCompressLiterals(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:15948
ZSTD_sizeof_localDict
static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict)
Definition: zstd.c:17800
ZSTD_WINDOW_START_INDEX
#define ZSTD_WINDOW_START_INDEX
Definition: zstd.c:14574
FSE_FUNCTION_TYPE
#define FSE_FUNCTION_TYPE
Definition: zstd.c:2800
XXH3_128bits_reset_withSeed
#define XXH3_128bits_reset_withSeed
ZSTD_sizeof_DCtx
size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx *dctx)
Definition: zstd.c:35572
ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
Definition: zstd.c:22634
ZSTD_in_dst
@ ZSTD_in_dst
Definition: zstd.c:34898
_trbudget_t::chance
int chance
Definition: zstd.c:42907
ZSTD_DDictHashSet_getDDict
static const ZSTD_DDict * ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet *hashSet, U32 dictID)
Definition: zstd.c:35507
ZSTDMT_CCtx_s::seqPool
ZSTDMT_seqPool * seqPool
Definition: zstd.c:31837
ZSTD_cwksp_static_alloc
@ ZSTD_cwksp_static_alloc
Definition: zstd.c:13596
COVER_ctx_t::suffixSize
size_t suffixSize
Definition: zstd.c:40767
XXH32_state_s::reserved
XXH32_hash_t reserved
Definition: zstd.c:5893
POOL_function
void(* POOL_function)(void *)
Definition: zstd.c:4273
ldmMatchCandidate_t::checksum
U32 checksum
Definition: zstd.c:14639
ZSTD_cpuid_t::f1c
U32 f1c
Definition: zstd.c:4721
ZSTD_initStaticCCtx
ZSTD_CCtx * ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
Definition: zstd.c:17764
ZSTD_cwksp_free
MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp *ws, ZSTD_customMem customMem)
Definition: zstd.c:14201
ZSTD_matchState_t::loadedDictEnd
U32 loadedDictEnd
Definition: zstd.c:14582
dictItem::length
U32 length
Definition: zstd.c:44703
XXH3_64bits_reset_withSeed
#define XXH3_64bits_reset_withSeed
ZSTD_writeLastEmptyBlock
size_t ZSTD_writeLastEmptyBlock(void *dst, size_t dstCapacity)
Definition: zstd.c:22185
set_rle
@ set_rle
Definition: zstd.c:10835
ZDICT_insertDictItem
static void ZDICT_insertDictItem(dictItem *table, U32 maxSize, dictItem elt, const void *buffer)
Definition: zstd.c:44975
ldmEntry_t::offset
U32 offset
Definition: zstd.c:14632
ZSTD_optLdm_skipRawSeqStoreBytes
static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t *rawSeqStore, size_t nbBytes)
Definition: zstd.c:30427
ZSTD_reduceTable
static void ZSTD_reduceTable(U32 *const table, U32 const size, U32 const reducerValue)
Definition: zstd.c:20236
ZSTD_loadDictionaryContent
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t *ms, ldmState_t *ls, ZSTD_cwksp *ws, ZSTD_CCtx_params const *params, const void *src, size_t srcSize, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp)
Definition: zstd.c:22320
seqStore_t::maxNbSeq
size_t maxNbSeq
Definition: zstd.c:11039
COVER_map_pair_t_s::key
U32 key
Definition: zstd.c:40638
ZSTDMT_releaseAllJobResources
static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:31973
ZSTD_PREDEF_THRESHOLD
#define ZSTD_PREDEF_THRESHOLD
Definition: zstd.c:29541
HUF_fillDTableX2ForWeight
static void HUF_fillDTableX2ForWeight(HUF_DEltX2 *DTableRank, sortedSymbol_t const *begin, sortedSymbol_t const *end, U32 nbBits, U32 tableLog, U16 baseSeq, int const level)
Definition: zstd.c:33827
ZSTD_sizeof_mtctx
static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx *cctx)
Definition: zstd.c:17831
OFFBASE_TO_REPCODE
#define OFFBASE_TO_REPCODE(o)
Definition: zstd.c:15009
nodeElt_s
Definition: zstd.c:12095
XXH_read64
static xxh_u64 XXH_read64(const void *memPtr)
Definition: zstd.c:7222
POOL_resize_internal
static int POOL_resize_internal(POOL_ctx *ctx, size_t numThreads)
Definition: zstd.c:4496
ZSTD_maxNbSeq
static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useSequenceProducer)
Definition: zstd.c:19280
ZSTD_DCtx_s::expectedOutBuffer
ZSTD_outBuffer expectedOutBuffer
Definition: zstd.c:34965
MEM_writeLEST
MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val)
Definition: zstd.c:1207
ZSTD_c_compressionLevel
@ ZSTD_c_compressionLevel
Definition: zstd.h:334
ZSTD_cParamMode_e
ZSTD_cParamMode_e
Definition: zstd.c:14860
ZSTD_DCtx_trace_end
static void ZSTD_DCtx_trace_end(ZSTD_DCtx const *dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
Definition: zstd.c:36267
unroll
static void unroll(lua_State *L, void *ud)
Definition: ldo.c:677
ZSTD_error_memory_allocation
@ ZSTD_error_memory_allocation
Definition: zstd.c:1385
ZSTD_estimateDStreamSize
size_t ZSTD_estimateDStreamSize(size_t windowSize)
Definition: zstd.c:37294
ZSTDMT_getBuffer
static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool *bufPool)
Definition: zstd.c:31181
LL_defaultNorm
static const UNUSED_ATTR S16 LL_defaultNorm[MaxLL+1]
Definition: zstd.c:10867
HUF_simpleQuickSort
static void HUF_simpleQuickSort(nodeElt arr[], int low, int high)
Definition: zstd.c:12614
ZSTD_adjustCParams_internal
static ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize, ZSTD_cParamMode_e mode, ZSTD_paramSwitch_e useRowMatchFinder)
Definition: zstd.c:19099
COVER_selectDict
COVER_dictSelection_t COVER_selectDict(BYTE *customDictContent, size_t dictBufferCapacity, size_t dictContentSize, const BYTE *samplesBuffer, const size_t *samplesSizes, unsigned nbFinalizeSamples, size_t nbCheckSamples, size_t nbSamples, ZDICT_cover_params_t params, size_t *offsets, size_t totalCompressedSize)
Definition: zstd.c:41513
ZSTD_CCtx_s::outBuffContentSize
size_t outBuffContentSize
Definition: zstd.c:14818
HUF_minTableLog
unsigned HUF_minTableLog(unsigned symbolCardinality)
Definition: zstd.c:13281
ZSTD_MULTITHREAD
#define ZSTD_MULTITHREAD
Definition: zstd.c:47
ZSTD_useTargetCBlockSize
static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params *cctxParams)
Definition: zstd.c:20307
ZSTD_decodeFrameHeader
static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx *dctx, const void *src, size_t headerSize)
Definition: zstd.c:36049
COVER_prime4bytes
static const U32 COVER_prime4bytes
Definition: zstd.c:40679
ZSTDcs_ongoing
@ ZSTDcs_ongoing
Definition: zstd.c:14413
ZSTD_optLdm_t
Definition: zstd.c:30416
ZSTD_hash3PtrS
MEM_STATIC size_t ZSTD_hash3PtrS(const void *ptr, U32 h, U32 s)
Definition: zstd.c:15165
ZSTD_memset
#define ZSTD_memset(p, v, l)
Definition: zstd.c:94
ZSTD_CCtx_s::appliedParams
ZSTD_CCtx_params appliedParams
Definition: zstd.c:14781
HUF_quickSortPartition
static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high)
Definition: zstd.c:12594
FSE_initCState
static void FSE_initCState(FSE_CState_t *CStatePtr, const FSE_CTable *ct)
Definition: zstd.c:2627
nlohmann::detail::hash
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5097
ZSTDMT_expandCCtxPool
static ZSTDMT_CCtxPool * ZSTDMT_expandCCtxPool(ZSTDMT_CCtxPool *srcPool, int nbWorkers)
Definition: zstd.c:31385
ZSTD_createDDict_advanced
ZSTD_DDict * ZSTD_createDDict_advanced(const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_customMem customMem)
Definition: zstd.c:35181
WILDCOPY_OVERLENGTH
#define WILDCOPY_OVERLENGTH
Definition: zstd.c:10940
ZSTD_CCtx_params_s::enableMatchFinderFallback
int enableMatchFinderFallback
Definition: zstd.c:14725
XXH_swap64
static xxh_u64 XXH_swap64(xxh_u64 x)
Definition: zstd.c:7236
ZDICT_fastCover_params_t::steps
unsigned steps
Definition: zstd.c:40262
HUF_OPTIMAL_DEPTH_THRESHOLD
#define HUF_OPTIMAL_DEPTH_THRESHOLD
Definition: zstd.c:2954
HUF_compress1X_usingCTable_internal_body_loop
FORCE_INLINE_TEMPLATE void HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t *bitC, const BYTE *ip, size_t srcSize, const HUF_CElt *ct, int kUnroll, int kFastFlush, int kLastFast)
Definition: zstd.c:13006
OF_defaultNorm
static const UNUSED_ATTR S16 OF_defaultNorm[DefaultMaxOff+1]
Definition: zstd.c:10898
ZSTD_dedicatedDictSearch_revertCParams
static void ZSTD_dedicatedDictSearch_revertCParams(ZSTD_compressionParameters *cParams)
Definition: zstd.c:24686
COVER_dictSelectionFree
void COVER_dictSelectionFree(COVER_dictSelection_t selection)
Definition: zstd.c:41509
ZSTD_error_noForwardProgress_inputEmpty
@ ZSTD_error_noForwardProgress_inputEmpty
Definition: zstd.c:1391
_trbudget_t::count
int count
Definition: zstd.c:42910
COVER_map_index
static U32 COVER_map_index(COVER_map_t *map, U32 key)
Definition: zstd.c:40687
ZSTD_sequencePosition
Definition: zstd.c:14517
ZSTD_sequenceLength::matchLength
U32 matchLength
Definition: zstd.c:11052
offsetCount_t
Definition: zstd.c:45171
ZSTD_DCtx_s::refMultipleDDicts
ZSTD_refMultipleDDicts_e refMultipleDDicts
Definition: zstd.c:34943
ZSTD_compressBlock_lazy_dictMatchState
size_t ZSTD_compressBlock_lazy_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28331
ZSTD_compressBlock_splitBlock
static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastBlock)
Definition: zstd.c:21832
ZSTD_matchState_t::opt
optState_t opt
Definition: zstd.c:14607
ZSTDMT_setBufferSize
static void ZSTDMT_setBufferSize(ZSTDMT_bufferPool *const bufPool, size_t const bSize)
Definition: zstd.c:31151
HUF_validateCTable
int HUF_validateCTable(const HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
Definition: zstd.c:12826
srcSize
char int srcSize
Definition: lz4.h:765
FASTCOVER_tryParameters_data_t
struct FASTCOVER_tryParameters_data_s FASTCOVER_tryParameters_data_t
COVER_map_pair_t_s::value
U32 value
Definition: zstd.c:40639
ZSTD_CDict_s::compressionLevel
int compressionLevel
Definition: zstd.c:17728
XXH3_128bits_withSecretandSeed
#define XXH3_128bits_withSecretandSeed
ZSTD_createCStream
ZSTD_CStream * ZSTD_createCStream(void)
Definition: zstd.c:23326
ZSTD_blockSplitCtx::partitions
U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS]
Definition: zstd.c:14764
COVER_tryParameters_data_s::best
COVER_best_t * best
Definition: zstd.c:41605
ZSTD_copyDCtx
void ZSTD_copyDCtx(ZSTD_DCtx *dstDCtx, const ZSTD_DCtx *srcDCtx)
Definition: zstd.c:35695
op
#define op
COVER_map_destroy
static void COVER_map_destroy(COVER_map_t *map)
Definition: zstd.c:40747
zdss_read
@ zdss_read
Definition: zstd.c:34871
FSE_buildCTable_wksp
size_t FSE_buildCTable_wksp(FSE_CTable *ct, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize)
Definition: zstd.c:11307
ZSTD_compressBlock_greedy_dictMatchState_row
size_t ZSTD_compressBlock_greedy_dictMatchState_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28403
zop_predef
@ zop_predef
Definition: zstd.c:14533
ZSTD_hufCTablesMetadata_t
Definition: zstd.c:14457
optState_t::priceTable
ZSTD_optimal_t * priceTable
Definition: zstd.c:14542
ZSTD_initCCtx
static void ZSTD_initCCtx(ZSTD_CCtx *cctx, ZSTD_customMem memManager)
Definition: zstd.c:17740
POOL_ctx_s::queuePopCond
ZSTD_pthread_cond_t queuePopCond
Definition: zstd.c:4338
ZSTD_rollingHash_rotate
MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower)
Definition: zstd.c:15279
COVER_tryParameters_data_s
Definition: zstd.c:41603
ZSTD_getErrorCode
ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult)
Definition: zstd.c:11156
POOL_tryAdd
int POOL_tryAdd(POOL_ctx *ctx, POOL_function function, void *opaque)
Definition: zstd.c:4580
ZSTD_error_version_unsupported
@ ZSTD_error_version_unsupported
Definition: zstd.c:1367
PREFIX
#define PREFIX(name)
Definition: zstd.c:1438
ZSTD_isUpdateAuthorized
static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
Definition: zstd.c:18297
trustInput
@ trustInput
Definition: zstd.c:11921
ERR_getErrorString
const char * ERR_getErrorString(ERR_enum code)
Definition: zstd.c:3441
ZSTDMT_CCtxPool::cctx
ZSTD_CCtx * cctx[1]
Definition: zstd.c:31350
ZSTD_ldm_gear_init
static void ZSTD_ldm_gear_init(ldmRollingHashState_t *state, ldmParams_t const *params)
Definition: zstd.c:28828
ZSTD_compressBlock_lazy2_dictMatchState
size_t ZSTD_compressBlock_lazy2_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28324
ZSTD_createDDictHashSet
static ZSTD_DDictHashSet * ZSTD_createDDictHashSet(ZSTD_customMem customMem)
Definition: zstd.c:35529
detail::first
auto first(const T &value, const Tail &...) -> const T &
Definition: compile.h:60
COVER_epoch_info_t::size
U32 size
Definition: zstd.c:40475
ZSTD_checkCParams
size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
Definition: zstd.c:19015
sol::stack::top
int top(lua_State *L)
Definition: sol.hpp:11684
ZSTD_dParam_getBounds
ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
Definition: zstd.c:37145
BIT_DStream_t::bitContainer
size_t bitContainer
Definition: zstd.c:2083
XXH_memcpy
static void * XXH_memcpy(void *dest, const void *src, size_t size)
Definition: zstd.c:6378
ZSTDMT_updateCParams_whileCompressing
void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx *mtctx, const ZSTD_CCtx_params *cctxParams)
Definition: zstd.c:32062
ZDICT_params_t
Definition: zstd.c:40156
ZSTD_dictNCountRepeat
static FSE_repeat ZSTD_dictNCountRepeat(short *normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue)
Definition: zstd.c:22447
ZSTD_e_flush
@ ZSTD_e_flush
Definition: zstd.h:747
ZSTD_cwksp_alloc_objects
@ ZSTD_cwksp_alloc_objects
Definition: zstd.c:13583
ZSTD_buildSequencesStatistics
static ZSTD_symbolEncodingTypeStats_t ZSTD_buildSequencesStatistics(const seqStore_t *seqStorePtr, size_t nbSeq, const ZSTD_fseCTables_t *prevEntropy, ZSTD_fseCTables_t *nextEntropy, BYTE *dst, const BYTE *const dstEnd, ZSTD_strategy strategy, unsigned *countWorkspace, void *entropyWorkspace, size_t entropyWkspSize)
Definition: zstd.c:20345
ZSTD_insertAndFindFirstIndex_internal
FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(ZSTD_matchState_t *ms, const ZSTD_compressionParameters *const cParams, const BYTE *ip, U32 const mls, U32 const lazySkipping)
Definition: zstd.c:27150
ZSTD_hashPtrSalted
MEM_STATIC FORCE_INLINE_ATTR size_t ZSTD_hashPtrSalted(const void *p, U32 hBits, U32 mls, const U64 hashSalt)
Definition: zstd.c:15212
ZSTD_pthread_cond_t
#define ZSTD_pthread_cond_t
Definition: zstd.c:3910
ZSTD_dictMode_e
ZSTD_dictMode_e
Definition: zstd.c:14853
ZSTD_resolveBlockSplitterMode
static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode, const ZSTD_compressionParameters *const cParams)
Definition: zstd.c:17893
optState_t::literalCompressionMode
ZSTD_paramSwitch_e literalCompressionMode
Definition: zstd.c:14554
ZSTD_getLowestPrefixIndex
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t *ms, U32 curr, unsigned windowLog)
Definition: zstd.c:15670
ZSTD_error_srcBuffer_wrong
@ ZSTD_error_srcBuffer_wrong
Definition: zstd.c:1396
ZSTD_matchState_t::cParams
ZSTD_compressionParameters cParams
Definition: zstd.c:14609
ZSTD_cwksp_clear_tables
MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp *ws)
Definition: zstd.c:14114
MEM_writeBE32
MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32)
Definition: zstd.c:1225
COVER_map_remove
static void COVER_map_remove(COVER_map_t *map, U32 key)
Definition: zstd.c:40718
XXH_FORCE_INLINE
#define XXH_FORCE_INLINE
Definition: zstd.c:6407
ZSTDMT_sizeof_bufferPool
static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool *bufPool)
Definition: zstd.c:31133
MEM_write16
MEM_STATIC void MEM_write16(void *memPtr, U16 value)
Definition: zstd.c:1064
ZSTD_hash8PtrS
static size_t ZSTD_hash8PtrS(const void *p, U32 h, U64 s)
Definition: zstd.c:15190
ZSTD_bufferMode_e
ZSTD_bufferMode_e
Definition: zstd.c:11009
dictItem
Definition: zstd.c:44701
POOL_ctx_s::queue
POOL_job * queue
Definition: zstd.c:4323
ZSTD_CCtx_s::mtctx
ZSTDMT_CCtx * mtctx
Definition: zstd.c:14835
seqDef_s
Definition: zstd.c:11018
FASTCOVER_computeFrequency
static void FASTCOVER_computeFrequency(U32 *freqs, const FASTCOVER_ctx_t *ctx)
Definition: zstd.c:44064
ldmState_t::splitIndices
size_t splitIndices[LDM_BATCH_SIZE]
Definition: zstd.c:14650
ZSTD_error_tableLog_tooLarge
@ ZSTD_error_tableLog_tooLarge
Definition: zstd.c:1379
ZSTD_encodeSequences_body
FORCE_INLINE_TEMPLATE size_t ZSTD_encodeSequences_body(void *dst, size_t dstCapacity, FSE_CTable const *CTable_MatchLength, BYTE const *mlCodeTable, FSE_CTable const *CTable_OffsetBits, BYTE const *ofCodeTable, FSE_CTable const *CTable_LitLength, BYTE const *llCodeTable, seqDef const *sequences, size_t nbSeq, int longOffsets)
Definition: zstd.c:16492
COVER_ctx_t::suffix
U32 * suffix
Definition: zstd.c:40766
MERGE_CHECK
#define MERGE_CHECK(a, b, c)
HUF_getIndex
static U32 HUF_getIndex(U32 const count)
Definition: zstd.c:12553
ZSTD_lazy2
@ ZSTD_lazy2
Definition: zstd.h:321
XXH32_finalize
static xxh_u32 XXH32_finalize(xxh_u32 h32, const xxh_u8 *ptr, size_t len, XXH_alignment align)
Definition: zstd.c:6888
ZSTD_NCountCost
static size_t ZSTD_NCountCost(unsigned const *count, unsigned const max, size_t const nbSeq, unsigned const FSELog)
Definition: zstd.c:16271
ZSTD_compressBlock_fast_noDict_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_fast_noDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls, U32 const hasStep)
Definition: zstd.c:25711
ldmMatchCandidate_t
Definition: zstd.c:14636
COVER_map_pair_t_s
Definition: zstd.c:40637
ss_rotate
static INLINE void ss_rotate(int *first, int *middle, int *last)
Definition: zstd.c:42416
ZSTD_c_ldmHashLog
@ ZSTD_c_ldmHashLog
Definition: zstd.h:402
MEM_swap64
MEM_STATIC U64 MEM_swap64(U64 in)
Definition: zstd.c:1113
detail::state
state
Definition: core.h:2305
COVER_MAX_SAMPLES_SIZE
#define COVER_MAX_SAMPLES_SIZE
Definition: zstd.c:40589
ZSTD_ldm_insertEntry
static void ZSTD_ldm_insertEntry(ldmState_t *ldmState, size_t const hash, const ldmEntry_t entry, ldmParams_t const ldmParams)
Definition: zstd.c:28976
optState_t::matchLengthSumBasePrice
U32 matchLengthSumBasePrice
Definition: zstd.c:14550
XXH_unaligned
@ XXH_unaligned
Definition: zstd.c:6714
align
Definition: core.h:2016
ZSTD_c_ldmHashRateLog
@ ZSTD_c_ldmHashRateLog
Definition: zstd.h:416
rawSeqStore_t::pos
size_t pos
Definition: zstd.c:14510
tr_ilg
static INLINE int tr_ilg(int n)
Definition: zstd.c:42776
ZSTD_clampCParams
static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters cParams)
Definition: zstd.c:19031
ZSTD_fseCTablesMetadata_t::llType
symbolEncodingType_e llType
Definition: zstd.c:14469
ZSTD_CCtx_params_s::jobSize
size_t jobSize
Definition: zstd.c:14690
XXH32_canonical_t
#define XXH32_canonical_t
MEM_readBE64
MEM_STATIC U64 MEM_readBE64(const void *memPtr)
Definition: zstd.c:1233
ZSTD_optimal_t::off
U32 off
Definition: zstd.c:14527
ZSTD_createCCtxParams_advanced
static ZSTD_CCtx_params * ZSTD_createCCtxParams_advanced(ZSTD_customMem customMem)
Definition: zstd.c:17973
ZSTD_c_ldmMinMatch
@ ZSTD_c_ldmMinMatch
Definition: zstd.h:408
FSE_FLUSHBITS
#define FSE_FLUSHBITS(s)
kLazySkippingStep
#define kLazySkippingStep
Definition: zstd.c:26545
ZDICT_CONTENTSIZE_MIN
#define ZDICT_CONTENTSIZE_MIN
Definition: zstd.c:40241
ZSTD_isAligned
MEM_STATIC int ZSTD_isAligned(void const *ptr, size_t align)
Definition: zstd.c:27325
seqDef
struct seqDef_s seqDef
ZSTD_matchState_dictMode
MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
Definition: zstd.c:15334
BUCKET_B_SIZE
#define BUCKET_B_SIZE
Definition: zstd.c:41924
writeBlockHeader
static void writeBlockHeader(void *op, size_t cSize, size_t blockSize, U32 lastBlock)
Definition: zstd.c:21095
XXH32_hashFromCanonical
#define XXH32_hashFromCanonical
tr_fixdown
static INLINE void tr_fixdown(const int *ISAd, int *SA, int i, int size)
Definition: zstd.c:42811
ZSTD_matchState_t::hashTable
U32 * hashTable
Definition: zstd.c:14598
ZSTD_updateDUBT
static void ZSTD_updateDUBT(ZSTD_matchState_t *ms, const BYTE *ip, const BYTE *iend, U32 mls)
Definition: zstd.c:26553
bytes
Definition: format.h:4101
ZSTD_resetCCtx_usingCDict
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, const ZSTD_CCtx_params *params, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff)
Definition: zstd.c:20069
_force_has_format_string
static INLINE_KEYWORD UNUSED_ATTR void _force_has_format_string(const char *format,...)
Definition: zstd.c:1478
ZSTD_matchState_t::tagTable
BYTE * tagTable
Definition: zstd.c:14593
ZSTDMT_createSeqPool
static ZSTDMT_seqPool * ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem)
Definition: zstd.c:31323
ZSTD_buildSeqTable
static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol *DTableSpace, const ZSTD_seqSymbol **DTablePtr, symbolEncodingType_e type, unsigned max, U32 maxLog, const void *src, size_t srcSize, const U32 *baseValue, const U8 *nbAdditionalBits, const ZSTD_seqSymbol *defaultTable, U32 flagRepeatTable, int ddictIsCold, int nbSeq, U32 *wksp, size_t wkspSize, int bmi2)
Definition: zstd.c:38325
MEM_writeBE64
MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64)
Definition: zstd.c:1241
ZSTD_CCtx_s::expectedOutBufferSize
size_t expectedOutBufferSize
Definition: zstd.c:14826
ZSTD_fillHashTable
void ZSTD_fillHashTable(ZSTD_matchState_t *ms, void const *end, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp)
Definition: zstd.c:25651
assert
#define assert(condition)
Definition: zstd.c:266
EStats_ress_t::zc
ZSTD_CCtx * zc
Definition: zstd.c:45102
HUF_cardinality
unsigned HUF_cardinality(const unsigned *count, unsigned maxSymbolValue)
Definition: zstd.c:13269
COVER_ctx_t
Definition: zstd.c:40759
ZSTD_cwksp_check_wasteful
MEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp *ws, size_t additionalNeededSpace)
Definition: zstd.c:14259
HUF_ReadDTableX1_Workspace::symbols
BYTE symbols[HUF_SYMBOLVALUE_MAX+1]
Definition: zstd.c:33221
ZSTDMT_bufferPool_s
Definition: zstd.c:31094
prime5bytes
static const U64 prime5bytes
Definition: zstd.c:15172
ZSTD_checkContinuity
void ZSTD_checkContinuity(ZSTD_DCtx *dctx, const void *dst, size_t dstSize)
Definition: zstd.c:39872
rsyncState_t::hash
U64 hash
Definition: zstd.c:31827
ZSTD_sequencePosition::posInSequence
U32 posInSequence
Definition: zstd.c:14519
ZSTD_buildSeqStore_e
ZSTD_buildSeqStore_e
Definition: zstd.c:20783
ZSTDMT_jobDescription::firstJob
unsigned firstJob
Definition: zstd.c:31648
ZSTD_opt_getNextMatchAndUpdateSeqStore
static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t *optLdm, U32 currPosInBlock, U32 blockBytesRemaining)
Definition: zstd.c:30450
ZSTD_DCtx_s::headerSize
size_t headerSize
Definition: zstd.c:34923
ZSTD_bitWeight
MEM_STATIC U32 ZSTD_bitWeight(U32 stat)
Definition: zstd.c:29564
ZSTD_compressBlock_lazy_extDict_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize, const searchMethod_e searchMethod, const U32 depth)
Definition: zstd.c:28433
seqStore_t::sequencesStart
seqDef * sequencesStart
Definition: zstd.c:11032
FASTCOVER_ctx_destroy
static void FASTCOVER_ctx_destroy(FASTCOVER_ctx_t *ctx)
Definition: zstd.c:44048
ZSTD_DCtx_s::litSize
size_t litSize
Definition: zstd.c:34929
POOL_job_s
Definition: zstd.c:4310
ZSTD_matchState_t::dedicatedDictSearch
int dedicatedDictSearch
Definition: zstd.c:14604
ZSTD_CCtx_params_s::customMem
ZSTD_customMem customMem
Definition: zstd.c:14718
nodeElt_s::parent
U16 parent
Definition: zstd.c:12097
ZSTD_nextInputSizeHint_MTorST
static size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx *cctx)
Definition: zstd.c:23687
DISPLAYUPDATE
#define DISPLAYUPDATE(l,...)
Definition: zstd.c:43863
COVER_epoch_info_t
Definition: zstd.c:40473
sssort
static void sssort(const unsigned char *T, const int *PA, int *first, int *last, int *buf, int bufsize, int depth, int n, int lastsuffix)
Definition: zstd.c:42701
ZSTD_DDict
struct ZSTD_DDict_s ZSTD_DDict
Definition: zstd.h:963
ZDICT_isError
ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode)
Definition: zstd.c:44646
ZSTD_greedy
@ ZSTD_greedy
Definition: zstd.h:319
ZSTD_error_dictionary_wrong
@ ZSTD_error_dictionary_wrong
Definition: zstd.c:1374
FSE_MIN_TABLELOG
#define FSE_MIN_TABLELOG
Definition: zstd.c:2815
ZSTD_ldm_gearTab
static const UNUSED_ATTR U64 ZSTD_ldm_gearTab[256]
Definition: zstd.c:28723
ZSTD_CCtx_s::externSeqStore
rawSeqStore_t externSeqStore
Definition: zstd.c:14803
ZSTD_shouldAttachDict
static int ZSTD_shouldAttachDict(const ZSTD_CDict *cdict, const ZSTD_CCtx_params *params, U64 pledgedSrcSize)
Definition: zstd.c:19892
ZSTD_getErrorString
const ZSTDERRORLIB_API char * ZSTD_getErrorString(ZSTD_ErrorCode code)
Definition: zstd.c:11160
ZSTDMT_CCtx_s::produced
unsigned long long produced
Definition: zstd.c:31853
ZSTD_CCtx_s::inBuff
char * inBuff
Definition: zstd.c:14811
COVER_computeEpochs
COVER_epoch_info_t COVER_computeEpochs(U32 maxDictSize, U32 nbDmers, U32 k, U32 passes)
Definition: zstd.c:41202
ZSTD_ResetDirective
ZSTD_ResetDirective
Definition: zstd.h:554
FSE_DTableHeader::fastMode
U16 fastMode
Definition: zstd.c:2706
XXH_PRIME64_5
#define XXH_PRIME64_5
Definition: zstd.c:7313
BIT_mask
static const unsigned BIT_mask[]
Definition: zstd.c:2126
HUF_readDTableX1_wksp
size_t HUF_readDTableX1_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:33225
FSE_DEFAULT_TABLELOG
#define FSE_DEFAULT_TABLELOG
Definition: zstd.c:2814
XXH_FORCE_ALIGN_CHECK
#define XXH_FORCE_ALIGN_CHECK
Definition: zstd.c:6345
HUF_getNbBits
static size_t HUF_getNbBits(HUF_CElt elt)
Definition: zstd.c:12236
HUF_compress4X_usingCTable
size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable, int flags)
Definition: zstd.c:13232
BIT_DStream_endOfBuffer
@ BIT_DStream_endOfBuffer
Definition: zstd.c:2091
FSE_repeat
FSE_repeat
Definition: zstd.c:2477
ZSTD_row_update
void ZSTD_row_update(ZSTD_matchState_t *const ms, const BYTE *ip)
Definition: zstd.c:27458
udp_client.default
default
Definition: udp_client.py:10
ZSTD_isSkippableFrame
unsigned ZSTD_isSkippableFrame(const void *buffer, size_t size)
Definition: zstd.c:35751
ZDICT_totalSampleSize
static size_t ZDICT_totalSampleSize(const size_t *fileSizes, unsigned nbFiles)
Definition: zstd.c:45163
FSE_initCState2
MEM_STATIC void FSE_initCState2(FSE_CState_t *statePtr, const FSE_CTable *ct, U32 symbol)
Definition: zstd.c:2642
HUF_singleStream
@ HUF_singleStream
Definition: zstd.c:13237
ZSTD_error_dictionaryCreation_failed
@ ZSTD_error_dictionaryCreation_failed
Definition: zstd.c:1375
ZSTD_estimateSubBlockSize_sequences
static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE *ofCodeTable, const BYTE *llCodeTable, const BYTE *mlCodeTable, size_t nbSeq, const ZSTD_fseCTables_t *fseTables, const ZSTD_fseCTablesMetadata_t *fseMetadata, void *workspace, size_t wkspSize, int writeEntropy)
Definition: zstd.c:17042
ZSTD_error_stage_wrong
@ ZSTD_error_stage_wrong
Definition: zstd.c:1383
FSE_compress_usingCTable
FSE_PUBLIC_API size_t FSE_compress_usingCTable(void *dst, size_t dstCapacity, const void *src, size_t srcSize, const FSE_CTable *ct)
Definition: zstd.c:11848
tr_partialcopy
static void tr_partialcopy(int *ISA, const int *SA, int *first, int *a, int *b, int *last, int depth)
Definition: zstd.c:43002
ZSTD_cwksp_reserve_buffer
MEM_STATIC BYTE * ZSTD_cwksp_reserve_buffer(ZSTD_cwksp *ws, size_t bytes)
Definition: zstd.c:13923
ZSTD_INDEXOVERFLOW_MARGIN
#define ZSTD_INDEXOVERFLOW_MARGIN
Definition: zstd.c:19661
LL_defaultNormLog
static const UNUSED_ATTR U32 LL_defaultNormLog
Definition: zstd.c:10875
ZSTD_writeTaggedIndex
MEM_STATIC void ZSTD_writeTaggedIndex(U32 *const hashTable, size_t hashAndTag, U32 index)
Definition: zstd.c:15738
ZSTD_compressBlock_lazy_extDict_row
size_t ZSTD_compressBlock_lazy_extDict_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28674
FSE_minTableLog
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
Definition: zstd.c:11586
ZSTD_CDict_s::customMem
ZSTD_customMem customMem
Definition: zstd.c:17726
trsort
static void trsort(int *ISA, int *SA, int n, int depth)
Definition: zstd.c:43267
HUF_decompress4X1_usingDTable_internal_default
static size_t HUF_decompress4X1_usingDTable_internal_default(void *dst, size_t dstSize, void const *cSrc, size_t cSrcSize, HUF_DTable const *DTable)
Definition: zstd.c:33544
FSE_compressBound
FSE_PUBLIC_API size_t FSE_compressBound(size_t size)
Definition: zstd.c:11861
HUF_ReadDTableX2_Workspace
Definition: zstd.c:33987
LOCALDISPLAYUPDATE
#define LOCALDISPLAYUPDATE(displayLevel, l,...)
Definition: zstd.c:43855
ZSTD_sequenceCopier
size_t(* ZSTD_sequenceCopier)(ZSTD_CCtx *cctx, ZSTD_sequencePosition *seqPos, const ZSTD_Sequence *const inSeqs, size_t inSeqsSize, const void *src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch)
Definition: zstd.c:24240
ZSTD_readMINMATCH
MEM_STATIC U32 ZSTD_readMINMATCH(const void *memPtr, U32 length)
Definition: zstd.c:29911
COVER_tryParameters
static void COVER_tryParameters(void *opaque)
Definition: zstd.c:41615
sol::lib::base
@ base
ZSTD_symbolEncodingTypeStats_t::LLtype
U32 LLtype
Definition: zstd.c:20329
JOB_ERROR
#define JOB_ERROR(e)
Definition: zstd.c:31657
ZSTD_compressedBlockState_t::entropy
ZSTD_entropyCTables_t entropy
Definition: zstd.c:14558
POOL_ctx_s::queuePushCond
ZSTD_pthread_cond_t queuePushCond
Definition: zstd.c:4336
XXH32_state_s::total_len_32
XXH32_hash_t total_len_32
Definition: zstd.c:5888
expect
#define expect(expr, value)
Definition: lz4.c:171
ZSTD_updateRep
MEM_STATIC void ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
Definition: zstd.c:15082
RSYNC_LENGTH
#define RSYNC_LENGTH
Definition: zstd.c:31815
backward::ColorMode::type
type
Definition: backward.hpp:3600
ZSTD_localDict::dictContentType
ZSTD_dictContentType_e dictContentType
Definition: zstd.c:14426
lg_table
static const int lg_table[256]
Definition: zstd.c:42005
searchMethod_e
searchMethod_e
Definition: zstd.c:27932
ZSTD_dont_use
@ ZSTD_dont_use
Definition: zstd.c:34875
ZSTD_insertAndFindFirstIndexHash3
static U32 ZSTD_insertAndFindFirstIndexHash3(const ZSTD_matchState_t *ms, U32 *nextToUpdate3, const BYTE *const ip)
Definition: zstd.c:29927
optState_t
Definition: zstd.c:14535
XXH64_endian_align
XXH_FORCE_INLINE xxh_u64 XXH64_endian_align(const xxh_u8 *input, size_t len, xxh_u64 seed, XXH_alignment align)
Definition: zstd.c:7389
ZSTD_optimal_t::litlen
U32 litlen
Definition: zstd.c:14529
ZSTD_DCtx_s::MLTptr
const ZSTD_seqSymbol * MLTptr
Definition: zstd.c:34905
HUF_decompress1X_usingDTable
size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable, int flags)
Definition: zstd.c:34682
ZSTD_compressBlock_lazy2
size_t ZSTD_compressBlock_lazy2(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28296
nonstd::span_lite::size_t
span_CONFIG_SIZE_TYPE size_t
Definition: span.hpp:576
ZSTD_externalMatchCtx
Definition: zstd.c:14769
ZSTD_cwksp_initialAllocStart
MEM_STATIC void * ZSTD_cwksp_initialAllocStart(ZSTD_cwksp *ws)
Definition: zstd.c:13808
COVER_selectSegment
static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs, COVER_map_t *activeDmers, U32 begin, U32 end, ZDICT_cover_params_t parameters)
Definition: zstd.c:40952
ldmMatchCandidate_t::split
BYTE const * split
Definition: zstd.c:14637
ZSTD_getAllMatchesFn
U32(* ZSTD_getAllMatchesFn)(ZSTD_match_t *, ZSTD_matchState_t *, U32 *, const BYTE *, const BYTE *, const U32 rep[ZSTD_REP_NUM], U32 const ll0, U32 const lengthToBeat)
Definition: zstd.c:30331
FSE_readNCount_body
FORCE_INLINE_TEMPLATE size_t FSE_readNCount_body(short *normalizedCounter, unsigned *maxSVPtr, unsigned *tableLogPtr, const void *headerBuffer, size_t hbSize)
Definition: zstd.c:3126
inBuff_t::buffer
buffer_t buffer
Definition: zstd.c:31795
XXH3_state_s
#define XXH3_state_s
ZSTD_hash3Ptr
MEM_STATIC size_t ZSTD_hash3Ptr(const void *ptr, U32 h)
Definition: zstd.c:15164
optState_t::matchTable
ZSTD_match_t * matchTable
Definition: zstd.c:14541
ldmParams_t::enableLdm
ZSTD_paramSwitch_e enableLdm
Definition: zstd.c:14655
ZDICT_initDictItem
static void ZDICT_initDictItem(dictItem *d)
Definition: zstd.c:44707
XXH_readBE32
static xxh_u32 XXH_readBE32(const void *ptr)
Definition: zstd.c:6748
HUF_DEltX1::byte
BYTE byte
Definition: zstd.c:33169
ZSTD_ldm_countBackwardsMatch
static size_t ZSTD_ldm_countBackwardsMatch(const BYTE *pIn, const BYTE *pAnchor, const BYTE *pMatch, const BYTE *pMatchBase)
Definition: zstd.c:28992
ZSTD_createDDict_byReference
ZSTD_DDict * ZSTD_createDDict_byReference(const void *dictBuffer, size_t dictSize)
Definition: zstd.c:35216
ML_DEFAULTNORMLOG
#define ML_DEFAULTNORMLOG
Definition: zstd.c:10895
ZSTD_fracWeight
MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat)
Definition: zstd.c:29572
ZSTD_DCtx_resetParameters
static void ZSTD_DCtx_resetParameters(ZSTD_DCtx *dctx)
Definition: zstd.c:35591
HUF_setNbBits
static void HUF_setNbBits(HUF_CElt *elt, size_t nbBits)
Definition: zstd.c:12256
HUF_CStream_t
Definition: zstd.c:12858
COVER_best_s
Definition: zstd.c:40451
MEM_write64
MEM_STATIC void MEM_write64(void *memPtr, U64 value)
Definition: zstd.c:1074
ZSTD_overflowCorrectIfNeeded
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t *ms, ZSTD_cwksp *ws, ZSTD_CCtx_params const *params, void const *ip, void const *iend)
Definition: zstd.c:21999
HUF_CompressWeightsWksp::scratchBuffer
U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)]
Definition: zstd.c:12189
ZSTD_matchState_t::nextToUpdate
U32 nextToUpdate
Definition: zstd.c:14589
FASTCOVER_selectSegment
static COVER_segment_t FASTCOVER_selectSegment(const FASTCOVER_ctx_t *ctx, U32 *freqs, U32 begin, U32 end, ZDICT_cover_params_t parameters, U16 *segmentFreqs)
Definition: zstd.c:43936
ZSTD_DDictHashSet_getIndex
static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet *hashSet, U32 dictID)
Definition: zstd.c:35446
buffer_t
struct buffer_s buffer_t
zcss_init
@ zcss_init
Definition: zstd.c:14414
XXH64_hash_t
unsigned long long XXH64_hash_t
Definition: xxhash.h:219
ZSTD_DCtx_s::litBufferEnd
const BYTE * litBufferEnd
Definition: zstd.c:34969
ZSTD_externalMatchCtx::seqBuffer
ZSTD_Sequence * seqBuffer
Definition: zstd.c:14772
ZSTD_DCtx_refPrefix_advanced
size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx *dctx, const void *prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:37049
XXH64_canonical_t
#define XXH64_canonical_t
ldmParams_t::hashRateLog
U32 hashRateLog
Definition: zstd.c:14659
HUF_compress1X_repeat
size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int flags)
Definition: zstd.c:13455
blockProperties_t::origSize
U32 origSize
Definition: zstd.c:11101
ZSTD_writeEpilogue
static size_t ZSTD_writeEpilogue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity)
Definition: zstd.c:22745
COVER_DEFAULT_SPLITPOINT
#define COVER_DEFAULT_SPLITPOINT
Definition: zstd.c:40590
ZSTDLIB_HIDDEN
#define ZSTDLIB_HIDDEN
Definition: zstd.h:38
ZSTD_DDictHashSet::ddictPtrTable
const ZSTD_DDict ** ddictPtrTable
Definition: zstd.c:34881
tr_partition
static INLINE void tr_partition(const int *ISAd, int *first, int *middle, int *last, int **pa, int **pb, int v)
Definition: zstd.c:42935
ZSTD_dedicatedDictSearch
@ ZSTD_dedicatedDictSearch
Definition: zstd.c:14857
XXH64_reset
#define XXH64_reset
XXH_COMPILER_GUARD
#define XXH_COMPILER_GUARD(var)
Definition: zstd.c:6471
sqq_table
static const int sqq_table[256]
Definition: zstd.c:42042
COVER_best_s::mutex
ZSTD_pthread_mutex_t mutex
Definition: zstd.c:40452
roundBuff_t::buffer
BYTE * buffer
Definition: zstd.c:31800
ZSTD_ipow
static U64 ZSTD_ipow(U64 base, U64 exponent)
Definition: zstd.c:15232
ZSTD_DDict_s::cMem
ZSTD_customMem cMem
Definition: zstd.c:35079
ZSTD_row_update_internalImpl
FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t *ms, U32 updateStartIdx, U32 const updateEndIdx, U32 const mls, U32 const rowLog, U32 const rowMask, U32 const useCache)
Definition: zstd.c:27396
roundBuff_t::pos
size_t pos
Definition: zstd.c:31806
HUF_initCStream
static size_t HUF_initCStream(HUF_CStream_t *bitC, void *startPtr, size_t dstCapacity)
Definition: zstd.c:12871
ZSTDMT_CCtx_s::frameContentSize
unsigned long long frameContentSize
Definition: zstd.c:31851
ZSTD_bounds::error
size_t error
Definition: zstd.h:510
ZSTD_extDict
@ ZSTD_extDict
Definition: zstd.c:14855
FASTCOVER_convertToFastCoverParams
static void FASTCOVER_convertToFastCoverParams(ZDICT_cover_params_t coverParams, ZDICT_fastCover_params_t *fastCoverParams, unsigned f, unsigned accel)
Definition: zstd.c:44312
ZSTD_CDict_s::dictContent
const void * dictContent
Definition: zstd.c:17719
ZSTDMT_serialState_free
static void ZSTDMT_serialState_free(serialState_t *serialState)
Definition: zstd.c:31549
ZSTD_compressBlock_greedy_dedicatedDictSearch_row
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28425
ZSTD_REP_NUM
#define ZSTD_REP_NUM
Definition: zstd.c:10805
ZDICT_countEStats
static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters *params, unsigned *countLit, unsigned *offsetcodeCount, unsigned *matchlengthCount, unsigned *litlengthCount, U32 *repOffsets, const void *src, size_t srcSize, U32 notificationLevel)
Definition: zstd.c:45108
HUF_compress_tables_t
Definition: zstd.c:13256
ZSTD_CCtx_params_s::ldmParams
ldmParams_t ldmParams
Definition: zstd.c:14695
ZSTD_WEAK_ATTR
#define ZSTD_WEAK_ATTR
Definition: zstd.c:10650
BIT_CStream_t::bitContainer
size_t bitContainer
Definition: zstd.c:2049
ZSTD_hash7Ptr
static size_t ZSTD_hash7Ptr(const void *p, U32 h)
Definition: zstd.c:15184
DISPLAYLEVEL
#define DISPLAYLEVEL(l,...)
Definition: zstd.c:44627
ZSTDMT_CCtx_s::targetSectionSize
size_t targetSectionSize
Definition: zstd.c:31839
ZSTDMT_expandSeqPool
static ZSTDMT_seqPool * ZSTDMT_expandSeqPool(ZSTDMT_seqPool *pool, U32 nbWorkers)
Definition: zstd.c:31336
ZSTD_MAGIC_SKIPPABLE_MASK
#define ZSTD_MAGIC_SKIPPABLE_MASK
Definition: zstd.h:140
zdss_flush
@ zdss_flush
Definition: zstd.c:34871
ZSTD_CCtx_s::seqCollector
SeqCollector seqCollector
Definition: zstd.c:14795
POOL_ctx_s::queueTail
size_t queueTail
Definition: zstd.c:4325
DTableDesc::tableType
BYTE tableType
Definition: zstd.c:33003
WARNING
#define WARNING
Definition: kiss_fft_log.h:13
ZSTD_DCtx_s::previousDstEnd
const void * previousDstEnd
Definition: zstd.c:34910
cond
static int cond(LexState *ls)
Definition: lparser.c:1394
s
XmlRpcServer s
HUF_DEltX1
Definition: zstd.c:33169
DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT
Definition: zstd.c:35438
ZSTD_cParam_clampBounds
static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int *value)
Definition: zstd.c:18282
ZSTD_NO_FORWARD_PROGRESS_MAX
#define ZSTD_NO_FORWARD_PROGRESS_MAX
Definition: zstd.c:35333
XXH128_canonical_t
#define XXH128_canonical_t
ZSTD_compressBegin_usingCDict_advanced
size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx *const cctx, const ZSTD_CDict *const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
Definition: zstd.c:23263
ZSTD_encodeSequences_default
static size_t ZSTD_encodeSequences_default(void *dst, size_t dstCapacity, FSE_CTable const *CTable_MatchLength, BYTE const *mlCodeTable, FSE_CTable const *CTable_OffsetBits, BYTE const *ofCodeTable, FSE_CTable const *CTable_LitLength, BYTE const *llCodeTable, seqDef const *sequences, size_t nbSeq, int longOffsets)
Definition: zstd.c:16586
ZSTD_pthread_create
#define ZSTD_pthread_create(a, b, c, d)
Definition: zstd.c:3918
BITCOST_ACCURACY
#define BITCOST_ACCURACY
Definition: zstd.c:29557
blockSize_noDelimiter
static size_t blockSize_noDelimiter(size_t blockSize, size_t remaining)
Definition: zstd.c:24284
RETURN_ERROR_IF
#define RETURN_ERROR_IF(cond, err,...)
Definition: zstd.c:1502
COVER_best_start
void COVER_best_start(COVER_best_t *best)
Definition: zstd.c:41434
ZSTD_estimateSubBlockSize_symbolType
static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, const BYTE *codeTable, unsigned maxCode, size_t nbSeq, const FSE_CTable *fseCTable, const U8 *additionalBits, short const *defaultNorm, U32 defaultNormLog, U32 defaultMax, void *workspace, size_t wkspSize)
Definition: zstd.c:17007
ZSTD_CDict_s::matchState
ZSTD_matchState_t matchState
Definition: zstd.c:17724
ZSTD_rollingHash_append
static U64 ZSTD_rollingHash_append(U64 hash, void const *buf, size_t size)
Definition: zstd.c:15248
HUF_SYMBOLVALUE_MAX
#define HUF_SYMBOLVALUE_MAX
Definition: zstd.c:2876
HUF_zeroIndex1
FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t *bitC)
Definition: zstd.c:12926
ZSTD_newRep
MEM_STATIC repcodes_t ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
Definition: zstd.c:15106
ZSTD_DCtx_isOverflow
static int ZSTD_DCtx_isOverflow(ZSTD_DStream *zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
Definition: zstd.c:37317
ZSTD_cwksp_reserve_internal
MEM_STATIC void * ZSTD_cwksp_reserve_internal(ZSTD_cwksp *ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase)
Definition: zstd.c:13890
INLINE_KEYWORD
#define INLINE_KEYWORD
Definition: zstd.c:526
SWAP
#define SWAP(_a, _b)
Definition: zstd.c:41959
ZSTD_storeLastLiterals
static void ZSTD_storeLastLiterals(seqStore_t *seqStorePtr, const BYTE *anchor, size_t lastLLSize)
Definition: zstd.c:20703
FASTCOVER_ctx_t::freqs
U32 * freqs
Definition: zstd.c:43915
prime7bytes
static const U64 prime7bytes
Definition: zstd.c:15182
ZSTD_e_end
@ ZSTD_e_end
Definition: zstd.h:751
ZSTD_decompressSequences_body
FORCE_INLINE_TEMPLATE size_t DONT_VECTORIZE ZSTD_decompressSequences_body(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, const int frame)
Definition: zstd.c:39277
ZSTDds_decodeFrameHeader
@ ZSTDds_decodeFrameHeader
Definition: zstd.c:34865
OffFSELog
#define OffFSELog
Definition: zstd.c:10851
literals
Definition: xchar.h:71
ZSTD_blockSplitCtx::firstHalfSeqStore
seqStore_t firstHalfSeqStore
Definition: zstd.c:14759
ZSTD_pthread_cond_init
#define ZSTD_pthread_cond_init(a, b)
Definition: zstd.c:3911
ZDICT_addEntropyTablesFromBuffer_advanced
static size_t ZDICT_addEntropyTablesFromBuffer_advanced(void *dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_params_t params)
Definition: zstd.c:45482
BIT_MASK_SIZE
#define BIT_MASK_SIZE
Definition: zstd.c:2133
ML_defaultNormLog
static const UNUSED_ATTR U32 ML_defaultNormLog
Definition: zstd.c:10896
XXH_PRIME32_2
#define XXH_PRIME32_2
Definition: zstd.c:6783
ZSTD_use_once
@ ZSTD_use_once
Definition: zstd.c:34876
ZSTD_PTHREAD_MUTEX_LOCK
#define ZSTD_PTHREAD_MUTEX_LOCK(m)
Definition: zstd.c:31078
ZSTD_matchState_t::forceNonContiguous
U32 forceNonContiguous
Definition: zstd.c:14602
SeqCollector::collectSequences
int collectSequences
Definition: zstd.c:14664
ZSTD_error_parameter_outOfBound
@ ZSTD_error_parameter_outOfBound
Definition: zstd.c:1378
ZSTD_entropyDTables_t::LLTable
ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]
Definition: zstd.c:34857
HUF_CompressWeightsWksp::CTable
FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]
Definition: zstd.c:12188
ZSTD_countLeadingZeros32
MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val)
Definition: zstd.c:1888
ZSTD_compressedLiterals
static int ZSTD_compressedLiterals(optState_t const *const optPtr)
Definition: zstd.c:29596
kNullRoundBuff
static const roundBuff_t kNullRoundBuff
Definition: zstd.c:31813
ZSTD_getParams_internal
static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
Definition: zstd.c:24771
ZSTD_compressBlock_lazy2_dictMatchState_row
size_t ZSTD_compressBlock_lazy2_dictMatchState_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28389
ZSTD_FALLTHROUGH
#define ZSTD_FALLTHROUGH
Definition: zstd.c:748
FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)
Definition: zstd.c:2462
ZSTD_getFrameProgression
ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx *cctx)
Definition: zstd.c:19452
FSE_DecompressWksp::dtable
FSE_DTable dtable[1]
Definition: zstd.c:3731
g_time
static clock_t g_time
Definition: zstd.c:40614
POOL_free
void POOL_free(POOL_ctx *ctx)
Definition: zstd.c:4461
FSE_flushCState
static void FSE_flushCState(BIT_CStream_t *bitC, const FSE_CState_t *CStatePtr)
Definition: zstd.c:2662
ZSTD_compressBlock_lazy_dedicatedDictSearch_row
size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28418
ZSTD_matchState_t::hashTable3
U32 * hashTable3
Definition: zstd.c:14599
HUF_DECODE_SYMBOLX1_1
#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr)
Definition: zstd.c:33373
HUF_setValue
static void HUF_setValue(HUF_CElt *elt, size_t value)
Definition: zstd.c:12262
ZSTD_compressBlock_doubleFast_extDict
size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:25549
ZSTD_resetCCtx_internal
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx *zc, ZSTD_CCtx_params const *params, U64 const pledgedSrcSize, size_t const loadedDictSize, ZSTD_compResetPolicy_e const crp, ZSTD_buffered_policy_e const zbuff)
Definition: zstd.c:19683
REPCODE_TO_OFFBASE
#define REPCODE_TO_OFFBASE(r)
Definition: zstd.c:15004
time.h
ZSTD_DCtx_s::prefixStart
const void * prefixStart
Definition: zstd.c:34911
MEM_swap32
MEM_STATIC U32 MEM_swap32(U32 in)
Definition: zstd.c:1089
set_compressed
@ set_compressed
Definition: zstd.c:10835
ZSTD_entropyCompressSeqStore
MEM_STATIC size_t ZSTD_entropyCompressSeqStore(const seqStore_t *seqStorePtr, const ZSTD_entropyCTables_t *prevEntropy, ZSTD_entropyCTables_t *nextEntropy, const ZSTD_CCtx_params *cctxParams, void *dst, size_t dstCapacity, size_t srcSize, void *entropyWorkspace, size_t entropyWkspSize, int bmi2)
Definition: zstd.c:20590
ZSTD_initStats_ultra
static void ZSTD_initStats_ultra(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize)
Definition: zstd.c:30903
ZSTD_error_maxSymbolValue_tooSmall
@ ZSTD_error_maxSymbolValue_tooSmall
Definition: zstd.c:1381
ZSTD_CCtx_s::inBuffTarget
size_t inBuffTarget
Definition: zstd.c:14815
ZSTD_WORKSPACETOOLARGE_FACTOR
#define ZSTD_WORKSPACETOOLARGE_FACTOR
Definition: zstd.c:10999
ZSTD_c_minMatch
@ ZSTD_c_minMatch
Definition: zstd.h:373
ZSTDMT_jobDescription::consumed
size_t consumed
Definition: zstd.c:31636
ZSTD_buildBlockEntropyStats_sequences
static size_t ZSTD_buildBlockEntropyStats_sequences(const seqStore_t *seqStorePtr, const ZSTD_fseCTables_t *prevEntropy, ZSTD_fseCTables_t *nextEntropy, const ZSTD_CCtx_params *cctxParams, ZSTD_fseCTablesMetadata_t *fseMetadata, void *workspace, size_t wkspSize)
Definition: zstd.c:21238
MaxML
#define MaxML
Definition: zstd.c:10844
COVER_dictSelection::totalCompressedSize
size_t totalCompressedSize
Definition: zstd.c:40484
is_streaming
@ is_streaming
Definition: zstd.c:35389
ldmMatchCandidate_t::bucket
ldmEntry_t * bucket
Definition: zstd.c:14640
ZSTD_initCStream_internal
size_t ZSTD_initCStream_internal(ZSTD_CStream *zcs, const void *dict, size_t dictSize, const ZSTD_CDict *cdict, const ZSTD_CCtx_params *params, unsigned long long pledgedSrcSize)
Definition: zstd.c:23385
ZSTD_CCtx_params_s::deterministicRefPrefix
int deterministicRefPrefix
Definition: zstd.c:14715
ZSTD_DCtx
struct ZSTD_DCtx_s ZSTD_DCtx
Definition: zstd.h:282
prime8bytes
static const U64 prime8bytes
Definition: zstd.c:15187
ZDICT_trainFromBuffer_unsafe_legacy
static size_t ZDICT_trainFromBuffer_unsafe_legacy(void *dictBuffer, size_t maxDictSize, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_legacy_params_t params)
Definition: zstd.c:45520
ZSTD_DCtx_s::dictEnd
const void * dictEnd
Definition: zstd.c:34913
MEM_readLE16
MEM_STATIC U16 MEM_readLE16(const void *memPtr)
Definition: zstd.c:1135
ZSTDMT_waitForLdmComplete
static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx *mtctx, buffer_t buffer)
Definition: zstd.c:32598
FSE_peekSymbol
MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t *DStatePtr)
Definition: zstd.c:2725
OFFSET_TO_OFFBASE
#define OFFSET_TO_OFFBASE(o)
Definition: zstd.c:15005
HUF_ReadDTableX1_Workspace::statsWksp
U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]
Definition: zstd.c:33220
ZSTD_reset_parameters
@ ZSTD_reset_parameters
Definition: zstd.h:556
detail::mod
auto mod(T x, int y) -> T
Definition: chrono.h:1652
ZSTD_blockState_t::nextCBlock
ZSTD_compressedBlockState_t * nextCBlock
Definition: zstd.c:14627
ZSTD_cwksp::allocFailed
BYTE allocFailed
Definition: zstd.c:13703
ZSTD_getDDict
static ZSTD_DDict const * ZSTD_getDDict(ZSTD_DCtx *dctx)
Definition: zstd.c:36507
ZSTDMT_jobDescription::src
range_t src
Definition: zstd.c:31646
ERR_isError
ERR_STATIC unsigned ERR_isError(size_t code)
Definition: zstd.c:1448
HIST_count_parallel_wksp
static size_t HIST_count_parallel_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, HIST_checkInput_e check, U32 *const workSpace)
Definition: zstd.c:11931
ZSTD_CCtx_s::isFirstBlock
int isFirstBlock
Definition: zstd.c:14796
ZSTD_ldm_gear_feed
static size_t ZSTD_ldm_gear_feed(ldmRollingHashState_t *state, BYTE const *data, size_t size, size_t *splits, unsigned *numSplits)
Definition: zstd.c:28892
FSE_optimalTableLog
FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
Definition: zstd.c:11609
xxh_u8
unsigned char xxh_u8
Definition: zstd.c:6483
divbwt
int divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char *num_indexes, int *indexes, int openMP)
Definition: zstd.c:43741
ZDICT_addEntropyTablesFromBuffer
ZDICTLIB_STATIC_API size_t ZDICT_addEntropyTablesFromBuffer(void *dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples)
Definition: zstd.c:45667
ZSTD_hufCTablesMetadata_t::hufDesSize
size_t hufDesSize
Definition: zstd.c:14462
U16
unsigned short U16
Definition: zstd.c:911
ZSTD_DCtx_refDDict
size_t ZSTD_DCtx_refDDict(ZSTD_DCtx *dctx, const ZSTD_DDict *ddict)
Definition: zstd.c:37104
HUF_isError
#define HUF_isError
Definition: zstd.c:32940
XXH64_update
#define XXH64_update
syncPoint_t
Definition: zstd.c:32675
ZSTD_tfp_forCCtx
@ ZSTD_tfp_forCCtx
Definition: zstd.c:14851
nonstd::span_lite::ssize
span_constexpr std::ptrdiff_t ssize(span< T, Extent > const &spn)
Definition: span.hpp:1560
COVER_groupBy
static void COVER_groupBy(const void *data, size_t count, size_t size, COVER_ctx_t *ctx, int(*cmp)(COVER_ctx_t *, const void *, const void *), void(*grp)(COVER_ctx_t *, const void *, const void *))
Definition: zstd.c:40865
ZSTD_DCtx_s::outStart
size_t outStart
Definition: zstd.c:34954
BIT_CStream_t::bitPos
unsigned bitPos
Definition: zstd.c:2050
ZSTD_count_2segments
MEM_STATIC size_t ZSTD_count_2segments(const BYTE *ip, const BYTE *match, const BYTE *iEnd, const BYTE *mEnd, const BYTE *iStart)
Definition: zstd.c:15144
repcodes_s
Definition: zstd.c:15101
ZSTD_adjustCParams
ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
Definition: zstd.c:19196
ZSTD_decompressSequences_bodySplitLitBuffer
FORCE_INLINE_TEMPLATE size_t DONT_VECTORIZE ZSTD_decompressSequences_bodySplitLitBuffer(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, const int frame)
Definition: zstd.c:39060
ZSTD_defaultCLevel
int ZSTD_defaultCLevel(void)
Definition: zstd.c:24649
rawSeqStore_t
Definition: zstd.c:14508
seqStore_t::mlCode
BYTE * mlCode
Definition: zstd.c:11037
ZSTD_row_fillHashCache
FORCE_INLINE_TEMPLATE void ZSTD_row_fillHashCache(ZSTD_matchState_t *ms, const BYTE *base, U32 const rowLog, U32 const mls, U32 idx, const BYTE *const iLimit)
Definition: zstd.c:27352
ZSTD_matchState_t::hashSalt
U64 hashSalt
Definition: zstd.c:14595
ZSTD_nextSrcSizeToDecompress
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx)
Definition: zstd.c:36551
ZSTDMT_createCompressionJob
static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx *mtctx, size_t srcSize, ZSTD_EndDirective endOp)
Definition: zstd.c:32349
ZSTD_nextInputSizeHint
static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx *cctx)
Definition: zstd.c:23487
ZDICT_clockSpan
static clock_t ZDICT_clockSpan(clock_t nPrevious)
Definition: zstd.c:44629
prime4bytes
static const U32 prime4bytes
Definition: zstd.c:15167
ZSTD_pthread_cond_destroy
#define ZSTD_pthread_cond_destroy(a)
Definition: zstd.c:3912
ZSTD_DCtx_s::maxWindowSize
size_t maxWindowSize
Definition: zstd.c:34951
MaxSeq
#define MaxSeq
Definition: zstd.c:10848
ZSTD_cwksp::isStatic
ZSTD_cwksp_static_alloc_e isStatic
Definition: zstd.c:13706
ZSTD_CCtxParams_init
size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params *cctxParams, int compressionLevel)
Definition: zstd.c:18003
ZSTD_compressBegin
size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel)
Definition: zstd.c:22736
XXH_NO_INLINE
#define XXH_NO_INLINE
Definition: zstd.c:6408
FSE_buildDTable_wksp
FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize)
Definition: zstd.c:3655
sol
Definition: forward.hpp:1093
ZSTD_frameSizeInfo::nbBlocks
size_t nbBlocks
Definition: zstd.c:11082
MEM_writeLE16
MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val)
Definition: zstd.c:1145
ZSTD_compressBlock_opt_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize, const int optLevel, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:30583
ZSTD_BuildCTableWksp::wksp
U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)]
Definition: zstd.c:16440
ZSTD_BLOCKSIZE_MAX
#define ZSTD_BLOCKSIZE_MAX
Definition: zstd.h:143
FSE_TABLELOG_ABSOLUTE_MAX
#define FSE_TABLELOG_ABSOLUTE_MAX
Definition: zstd.c:2817
ZSTD_error_frameParameter_unsupported
@ ZSTD_error_frameParameter_unsupported
Definition: zstd.c:1368
XXH_aligned
@ XXH_aligned
Definition: zstd.c:6713
MINMATCH
#define MINMATCH
Definition: zstd.c:10839
HUF_fillDTableX2
static void HUF_fillDTableX2(HUF_DEltX2 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 *rankStart, rankValCol_t *rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline)
Definition: zstd.c:33941
STREAM_ACCUMULATOR_MIN
#define STREAM_ACCUMULATOR_MIN
Definition: zstd.c:2038
ZSTD_estimateCDictSize
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
Definition: zstd.c:22937
DEFAULT_ACCEL
#define DEFAULT_ACCEL
Definition: zstd.c:43827
BIT_closeCStream
MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC)
Definition: zstd.c:2223
ZDICT_trainBuffer_legacy
static size_t ZDICT_trainBuffer_legacy(dictItem *dictList, U32 dictListSize, const void *const buffer, size_t bufferSize, const size_t *fileSizes, unsigned nbFiles, unsigned minRatio, U32 notificationLevel)
Definition: zstd.c:45013
ZDICT_params_t::compressionLevel
int compressionLevel
Definition: zstd.c:40157
ZSTDds_checkChecksum
@ ZSTDds_checkChecksum
Definition: zstd.c:34867
BIT_readBits
MEM_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, unsigned nbBits)
Definition: zstd.c:2349
RANK_POSITION_DISTINCT_COUNT_CUTOFF
#define RANK_POSITION_DISTINCT_COUNT_CUTOFF
Definition: zstd.c:12548
Litbits
#define Litbits
Definition: zstd.c:10841
ss_swapmerge
static void ss_swapmerge(const unsigned char *T, const int *PA, int *first, int *middle, int *last, int *buf, int bufsize, int depth)
Definition: zstd.c:42609
trbudget_init
static INLINE void trbudget_init(trbudget_t *budget, int chance, int incval)
Definition: zstd.c:42915
ZSTD_dictAndWindowLog
static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
Definition: zstd.c:19065
BUCKET_BSTAR
#define BUCKET_BSTAR(_c0, _c1)
Definition: zstd.c:41996
ZSTD_compress_usingCDict_advanced
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict, ZSTD_frameParameters fParams)
Definition: zstd.c:23298
S32
signed int S32
Definition: zstd.c:917
ZDICT_cover_params_t::d
unsigned d
Definition: zstd.c:40249
ldmEntry_t::checksum
U32 checksum
Definition: zstd.c:14633
ZSTD_maxCLevel
int ZSTD_maxCLevel(void)
Definition: zstd.c:24647
ZSTD_hash6PtrS
static size_t ZSTD_hash6PtrS(const void *p, U32 h, U64 s)
Definition: zstd.c:15180
DefaultMaxOff
#define DefaultMaxOff
Definition: zstd.c:10846
roundBuff_t
Definition: zstd.c:31799
bt_rle
@ bt_rle
Definition: zstd.c:10827
FASTCOVER_ctx_t::nbTrainSamples
size_t nbTrainSamples
Definition: zstd.c:43912
optState_t::offCodeSum
U32 offCodeSum
Definition: zstd.c:14547
ZSTDcs_ending
@ ZSTDcs_ending
Definition: zstd.c:14413
arg
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1875
ZSTD_DDictHashSet
Definition: zstd.c:34880
HUF_DECODE_SYMBOLX1_2
#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr)
Definition: zstd.c:33377
ZSTD_DCtx_s::HUFptr
const HUF_DTable * HUFptr
Definition: zstd.c:34907
FASTCOVER_ctx_t::accelParams
FASTCOVER_accel_t accelParams
Definition: zstd.c:43918
ZSTD_buildFSETable
void ZSTD_buildFSETable(ZSTD_seqSymbol *dt, const short *normalizedCounter, unsigned maxSymbolValue, const U32 *baseValue, const U8 *nbAdditionalBits, unsigned tableLog, void *wksp, size_t wkspSize, int bmi2)
Definition: zstd.c:38304
XXH_alignment
XXH_alignment
Definition: xxhash.c:232
rankPos
Definition: zstd.c:12523
ZSTD_DCtx_s::forceIgnoreChecksum
ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum
Definition: zstd.c:34925
ZSTD_row_getMatchMask
FORCE_INLINE_TEMPLATE ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE *const tagRow, const BYTE tag, const U32 headGrouped, const U32 rowEntries)
Definition: zstd.c:27570
ZSTD_prefixDict_s
Definition: zstd.c:14416
COVER_map_at
static U32 * COVER_map_at(COVER_map_t *map, U32 key)
Definition: zstd.c:40706
nodeElt_s::byte
BYTE byte
Definition: zstd.c:12098
FASTCOVER_MAX_SAMPLES_SIZE
#define FASTCOVER_MAX_SAMPLES_SIZE
Definition: zstd.c:43822
ZSTD_c_windowLog
@ ZSTD_c_windowLog
Definition: zstd.h:347
optState_t::matchLengthSum
U32 matchLengthSum
Definition: zstd.c:14546
PREFETCH_L1
#define PREFETCH_L1(ptr)
Definition: zstd.c:627
ZSTD_CCtx_s::streamStage
ZSTD_cStreamStage streamStage
Definition: zstd.c:14820
ZSTD_btultra2
@ ZSTD_btultra2
Definition: zstd.h:325
ZSTD_initCStream
size_t ZSTD_initCStream(ZSTD_CStream *zcs, int compressionLevel)
Definition: zstd.c:23476
ZSTD_isFrame
unsigned ZSTD_isFrame(const void *buffer, size_t size)
Definition: zstd.c:35734
ZSTD_dtlm_fast
@ ZSTD_dtlm_fast
Definition: zstd.c:14850
ZSTD_compressBlock_btultra_dictMatchState
size_t ZSTD_compressBlock_btultra_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30971
XXH_OK
#define XXH_OK
XXH64_hash_t
unsigned long long XXH64_hash_t
Definition: zstd.c:5577
ZSTD_dictUses_e
ZSTD_dictUses_e
Definition: zstd.c:34873
COVER_cmp8
static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp)
Definition: zstd.c:40805
ERR_enum
ZSTD_ErrorCode ERR_enum
Definition: zstd.c:1437
ZSTD_dedicatedDictSearch_getCParams
static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize)
Definition: zstd.c:24651
ZSTD_setRleBlock
static size_t ZSTD_setRleBlock(void *dst, size_t dstCapacity, BYTE b, size_t regenSize)
Definition: zstd.c:36254
ZDICT_trainFromBuffer_legacy
ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_legacy_params_t parameters)
Definition: zstd.c:45626
rawSeqStore_t::posInSequence
size_t posInSequence
Definition: zstd.c:14511
ZSTD_CCtx_refCDict
size_t ZSTD_CCtx_refCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict)
Definition: zstd.c:18954
ZSTD_compressBegin_usingDict
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:22731
ZSTDMT_computeTargetJobLog
static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params *params)
Definition: zstd.c:32150
XXH_PROCESS4
#define XXH_PROCESS4
ZSTD_isRLE
static int ZSTD_isRLE(const BYTE *src, size_t length)
Definition: zstd.c:21051
ZSTD_decodeSeqHeaders
size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, size_t srcSize)
Definition: zstd.c:38373
ZSTD_compressBlock_btlazy2_extDict
size_t ZSTD_compressBlock_btlazy2_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28659
ZSTD_CCtx_params_s::useRowMatchFinder
ZSTD_paramSwitch_e useRowMatchFinder
Definition: zstd.c:14712
ZSTD_sizeof_DDict
size_t ZSTD_sizeof_DDict(const ZSTD_DDict *ddict)
Definition: zstd.c:35266
checkMaxSymbolValue
@ checkMaxSymbolValue
Definition: zstd.c:11921
ZSTD_DCtx_s::entropy
ZSTD_entropyDTables_t entropy
Definition: zstd.c:34908
XXH_get64bits
#define XXH_get64bits(p)
Definition: zstd.c:7350
ZSTD_createDCtx_internal
static ZSTD_DCtx * ZSTD_createDCtx_internal(ZSTD_customMem customMem)
Definition: zstd.c:35643
POOL_job_s::opaque
void * opaque
Definition: zstd.c:4312
U32
unsigned int U32
Definition: lz4.c:314
syncPoint_t::toLoad
size_t toLoad
Definition: zstd.c:32676
COVER_best_s::dict
void * dict
Definition: zstd.c:40455
MEM_write32
MEM_STATIC void MEM_write32(void *memPtr, U32 value)
Definition: zstd.c:1069
HUF_ASM_DECL
#define HUF_ASM_DECL
Definition: zstd.c:32929
ZSTDMT_resize
static size_t ZSTDMT_resize(ZSTDMT_CCtx *mtctx, unsigned nbWorkers)
Definition: zstd.c:32044
ZSTD_cwksp_slack_space_required
MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void)
Definition: zstd.c:13783
ZSTD_error_maxSymbolValue_tooLarge
@ ZSTD_error_maxSymbolValue_tooLarge
Definition: zstd.c:1380
FSE_NCountWriteBound
FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
Definition: zstd.c:11462
SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE
#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE
Definition: zstd.c:13266
BIT_DStream_completed
@ BIT_DStream_completed
Definition: zstd.c:2092
HUF_WriteCTableWksp::bitsToWeight
BYTE bitsToWeight[HUF_TABLELOG_MAX+1]
Definition: zstd.c:12273
ZSTD_DCtx_s::fseEntropy
U32 fseEntropy
Definition: zstd.c:34921
HUF_decompress4X2_DCtx_wksp
static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:34575
blockProperties_t::blockType
blockType_e blockType
Definition: zstd.c:11099
ldmParams_t::hashLog
U32 hashLog
Definition: zstd.c:14656
repStartValue
static const UNUSED_ATTR U32 repStartValue[ZSTD_REP_NUM]
Definition: zstd.c:10806
ZSTD_cpm_createCDict
@ ZSTD_cpm_createCDict
Definition: zstd.c:14869
serialState_t::params
ZSTD_CCtx_params params
Definition: zstd.c:31455
ZSTD_cParameter
ZSTD_cParameter
Definition: zstd.h:328
CHECK_F
#define CHECK_F(f)
Definition: zstd.c:1454
optState_t::litLengthSum
U32 litLengthSum
Definition: zstd.c:14545
ZSTD_cwksp::phase
ZSTD_cwksp_alloc_phase_e phase
Definition: zstd.c:13705
ZSTD_blockHeaderSize
static const UNUSED_ATTR size_t ZSTD_blockHeaderSize
Definition: zstd.c:10826
seqStore_t::longLengthPos
U32 longLengthPos
Definition: zstd.c:11047
ZSTD_createCDict
ZSTD_CDict * ZSTD_createCDict(const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:23108
ZSTD_blockState_t
Definition: zstd.c:14625
COVER_ctx_t::samples
const BYTE * samples
Definition: zstd.c:40760
ZSTDMT_bufferPool_s::poolMutex
ZSTD_pthread_mutex_t poolMutex
Definition: zstd.c:31095
tr_introsort
static void tr_introsort(int *ISA, const int *ISAd, int *SA, int *first, int *last, trbudget_t *budget)
Definition: zstd.c:43040
FSE_writeNCount_generic
static size_t FSE_writeNCount_generic(void *header, size_t headerBufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, unsigned writeIsSafe)
Definition: zstd.c:11473
detail::fp
basic_fp< unsigned long long > fp
Definition: format.h:1663
ZDICT_cover_params_t
Definition: zstd.c:40247
FASTCOVER_accel_t::skip
unsigned skip
Definition: zstd.c:43885
POOL_ctx_s::queueMutex
ZSTD_pthread_mutex_t queueMutex
Definition: zstd.c:4334
EStats_ress_t::workPlace
void * workPlace
Definition: zstd.c:45103
ZSTD_decompress_insertDictionary
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
Definition: zstd.c:36864
HUF_decodeLastSymbolX2
FORCE_INLINE_TEMPLATE U32 HUF_decodeLastSymbolX2(void *op, BIT_DStream_t *DStream, const HUF_DEltX2 *dt, const U32 dtLog)
Definition: zstd.c:34092
zdss_load
@ zdss_load
Definition: zstd.c:34871
ZDICT_MAX_SAMPLES_SIZE
#define ZDICT_MAX_SAMPLES_SIZE
Definition: zstd.c:44564
rawSeq::litLength
U32 litLength
Definition: zstd.c:14504
COVER_dictSelection::dictContent
BYTE * dictContent
Definition: zstd.c:40482
FSE_NCOUNTBOUND
#define FSE_NCOUNTBOUND
Definition: zstd.c:2434
ZSTD_optLdm_t::endPosInBlock
U32 endPosInBlock
Definition: zstd.c:30421
ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize
static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t *seqStore, ZSTD_CCtx *zc)
Definition: zstd.c:21427
HUF_CStream_t::bitPos
size_t bitPos[2]
Definition: zstd.c:12860
COVER_map_init
static int COVER_map_init(COVER_map_t *map, U32 size)
Definition: zstd.c:40662
ZSTDMT_createJobsTable
static ZSTDMT_jobDescription * ZSTDMT_createJobsTable(U32 *nbJobsPtr, ZSTD_customMem cMem)
Definition: zstd.c:31874
ZSTD_fastSequenceLengthSum
static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const *seqBuf, size_t seqBufSize)
Definition: zstd.c:20772
ZSTD_CCtx_params_s::compressionLevel
int compressionLevel
Definition: zstd.c:14675
ZSTD_totalLen
static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
Definition: zstd.c:30560
ZSTD_compressedBlockState_t
Definition: zstd.c:14557
mqtt_test_proto.x
x
Definition: mqtt_test_proto.py:34
FASTCOVER_accel_t
Definition: zstd.c:43883
ZSTD_cwksp_bytes_to_align_ptr
MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void *ptr, const size_t alignBytes)
Definition: zstd.c:13796
ZSTD_CCtx_s::inBuffSize
size_t inBuffSize
Definition: zstd.c:14812
ZSTD_MLcode
MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
Definition: zstd.c:14903
ZDICT_optimizeTrainFromBuffer_fastCover
ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_fastCover_params_t *parameters)
Definition: zstd.c:44398
ZSTD_compressStream
size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
Definition: zstd.c:23699
ZSTD_CCtx_refPrefix
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx *cctx, const void *prefix, size_t prefixSize)
Definition: zstd.c:18972
ZSTD_btGetAllMatches_internal
FORCE_INLINE_TEMPLATE U32 ZSTD_btGetAllMatches_internal(ZSTD_match_t *matches, ZSTD_matchState_t *ms, U32 *nextToUpdate3, const BYTE *ip, const BYTE *const iHighLimit, const U32 rep[ZSTD_REP_NUM], U32 const ll0, U32 const lengthToBeat, const ZSTD_dictMode_e dictMode, const U32 mls)
Definition: zstd.c:30341
COVER_ctx_t::nbTrainSamples
size_t nbTrainSamples
Definition: zstd.c:40764
bufferToSeq
static rawSeqStore_t bufferToSeq(buffer_t buffer)
Definition: zstd.c:31282
ZSTD_downscaleStats
static U32 ZSTD_downscaleStats(unsigned *table, U32 lastEltIndex, U32 shift, base_directive_e base1)
Definition: zstd.c:29624
ZSTD_decompressSequencesLong
static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, const int frame)
Definition: zstd.c:39669
ZSTD_seqDecompressedSize
static size_t ZSTD_seqDecompressedSize(seqStore_t const *seqStore, const seqDef *sequences, size_t nbSeq, size_t litSize, int lastSequence)
Definition: zstd.c:16807
base_directive_e
base_directive_e
Definition: zstd.c:29621
U64
unsigned long long U64
Definition: zstd.c:920
tr_pivot
static INLINE int * tr_pivot(const int *ISAd, int *first, int *last)
Definition: zstd.c:42880
ZSTD_window_t::nbOverflowCorrections
U32 nbOverflowCorrections
Definition: zstd.c:14568
ZSTD_cwksp::workspaceEnd
void * workspaceEnd
Definition: zstd.c:13695
ZSTD_DCtx_s::outBufferMode
ZSTD_bufferMode_e outBufferMode
Definition: zstd.c:34964
ZSTD_CCtx_s::ldmState
ldmState_t ldmState
Definition: zstd.c:14800
ZSTD_copySequencesToSeqStoreNoBlockDelim
size_t ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx *cctx, ZSTD_sequencePosition *seqPos, const ZSTD_Sequence *const inSeqs, size_t inSeqsSize, const void *src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch)
Definition: zstd.c:24118
HUF_STATIC_ASSERT
#define HUF_STATIC_ASSERT(c)
Definition: zstd.c:12089
ZSTD_hufCTables_t
Definition: zstd.c:14430
ZSTD_CCtx_s::stableIn_notConsumed
size_t stableIn_notConsumed
Definition: zstd.c:14825
XXH128_isEqual
#define XXH128_isEqual
symbolEncodingType_e
symbolEncodingType_e
Definition: zstd.c:10835
ZSTDMT_releaseBuffer
static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool *bufPool, buffer_t buf)
Definition: zstd.c:31244
ZSTD_DCtx_s::noForwardProgress
int noForwardProgress
Definition: zstd.c:34963
sol::meta_function::index
@ index
ZSTD_MAX_NB_BLOCK_SPLITS
#define ZSTD_MAX_NB_BLOCK_SPLITS
Definition: zstd.c:14756
ZSTDMT_nextInputSizeHint
size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32783
ML_base
static const UNUSED_ATTR U32 ML_base[MaxML+1]
Definition: zstd.c:34825
ZSTD_cStreamStage
ZSTD_cStreamStage
Definition: zstd.c:14414
seqStoreSplits::idx
size_t idx
Definition: zstd.c:21655
base_0possible
@ base_0possible
Definition: zstd.c:29621
ZSTDMT_computeOverlapSize
static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params *params)
Definition: zstd.c:32192
HUF_DTable
U32 HUF_DTable
Definition: zstd.c:2901
HUF_ReadDTableX2_Workspace::rankStats
U32 rankStats[HUF_TABLELOG_MAX+1]
Definition: zstd.c:33989
ZSTD_split
@ ZSTD_split
Definition: zstd.c:34899
ZSTD_CWKSP_ALIGNMENT_BYTES
#define ZSTD_CWKSP_ALIGNMENT_BYTES
Definition: zstd.c:13577
ZSTD_DDict_dictContent
const void * ZSTD_DDict_dictContent(const ZSTD_DDict *ddict)
Definition: zstd.c:35082
ZSTD_bounds::upperBound
int upperBound
Definition: zstd.h:512
ZSTD_NO_CLEVEL
#define ZSTD_NO_CLEVEL
Definition: zstd.c:18011
rankPos::curr
U16 curr
Definition: zstd.c:12525
HUF_repeat_none
@ HUF_repeat_none
Definition: zstd.c:2977
HUF_CTABLE_WORKSPACE_SIZE_U32
#define HUF_CTABLE_WORKSPACE_SIZE_U32
Definition: zstd.c:2998
detail::in
constexpr auto in(type t, int set) -> bool
Definition: core.h:628
HUF_decodeSymbolX2
FORCE_INLINE_TEMPLATE U32 HUF_decodeSymbolX2(void *op, BIT_DStream_t *DStream, const HUF_DEltX2 *dt, const U32 dtLog)
Definition: zstd.c:34083
FASTCOVER_ctx_t
Definition: zstd.c:43907
GEN_ZSTD_BT_GET_ALL_MATCHES
#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode)
Definition: zstd.c:30379
ZSTD_DCtx_loadDictionary
size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
Definition: zstd.c:37044
HUF_decompress4X_usingDTable
size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable, int flags)
Definition: zstd.c:34713
ZDICT_cover_params_t::k
unsigned k
Definition: zstd.c:40248
ZSTD_entropyCTablesMetadata_t::hufMetadata
ZSTD_hufCTablesMetadata_t hufMetadata
Definition: zstd.c:14478
ZSTD_dictTableLoadMethod_e
ZSTD_dictTableLoadMethod_e
Definition: zstd.c:14850
ML_bits
static const UNUSED_ATTR U8 ML_bits[MaxML+1]
Definition: zstd.c:10877
XXH_rotl32
#define XXH_rotl32(x, r)
Definition: zstd.c:6677
XXH64_digest
#define XXH64_digest
MEM_check
MEM_STATIC void MEM_check(void)
Definition: zstd.c:1266
XXH_PRIME32_5
#define XXH_PRIME32_5
Definition: zstd.c:6786
ZSTD_CCtxParams_init_advanced
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params *cctxParams, ZSTD_parameters params)
Definition: zstd.c:18040
ZSTD_no_overlap
@ ZSTD_no_overlap
Definition: zstd.c:10944
BUF_POOL_MAX_NB_BUFFERS
#define BUF_POOL_MAX_NB_BUFFERS(nbWorkers)
Definition: zstd.c:31267
MEM_writeLE32
MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32)
Definition: zstd.c:1175
ZSTD_freeCCtxContent
static void ZSTD_freeCCtxContent(ZSTD_CCtx *cctx)
Definition: zstd.c:17807
HUF_decompress4X1_usingDTable_internal_fast_c_loop
static HUF_FAST_BMI2_ATTRS void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs *args)
Definition: zstd.c:33556
ZSTDds_skipFrame
@ ZSTDds_skipFrame
Definition: zstd.c:34868
ZSTD_window_enforceMaxDist
MEM_STATIC void ZSTD_window_enforceMaxDist(ZSTD_window_t *window, const void *blockEnd, U32 maxDist, U32 *loadedDictEndPtr, const ZSTD_matchState_t **dictMatchStatePtr)
Definition: zstd.c:15517
LLFSELog
#define LLFSELog
Definition: zstd.c:10850
XXH32_update
#define XXH32_update
ZSTD_CCtx_s::staticSize
size_t staticSize
Definition: zstd.c:14794
FASTCOVER_checkParameters
static int FASTCOVER_checkParameters(ZDICT_cover_params_t parameters, size_t maxDictSize, unsigned f, unsigned accel)
Definition: zstd.c:44009
ZSTD_CCtx_setPledgedSrcSize
size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx *cctx, unsigned long long pledgedSrcSize)
Definition: zstd.c:18856
ZSTD_makeCCtxParamsFromCParams
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(ZSTD_compressionParameters cParams)
Definition: zstd.c:17948
ZSTD_initStaticDDict
const ZSTD_DDict * ZSTD_initStaticDDict(void *sBuffer, size_t sBufferSize, const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:35223
ZSTD_DCtx_s::inBuffSize
size_t inBuffSize
Definition: zstd.c:34949
ZSTD_optLdm_maybeAddMatch
static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t *matches, U32 *nbMatches, const ZSTD_optLdm_t *optLdm, U32 currPosInBlock)
Definition: zstd.c:30505
ZSTD_fcs_fieldSize
static const UNUSED_ATTR size_t ZSTD_fcs_fieldSize[4]
Definition: zstd.c:10820
ZSTD_cwksp_reserve_internal_buffer_space
MEM_STATIC void * ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp *ws, size_t const bytes)
Definition: zstd.c:13820
ZSTD_compressSubBlock_literal
static size_t ZSTD_compressSubBlock_literal(const HUF_CElt *hufTable, const ZSTD_hufCTablesMetadata_t *hufMetadata, const BYTE *literals, size_t litSize, void *dst, size_t dstSize, const int bmi2, int writeEntropy, int *entropyWritten)
Definition: zstd.c:16720
XXH3_64bits_update
#define XXH3_64bits_update
COVER_checkTotalCompressedSize
size_t COVER_checkTotalCompressedSize(const ZDICT_cover_params_t parameters, const size_t *samplesSizes, const BYTE *samples, size_t *offsets, size_t nbTrainSamples, size_t nbSamples, BYTE *const dict, size_t dictBufferCapacity)
Definition: zstd.c:41334
sort_typeBstar
static int sort_typeBstar(const unsigned char *T, int *SA, int *bucket_A, int *bucket_B, int n, int openMP)
Definition: zstd.c:43306
ZSTD_hufCTables_t::repeatMode
HUF_repeat repeatMode
Definition: zstd.c:14432
error
static l_noret error(LoadState *S, const char *why)
Definition: lundump.c:40
ALPHABET_SIZE
#define ALPHABET_SIZE
Definition: zstd.c:41921
XXH3_copyState
#define XXH3_copyState
FSE_DTABLE_SIZE
#define FSE_DTABLE_SIZE(maxTableLog)
Definition: zstd.c:2444
STACK_PUSH5
#define STACK_PUSH5(_a, _b, _c, _d, _e)
Definition: zstd.c:41973
POOL_job
struct POOL_job_s POOL_job
ZSTDMT_seqPool
ZSTDMT_bufferPool ZSTDMT_seqPool
Definition: zstd.c:31275
XXH32_createState
#define XXH32_createState
Allocates an XXH32_state_t.
Definition: zstd.c:7034
STACK_POP5
#define STACK_POP5(_a, _b, _c, _d, _e)
Definition: zstd.c:41986
ZSTD_BtFindBestMatch
FORCE_INLINE_TEMPLATE size_t ZSTD_BtFindBestMatch(ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iLimit, size_t *offBasePtr, const U32 mls, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:26915
ZSTDMT_bufferPool_s::bTable
buffer_t bTable[1]
Definition: zstd.c:31100
ZSTD_CCtx_params_s
Definition: zstd.c:14670
ZSTD_CDict_s::dictID
U32 dictID
Definition: zstd.c:17727
HUF_initRemainingDStream
static size_t HUF_initRemainingDStream(BIT_DStream_t *bit, HUF_DecompressFastArgs const *args, int stream, BYTE *segmentEnd)
Definition: zstd.c:33139
HUF_decompress4X2_usingDTable_internal_fast_c_loop
static HUF_FAST_BMI2_ATTRS void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs *args)
Definition: zstd.c:34336
ZSTD_cwksp::workspaceOversizedDuration
int workspaceOversizedDuration
Definition: zstd.c:13704
ZDICT_fastCover_params_t
Definition: zstd.c:40258
ZSTD_prefixDict
struct ZSTD_prefixDict_s ZSTD_prefixDict
ZSTD_initDStream_usingDict
size_t ZSTD_initDStream_usingDict(ZSTD_DStream *zds, const void *dict, size_t dictSize)
Definition: zstd.c:37065
DDICT_HASHSET_TABLE_BASE_SIZE
#define DDICT_HASHSET_TABLE_BASE_SIZE
Definition: zstd.c:35440
ZSTD_fseCTablesMetadata_t
Definition: zstd.c:14468
ZSTD_FRAMEIDSIZE
#define ZSTD_FRAMEIDSIZE
Definition: zstd.c:10823
COVER_map_s::size
U32 size
Definition: zstd.c:40645
ZSTD_DCtx_s::ddictLocal
ZSTD_DDict * ddictLocal
Definition: zstd.c:34937
ZSTD_setBasePrices
static void ZSTD_setBasePrices(optState_t *optPtr, int optLevel)
Definition: zstd.c:29601
ZSTDMT_sizeof_CCtx
size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32028
ZSTD_error_noForwardProgress_destFull
@ ZSTD_error_noForwardProgress_destFull
Definition: zstd.c:1390
ZSTDMT_CCtx_s::jobIDMask
unsigned jobIDMask
Definition: zstd.c:31846
repcodes_s::rep
U32 rep[3]
Definition: zstd.c:15102
HUF_DECOMPRESS_WORKSPACE_SIZE
#define HUF_DECOMPRESS_WORKSPACE_SIZE
Definition: zstd.c:3059
noDict
@ noDict
Definition: lz4.c:721
ZSTD_DCtx_s::dictID
U32 dictID
Definition: zstd.c:34939
XXH64_freeState
#define XXH64_freeState
ZSTD_CCtx_params_s::validateSequences
int validateSequences
Definition: zstd.c:14706
xxh_u32
XXH32_hash_t xxh_u32
Definition: zstd.c:6485
ZSTD_DDictHashSet_expand
static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet *hashSet, ZSTD_customMem customMem)
Definition: zstd.c:35482
ZSTD_compressSeqStore_singleBlock
static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx *zc, const seqStore_t *const seqStore, repcodes_t *const dRep, repcodes_t *const cRep, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastBlock, U32 isPartition)
Definition: zstd.c:21584
XXH3_freeState
#define XXH3_freeState
ZSTDMT_CCtx_s::allJobsCompleted
unsigned allJobsCompleted
Definition: zstd.c:31850
sol::thread
basic_thread< reference > thread
Definition: forward.hpp:1212
KB
#define KB
Definition: zstd.c:44610
ZSTD_freeDDict
size_t ZSTD_freeDDict(ZSTD_DDict *ddict)
Definition: zstd.c:35248
FSE_decode_t
Definition: zstd.c:2709
ZSTD_compress_usingCDict
size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict)
Definition: zstd.c:23311
construct_SA
static void construct_SA(const unsigned char *T, int *SA, int *bucket_A, int *bucket_B, int n, int m)
Definition: zstd.c:43478
HUF_readDTableX2_wksp
size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:33996
ZSTD_defaultAllowed
@ ZSTD_defaultAllowed
Definition: zstd.c:16179
ZSTD_compressBlock_opt0
static size_t ZSTD_compressBlock_opt0(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:30872
ZSTD_compResetPolicy_e
ZSTD_compResetPolicy_e
Definition: zstd.c:19533
HUF_ReadDTableX1_Workspace::rankStart
U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX+1]
Definition: zstd.c:33219
ZSTD_WINDOWLOG_ABSOLUTEMIN
#define ZSTD_WINDOWLOG_ABSOLUTEMIN
Definition: zstd.c:10819
ZSTDMT_getSeq
static rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool *seqPool)
Definition: zstd.c:31298
ZSTD_compress_usingDict
size_t ZSTD_compress_usingDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:22873
ZSTD_DCtx_s::litEntropy
U32 litEntropy
Definition: zstd.c:34920
optState_t::priceType
ZSTD_OptPrice_e priceType
Definition: zstd.c:14552
ZSTD_CCtx_setFParams
size_t ZSTD_CCtx_setFParams(ZSTD_CCtx *cctx, ZSTD_frameParameters fparams)
Definition: zstd.c:18834
ZSTD_createCDict_byReference
ZSTD_CDict * ZSTD_createCDict_byReference(const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:23119
ZSTD_finalizeOffBase
static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0)
Definition: zstd.c:24015
serialState_t::mutex
ZSTD_pthread_mutex_t mutex
Definition: zstd.c:31453
COVER_best_t
struct COVER_best_s COVER_best_t
ZSTD_getDictID_fromDict
unsigned ZSTD_getDictID_fromDict(const void *dict, size_t dictSize)
Definition: zstd.c:36948
ZSTD_pthread_mutex_init
#define ZSTD_pthread_mutex_init(a, b)
Definition: zstd.c:3905
HUF_buildCTable_wksp_tables::rankPosition
rankPos rankPosition[RANK_POSITION_TABLE_SIZE]
Definition: zstd.c:12535
construct_BWT_indexes
static int construct_BWT_indexes(const unsigned char *T, int *SA, int *bucket_A, int *bucket_B, int n, int m, unsigned char *num_indexes, int *indexes)
Definition: zstd.c:43613
COVER_ctx_t::freqs
U32 * freqs
Definition: zstd.c:40768
RAWLOG
#define RAWLOG(l,...)
Definition: zstd.c:290
ZSTD_SHORT_CACHE_TAG_MASK
#define ZSTD_SHORT_CACHE_TAG_MASK
Definition: zstd.c:15734
ZSTD_DCtx_s::dictUses
ZSTD_dictUses_e dictUses
Definition: zstd.c:34941
ZSTD_rollingHash_compute
MEM_STATIC U64 ZSTD_rollingHash_compute(void const *buf, size_t size)
Definition: zstd.c:15262
ZSTD_countLeadingZeros32_fallback
MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val)
Definition: zstd.c:1872
ZSTD_compressBlock_targetCBlockSize_body
static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const size_t bss, U32 lastBlock)
Definition: zstd.c:21923
ZSTD_createCDict_advanced2
ZSTD_CDict * ZSTD_createCDict_advanced2(const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, const ZSTD_CCtx_params *originalCctxParams, ZSTD_customMem customMem)
Definition: zstd.c:23058
ZDICT_DICTSIZE_MIN
#define ZDICT_DICTSIZE_MIN
Definition: zstd.c:40239
HUF_buildCTableFromTree
static void HUF_buildCTableFromTree(HUF_CElt *CTable, nodeElt const *huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits)
Definition: zstd.c:12753
ZSTDds_decodeSkippableHeader
@ ZSTDds_decodeSkippableHeader
Definition: zstd.c:34868
mqtt_test_proto.y
y
Definition: mqtt_test_proto.py:35
FASTCOVER_ctx_t::nbSamples
size_t nbSamples
Definition: zstd.c:43911
ZSTD_outBuffer_s
Definition: zstd.h:669
ZSTDMT_CCtx_s::cdict
const ZSTD_CDict * cdict
Definition: zstd.c:31856
ZSTD_HASHLOG3_MAX
#define ZSTD_HASHLOG3_MAX
Definition: zstd.c:17694
ZSTD_VERSION_STRING
#define ZSTD_VERSION_STRING
Definition: zstd.h:119
TR_INSERTIONSORT_THRESHOLD
#define TR_INSERTIONSORT_THRESHOLD
Definition: zstd.c:41953
del
ROSCPP_DECL bool del(const std::string &key)
ZSTD_getBlockSize_deprecated
static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx *cctx)
Definition: zstd.c:22288
ZSTD_hash5Ptr
static size_t ZSTD_hash5Ptr(const void *p, U32 h)
Definition: zstd.c:15174
ZSTD_loadZstdDictionary
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t *bs, ZSTD_matchState_t *ms, ZSTD_cwksp *ws, ZSTD_CCtx_params const *params, const void *dict, size_t dictSize, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp, void *workspace)
Definition: zstd.c:22562
algo_time_t
Definition: zstd.c:34599
ZSTD_cwksp_reserve_aligned_init_once
MEM_STATIC void * ZSTD_cwksp_reserve_aligned_init_once(ZSTD_cwksp *ws, size_t bytes)
Definition: zstd.c:13937
MEM_read16
MEM_STATIC U16 MEM_read16(const void *memPtr)
Definition: zstd.c:1044
SS_BLOCKSIZE
#define SS_BLOCKSIZE
Definition: zstd.c:41942
ZSTD_createCCtxParams
ZSTD_CCtx_params * ZSTD_createCCtxParams(void)
Definition: zstd.c:17986
ZSTD_defaultPolicy_e
ZSTD_defaultPolicy_e
Definition: zstd.c:16177
ZSTD_window_canOverflowCorrect
MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window, U32 cycleLog, U32 maxDist, U32 loadedDictEnd, void const *src)
Definition: zstd.c:15360
BIT_flushBitsFast
MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC)
Definition: zstd.c:2192
ZSTD_useLowProbCount
static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
Definition: zstd.c:16258
ZSTD_symbolEncodingTypeStats_t::longOffsets
int longOffsets
Definition: zstd.c:20334
ZDICT_cover_params_t::nbThreads
unsigned nbThreads
Definition: zstd.c:40251
ZSTD_calloc
#define ZSTD_calloc(n, s)
Definition: zstd.c:111
SS_INSERTIONSORT_THRESHOLD
#define SS_INSERTIONSORT_THRESHOLD
Definition: zstd.c:41931
ZSTD_compressSubBlock
static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t *entropy, const ZSTD_entropyCTablesMetadata_t *entropyMetadata, const seqDef *sequences, size_t nbSeq, const BYTE *literals, size_t litSize, const BYTE *llCode, const BYTE *mlCode, const BYTE *ofCode, const ZSTD_CCtx_params *cctxParams, void *dst, size_t dstCapacity, const int bmi2, int writeLitEntropy, int writeSeqEntropy, int *litEntropyWritten, int *seqEntropyWritten, U32 lastBlock)
Definition: zstd.c:16941
ZSTD_DUBT_findBestMatch
static size_t ZSTD_DUBT_findBestMatch(ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iend, size_t *offBasePtr, U32 const mls, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:26764
BYTE
unsigned char BYTE
Definition: zstd.c:905
HUF_DECODE_SYMBOLX2_0
#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
Definition: zstd.c:34109
HUF_compress4X_usingCTable_internal
static size_t HUF_compress4X_usingCTable_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable, int flags)
Definition: zstd.c:13183
XXH_get32bits
#define XXH_get32bits(p)
Definition: zstd.c:6871
ZSTD_loadCEntropy
size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t *bs, void *workspace, const void *const dict, size_t dictSize)
Definition: zstd.c:22461
ZSTD_estimateBlockSize_literal
static size_t ZSTD_estimateBlockSize_literal(const BYTE *literals, size_t litSize, const ZSTD_hufCTables_t *huf, const ZSTD_hufCTablesMetadata_t *hufMetadata, void *workspace, size_t wkspSize, int writeEntropy)
Definition: zstd.c:21309
f
f
COVER_best_finish
void COVER_best_finish(COVER_best_t *best, ZDICT_cover_params_t parameters, COVER_dictSelection_t selection)
Definition: zstd.c:41448
COVER_tryParameters_data_t
struct COVER_tryParameters_data_s COVER_tryParameters_data_t
ZSTD_compressBlock_internal
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 frame)
Definition: zstd.c:21860
ZSTD_error_dictionary_corrupted
@ ZSTD_error_dictionary_corrupted
Definition: zstd.c:1373
FSE_initDState
static void FSE_initDState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD, const FSE_DTable *dt)
Definition: zstd.c:2716
HIST_checkInput_e
HIST_checkInput_e
Definition: zstd.c:11921
HIST_count
size_t HIST_count(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize)
Definition: zstd.c:12040
ZSTD_postProcessSequenceProducerResult
static size_t ZSTD_postProcessSequenceProducerResult(ZSTD_Sequence *outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize)
Definition: zstd.c:20723
ZSTD_compressBlock_btultra_extDict
size_t ZSTD_compressBlock_btultra_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30985
ZDICT_fastCover_params_t::d
unsigned d
Definition: zstd.c:40260
ZSTD_decompressBegin_usingDDict
size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx *dctx, const ZSTD_DDict *ddict)
Definition: zstd.c:36925
ZSTDMT_compressionJob
static void ZSTDMT_compressionJob(void *jobDescription)
Definition: zstd.c:31665
ZSTD_compressContinue_public
size_t ZSTD_compressContinue_public(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22272
FASTCOVER_ctx_t::d
unsigned d
Definition: zstd.c:43916
BIT_initCStream
MEM_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *dstBuffer, size_t dstCapacity)
Definition: zstd.c:2142
ZSTD_window_t::lowLimit
U32 lowLimit
Definition: zstd.c:14567
ZSTD_DDict_s::dictID
U32 dictID
Definition: zstd.c:35077
HUF_decompress4X1_usingDTable_internal_body
FORCE_INLINE_TEMPLATE size_t HUF_decompress4X1_usingDTable_internal_body(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
Definition: zstd.c:33438
ZSTD_cpuSupportsBmi2
MEM_STATIC int ZSTD_cpuSupportsBmi2(void)
Definition: zstd.c:11119
ZSTD_cwksp::workspace
void * workspace
Definition: zstd.c:13694
HUF_compress1X_usingCTable
size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable, int flags)
Definition: zstd.c:13177
FSE_decodeSymbol
static unsigned char FSE_decodeSymbol(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
Definition: zstd.c:2739
ZSTD_resetTarget_e
ZSTD_resetTarget_e
Definition: zstd.c:19548
ZSTD_LAZY_DDSS_BUCKET_LOG
#define ZSTD_LAZY_DDSS_BUCKET_LOG
Definition: zstd.c:17388
ldmState_t::hashTable
ldmEntry_t * hashTable
Definition: zstd.c:14647
XXH3_64bits_digest
#define XXH3_64bits_digest
setDictSelection
static COVER_dictSelection_t setDictSelection(BYTE *buf, size_t s, size_t csz)
Definition: zstd.c:41492
ZSTD_estimateCCtxSize_usingCCtxParams
size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params *params)
Definition: zstd.c:19337
ZSTD_frameHeaderSize_internal
static size_t ZSTD_frameHeaderSize_internal(const void *src, size_t srcSize, ZSTD_format_e format)
Definition: zstd.c:35765
streaming_operation
streaming_operation
Definition: zstd.c:35387
ZSTD_fseCTables_t::offcode_repeatMode
FSE_repeat offcode_repeatMode
Definition: zstd.c:14439
ZSTD_initDCtx_internal
static void ZSTD_initDCtx_internal(ZSTD_DCtx *dctx)
Definition: zstd.c:35602
zdss_init
@ zdss_init
Definition: zstd.c:34870
ZSTD_freeCCtx
size_t ZSTD_freeCCtx(ZSTD_CCtx *cctx)
Definition: zstd.c:17818
COVER_ctx_t::dmerAt
U32 * dmerAt
Definition: zstd.c:40769
ZSTD_cwksp_bump_oversized_duration
MEM_STATIC void ZSTD_cwksp_bump_oversized_duration(ZSTD_cwksp *ws, size_t additionalNeededSpace)
Definition: zstd.c:14264
ZSTD_CCtx_s::blockSize
size_t blockSize
Definition: zstd.c:14787
ZSTD_getCParamsFromCCtxParams
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(const ZSTD_CCtx_params *CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
Definition: zstd.c:19221
ZSTD_estimateCCtxSize_internal
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
Definition: zstd.c:19369
ZSTD_compressBlock_fast_extDict_generic
static size_t ZSTD_compressBlock_fast_extDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls, U32 const hasStep)
Definition: zstd.c:26252
ZSTD_bounds::lowerBound
int lowerBound
Definition: zstd.h:511
ZSTD_decompressBlock_internal
size_t ZSTD_decompressBlock_internal(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const int frame, const streaming_operation streaming)
Definition: zstd.c:39761
ZSTD_blockSplitCtx::nextSeqStore
seqStore_t nextSeqStore
Definition: zstd.c:14762
XXH32_copyState
#define XXH32_copyState
compressedSize
char int compressedSize
Definition: lz4.h:792
ZSTD_DCtx_s::litBufferLocation
ZSTD_litLocation_e litBufferLocation
Definition: zstd.c:34970
ZSTD_DUBT_UNSORTED_MARK
#define ZSTD_DUBT_UNSORTED_MARK
Definition: zstd.c:14407
ZSTD_freeCStream
size_t ZSTD_freeCStream(ZSTD_CStream *zcs)
Definition: zstd.c:23342
tr_insertionsort
static void tr_insertionsort(const int *ISAd, int *first, int *last)
Definition: zstd.c:42792
ZSTD_CCtx_params_s::enableDedicatedDictSearch
int enableDedicatedDictSearch
Definition: zstd.c:14698
ZSTD_referenceExternalSequences
size_t ZSTD_referenceExternalSequences(ZSTD_CCtx *cctx, rawSeq *seq, size_t nbSeq)
Definition: zstd.c:22195
ZSTD_CCtx_refPrefix_advanced
size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx *cctx, const void *prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:18977
FSE_decodeSymbolFast
static unsigned char FSE_decodeSymbolFast(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
Definition: zstd.c:2752
ZSTD_versionString
const char * ZSTD_versionString(void)
Definition: zstd.c:11138
ZSTD_error_stabilityCondition_notRespected
@ ZSTD_error_stabilityCondition_notRespected
Definition: zstd.c:1382
FASTCOVER_tryParameters_data_s::parameters
ZDICT_cover_params_t parameters
Definition: zstd.c:44244
HUF_DEltX2
Definition: zstd.c:33770
buffer_s::start
void * start
Definition: zstd.c:31088
FASTCOVER_accel_t::finalize
unsigned finalize
Definition: zstd.c:43884
ZSTD_compressSequences
size_t ZSTD_compressSequences(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const ZSTD_Sequence *inSeqs, size_t inSeqsSize, const void *src, size_t srcSize)
Definition: zstd.c:24431
COVER_best_s::compressedSize
size_t compressedSize
Definition: zstd.c:40458
ZSTD_fseCTablesMetadata_t::lastCountSize
size_t lastCountSize
Definition: zstd.c:14474
ZSTD_getSequenceLength
MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const *seqStore, seqDef const *seq)
Definition: zstd.c:11059
ZSTD_writeSkippableFrame
size_t ZSTD_writeSkippableFrame(void *dst, size_t dstCapacity, const void *src, size_t srcSize, unsigned magicVariant)
Definition: zstd.c:22166
ZSTD_getcBlockSize
size_t ZSTD_getcBlockSize(const void *src, size_t srcSize, blockProperties_t *bpPtr)
Definition: zstd.c:37765
MIN_CBLOCK_SIZE
#define MIN_CBLOCK_SIZE
Definition: zstd.c:10832
ZSTD_DCtx_s::rleSize
size_t rleSize
Definition: zstd.c:34930
ZSTD_window_correctOverflow
MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t *window, U32 cycleLog, U32 maxDist, void const *src)
Definition: zstd.c:15420
zop_dynamic
@ zop_dynamic
Definition: zstd.c:14533
FASTCOVER_buildDictionary
static size_t FASTCOVER_buildDictionary(const FASTCOVER_ctx_t *ctx, U32 *freqs, void *dictBuffer, size_t dictBufferCapacity, ZDICT_cover_params_t parameters, U16 *segmentFreqs)
Definition: zstd.c:44180
ZSTD_c_contentSizeFlag
@ ZSTD_c_contentSizeFlag
Definition: zstd.h:424
FSE_bitCost
MEM_STATIC U32 FSE_bitCost(const void *symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog)
Definition: zstd.c:2684
ZSTD_dedicatedDictSearch_lazy_search
FORCE_INLINE_TEMPLATE size_t ZSTD_dedicatedDictSearch_lazy_search(size_t *offsetPtr, size_t ml, U32 nbAttempts, const ZSTD_matchState_t *const dms, const BYTE *const ip, const BYTE *const iLimit, const BYTE *const prefixStart, const U32 curr, const U32 dictLimit, const size_t ddsIdx)
Definition: zstd.c:27049
MaxLit
#define MaxLit
Definition: zstd.c:10843
FSE_compress_usingCTable_generic
static size_t FSE_compress_usingCTable_generic(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct, const unsigned fast)
Definition: zstd.c:11789
XXH32_reset
#define XXH32_reset
HUF_repeat
HUF_repeat
Definition: zstd.c:2976
ZSTD_getCParams
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
Definition: zstd.c:24761
bt_reserved
@ bt_reserved
Definition: zstd.c:10827
ZSTD_DCtx_s::oversizedDuration
size_t oversizedDuration
Definition: zstd.c:34974
ZSTD_compressRleLiteralsBlock
size_t ZSTD_compressRleLiteralsBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:15990
ZDICT_insertSortCount
static void ZDICT_insertSortCount(offsetCount_t table[ZSTD_REP_NUM+1], U32 val, U32 count)
Definition: zstd.c:45173
XXH3_64bits_reset_withSecretandSeed
#define XXH3_64bits_reset_withSecretandSeed
COVER_best_s::dictSize
size_t dictSize
Definition: zstd.c:40456
ZSTD_entropyDTables_t::MLTable
ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]
Definition: zstd.c:34859
ZSTD_writeFrameHeader
static size_t ZSTD_writeFrameHeader(void *dst, size_t dstCapacity, const ZSTD_CCtx_params *params, U64 pledgedSrcSize, U32 dictID)
Definition: zstd.c:22112
DEBUGLOG
#define DEBUGLOG(l,...)
Definition: zstd.c:291
XXH32_freeState
#define XXH32_freeState
HUF_DECODE_SYMBOLX1_0
#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
Definition: zstd.c:33370
ZSTD_cwksp_internal_advance_phase
MEM_STATIC size_t ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp *ws, ZSTD_cwksp_alloc_phase_e phase)
Definition: zstd.c:13848
ZSTD_entropyDTables_t
Definition: zstd.c:34856
ZDICT_getErrorName
const ZDICTLIB_API char * ZDICT_getErrorName(size_t errorCode)
Definition: zstd.c:44648
rankValCol_t
U32 rankValCol_t[HUF_TABLELOG_MAX+1]
Definition: zstd.c:33772
ss_mergeforward
static void ss_mergeforward(const unsigned char *T, const int *PA, int *first, int *middle, int *last, int *buf, int depth)
Definition: zstd.c:42500
ZSTD_CDict_s::cBlockState
ZSTD_compressedBlockState_t cBlockState
Definition: zstd.c:17725
HUF_compress_tables_t::writeCTable_wksp
HUF_WriteCTableWksp writeCTable_wksp
Definition: zstd.c:13261
ZSTD_ALIGNOF
#define ZSTD_ALIGNOF(T)
Definition: zstd.c:776
ZSTD_reduceTable_btlazy2
static void ZSTD_reduceTable_btlazy2(U32 *const table, U32 const size, U32 const reducerValue)
Definition: zstd.c:20241
HUF_estimateCompressedSize
size_t HUF_estimateCompressedSize(const HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
Definition: zstd.c:12815
ZSTDMT_jobDescription::fullFrameSize
unsigned long long fullFrameSize
Definition: zstd.c:31652
ZSTD_window_isEmpty
MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
Definition: zstd.c:15313
ZSTD_row_update_internal
FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t *ms, const BYTE *ip, U32 const mls, U32 const rowLog, U32 const rowMask, U32 const useCache)
Definition: zstd.c:27425
ZSTD_blockCompressor
size_t(* ZSTD_blockCompressor)(ZSTD_matchState_t *bs, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:14880
seqStore_t
Definition: zstd.c:11031
HUF_readStats
size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize)
Definition: zstd.c:3318
WIN_CDECL
#define WIN_CDECL
Definition: zstd.c:552
DTableDesc::tableLog
BYTE tableLog
Definition: zstd.c:33003
xxh_u64
XXH64_hash_t xxh_u64
Definition: zstd.c:7180
COVER_checkParameters
static int COVER_checkParameters(ZDICT_cover_params_t parameters, size_t maxDictSize)
Definition: zstd.c:41035
HUF_CompressWeightsWksp::count
unsigned count[HUF_TABLELOG_MAX+1]
Definition: zstd.c:12190
syncPoint_t::flush
int flush
Definition: zstd.c:32677
ZSTD_createCCtx
ZSTD_CCtx * ZSTD_createCCtx(void)
Definition: zstd.c:17735
ZSTD_initCStream_usingCDict_advanced
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream *zcs, const ZSTD_CDict *cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize)
Definition: zstd.c:23407
XXH_VERSION_NUMBER
#define XXH_VERSION_NUMBER
ZSTD_DCtx_s::ddictSet
ZSTD_DDictHashSet * ddictSet
Definition: zstd.c:34942
ZSTDMT_CCtxParam_setNbWorkers
static size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params *params, unsigned nbWorkers)
Definition: zstd.c:31911
ZSTD_compress_insertDictionary
static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t *bs, ZSTD_matchState_t *ms, ldmState_t *ls, ZSTD_cwksp *ws, const ZSTD_CCtx_params *params, const void *dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp, void *workspace)
Definition: zstd.c:22595
ZSTD_CCtx_params_s::searchForExternalRepcodes
ZSTD_paramSwitch_e searchForExternalRepcodes
Definition: zstd.c:14736
HUF_compressWeights
static size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, size_t wtSize, void *workspace, size_t workspaceSize)
Definition: zstd.c:12195
ZSTDMT_serialState_update
static void ZSTDMT_serialState_update(serialState_t *serialState, ZSTD_CCtx *jobCCtx, rawSeqStore_t seqStore, range_t src, unsigned jobID)
Definition: zstd.c:31560
FASTCOVER_ctx_t::samples
const BYTE * samples
Definition: zstd.c:43908
HUF_initFastDStream
static size_t HUF_initFastDStream(BYTE const *ip)
Definition: zstd.c:33012
ZSTD_MAX_CLEVEL
#define ZSTD_MAX_CLEVEL
Definition: zstd.c:24529
ZSTD_VecMask
U64 ZSTD_VecMask
Definition: zstd.c:27301
construct_BWT
static int construct_BWT(const unsigned char *T, int *SA, int *bucket_A, int *bucket_B, int n, int m)
Definition: zstd.c:43542
ZSTD_CCtx_s::blockSplitCtx
ZSTD_blockSplitCtx blockSplitCtx
Definition: zstd.c:14844
ZSTD_sequenceLength::litLength
U32 litLength
Definition: zstd.c:11051
ZSTD_compressBlock_doubleFast_dictMatchState_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls)
Definition: zstd.c:25116
ZDICT_finalizeDictionary
ZDICTLIB_API size_t ZDICT_finalizeDictionary(void *dstDictBuffer, size_t maxDictSize, const void *dictContent, size_t dictContentSize, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_params_t parameters)
Definition: zstd.c:45400
ZSTD_compressStream2
size_t ZSTD_compressStream2(ZSTD_CCtx *cctx, ZSTD_outBuffer *output, ZSTD_inBuffer *input, ZSTD_EndDirective endOp)
Definition: zstd.c:23840
HUF_CStream_t::endPtr
BYTE * endPtr
Definition: zstd.c:12864
HUF_flags_disableFast
@ HUF_flags_disableFast
Definition: zstd.c:2947
HUF_decompress1X2_usingDTable_internal_body
FORCE_INLINE_TEMPLATE size_t HUF_decompress1X2_usingDTable_internal_body(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
Definition: zstd.c:34166
dummy
int dummy
Definition: lstrlib.c:1350
ZSTD_c_chainLog
@ ZSTD_c_chainLog
Definition: zstd.h:361
ZSTD_hash8
static size_t ZSTD_hash8(U64 u, U32 h, U64 s)
Definition: zstd.c:15188
ZSTD_copy8
static void ZSTD_copy8(void *dst, const void *src)
Definition: zstd.c:10911
ZSTD_DDict_dictSize
size_t ZSTD_DDict_dictSize(const ZSTD_DDict *ddict)
Definition: zstd.c:35088
XXH32
#define XXH32
ZSTD_rotateRight_U64
MEM_STATIC U64 ZSTD_rotateRight_U64(U64 const value, U32 count)
Definition: zstd.c:2001
ZSTD_initCStream_usingCDict
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream *zcs, const ZSTD_CDict *cdict)
Definition: zstd.c:23421
ZSTD_malloc
#define ZSTD_malloc(s)
Definition: zstd.c:110
nonstd::span_lite::size
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1554
XXH_malloc
static void * XXH_malloc(size_t s)
Definition: zstd.c:6376
sortedSymbol_t::symbol
BYTE symbol
Definition: zstd.c:33771
ZSTD_DDict_s
Definition: zstd.c:35072
set_repeat
@ set_repeat
Definition: zstd.c:10835
ZSTD_CCtx_s::dictContentSize
size_t dictContentSize
Definition: zstd.c:14784
LONGNBSEQ
#define LONGNBSEQ
Definition: zstd.c:10837
ZSTD_fseCTablesMetadata_t::mlType
symbolEncodingType_e mlType
Definition: zstd.c:14471
COVER_ctx_t::samplesSizes
const size_t * samplesSizes
Definition: zstd.c:40762
ZSTD_CCtx_setParameter
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx *cctx, ZSTD_cParameter param, int value)
Definition: zstd.c:18346
ZSTD_error_parameter_unsupported
@ ZSTD_error_parameter_unsupported
Definition: zstd.c:1376
POOL_ctx_s::shutdown
int shutdown
Definition: zstd.c:4340
detail::count
constexpr auto count() -> size_t
Definition: core.h:1222
MEM_readLE64
MEM_STATIC U64 MEM_readLE64(const void *memPtr)
Definition: zstd.c:1183
tr_median3
static INLINE int * tr_median3(const int *ISAd, int *v1, int *v2, int *v3)
Definition: zstd.c:42852
buffer_s::capacity
size_t capacity
Definition: zstd.c:31089
ZSTD_matchState_t::hashSaltEntropy
U32 hashSaltEntropy
Definition: zstd.c:14596
ZSTD_entropyCompressSeqStore_internal
MEM_STATIC size_t ZSTD_entropyCompressSeqStore_internal(const seqStore_t *seqStorePtr, const ZSTD_entropyCTables_t *prevEntropy, ZSTD_entropyCTables_t *nextEntropy, const ZSTD_CCtx_params *cctxParams, void *dst, size_t dstCapacity, void *entropyWorkspace, size_t entropyWkspSize, const int bmi2)
Definition: zstd.c:20470
XXH_FALLTHROUGH
#define XXH_FALLTHROUGH
Definition: zstd.c:5545
ZSTDMT_compressStream_generic
size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx *mtctx, ZSTD_outBuffer *output, ZSTD_inBuffer *input, ZSTD_EndDirective endOp)
Definition: zstd.c:32794
ZSTD_createDCtx_advanced
ZSTD_DCtx * ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
Definition: zstd.c:35654
ZSTD_compressSubBlock_sequences
static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t *fseTables, const ZSTD_fseCTablesMetadata_t *fseMetadata, const seqDef *sequences, size_t nbSeq, const BYTE *llCode, const BYTE *mlCode, const BYTE *ofCode, const ZSTD_CCtx_params *cctxParams, void *dst, size_t dstCapacity, const int bmi2, int writeEntropy, int *entropyWritten)
Definition: zstd.c:16841
ZSTDMT_isOverlapped
static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
Definition: zstd.c:32556
seqStore_t::litStart
BYTE * litStart
Definition: zstd.c:11034
ZSTDMT_jobDescription::jobID
unsigned jobID
Definition: zstd.c:31647
SeqCollector::seqStart
ZSTD_Sequence * seqStart
Definition: zstd.c:14665
GEN_ZSTD_HC_SEARCH_FN
#define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls)
Definition: zstd.c:27883
determine_blockSize
static size_t determine_blockSize(ZSTD_sequenceFormat_e mode, size_t blockSize, size_t remaining, const ZSTD_Sequence *inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
Definition: zstd.c:24290
ZDICT_cover_params_t::splitPoint
double splitPoint
Definition: zstd.c:40252
ZSTD_sequenceLength
Definition: zstd.c:11050
WEIGHT
#define WEIGHT(stat, opt)
Definition: zstd.c:29559
ZSTD_DCtx_setFormat
size_t ZSTD_DCtx_setFormat(ZSTD_DCtx *dctx, ZSTD_format_e format)
Definition: zstd.c:37140
ZSTD_tfp_forCDict
@ ZSTD_tfp_forCDict
Definition: zstd.c:14851
ZSTD_decompress
size_t ZSTD_decompress(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:36530
XXH3_64bits_reset
#define XXH3_64bits_reset
FSE_DECOMPRESS_WKSP_SIZE
#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue)
Definition: zstd.c:2472
ZSTD_bm_buffered
@ ZSTD_bm_buffered
Definition: zstd.c:11010
HUF_ReadDTableX2_Workspace::calleeWksp
U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]
Definition: zstd.c:33993
ZSTD_fillDoubleHashTable
void ZSTD_fillDoubleHashTable(ZSTD_matchState_t *ms, void const *end, ZSTD_dictTableLoadMethod_e dtlm, ZSTD_tableFillPurpose_e tfp)
Definition: zstd.c:24892
algo_time_t::decode256Time
U32 decode256Time
Definition: zstd.c:34599
FSE_CState_t::symbolTT
const void * symbolTT
Definition: zstd.c:2493
FSE_buildCTable
FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable *ct, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
ldmState_t
Definition: zstd.c:14645
COVER_group
static void COVER_group(COVER_ctx_t *ctx, const void *group, const void *groupEnd)
Definition: zstd.c:40891
XXH_readLE64_align
XXH_FORCE_INLINE xxh_u64 XXH_readLE64_align(const void *ptr, XXH_alignment align)
Definition: zstd.c:7292
inBuff_t::prefix
range_t prefix
Definition: zstd.c:31794
ZSTDMT_bufferPool
struct ZSTDMT_bufferPool_s ZSTDMT_bufferPool
REPCODE3_TO_OFFBASE
#define REPCODE3_TO_OFFBASE
Definition: zstd.c:15003
ZSTD_hufCTablesMetadata_t::hufDesBuffer
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]
Definition: zstd.c:14461
ldmState_t::window
ZSTD_window_t window
Definition: zstd.c:14646
ZSTDMT_tryGetInputRange
static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32621
HUF_WriteCTableWksp::wksp
HUF_CompressWeightsWksp wksp
Definition: zstd.c:12272
U16
unsigned short U16
Definition: lz4.c:313
ZSTDMT_jobDescription::cdict
const ZSTD_CDict * cdict
Definition: zstd.c:31651
ZSTD_DCtx_s::headerBuffer
BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]
Definition: zstd.c:34972
ZDICT_fastCover_params_t::f
unsigned f
Definition: zstd.c:40261
HUF_compressBound
size_t HUF_compressBound(size_t size)
Definition: zstd.c:12836
ZDICT_fillNoise
static void ZDICT_fillNoise(void *buffer, size_t length)
Definition: zstd.c:45086
ZSTD_cwksp_static_alloc_e
ZSTD_cwksp_static_alloc_e
Definition: zstd.c:13594
S16
signed short S16
Definition: zstd.c:912
rawSeq::offset
U32 offset
Definition: zstd.c:14503
ZSTD_DCtx_s::decodedSize
U64 decodedSize
Definition: zstd.c:34917
ZDICT_trainFromBuffer_cover
ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_cover_params_t parameters)
Definition: zstd.c:41274
ZSTD_dStreamStage
ZSTD_dStreamStage
Definition: zstd.c:34870
BOUNDED
#define BOUNDED(min, val, max)
Definition: zstd.c:10797
ZSTD_entropyCTables_t::fse
ZSTD_fseCTables_t fse
Definition: zstd.c:14446
ZSTD_versionNumber
unsigned ZSTD_versionNumber(void)
Definition: zstd.c:11136
ZSTD_cpuid_t::f1d
U32 f1d
Definition: zstd.c:4722
ZSTD_DCtx_refPrefix
size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx *dctx, const void *prefix, size_t prefixSize)
Definition: zstd.c:37056
XXH_STATIC_ASSERT
#define XXH_STATIC_ASSERT(c)
Definition: zstd.c:6449
OF_defaultNormLog
static const UNUSED_ATTR U32 OF_defaultNormLog
Definition: zstd.c:10905
ZSTD_fillHashTableForCDict
static void ZSTD_fillHashTableForCDict(ZSTD_matchState_t *ms, const void *const end, ZSTD_dictTableLoadMethod_e dtlm)
Definition: zstd.c:25582
ZSTD_error_workSpace_tooSmall
@ ZSTD_error_workSpace_tooSmall
Definition: zstd.c:1386
ZSTD_CCtx_s::customMem
ZSTD_customMem customMem
Definition: zstd.c:14792
COVER_best_wait
void COVER_best_wait(COVER_best_t *best)
Definition: zstd.c:41404
XXH32_state_s::memsize
XXH32_hash_t memsize
Definition: zstd.c:5892
ZSTDirp_continue
@ ZSTDirp_continue
Definition: zstd.c:19544
ZSTDMT_overlapLog
static int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat)
Definition: zstd.c:32185
CHECK_V_F
#define CHECK_V_F(e, f)
Definition: zstd.c:1453
ZSTD_CCtx_params_s::forceWindow
int forceWindow
Definition: zstd.c:14676
ZSTD_hashPtr
MEM_STATIC FORCE_INLINE_ATTR size_t ZSTD_hashPtr(const void *p, U32 hBits, U32 mls)
Definition: zstd.c:15194
ZSTD_findFrameCompressedSize
size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
Definition: zstd.c:36153
MEM_readBEST
MEM_STATIC size_t MEM_readBEST(const void *memPtr)
Definition: zstd.c:1249
HUF_flags_disableAsm
@ HUF_flags_disableAsm
Definition: zstd.c:2942
XXH_PRIME32_1
#define XXH_PRIME32_1
Definition: zstd.c:6782
XXH_free
static void XXH_free(void *p)
Definition: zstd.c:6377
FSE_versionNumber
FSE_PUBLIC_API unsigned FSE_versionNumber(void)
Definition: zstd.c:3111
ZSTD_compressBlock_opt2
static size_t ZSTD_compressBlock_opt2(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:30879
EStats_ress_t
Definition: zstd.c:45099
HUF_fourStreams
@ HUF_fourStreams
Definition: zstd.c:13237
ZSTD_getFrameHeader_advanced
size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader *zfhPtr, const void *src, size_t srcSize, ZSTD_format_e format)
Definition: zstd.c:35796
XXH3_128bits_withSeed
#define XXH3_128bits_withSeed
ZSTD_inBuffer_s
Definition: zstd.h:663
COVER_strict_cmp
static int WIN_CDECL COVER_strict_cmp(const void *lp, const void *rp)
Definition: zstd.c:40820
ZSTD_hash5
static size_t ZSTD_hash5(U64 u, U32 h, U64 s)
Definition: zstd.c:15173
ldmState_t::matchCandidates
ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE]
Definition: zstd.c:14651
ZDICT_optimizeTrainFromBuffer_cover
ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_cover_params_t *parameters)
Definition: zstd.c:41660
ZSTD_initLocalDict
static size_t ZSTD_initLocalDict(ZSTD_CCtx *cctx)
Definition: zstd.c:18878
ZSTD_cwksp_create
MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp *ws, size_t size, ZSTD_customMem customMem)
Definition: zstd.c:14193
FSE_normalizeCount
FSE_PUBLIC_API size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount)
Definition: zstd.c:11703
ZSTD_estimateCStreamSize_internal
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
Definition: zstd.c:19431
ZSTD_hash6
static size_t ZSTD_hash6(U64 u, U32 h, U64 s)
Definition: zstd.c:15178
optState_t::matchLengthFreq
unsigned * matchLengthFreq
Definition: zstd.c:14539
ZSTD_seqToCodes
int ZSTD_seqToCodes(const seqStore_t *seqStorePtr)
Definition: zstd.c:20275
ZSTD_findFrameSizeInfo
static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void *src, size_t srcSize)
Definition: zstd.c:36081
BOUNDCHECK
#define BOUNDCHECK(cParam, val)
Definition: zstd.c:18291
HUF_decompress1X1_DCtx_wksp
size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:34700
ZSTDMT_serialState_ensureFinished
static void ZSTDMT_serialState_ensureFinished(serialState_t *serialState, unsigned jobID, size_t cSize)
Definition: zstd.c:31609
COVER_ctx_t::nbSamples
size_t nbSamples
Definition: zstd.c:40763
ZSTD_countTrailingZeros32
MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val)
Definition: zstd.c:1849
BYTE
unsigned char BYTE
Definition: lz4.c:312
ZSTD_optimal_t
Definition: zstd.c:14525
ZDICT_tryMerge
static U32 ZDICT_tryMerge(dictItem *table, dictItem elt, U32 eltNbToSkip, const void *buffer)
Definition: zstd.c:44904
COVER_ctx_t::nbTestSamples
size_t nbTestSamples
Definition: zstd.c:40765
DICTLISTSIZE_DEFAULT
#define DICTLISTSIZE_DEFAULT
Definition: zstd.c:44614
ZSTD_LDM_DEFAULT_WINDOW_LOG
#define ZSTD_LDM_DEFAULT_WINDOW_LOG
Definition: zstd.c:17574
zmq::version
void version(int *major_, int *minor_, int *patch_)
Definition: zmq.hpp:360
ZSTD_fseCTablesMetadata_t::fseTablesBuffer
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]
Definition: zstd.c:14472
ZSTD_getBlockSize
size_t ZSTD_getBlockSize(const ZSTD_CCtx *cctx)
Definition: zstd.c:22296
ZSTD_DCtx_s::litBuffer
BYTE * litBuffer
Definition: zstd.c:34968
ZSTD_localDict::dictSize
size_t dictSize
Definition: zstd.c:14425
ZSTD_VecMask_next
MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val)
Definition: zstd.c:27307
XXH3_128bits_digest
#define XXH3_128bits_digest
ZSTD_MAGIC_DICTIONARY
#define ZSTD_MAGIC_DICTIONARY
Definition: zstd.h:138
MLFSELog
#define MLFSELog
Definition: zstd.c:10849
HBUFFSIZE
#define HBUFFSIZE
MEM_64bits
MEM_STATIC unsigned MEM_64bits(void)
Definition: zstd.c:988
ZSTD_estimateDStreamSize_fromFrame
size_t ZSTD_estimateDStreamSize_fromFrame(const void *src, size_t srcSize)
Definition: zstd.c:37302
BUCKET_A_SIZE
#define BUCKET_A_SIZE
Definition: zstd.c:41923
LL_base
static const UNUSED_ATTR U32 LL_base[MaxLL+1]
Definition: zstd.c:34806
ZSTD_freeCDict
size_t ZSTD_freeCDict(ZSTD_CDict *cdict)
Definition: zstd.c:23130
ZSTD_fseCTables_t::litlengthCTable
FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]
Definition: zstd.c:14438
POOL_ctx_s::queueHead
size_t queueHead
Definition: zstd.c:4324
ZSTD_minLiteralsToCompress
static size_t ZSTD_minLiteralsToCompress(ZSTD_strategy strategy, HUF_repeat huf_repeat)
Definition: zstd.c:16024
ZDICT_legacy_params_t
Definition: zstd.c:40357
HUF_decodeStreamX2
HINT_INLINE size_t HUF_decodeStreamX2(BYTE *p, BIT_DStream_t *bitDPtr, BYTE *const pEnd, const HUF_DEltX2 *const dt, const U32 dtLog)
Definition: zstd.c:34121
POOL_ctx_s::numThreadsBusy
size_t numThreadsBusy
Definition: zstd.c:4329
ZSTD_compressBlock_greedy_extDict_row
size_t ZSTD_compressBlock_greedy_extDict_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28667
FSE_DState_t
Definition: zstd.c:2550
XXH32_hash_t
unsigned int XXH32_hash_t
Definition: xxhash.h:162
ZDICT_analyzePos
static dictItem ZDICT_analyzePos(BYTE *doneMarks, const int *suffix, U32 start, const void *buffer, U32 minRatio, U32 notificationLevel)
Definition: zstd.c:44717
ZSTD_cwksp_sizeof
MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp *ws)
Definition: zstd.c:14217
ZSTD_prefixDict_s::dictContentType
ZSTD_dictContentType_e dictContentType
Definition: zstd.c:14419
FSE_CState_t
Definition: zstd.c:2490
ZDICT_getDictID
ZDICTLIB_API unsigned ZDICT_getDictID(const void *dictBuffer, size_t dictSize)
Definition: zstd.c:44650
FSE_symbolCompressionTransform::deltaNbBits
U32 deltaNbBits
Definition: zstd.c:2624
OFFCODE_MAX
#define OFFCODE_MAX
Definition: zstd.c:45200
ZSTD_cwksp_reserve_aligned
MEM_STATIC void * ZSTD_cwksp_reserve_aligned(ZSTD_cwksp *ws, size_t bytes)
Definition: zstd.c:13961
inputSize
const char char int inputSize
Definition: lz4.h:767
output
static const char * output
Definition: luac.c:38
COVER_map_pair_t
struct COVER_map_pair_t_s COVER_map_pair_t
ZSTD_generateSequences
size_t ZSTD_generateSequences(ZSTD_CCtx *zc, ZSTD_Sequence *outSeqs, size_t outSeqsSize, const void *src, size_t srcSize)
Definition: zstd.c:21014
POOL_ctx_s::queueSize
size_t queueSize
Definition: zstd.c:4326
BIT_getUpperBits
MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
Definition: zstd.c:2289
ZSTD_decodeLiteralsBlock
size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize, void *dst, size_t dstCapacity, const streaming_operation streaming)
Definition: zstd.c:37828
ss_blockswap
static INLINE void ss_blockswap(int *a, int *b, int n)
Definition: zstd.c:42407
XXH32_round
static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
Definition: zstd.c:6807
FSE_normalizeM2
static size_t FSE_normalizeM2(short *norm, U32 tableLog, const unsigned *count, size_t total, U32 maxSymbolValue, short lowProbCount)
Definition: zstd.c:11617
ZSTD_compressBlock_lazy2_extDict
size_t ZSTD_compressBlock_lazy2_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28651
ZSTD_row_matchMaskGroupWidth
FORCE_INLINE_TEMPLATE U32 ZSTD_row_matchMaskGroupWidth(const U32 rowEntries)
Definition: zstd.c:27472
ZSTD_resolveExternalSequenceValidation
static int ZSTD_resolveExternalSequenceValidation(int mode)
Definition: zstd.c:17920
range_format::map
@ map
ZSTD_entropyDTables_t::hufTable
HUF_DTable hufTable[HUF_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)]
Definition: zstd.c:34860
ZSTD_getCParamMode
static ZSTD_cParamMode_e ZSTD_getCParamMode(ZSTD_CDict const *cdict, ZSTD_CCtx_params const *params, U64 pledgedSrcSize)
Definition: zstd.c:23358
HUF_getNbBitsFast
static size_t HUF_getNbBitsFast(HUF_CElt elt)
Definition: zstd.c:12241
ZSTD_ldm_blockCompress
size_t ZSTD_ldm_blockCompress(rawSeqStore_t *rawSeqStore, ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_paramSwitch_e useRowMatchFinder, void const *src, size_t srcSize)
Definition: zstd.c:29456
ZSTD_window_t::nextSrc
BYTE const * nextSrc
Definition: zstd.c:14563
ZSTD_error_no_error
@ ZSTD_error_no_error
Definition: zstd.c:1364
ZSTD_OPT_NUM
#define ZSTD_OPT_NUM
Definition: zstd.c:10803
ZSTDMT_expandBufferPool
static ZSTDMT_bufferPool * ZSTDMT_expandBufferPool(ZSTDMT_bufferPool *srcBufPool, unsigned maxNbBuffers)
Definition: zstd.c:31160
rsyncState_t::hitMask
U64 hitMask
Definition: zstd.c:31828
ZSTD_dedicatedDictSearch_lazy_loadDictionary
void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t *ms, const BYTE *const ip)
Definition: zstd.c:26931
ZDICT_flatLit
static void ZDICT_flatLit(unsigned *countLit)
Definition: zstd.c:45191
ZSTD_compress2
size_t ZSTD_compress2(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:23961
rawSeqStore_t::capacity
size_t capacity
Definition: zstd.c:14514
ZSTDMT_jobDescription::lastJob
unsigned lastJob
Definition: zstd.c:31649
sum_u32
static U32 sum_u32(const unsigned table[], size_t nbElts)
Definition: zstd.c:29611
ZSTD_COMPRESSBOUND
#define ZSTD_COMPRESSBOUND(srcSize)
Definition: zstd.h:232
ZSTD_compressBlock_btultra2
size_t ZSTD_compressBlock_btultra2(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30936
ZSTD_bounds
Definition: zstd.h:509
MEM_readLE32
MEM_STATIC U32 MEM_readLE32(const void *memPtr)
Definition: zstd.c:1167
ZSTD_compressBlock
size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22312
ZSTD_window_clear
MEM_STATIC void ZSTD_window_clear(ZSTD_window_t *window)
Definition: zstd.c:15304
websocket_client.ws
ws
Definition: websocket_client.py:10
ZSTDMT_sizeof_seqPool
static size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool *seqPool)
Definition: zstd.c:31277
HUF_tightCompressBound
static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog)
Definition: zstd.c:13064
SeqCollector
Definition: zstd.c:14663
ZSTD_CCtx_s::seqStore
seqStore_t seqStore
Definition: zstd.c:14799
ZSTD_compressBlock_greedy
size_t ZSTD_compressBlock_greedy(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28310
rankVal_t
rankValCol_t rankVal_t[HUF_TABLELOG_MAX]
Definition: zstd.c:33773
STACK_PUSH
#define STACK_PUSH(_a, _b, _c, _d)
Definition: zstd.c:41967
XXH64_finalize
static xxh_u64 XXH64_finalize(xxh_u64 h64, const xxh_u8 *ptr, size_t len, XXH_alignment align)
Definition: zstd.c:7353
ZSTD_CDict_s::entropyWorkspace
U32 * entropyWorkspace
Definition: zstd.c:17722
ZSTDMT_bufferPool_s::cMem
ZSTD_customMem cMem
Definition: zstd.c:31099
HUF_buildDEltX2U64
static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level)
Definition: zstd.c:33809
HIST_count_wksp
size_t HIST_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize, void *workSpace, size_t workSpaceSize)
Definition: zstd.c:12019
ZSTD_loadDEntropy
size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t *entropy, const void *const dict, size_t const dictSize)
Definition: zstd.c:36777
ZSTD_getErrorName
const char * ZSTD_getErrorName(size_t code)
Definition: zstd.c:11152
XXH64_state_s
Definition: zstd.c:5911
XXH_ERROR
#define XXH_ERROR
ss_inplacemerge
static void ss_inplacemerge(const unsigned char *T, const int *PA, int *first, int *middle, int *last, int depth)
Definition: zstd.c:42457
ZSTD_resetTarget_CCtx
@ ZSTD_resetTarget_CCtx
Definition: zstd.c:19550
HUF_closeCStream
static size_t HUF_closeCStream(HUF_CStream_t *bitC)
Definition: zstd.c:12988
FSE_VERSION_NUMBER
#define FSE_VERSION_NUMBER
Definition: zstd.c:1604
ZSTD_fillDoubleHashTableForCCtx
static void ZSTD_fillDoubleHashTableForCCtx(ZSTD_matchState_t *ms, void const *end, ZSTD_dictTableLoadMethod_e dtlm)
Definition: zstd.c:24858
HUF_flags_preferRepeat
@ HUF_flags_preferRepeat
Definition: zstd.c:2932
COVER_lower_bound
static const size_t * COVER_lower_bound(const size_t *first, const size_t *last, size_t value)
Definition: zstd.c:40842
ZSTD_invalidateRepCodes
void ZSTD_invalidateRepCodes(ZSTD_CCtx *cctx)
Definition: zstd.c:19869
ZSTD_DCtx_s::validateChecksum
U32 validateChecksum
Definition: zstd.c:34926
serialState_t::ldmState
ldmState_t ldmState
Definition: zstd.c:31456
ZDICT_trainFromBuffer_fastCover
ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, ZDICT_fastCover_params_t parameters)
Definition: zstd.c:44329
HUF_DGEN
#define HUF_DGEN(fn)
Definition: zstd.c:32989
MAX
#define MAX(a, b)
Definition: zstd.c:10796
BIT_CStream_t::startPtr
char * startPtr
Definition: zstd.c:2051
STACK_POP
#define STACK_POP(_a, _b, _c, _d)
Definition: zstd.c:41979
FSE_COMPRESSBOUND
#define FSE_COMPRESSBOUND(size)
Definition: zstd.c:2436
HASH_READ_SIZE
#define HASH_READ_SIZE
Definition: zstd.c:14406
ZSTD_ldm_getBucket
static ldmEntry_t * ZSTD_ldm_getBucket(ldmState_t *ldmState, size_t hash, ldmParams_t const ldmParams)
Definition: zstd.c:28968
FSE_optimalTableLog_internal
unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
Definition: zstd.c:11595
HUF_DecompressFastLoopFn
void(* HUF_DecompressFastLoopFn)(HUF_DecompressFastArgs *)
Definition: zstd.c:33044
ZSTD_ROWSIZE
#define ZSTD_ROWSIZE
Definition: zstd.c:20187
ZSTD_CCtxParams_getParameter
size_t ZSTD_CCtxParams_getParameter(ZSTD_CCtx_params const *CCtxParams, ZSTD_cParameter param, int *value)
Definition: zstd.c:18657
ZSTDMT_jobDescription::dstFlushed
size_t dstFlushed
Definition: zstd.c:31653
ZSTD_hash5PtrS
static size_t ZSTD_hash5PtrS(const void *p, U32 h, U64 s)
Definition: zstd.c:15175
ss_compare
static INLINE int ss_compare(const unsigned char *T, const int *p1, const int *p2, int depth)
Definition: zstd.c:42096
ZSTD_optLdm_t::seqStore
rawSeqStore_t seqStore
Definition: zstd.c:30419
ZSTD_match_t
Definition: zstd.c:14497
ZSTD_sequenceBound
size_t ZSTD_sequenceBound(size_t srcSize)
Definition: zstd.c:21010
HUF_CompressWeightsWksp::norm
S16 norm[HUF_TABLELOG_MAX+1]
Definition: zstd.c:12191
ZSTD_DCtx_s::hostageByte
U32 hostageByte
Definition: zstd.c:34962
ZSTDds_getFrameHeaderSize
@ ZSTDds_getFrameHeaderSize
Definition: zstd.c:34865
check
static void check(LexState *ls, int c)
Definition: lparser.c:107
ZSTDMT_freeCCtxPool
static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool *pool)
Definition: zstd.c:31354
ZSTD_mergeBlockDelimiters
size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence *sequences, size_t seqsSize)
Definition: zstd.c:21034
HUF_DecompressFastArgs
Definition: zstd.c:33034
HUF_decodeSymbolX1
FORCE_INLINE_TEMPLATE BYTE HUF_decodeSymbolX1(BIT_DStream_t *Dstream, const HUF_DEltX1 *dt, const U32 dtLog)
Definition: zstd.c:33362
BIT_DStream_status
BIT_DStream_status
Definition: zstd.c:2090
FSE_BLOCKBOUND
#define FSE_BLOCKBOUND(size)
Definition: zstd.c:2435
optState_t::litFreq
unsigned * litFreq
Definition: zstd.c:14537
ZSTDMT_createBufferPool
static ZSTDMT_bufferPool * ZSTDMT_createBufferPool(unsigned maxNbBuffers, ZSTD_customMem cMem)
Definition: zstd.c:31103
DEBUGLEVEL
#define DEBUGLEVEL
Definition: zstd.c:37
optState_t::litSumBasePrice
U32 litSumBasePrice
Definition: zstd.c:14548
MINMATCHLENGTH
#define MINMATCHLENGTH
Definition: zstd.c:44716
ZSTDMT_getInputDataInUse
static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32525
serialState_t
Definition: zstd.c:31451
ZSTD_blockSplitterEnabled
static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params *cctxParams)
Definition: zstd.c:20318
HUF_swapNodes
static void HUF_swapNodes(nodeElt *a, nodeElt *b)
Definition: zstd.c:12560
ldmParams_t::bucketSizeLog
U32 bucketSizeLog
Definition: zstd.c:14657
ZSTDMT_freeSeqPool
static void ZSTDMT_freeSeqPool(ZSTDMT_seqPool *seqPool)
Definition: zstd.c:31331
ZSTD_CCtx_params_s::useSequenceProducer
int useSequenceProducer
Definition: zstd.c:14730
HUF_decompress1X1_usingDTable_internal_body
FORCE_INLINE_TEMPLATE size_t HUF_decompress1X1_usingDTable_internal_body(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
Definition: zstd.c:33411
ZSTD_window_init
MEM_STATIC void ZSTD_window_init(ZSTD_window_t *window)
Definition: zstd.c:15595
XXH_PRIME64_1
#define XXH_PRIME64_1
Definition: zstd.c:7309
ZSTD_inBuffer_s::size
size_t size
Definition: zstd.h:667
ZSTD_DUBT_findBetterDictMatch
static size_t ZSTD_DUBT_findBetterDictMatch(const ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iend, size_t *offsetPtr, size_t bestLength, U32 nbCompares, U32 const mls, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:26686
ZSTD_blockSplitCtx::currSeqStore
seqStore_t currSeqStore
Definition: zstd.c:14761
ZSTDMT_releaseSeq
static void ZSTDMT_releaseSeq(ZSTDMT_seqPool *seqPool, rawSeqStore_t seq)
Definition: zstd.c:31313
ZSTDMT_CCtx_s::providedFactory
unsigned providedFactory
Definition: zstd.c:31857
ZSTDcrp_leaveDirty
@ ZSTDcrp_leaveDirty
Definition: zstd.c:19535
XXH64_copyState
#define XXH64_copyState
ZDICTLIB_STATIC_API
#define ZDICTLIB_STATIC_API
Definition: zstd.c:40228
ZSTD_bm_stable
@ ZSTD_bm_stable
Definition: zstd.c:11011
OF_DEFAULTNORMLOG
#define OF_DEFAULTNORMLOG
Definition: zstd.c:10904
COVER_tryParameters_data_s::dictBufferCapacity
size_t dictBufferCapacity
Definition: zstd.c:41606
ZSTD_storeSeq
HINT_INLINE UNUSED_ATTR void ZSTD_storeSeq(seqStore_t *seqStorePtr, size_t litLength, const BYTE *literals, const BYTE *litLimit, U32 offBase, size_t matchLength)
Definition: zstd.c:15018
inBuffer_forEndFlush
static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream *zcs)
Definition: zstd.c:24476
kInverseProbabilityLog256
static const unsigned kInverseProbabilityLog256[256]
Definition: zstd.c:16222
POOL_thread
static void * POOL_thread(void *opaque)
Definition: zstd.c:4348
ZDICT_getDictHeaderSize
ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void *dictBuffer, size_t dictSize)
Definition: zstd.c:44657
ZSTD_BuildCTableWksp::norm
S16 norm[MaxSeq+1]
Definition: zstd.c:16439
ZSTD_entropyCTablesMetadata_t
Definition: zstd.c:14477
BIT_getLowerBits
MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
Definition: zstd.c:2154
FSE_symbolCompressionTransform::deltaFindState
int deltaFindState
Definition: zstd.c:2623
ZSTD_getDictID_fromDDict
unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict)
Definition: zstd.c:35276
ldmParams_t::windowLog
U32 windowLog
Definition: zstd.c:14660
POOL_add_internal
static void POOL_add_internal(POOL_ctx *ctx, POOL_function function, void *opaque)
Definition: zstd.c:4553
HUF_insertionSort
HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high)
Definition: zstd.c:12578
ZSTD_compressBound
size_t ZSTD_compressBound(size_t srcSize)
Definition: zstd.c:17708
ZSTD_RowFindBestMatch
FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch(ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 mls, const ZSTD_dictMode_e dictMode, const U32 rowLog)
Definition: zstd.c:27649
ERROR
#define ERROR(name)
Definition: zstd.c:1445
ZSTD_fseCTablesMetadata_t::ofType
symbolEncodingType_e ofType
Definition: zstd.c:14470
search_rowHash
@ search_rowHash
Definition: zstd.c:27932
XXH_errorcode
XXH_errorcode
Definition: xxhash.h:79
ZSTD_registerSequenceProducer
void ZSTD_registerSequenceProducer(ZSTD_CCtx *zc, void *mState, ZSTD_sequenceProducer_F *mFinder)
Definition: zstd.c:24790
ZSTD_customMalloc
MEM_STATIC void * ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
Definition: zstd.c:4173
ZSTD_estimateCCtxSize
size_t ZSTD_estimateCCtxSize(int compressionLevel)
Definition: zstd.c:19382
LL_DEFAULTNORMLOG
#define LL_DEFAULTNORMLOG
Definition: zstd.c:10874
ZSTD_decompressStream_simpleArgs
size_t ZSTD_decompressStream_simpleArgs(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, size_t *dstPos, const void *src, size_t srcSize, size_t *srcPos)
Definition: zstd.c:37689
XXH3_128bits_reset
#define XXH3_128bits_reset
ZSTD_getCParamRowSize
static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
Definition: zstd.c:24708
MINRATIO
#define MINRATIO
Definition: zstd.c:44563
seqStore_t::longLengthType
ZSTD_longLengthType_e longLengthType
Definition: zstd.c:11046
ZSTD_memmove
#define ZSTD_memmove(d, s, l)
Definition: zstd.c:93
ZSTD_lazy
@ ZSTD_lazy
Definition: zstd.h:320
PREFETCH_AREA
#define PREFETCH_AREA(p, s)
Definition: zstd.c:634
ZSTDirp_reset
@ ZSTDirp_reset
Definition: zstd.c:19545
HUF_decompress4X_hufOnly_wksp
size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:34730
HUF_compress4X_repeat
size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int flags)
Definition: zstd.c:13472
ZSTD_BLOCKHEADERSIZE
#define ZSTD_BLOCKHEADERSIZE
Definition: zstd.c:10825
HUF_DEltX2::nbBits
BYTE nbBits
Definition: zstd.c:33770
XXH32_avalanche
static xxh_u32 XXH32_avalanche(xxh_u32 h32)
Definition: zstd.c:6861
ZSTD_defaultCParameters
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1]
Definition: zstd.c:24535
ZSTD_compressBlock_doubleFast
size_t ZSTD_compressBlock_doubleFast(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:25360
ZSTD_DCtx_s::streamStage
ZSTD_dStreamStage streamStage
Definition: zstd.c:34947
ZSTD_DStreamInSize
size_t ZSTD_DStreamInSize(void)
Definition: zstd.c:37020
ZSTD_fseCTables_t::matchlengthCTable
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]
Definition: zstd.c:14437
BMI2_TARGET_ATTRIBUTE
#define BMI2_TARGET_ATTRIBUTE
Definition: zstd.c:608
g_refreshRate
static const clock_t g_refreshRate
Definition: zstd.c:40613
ZSTD_CCtx_init_compressStream2
static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx *cctx, ZSTD_EndDirective endOp, size_t inSize)
Definition: zstd.c:23742
ZSTDMT_serialState_init
static int ZSTDMT_serialState_init(serialState_t *serialState)
Definition: zstd.c:31538
ZSTD_EndDirective
ZSTD_EndDirective
Definition: zstd.h:745
ZSTD_compressBlock_doubleFast_noDict_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_doubleFast_noDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls)
Definition: zstd.c:24906
ZSTD_matchState_t::rowHashLog
U32 rowHashLog
Definition: zstd.c:14592
ZSTD_estimateSubBlockSize_literal
static size_t ZSTD_estimateSubBlockSize_literal(const BYTE *literals, size_t litSize, const ZSTD_hufCTables_t *huf, const ZSTD_hufCTablesMetadata_t *hufMetadata, void *workspace, size_t wkspSize, int writeEntropy)
Definition: zstd.c:16984
ZSTD_compressBegin_usingCDict_deprecated
size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict)
Definition: zstd.c:23272
XXH3_64bits
#define XXH3_64bits
MEM_readLEST
MEM_STATIC size_t MEM_readLEST(const void *memPtr)
Definition: zstd.c:1199
ZSTD_DCtx_s::staticSize
size_t staticSize
Definition: zstd.c:34931
ZSTD_DCtx_setMaxWindowSize
size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx *dctx, size_t maxWindowSize)
Definition: zstd.c:37128
ZSTD_resolveEnableLdm
static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode, const ZSTD_compressionParameters *const cParams)
Definition: zstd.c:17914
ZSTD_d_windowLogMax
@ ZSTD_d_windowLogMax
Definition: zstd.h:608
ZSTDMT_CCtxPool::poolMutex
ZSTD_pthread_mutex_t poolMutex
Definition: zstd.c:31346
ZSTD_CCtx_params_s::maxBlockSize
size_t maxBlockSize
Definition: zstd.c:14733
ZSTD_DCtx_s::expected
size_t expected
Definition: zstd.c:34914
ZSTDMT_jobDescription
Definition: zstd.c:31635
ZSTD_startingInputLength
static size_t ZSTD_startingInputLength(ZSTD_format_e format)
Definition: zstd.c:35583
XXH32_state_s::mem32
XXH32_hash_t mem32[4]
Definition: zstd.c:5891
ZSTD_CCtx_setCParams
size_t ZSTD_CCtx_setCParams(ZSTD_CCtx *cctx, ZSTD_compressionParameters cparams)
Definition: zstd.c:18818
ZSTDMT_toFlushNow
size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32113
LDM_BUCKET_SIZE_LOG
#define LDM_BUCKET_SIZE_LOG
Definition: zstd.c:28815
ZSTD_WORKSPACETOOLARGE_MAXDURATION
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION
Definition: zstd.c:11006
ZSTD_selectBlockCompressor
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode)
Definition: zstd.c:20629
FASTCOVER_ctx_init
static size_t FASTCOVER_ctx_init(FASTCOVER_ctx_t *ctx, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, unsigned d, double splitPoint, unsigned f, FASTCOVER_accel_t accelParams)
Definition: zstd.c:44093
ZSTD_literalsCompressionIsDisabled
MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params *cctxParams)
Definition: zstd.c:14968
MEM_writeLE64
MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64)
Definition: zstd.c:1191
FASTCOVER_defaultAccelParameters
static const FASTCOVER_accel_t FASTCOVER_defaultAccelParameters[FASTCOVER_MAX_ACCEL+1]
Definition: zstd.c:43889
ZSTDMT_jobDescription::bufPool
ZSTDMT_bufferPool * bufPool
Definition: zstd.c:31641
MaxFSELog
#define MaxFSELog
Definition: zstd.c:10852
blockSize_explicitDelimiter
static size_t blockSize_explicitDelimiter(const ZSTD_Sequence *inSeqs, size_t inSeqsSize, ZSTD_sequencePosition seqPos)
Definition: zstd.c:24261
ZDICT_count
static size_t ZDICT_count(const void *pIn, const void *pMatch)
Definition: zstd.c:44685
ZSTD_createThreadPool
POOL_ctx * ZSTD_createThreadPool(size_t numThreads)
Definition: zstd.c:4388
FSE_decompress_usingDTable_generic
FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt, const unsigned fast)
Definition: zstd.c:3667
XXH32_ENDJMP
#define XXH32_ENDJMP
Definition: zstd.c:6360
XXH32_digest
#define XXH32_digest
ZSTDMT_jobDescription::job_cond
ZSTD_pthread_cond_t job_cond
Definition: zstd.c:31639
ZSTD_ldm_adjustParameters
void ZSTD_ldm_adjustParameters(ldmParams_t *params, ZSTD_compressionParameters const *cParams)
Definition: zstd.c:28931
ZSTD_bitmix
static U64 ZSTD_bitmix(U64 val, U64 len)
Definition: zstd.c:19554
ZSTD_noCompressBlock
MEM_STATIC size_t ZSTD_noCompressBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastBlock)
Definition: zstd.c:14933
ZSTD_copy16
static void ZSTD_copy16(void *dst, const void *src)
Definition: zstd.c:10924
CLAMP
#define CLAMP(cParam, val)
ENTROPY_WORKSPACE_SIZE
#define ENTROPY_WORKSPACE_SIZE
Definition: zstd.c:14740
ZSTD_dictTooBig
static int ZSTD_dictTooBig(size_t const loadedDictSize)
Definition: zstd.c:19672
ZSTD_error_init_missing
@ ZSTD_error_init_missing
Definition: zstd.c:1384
ZSTD_symbolEncodingTypeStats_t::Offtype
U32 Offtype
Definition: zstd.c:20330
ZSTD_DDictHashSet::ddictPtrTableSize
size_t ddictPtrTableSize
Definition: zstd.c:34882
ZSTD_externalMatchCtx::mState
void * mState
Definition: zstd.c:14770
ZSTD_sizeof_DStream
size_t ZSTD_sizeof_DStream(const ZSTD_DStream *dctx)
Definition: zstd.c:37277
ZSTD_cwksp::tableEnd
void * tableEnd
Definition: zstd.c:13698
ZSTD_checkBufferStability
static size_t ZSTD_checkBufferStability(ZSTD_CCtx const *cctx, ZSTD_outBuffer const *output, ZSTD_inBuffer const *input, ZSTD_EndDirective endOp)
Definition: zstd.c:23723
ZDICT_DEPRECATED
#define ZDICT_DEPRECATED(message)
Definition: zstd.c:40402
ZSTD_CCtxParams_reset
size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params *params)
Definition: zstd.c:17998
d
d
ZDICT_trainFromBuffer
ZDICTLIB_API size_t ZDICT_trainFromBuffer(void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples)
Definition: zstd.c:45649
ZSTD_CCtx_refThreadPool
size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx *cctx, ZSTD_threadPool *pool)
Definition: zstd.c:18964
BIT_addBits
MEM_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
Definition: zstd.c:2167
base_1guaranteed
@ base_1guaranteed
Definition: zstd.c:29621
FSE_readNCount
FSE_PUBLIC_API size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSymbolValuePtr, unsigned *tableLogPtr, const void *rBuffer, size_t rBuffSize)
Definition: zstd.c:3303
ZSTD_decompressMultiFrame
static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, const ZSTD_DDict *ddict)
Definition: zstd.c:36406
XXH64_mergeRound
static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
Definition: zstd.c:7331
ZSTD_copyDDictParameters
void ZSTD_copyDDictParameters(ZSTD_DCtx *dctx, const ZSTD_DDict *ddict)
Definition: zstd.c:35094
SeqCollector::maxSequences
size_t maxSequences
Definition: zstd.c:14667
ZSTD_compressBlock_lazy_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_lazy_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], const void *src, size_t srcSize, const searchMethod_e searchMethod, const U32 depth, ZSTD_dictMode_e const dictMode)
Definition: zstd.c:28023
ZSTD_sequencePosition::posInSrc
size_t posInSrc
Definition: zstd.c:14520
ZSTD_CCtx_s::localDict
ZSTD_localDict localDict
Definition: zstd.c:14829
ZSTDMT_JOBSIZE_MAX
#define ZSTDMT_JOBSIZE_MAX
Definition: zstd.c:14322
ZSTD_HcFindBestMatch
FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch(ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 mls, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:27184
XXH3_64bits_withSecret
#define XXH3_64bits_withSecret
ZSTD_overrideCParams
static void ZSTD_overrideCParams(ZSTD_compressionParameters *cParams, const ZSTD_compressionParameters *overrides)
Definition: zstd.c:19208
ZSTD_minCLevel
int ZSTD_minCLevel(void)
Definition: zstd.c:24648
ZSTD_ldm_skipSequences
void ZSTD_ldm_skipSequences(rawSeqStore_t *rawSeqStore, size_t srcSize, U32 const minMatch)
Definition: zstd.c:29379
dictItem::pos
U32 pos
Definition: zstd.c:44702
ZSTD_DDict_s::dictSize
size_t dictSize
Definition: zstd.c:35075
ZSTD_CCtx_s::outBuffSize
size_t outBuffSize
Definition: zstd.c:14817
ZSTD_safecopyLiterals
static void ZSTD_safecopyLiterals(BYTE *op, BYTE const *ip, BYTE const *const iend, BYTE const *ilimit_w)
Definition: zstd.c:14989
ZSTD_prefixDict_s::dictSize
size_t dictSize
Definition: zstd.c:14418
XXH64_round
static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
Definition: zstd.c:7323
ZSTD_DCtx_s::OFTptr
const ZSTD_seqSymbol * OFTptr
Definition: zstd.c:34906
ZSTD_countSeqStoreLiteralsBytes
static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t *const seqStore)
Definition: zstd.c:21448
ZSTD_CHUNKSIZE_MAX
#define ZSTD_CHUNKSIZE_MAX
Definition: zstd.c:15296
inBuff_t::filled
size_t filled
Definition: zstd.c:31796
ZSTD_rleCompressBlock
MEM_STATIC size_t ZSTD_rleCompressBlock(void *dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock)
Definition: zstd.c:14945
range_t
Definition: zstd.c:31446
ZSTD_decompressBound
unsigned long long ZSTD_decompressBound(const void *src, size_t srcSize)
Definition: zstd.c:36165
HUF_decompress1X_DCtx_wksp
size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:34651
HUF_sort
static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[])
Definition: zstd.c:12643
ZDICT_analyzeEntropy
static size_t ZDICT_analyzeEntropy(void *dstBuffer, size_t maxDstSize, int compressionLevel, const void *srcBuffer, const size_t *fileSizes, unsigned nbFiles, const void *dictBuffer, size_t dictBufferSize, unsigned notificationLevel)
Definition: zstd.c:45201
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
ZSTD_DCtx_s::disableHufAsm
int disableHufAsm
Definition: zstd.c:34944
ZSTD_pthread_t
#define ZSTD_pthread_t
Definition: zstd.c:3917
ZSTDMT_CCtx_s::frameEnded
unsigned frameEnded
Definition: zstd.c:31849
ZSTD_preserveUnsortedMark
void ZSTD_preserveUnsortedMark(U32 *const table, U32 const size, U32 const reducerValue)
COVER_map_s
Definition: zstd.c:40642
ZSTD_CDict_s
Definition: zstd.c:17718
ZSTD_compressSequences_internal
static size_t ZSTD_compressSequences_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const ZSTD_Sequence *inSeqs, size_t inSeqsSize, const void *src, size_t srcSize)
Definition: zstd.c:24313
HUF_ReadDTableX1_Workspace::rankVal
U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX+1]
Definition: zstd.c:33218
HUF_getDTableDesc
static DTableDesc HUF_getDTableDesc(const HUF_DTable *table)
Definition: zstd.c:33005
ZSTD_cwksp_alloc_aligned
@ ZSTD_cwksp_alloc_aligned
Definition: zstd.c:13585
ZSTD_dictMatchState
@ ZSTD_dictMatchState
Definition: zstd.c:14856
ZSTD_compressBlock_lazy_dedicatedDictSearch
size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28353
NEXT_IN_CHAIN
#define NEXT_IN_CHAIN(d, mask)
Definition: zstd.c:27146
ZSTD_DCtx_get_bmi2
MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx)
Definition: zstd.c:34987
ZSTD_getDictID_fromCDict
unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict *cdict)
Definition: zstd.c:23213
U8
unsigned char U8
Definition: zstd.c:906
optState_t::offCodeFreq
unsigned * offCodeFreq
Definition: zstd.c:14540
ZSTD_CCtxParams_setParameter
size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params *CCtxParams, ZSTD_cParameter param, int value)
Definition: zstd.c:18407
XXH64_hashFromCanonical
#define XXH64_hashFromCanonical
ZSTD_compressSubBlock_multi
static size_t ZSTD_compressSubBlock_multi(const seqStore_t *seqStorePtr, const ZSTD_compressedBlockState_t *prevCBlock, ZSTD_compressedBlockState_t *nextCBlock, const ZSTD_entropyCTablesMetadata_t *entropyMetadata, const ZSTD_CCtx_params *cctxParams, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const int bmi2, U32 lastBlock, void *workspace, size_t wkspSize)
Definition: zstd.c:17107
seqStoreSplits::splitLocations
U32 * splitLocations
Definition: zstd.c:21654
ZSTD_entropyCost
static size_t ZSTD_entropyCost(unsigned const *count, unsigned const max, size_t const total)
Definition: zstd.c:16285
ZSTD_validateSequence
static size_t ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch, size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
Definition: zstd.c:23997
ZSTD_createCStream_advanced
ZSTD_CStream * ZSTD_createCStream_advanced(ZSTD_customMem customMem)
Definition: zstd.c:23337
ZSTD_CCtx_params_s::prefetchCDictTables
ZSTD_paramSwitch_e prefetchCDictTables
Definition: zstd.c:14721
ZSTD_CCtx_s::entropyWorkspace
U32 * entropyWorkspace
Definition: zstd.c:14805
ZSTD_SHORT_CACHE_TAG_BITS
#define ZSTD_SHORT_CACHE_TAG_BITS
Definition: zstd.c:15733
ZSTD_resetTarget_CDict
@ ZSTD_resetTarget_CDict
Definition: zstd.c:19549
FSE_buildCTable_rle
size_t FSE_buildCTable_rle(FSE_CTable *ct, unsigned char symbolValue)
Definition: zstd.c:11766
MAXREPOFFSET
#define MAXREPOFFSET
Definition: zstd.c:45106
XXH3_createState
#define XXH3_createState
ZSTD_customFree
MEM_STATIC void ZSTD_customFree(void *ptr, ZSTD_customMem customMem)
Definition: zstd.c:4192
ZSTD_CCtxParams_init_internal
static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params *cctxParams, const ZSTD_parameters *params, int compressionLevel)
Definition: zstd.c:18018
trbudget_check
static INLINE int trbudget_check(trbudget_t *budget, int size)
Definition: zstd.c:42922
ZSTD_entropyCTablesMetadata_t::fseMetadata
ZSTD_fseCTablesMetadata_t fseMetadata
Definition: zstd.c:14479
ZSTD_DCtx_s::outBuffSize
size_t outBuffSize
Definition: zstd.c:34953
ZSTD_sizeof_CStream
size_t ZSTD_sizeof_CStream(const ZSTD_CStream *zcs)
Definition: zstd.c:17852
POOL_ctx_s::threadCapacity
size_t threadCapacity
Definition: zstd.c:4319
ZSTD_compressSuperBlock
size_t ZSTD_compressSuperBlock(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, void const *src, size_t srcSize, unsigned lastBlock)
Definition: zstd.c:17233
ZSTD_ldm_fillFastTables
static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t *ms, void const *end)
Definition: zstd.c:29033
ZSTD_clearDict
static void ZSTD_clearDict(ZSTD_DCtx *dctx)
Definition: zstd.c:35665
MaxLL
#define MaxLL
Definition: zstd.c:10845
ZSTDMT_CCtx_s::jobs
ZSTDMT_jobDescription * jobs
Definition: zstd.c:31834
nlohmann::detail::parse_event_t::value
@ value
the parser finished reading a JSON value
GEN_ZSTD_ROW_SEARCH_FN
#define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)
Definition: zstd.c:27893
ZSTD_ldm_fillHashTable
void ZSTD_ldm_fillHashTable(ldmState_t *state, const BYTE *ip, const BYTE *iend, ldmParams_t const *params)
Definition: zstd.c:29063
ZSTD_cpm_noAttachDict
@ ZSTD_cpm_noAttachDict
Definition: zstd.c:14861
ZSTD_createDStream_advanced
ZSTD_DStream * ZSTD_createDStream_advanced(ZSTD_customMem customMem)
Definition: zstd.c:37007
ZSTD_cwksp_estimated_space_within_bounds
MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace)
Definition: zstd.c:14238
ZSTD_cwksp_alloc_phase_e
ZSTD_cwksp_alloc_phase_e
Definition: zstd.c:13582
DTableDesc::maxTableLog
BYTE maxTableLog
Definition: zstd.c:33003
ZSTD_DCtx_s::ddict
const ZSTD_DDict * ddict
Definition: zstd.c:34938
ZSTD_CCtx_params_s::nbWorkers
int nbWorkers
Definition: zstd.c:14689
ZSTD_pthread_join
#define ZSTD_pthread_join(a)
Definition: zstd.c:3919
ZSTDMT_CCtx_s::jobReady
int jobReady
Definition: zstd.c:31841
ZSTD_DDictHashSet::ddictPtrCount
size_t ddictPtrCount
Definition: zstd.c:34883
COVER_ctx_init
static size_t COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, unsigned d, double splitPoint)
Definition: zstd.c:41088
ZSTDMT_doesOverlapWindow
static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
Definition: zstd.c:32576
FSE_DecompressWksp::ncount
short ncount[FSE_MAX_SYMBOL_VALUE+1]
Definition: zstd.c:3730
XXH64_state_s::total_len
XXH64_hash_t total_len
Definition: zstd.c:5912
ZSTDMT_writeLastEmptyBlock
static void ZSTDMT_writeLastEmptyBlock(ZSTDMT_jobDescription *job)
Definition: zstd.c:32331
BIT_DStream_t::ptr
const char * ptr
Definition: zstd.c:2085
ZDICT_dictSize
static U32 ZDICT_dictSize(const dictItem *dictList)
Definition: zstd.c:45004
ZSTD_llt_none
@ ZSTD_llt_none
Definition: zstd.c:11026
MEM_read64
MEM_STATIC U64 MEM_read64(const void *memPtr)
Definition: zstd.c:1054
ZSTD_frameSizeInfo
Definition: zstd.c:11081
XXH3_128bits_update
#define XXH3_128bits_update
ZSTD_ldm_limitTableUpdate
static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t *ms, const BYTE *anchor)
Definition: zstd.c:29108
MEM_STATIC
#define MEM_STATIC
Definition: zstd.c:879
ZSTD_highbit32
MEM_STATIC unsigned ZSTD_highbit32(U32 val)
Definition: zstd.c:1990
RANK_POSITION_TABLE_SIZE
#define RANK_POSITION_TABLE_SIZE
Definition: zstd.c:12531
FSE_buildDTable_internal
static size_t FSE_buildDTable_internal(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize)
Definition: zstd.c:3550
ZSTD_compressBlock_fast_dictMatchState_generic
FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_fast_dictMatchState_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls, U32 const hasStep)
Definition: zstd.c:26027
ZSTDMT_CCtx_s
Definition: zstd.c:31832
FSE_BUILD_DTABLE_WKSP_SIZE
#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue)
Definition: zstd.c:2466
BIT_reloadDStream
MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD)
Definition: zstd.c:2388
INLINE
#define INLINE
Definition: zstd.c:41915
ZSTD_estimateBlockSize
static size_t ZSTD_estimateBlockSize(const BYTE *literals, size_t litSize, const BYTE *ofCodeTable, const BYTE *llCodeTable, const BYTE *mlCodeTable, size_t nbSeq, const ZSTD_entropyCTables_t *entropy, const ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, size_t wkspSize, int writeLitEntropy, int writeSeqEntropy)
Definition: zstd.c:21403
POOL_joinJobs
void POOL_joinJobs(POOL_ctx *ctx)
Definition: zstd.c:4475
ZSTD_compressBlock_greedy_dedicatedDictSearch
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28360
ZSTD_cwksp_alloc_aligned_init_once
@ ZSTD_cwksp_alloc_aligned_init_once
Definition: zstd.c:13584
ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
Definition: zstd.c:22633
FSE_isError
#define FSE_isError
Definition: zstd.c:11274
ZSTD_advanceHashSalt
static void ZSTD_advanceHashSalt(ZSTD_matchState_t *ms)
Definition: zstd.c:19563
ZSTD_strategy
ZSTD_strategy
Definition: zstd.h:315
HUF_decompress4X1_usingDTable_internal
static size_t HUF_decompress4X1_usingDTable_internal(void *dst, size_t dstSize, void const *cSrc, size_t cSrcSize, HUF_DTable const *DTable, int flags)
Definition: zstd.c:33714
ZSTD_entropyDTables_t::rep
U32 rep[ZSTD_REP_NUM]
Definition: zstd.c:34861
ZSTD_estimateCStreamSize_usingCCtxParams
size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params *params)
Definition: zstd.c:19394
ZSTD_btultra
@ ZSTD_btultra
Definition: zstd.h:324
BIT_lookBitsFast
MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t *bitD, U32 nbBits)
Definition: zstd.c:2333
source
const char * source
Definition: lz4.h:767
ZSTD_ldm_skipRawSeqStoreBytes
void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t *rawSeqStore, size_t nbBytes)
Definition: zstd.c:29439
ZSTD_cwksp::allocStart
void * allocStart
Definition: zstd.c:13700
ZSTD_error_frameParameter_windowTooLarge
@ ZSTD_error_frameParameter_windowTooLarge
Definition: zstd.c:1369
ZSTDMT_CCtx_s::params
ZSTD_CCtx_params params
Definition: zstd.c:31838
ZSTDMT_CCtx_s::bufPool
ZSTDMT_bufferPool * bufPool
Definition: zstd.c:31835
XXH_readLE32
XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void *ptr)
Definition: zstd.c:6743
seqStore_t::lit
BYTE * lit
Definition: zstd.c:11035
COVER_segment_t::score
U32 score
Definition: zstd.c:40467
seqDef_s::offBase
U32 offBase
Definition: zstd.c:11019
XXH32_endian_align
XXH_FORCE_INLINE xxh_u32 XXH32_endian_align(const xxh_u8 *input, size_t len, xxh_u32 seed, XXH_alignment align)
Definition: zstd.c:6977
ZSTD_MAGIC_SKIPPABLE_START
#define ZSTD_MAGIC_SKIPPABLE_START
Definition: zstd.h:139
COVER_map_s::data
COVER_map_pair_t * data
Definition: zstd.c:40643
ZSTD_reset_compressedBlockState
void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t *bs)
Definition: zstd.c:19501
ZSTD_selectBtGetAllMatches
static ZSTD_getAllMatchesFn ZSTD_selectBtGetAllMatches(ZSTD_matchState_t const *ms, ZSTD_dictMode_e const dictMode)
Definition: zstd.c:30398
ZSTD_blockSplitCtx
Definition: zstd.c:14757
ZSTD_initFseState
static void ZSTD_initFseState(ZSTD_fseState *DStatePtr, BIT_DStream_t *bitD, const ZSTD_seqSymbol *dt)
Definition: zstd.c:38863
ZSTDMT_CCtx_s::roundBuff
roundBuff_t roundBuff
Definition: zstd.c:31843
ZSTDMT_jobDescription::prefix
range_t prefix
Definition: zstd.c:31645
ZSTD_CCtx_params_s::overlapLog
int overlapLog
Definition: zstd.c:14691
ZSTD_CCtx_s::stage
ZSTD_compressionStage_e stage
Definition: zstd.c:14777
COVER_map_s::sizeMask
U32 sizeMask
Definition: zstd.c:40646
ZSTD_CCtx_getParameter
size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const *cctx, ZSTD_cParameter param, int *value)
Definition: zstd.c:18652
ZSTD_compressBlock_fast_extDict
size_t ZSTD_compressBlock_fast_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:26510
FSE_decode_t::newState
unsigned short newState
Definition: zstd.c:2711
MEM_readST
MEM_STATIC size_t MEM_readST(const void *memPtr)
Definition: zstd.c:1059
ZSTD_DCtx_s::bType
blockType_e bType
Definition: zstd.c:34918
kSearchStrength
#define kSearchStrength
Definition: zstd.c:14405
ZSTD_ErrorCode
ZSTD_ErrorCode
Definition: zstd.c:1363
HUF_DECODE_SYMBOLX2_2
#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr)
Definition: zstd.c:34116
ZSTD_compressBlock_fast
size_t ZSTD_compressBlock_fast(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:25990
U64
unsigned long long U64
Definition: lz4.c:316
ZSTDcrp_makeClean
@ ZSTDcrp_makeClean
Definition: zstd.c:19534
ldmState_t::loadedDictEnd
U32 loadedDictEnd
Definition: zstd.c:14648
_trbudget_t
Definition: zstd.c:42906
ZSTD_DStreamOutSize
size_t ZSTD_DStreamOutSize(void)
Definition: zstd.c:37021
seqStore_t::ofCode
BYTE * ofCode
Definition: zstd.c:11038
ZSTD_CCtxParams_setZstdParams
static void ZSTD_CCtxParams_setZstdParams(ZSTD_CCtx_params *cctxParams, const ZSTD_parameters *params)
Definition: zstd.c:18052
ZSTD_pthread_mutex_unlock
#define ZSTD_pthread_mutex_unlock(a)
Definition: zstd.c:3908
ZSTD_not_in_dst
@ ZSTD_not_in_dst
Definition: zstd.c:34897
ZSTD_LITBUFFEREXTRASIZE
#define ZSTD_LITBUFFEREXTRASIZE
Definition: zstd.c:34894
ZSTD_copyBlockSequences
static void ZSTD_copyBlockSequences(ZSTD_CCtx *zc)
Definition: zstd.c:20946
ZSTD_DCtx_s::fParams
ZSTD_frameHeader fParams
Definition: zstd.c:34915
ZSTD_dtlm_full
@ ZSTD_dtlm_full
Definition: zstd.c:14850
ZSTD_defaultDisallowed
@ ZSTD_defaultDisallowed
Definition: zstd.c:16178
ZSTD_CCtx_s
Definition: zstd.c:14776
HINT_INLINE
#define HINT_INLINE
Definition: zstd.c:575
XXH_readLE64
XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void *ptr)
Definition: zstd.c:7280
format
auto format(const text_style &ts, const S &format_str, const Args &... args) -> std::basic_string< Char >
Definition: color.h:543
ldmParams_t
Definition: zstd.c:14654
ZSTD_compress_frameChunk
static size_t ZSTD_compress_frameChunk(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastFrameChunk)
Definition: zstd.c:22030
ZSTD_getSeqStore
const seqStore_t * ZSTD_getSeqStore(const ZSTD_CCtx *ctx)
Definition: zstd.c:17858
ZSTD_CCtx_params_s::useBlockSplitter
ZSTD_paramSwitch_e useBlockSplitter
Definition: zstd.c:14709
HUF_isSorted
MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1)
Definition: zstd.c:12567
ZSTD_CCtx_s::dictID
U32 dictID
Definition: zstd.c:14783
ZSTD_e_continue
@ ZSTD_e_continue
Definition: zstd.h:746
ZSTD_c_nbWorkers
@ ZSTD_c_nbWorkers
Definition: zstd.h:437
DEBUG_STATIC_ASSERT
#define DEBUG_STATIC_ASSERT(c)
Definition: zstd.c:235
ZDICT_fastCover_params_t::k
unsigned k
Definition: zstd.c:40259
maxDstSize
char int int maxDstSize
Definition: lz4.h:792
FSE_symbolCompressionTransform
Definition: zstd.c:2622
ZSTD_hash4PtrS
static size_t ZSTD_hash4PtrS(const void *ptr, U32 h, U32 s)
Definition: zstd.c:15170
XXH3_128bits_withSecret
#define XXH3_128bits_withSecret
BIT_flushBits
MEM_STATIC void BIT_flushBits(BIT_CStream_t *bitC)
Definition: zstd.c:2208
ZSTD_setBufferExpectations
static void ZSTD_setBufferExpectations(ZSTD_CCtx *cctx, const ZSTD_outBuffer *output, const ZSTD_inBuffer *input)
Definition: zstd.c:23709
ZSTD_estimateCStreamSize
size_t ZSTD_estimateCStreamSize(int compressionLevel)
Definition: zstd.c:19437
ZSTD_CCtx_params_s::attachDictPref
ZSTD_dictAttachPref_e attachDictPref
Definition: zstd.c:14685
ZSTD_resolveMaxBlockSize
static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize)
Definition: zstd.c:17925
ZSTD_VERSION_NUMBER
#define ZSTD_VERSION_NUMBER
Definition: zstd.h:110
ZSTD_optLdm_processMatchCandidate
static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t *optLdm, ZSTD_match_t *matches, U32 *nbMatches, U32 currPosInBlock, U32 remainingBytes)
Definition: zstd.c:30533
ZSTD_flushStream
size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)
Definition: zstd.c:24485
kNullRawSeqStore
static const UNUSED_ATTR rawSeqStore_t kNullRawSeqStore
Definition: zstd.c:14523
ZSTD_initStaticDStream
ZSTD_DStream * ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
Definition: zstd.c:37002
ZSTD_CCtx_s::maxNbLdmSequences
size_t maxNbLdmSequences
Definition: zstd.c:14802
HUF_WORKSPACE_MAX_ALIGNMENT
#define HUF_WORKSPACE_MAX_ALIGNMENT
Definition: zstd.c:12158
ZSTD_error_maxCode
@ ZSTD_error_maxCode
Definition: zstd.c:1399
HUF_optimalTableLog
unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void *workSpace, size_t wkspSize, HUF_CElt *table, const unsigned *count, int flags)
Definition: zstd.c:13287
ZSTD_insertBt1
static U32 ZSTD_insertBt1(const ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iend, U32 const target, U32 const mls, const int extDict)
Definition: zstd.c:29956
GETIDX
#define GETIDX(a)
ZSTDMT_jobDescription::dstBuff
buffer_t dstBuff
Definition: zstd.c:31644
ZSTD_hash6Ptr
static size_t ZSTD_hash6Ptr(const void *p, U32 h)
Definition: zstd.c:15179
ZSTD_longLengthType_e
ZSTD_longLengthType_e
Definition: zstd.c:11025
ZSTD_comparePackedTags
MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2)
Definition: zstd.c:15747
ZSTD_matchState_t::hashLog3
U32 hashLog3
Definition: zstd.c:14590
ZSTD_llt_literalLength
@ ZSTD_llt_literalLength
Definition: zstd.c:11027
ZSTD_cwksp_aligned_alloc_size
MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size)
Definition: zstd.c:13775
ZSTD_CCtx_trace
void ZSTD_CCtx_trace(ZSTD_CCtx *cctx, size_t extraCSize)
Definition: zstd.c:22784
ZSTD_getMatchPrice
FORCE_INLINE_TEMPLATE U32 ZSTD_getMatchPrice(U32 const offBase, U32 const matchLength, const optState_t *const optPtr, int const optLevel)
Definition: zstd.c:29842
ZSTD_seqSymbol_header
Definition: zstd.c:34838
HUF_DECODE_SYMBOLX2_1
#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr)
Definition: zstd.c:34112
ZSTD_CCtx_params_s::format
ZSTD_format_e format
Definition: zstd.c:14671
XXH_read32
static xxh_u32 XXH_read32(const void *memPtr)
Definition: zstd.c:6581
MEM_read32
MEM_STATIC U32 MEM_read32(const void *memPtr)
Definition: zstd.c:1049
ZSTD_cwksp_reserve_table
MEM_STATIC void * ZSTD_cwksp_reserve_table(ZSTD_cwksp *ws, size_t bytes)
Definition: zstd.c:13974
HUF_CElt
size_t HUF_CElt
Definition: zstd.c:2894
BIT_reloadDStreamFast
MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t *bitD)
Definition: zstd.c:2372
ZSTD_error_dstSize_tooSmall
@ ZSTD_error_dstSize_tooSmall
Definition: zstd.c:1387
ZSTD_countTrailingZeros64
MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val)
Definition: zstd.c:1911
ZSTD_reduceIndex
static void ZSTD_reduceIndex(ZSTD_matchState_t *ms, ZSTD_CCtx_params const *params, const U32 reducerValue)
Definition: zstd.c:20248
ZSTDMT_jobDescription::seqPool
ZSTDMT_seqPool * seqPool
Definition: zstd.c:31642
MaxOff
#define MaxOff
Definition: zstd.c:10847
HUF_DEltX2::sequence
U16 sequence
Definition: zstd.c:33770
XXH64_avalanche
static xxh_u64 XXH64_avalanche(xxh_u64 h64)
Definition: zstd.c:7339
DTableDesc
Definition: zstd.c:33003
compressionLevel
char int int compressionLevel
Definition: lz4hc.h:256
ZSTD_window_t::base
BYTE const * base
Definition: zstd.c:14564
HUF_ReadDTableX2_Workspace::rankStart0
U32 rankStart0[HUF_TABLELOG_MAX+3]
Definition: zstd.c:33990
HUF_repeat_check
@ HUF_repeat_check
Definition: zstd.c:2978
COVER_dictSelection
Definition: zstd.c:40481
ZSTD_insertAndFindFirstIndex
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t *ms, const BYTE *ip)
Definition: zstd.c:27177
ZSTD_getLowestMatchIndex
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t *ms, U32 curr, unsigned windowLog)
Definition: zstd.c:15653
UNLIKELY
#define UNLIKELY(x)
Definition: zstd.c:666
ZSTDds_decompressBlock
@ ZSTDds_decompressBlock
Definition: zstd.c:34866
loadSize
static size_t loadSize(LoadState *S)
Definition: lundump.c:83
ZSTDMT_CCtxPool::totalCCtx
int totalCCtx
Definition: zstd.c:31347
ZSTD_CStreamOutSize
size_t ZSTD_CStreamOutSize(void)
Definition: zstd.c:23353
FSE_MAX_SYMBOL_VALUE
#define FSE_MAX_SYMBOL_VALUE
Definition: zstd.c:2794
ZDICT_legacy_params_t::selectivityLevel
unsigned selectivityLevel
Definition: zstd.c:40358
BIT_initDStream
MEM_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize)
Definition: zstd.c:2241
HUF_flags_bmi2
@ HUF_flags_bmi2
Definition: zstd.c:2922
ZSTDMT_CCtxPool
Definition: zstd.c:31345
ZSTD_cwksp_check_available
MEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp *ws, size_t additionalNeededSpace)
Definition: zstd.c:14250
ZSTD_window_t
Definition: zstd.c:14562
COVER_warnOnSmallCorpus
void COVER_warnOnSmallCorpus(size_t maxDictSize, size_t nbDmers, int displayLevel)
Definition: zstd.c:41186
search_hashChain
@ search_hashChain
Definition: zstd.c:27932
SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO
#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO
Definition: zstd.c:20468
FSE_decompress_wksp_bmi2
size_t FSE_decompress_wksp_bmi2(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workSpace, size_t wkspSize, int bmi2)
Definition: zstd.c:3791
ZSTD_searchMax
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)
Definition: zstd.c:27995
ZSTD_FOR_EACH_MLS
#define ZSTD_FOR_EACH_MLS(X, dictMode)
Definition: zstd.c:27914
HUF_ReadDTableX1_Workspace
Definition: zstd.c:33217
ZSTD_entropyCTables_t
Definition: zstd.c:14444
ZSTDMT_CCtx_s::nextJobID
unsigned nextJobID
Definition: zstd.c:31848
ZSTD_deriveBlockSplits
static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx *zc, U32 partitions[], U32 nbSeq)
Definition: zstd.c:21717
ZSTDMT_getFrameProgression
ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32079
FSE_DTableHeader
Definition: zstd.c:2704
ZSTD_compressLiterals
size_t ZSTD_compressLiterals(void *dst, size_t dstCapacity, const void *src, size_t srcSize, void *entropyWorkspace, size_t entropyWorkspaceSize, const ZSTD_hufCTables_t *prevHuf, ZSTD_hufCTables_t *nextHuf, ZSTD_strategy strategy, int disableLiteralCompression, int suspectUncompressible, int bmi2)
Definition: zstd.c:16038
ZSTD_blockState_t::matchState
ZSTD_matchState_t matchState
Definition: zstd.c:14628
ZSTD_nextInputType
ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx)
Definition: zstd.c:36571
ZSTD_buildBlockEntropyStats
size_t ZSTD_buildBlockEntropyStats(const seqStore_t *seqStorePtr, const ZSTD_entropyCTables_t *prevEntropy, ZSTD_entropyCTables_t *nextEntropy, const ZSTD_CCtx_params *cctxParams, ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, size_t wkspSize)
Definition: zstd.c:21277
ZSTD_DCtx_s::customMem
ZSTD_customMem customMem
Definition: zstd.c:34928
ZSTD_use_indefinitely
@ ZSTD_use_indefinitely
Definition: zstd.c:34874
ZSTD_cpm_attachDict
@ ZSTD_cpm_attachDict
Definition: zstd.c:14865
seqStore_t::llCode
BYTE * llCode
Definition: zstd.c:11036
ZSTD_litLengthPrice
static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t *const optPtr, int optLevel)
Definition: zstd.c:29813
ZSTD_endStream
size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)
Definition: zstd.c:24493
dest
char * dest
Definition: lz4.h:765
ZSTD_localDict::dictBuffer
void * dictBuffer
Definition: zstd.c:14423
ZSTD_CCtx_s::cdict
const ZSTD_CDict * cdict
Definition: zstd.c:14830
COVER_best_destroy
void COVER_best_destroy(COVER_best_t *best)
Definition: zstd.c:41418
ZSTD_compressedBlockState_t::rep
U32 rep[ZSTD_REP_NUM]
Definition: zstd.c:14559
ZSTD_dfast
@ ZSTD_dfast
Definition: zstd.h:318
ZSTD_needSequenceEntropyTables
static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const *fseMetadata)
Definition: zstd.c:17089
ZSTDMT_setNbSeq
static void ZSTDMT_setNbSeq(ZSTDMT_seqPool *const seqPool, size_t const nbSeq)
Definition: zstd.c:31318
ZSTD_reset_session_only
@ ZSTD_reset_session_only
Definition: zstd.h:555
ZSTD_compressBlock_lazy_row
size_t ZSTD_compressBlock_lazy_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28375
FSE_MAX_TABLELOG
#define FSE_MAX_TABLELOG
Definition: zstd.c:2811
COVER_epoch_info_t::num
U32 num
Definition: zstd.c:40474
ZSTD_match_t::off
U32 off
Definition: zstd.c:14500
ZSTD_freeDCtx
size_t ZSTD_freeDCtx(ZSTD_DCtx *dctx)
Definition: zstd.c:35673
ZSTD_DDict_s::dictBuffer
void * dictBuffer
Definition: zstd.c:35073
ZSTD_buildDummySequencesStatistics
static ZSTD_symbolEncodingTypeStats_t ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t *nextEntropy)
Definition: zstd.c:21223
divsufsort
int divsufsort(const unsigned char *T, int *SA, int n, int openMP)
Definition: zstd.c:43712
ZSTD_c_strategy
@ ZSTD_c_strategy
Definition: zstd.h:389
ZSTD_error_dstBuffer_null
@ ZSTD_error_dstBuffer_null
Definition: zstd.c:1389
HUF_ReadDTableX1_Workspace::huffWeight
BYTE huffWeight[HUF_SYMBOLVALUE_MAX+1]
Definition: zstd.c:33222
optState_t::litLengthFreq
unsigned * litLengthFreq
Definition: zstd.c:14538
sol::meta_function::mode
@ mode
ZSTDMT_CCtxPool::availCCtx
int availCCtx
Definition: zstd.c:31348
ZSTD_buildCTable
size_t ZSTD_buildCTable(void *dst, size_t dstCapacity, FSE_CTable *nextCTable, U32 FSELog, symbolEncodingType_e type, unsigned *count, U32 max, const BYTE *codeTable, size_t nbSeq, const S16 *defaultNorm, U32 defaultNormLog, U32 defaultMax, const FSE_CTable *prevCTable, size_t prevCTableSize, void *entropyWorkspace, size_t entropyWorkspaceSize)
Definition: zstd.c:16444
prime6bytes
static const U64 prime6bytes
Definition: zstd.c:15177
ERR_getErrorCode
ERR_STATIC ERR_enum ERR_getErrorCode(size_t code)
Definition: zstd.c:1450
ZSTD_externalMatchCtx::seqBufferCapacity
size_t seqBufferCapacity
Definition: zstd.c:14773
ZSTD_resolveExternalRepcodeSearch
static ZSTD_paramSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_paramSwitch_e value, int cLevel)
Definition: zstd.c:17933
ZSTD_compressEnd_public
size_t ZSTD_compressEnd_public(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22808
ZSTD_btopt
@ ZSTD_btopt
Definition: zstd.h:323
ZSTDMT_jobDescription::cctxPool
ZSTDMT_CCtxPool * cctxPool
Definition: zstd.c:31640
search_binaryTree
@ search_binaryTree
Definition: zstd.c:27932
HUF_getValue
static size_t HUF_getValue(HUF_CElt elt)
Definition: zstd.c:12246
start
ROSCPP_DECL void start()
BIT_CStream_t::endPtr
char * endPtr
Definition: zstd.c:2053
backward::Color::reset
@ reset
Definition: backward.hpp:3678
OFFBASE_IS_REPCODE
#define OFFBASE_IS_REPCODE(o)
Definition: zstd.c:15007
LOCALDISPLAYLEVEL
#define LOCALDISPLAYLEVEL(displayLevel, l,...)
Definition: zstd.c:43843
ZSTD_error_GENERIC
@ ZSTD_error_GENERIC
Definition: zstd.c:1365
POOL_resize
int POOL_resize(POOL_ctx *ctx, size_t numThreads)
Definition: zstd.c:4525
ZSTD_decompressContinue
size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:36602
HIST_WKSP_SIZE_U32
#define HIST_WKSP_SIZE_U32
Definition: zstd.c:11222
g_coverCtx
static COVER_ctx_t * g_coverCtx
Definition: zstd.c:40774
ZSTD_decompressBegin
size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx)
Definition: zstd.c:36885
udp_client.int
int
Definition: udp_client.py:11
ZSTD_cpuid_t
Definition: zstd.c:4720
STARTNODE
#define STARTNODE
Definition: zstd.c:12695
XXH3_64bits_withSecretandSeed
#define XXH3_64bits_withSecretandSeed
ZSTD_symbolEncodingTypeStats_t::lastCountSize
size_t lastCountSize
Definition: zstd.c:20333
ZSTD_seqStore_resolveOffCodes
static void ZSTD_seqStore_resolveOffCodes(repcodes_t *const dRepcodes, repcodes_t *const cRepcodes, const seqStore_t *const seqStore, U32 const nbSeq)
Definition: zstd.c:21549
ZSTD_cwksp_alloc_buffers
@ ZSTD_cwksp_alloc_buffers
Definition: zstd.c:13586
ZSTD_CCtx_s::prefixDict
ZSTD_prefixDict prefixDict
Definition: zstd.c:14831
ZSTD_cpuid
MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void)
Definition: zstd.c:4727
ZSTD_createDDict
ZSTD_DDict * ZSTD_createDDict(const void *dict, size_t dictSize)
Definition: zstd.c:35206
XXH_readLE32_align
XXH_FORCE_INLINE xxh_u32 XXH_readLE32_align(const void *ptr, XXH_alignment align)
Definition: zstd.c:6755
POOL_job_s::function
POOL_function function
Definition: zstd.c:4311
ZSTD_DCtx_s::processedCSize
U64 processedCSize
Definition: zstd.c:34916
HUF_DECODER_FAST_TABLELOG
#define HUF_DECODER_FAST_TABLELOG
Definition: zstd.c:32899
HUF_readStats_body_default
static size_t HUF_readStats_body_default(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workSpace, size_t wkspSize)
Definition: zstd.c:3393
ss_isqrt
static INLINE int ss_isqrt(int x)
Definition: zstd.c:42063
zdss_loadHeader
@ zdss_loadHeader
Definition: zstd.c:34870
serialState_t::ldmWindowMutex
ZSTD_pthread_mutex_t ldmWindowMutex
Definition: zstd.c:31462
FORCE_INLINE_ATTR
#define FORCE_INLINE_ATTR
Definition: zstd.c:534
SEQ_POOL_MAX_NB_BUFFERS
#define SEQ_POOL_MAX_NB_BUFFERS(nbWorkers)
Definition: zstd.c:31271
ZSTD_window_update
MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t *window, void const *src, size_t srcSize, int forceNonContiguous)
Definition: zstd.c:15613
HUF_getNbBitsFromCTable
U32 HUF_getNbBitsFromCTable(const HUF_CElt *symbolTable, U32 symbolValue)
Definition: zstd.c:12370
COVER_dictSelectionError
COVER_dictSelection_t COVER_dictSelectionError(size_t error)
Definition: zstd.c:41501
ZSTD_compressBlock_greedy_row
size_t ZSTD_compressBlock_greedy_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28382
XXH32_canonicalFromHash
#define XXH32_canonicalFromHash
ZSTD_estimateCDictSize_advanced
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod)
Definition: zstd.c:22922
tr_copy
static void tr_copy(int *ISA, const int *SA, int *first, int *a, int *b, int *last, int depth)
Definition: zstd.c:42977
COVER_tryParameters_data_s::ctx
const COVER_ctx_t * ctx
Definition: zstd.c:41604
ZSTD_CCtx_s::producedCSize
unsigned long long producedCSize
Definition: zstd.c:14790
ZDICT_fastCover_params_t::zParams
ZDICT_params_t zParams
Definition: zstd.c:40269
ZSTD_compressBlock_splitBlock_internal
static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t blockSize, U32 lastBlock, U32 nbSeq)
Definition: zstd.c:21739
ZSTD_DCtx_isOversizedTooLong
static int ZSTD_DCtx_isOversizedTooLong(ZSTD_DStream *zds)
Definition: zstd.c:37330
ZSTD_did_fieldSize
static const UNUSED_ATTR size_t ZSTD_did_fieldSize[4]
Definition: zstd.c:10821
XXH64_state_s::v
XXH64_hash_t v[4]
Definition: zstd.c:5913
ZSTD_window_hasExtDict
MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)
Definition: zstd.c:15324
ZSTD_updateTree_internal
FORCE_INLINE_TEMPLATE void ZSTD_updateTree_internal(ZSTD_matchState_t *ms, const BYTE *const ip, const BYTE *const iend, const U32 mls, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:30075
ZSTDMT_sizeof_CCtxPool
static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool *cctxPool)
Definition: zstd.c:31398
ZSTD_createDStream
ZSTD_DStream * ZSTD_createDStream(void)
Definition: zstd.c:36996
ZSTD_compressStream_generic
static size_t ZSTD_compressStream_generic(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input, ZSTD_EndDirective const flushMode)
Definition: zstd.c:23502
ZSTD_BT_GET_ALL_MATCHES_ARRAY
#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode)
Definition: zstd.c:30389
ZSTD_CCtx_loadDictionary_byReference
size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx *cctx, const void *dict, size_t dictSize)
Definition: zstd.c:18940
ZSTD_inBuffer_s::src
const void * src
Definition: zstd.h:666
ZSTD_fillDoubleHashTableForCDict
static void ZSTD_fillDoubleHashTableForCDict(ZSTD_matchState_t *ms, void const *end, ZSTD_dictTableLoadMethod_e dtlm)
Definition: zstd.c:24822
ZSTD_ROW_HASH_TAG_BITS
#define ZSTD_ROW_HASH_TAG_BITS
Definition: zstd.c:17390
ZSTD_cParam_withinBounds
MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
Definition: zstd.c:14920
rawSeq::matchLength
U32 matchLength
Definition: zstd.c:14505
ERR_getErrorName
const ERR_STATIC char * ERR_getErrorName(size_t code)
Definition: zstd.c:1463
ZSTD_noDict
@ ZSTD_noDict
Definition: zstd.c:14854
ZSTD_initDDict_internal
static size_t ZSTD_initDDict_internal(ZSTD_DDict *ddict, const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:35156
ZSTD_ldm_generateSequences
size_t ZSTD_ldm_generateSequences(ldmState_t *ldms, rawSeqStore_t *sequences, ldmParams_t const *params, void const *src, size_t srcSize)
Definition: zstd.c:29301
readSkippableFrameSize
static size_t readSkippableFrameSize(void const *src, size_t srcSize)
Definition: zstd.c:35934
COVER_map_hash
static U32 COVER_map_hash(COVER_map_t *map, U32 key)
Definition: zstd.c:40680
ZSTD_decompressContinueStream
static size_t ZSTD_decompressContinueStream(ZSTD_DStream *zds, char **op, char *oend, void const *src, size_t srcSize)
Definition: zstd.c:37358
FSE_DTableHeader::tableLog
U16 tableLog
Definition: zstd.c:2705
COPY8
#define COPY8(d, s)
Definition: zstd.c:10918
ZSTD_c_targetLength
@ ZSTD_c_targetLength
Definition: zstd.h:381
FSE_updateState
MEM_STATIC void FSE_updateState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
Definition: zstd.c:2731
ZSTDbss_noCompress
@ ZSTDbss_noCompress
Definition: zstd.c:20783
EStats_ress_t::dict
ZSTD_CDict * dict
Definition: zstd.c:45101
sortedSymbol_t
Definition: zstd.c:33771
ZSTD_DCtx_s
Definition: zstd.c:34902
ZSTDMT_CCtx_s::targetPrefixSize
size_t targetPrefixSize
Definition: zstd.c:31840
ZSTDMT_initCStream_internal
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx *mtctx, const void *dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, const ZSTD_CDict *cdict, ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
Definition: zstd.c:32215
ZSTD_sizeof_CDict
size_t ZSTD_sizeof_CDict(const ZSTD_CDict *cdict)
Definition: zstd.c:22943
ldmMatchCandidate_t::hash
U32 hash
Definition: zstd.c:14638
XXH32_state_s
Definition: zstd.c:5887
ZSTD_c_hashLog
@ ZSTD_c_hashLog
Definition: zstd.h:355
XXH32_state_s::v
XXH32_hash_t v[4]
Definition: zstd.c:5890
ZSTD_DCtx_s::lhSize
size_t lhSize
Definition: zstd.c:34956
FASTCOVER_convertToCoverParams
static void FASTCOVER_convertToCoverParams(ZDICT_fastCover_params_t fastCoverParams, ZDICT_cover_params_t *coverParams)
Definition: zstd.c:44298
ZSTD_toFlushNow
size_t ZSTD_toFlushNow(ZSTD_CCtx *cctx)
Definition: zstd.c:19476
ZSTD_btlazy2
@ ZSTD_btlazy2
Definition: zstd.h:322
HUF_buildTree
static int HUF_buildTree(nodeElt *huffNode, U32 maxSymbolValue)
Definition: zstd.c:12704
HUF_buildCTable_wksp_tables
Definition: zstd.c:12533
COVER_buildDictionary
static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs, COVER_map_t *activeDmers, void *dictBuffer, size_t dictBufferCapacity, ZDICT_cover_params_t parameters)
Definition: zstd.c:41222
ZSTD_decompressSequencesSplitLitBuffer
static size_t ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, const int frame)
Definition: zstd.c:39646
BIT_DStream_overflow
@ BIT_DStream_overflow
Definition: zstd.c:2093
BIT_CStream_t
Definition: zstd.c:2048
ZSTD_compressBlock_lazy_dictMatchState_row
size_t ZSTD_compressBlock_lazy_dictMatchState_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28396
ZSTD_compressBlock_greedy_dictMatchState
size_t ZSTD_compressBlock_greedy_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28338
ZSTD_ldm_generateSequences_internal
static size_t ZSTD_ldm_generateSequences_internal(ldmState_t *ldmState, rawSeqStore_t *rawSeqStore, ldmParams_t const *params, void const *src, size_t srcSize)
Definition: zstd.c:29117
ldmEntry_t
Definition: zstd.c:14631
ZSTD_c_ldmBucketSizeLog
@ ZSTD_c_ldmBucketSizeLog
Definition: zstd.h:412
g_displayLevel
static int g_displayLevel
Definition: zstd.c:40596
ZSTD_compress_usingCDict_internal
static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict, ZSTD_frameParameters fParams)
Definition: zstd.c:23286
HUF_WORKSPACE_SIZE
#define HUF_WORKSPACE_SIZE
Definition: zstd.c:2870
ZSTD_compressBegin_usingCDict
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict)
Definition: zstd.c:23278
ZSTD_readSkippableFrame
size_t ZSTD_readSkippableFrame(void *dst, size_t dstCapacity, unsigned *magicVariant, const void *src, size_t srcSize)
Definition: zstd.c:35961
HUF_nbStreams_e
HUF_nbStreams_e
Definition: zstd.c:13237
ZSTD_match_t::len
U32 len
Definition: zstd.c:14501
HUF_rescaleStats
static U32 HUF_rescaleStats(BYTE *huffWeight, U32 *rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog)
Definition: zstd.c:33192
_trbudget_t::remain
int remain
Definition: zstd.c:42908
ZSTD_dParameter
ZSTD_dParameter
Definition: zstd.h:604
ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32
#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32
Definition: zstd.c:34853
ZSTDMT_createCCtxPool
static ZSTDMT_CCtxPool * ZSTDMT_createCCtxPool(int nbWorkers, ZSTD_customMem cMem)
Definition: zstd.c:31365
COVER_segment_t
Definition: zstd.c:40464
ZSTD_window_needOverflowCorrection
MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, U32 cycleLog, U32 maxDist, U32 loadedDictEnd, void const *src, void const *srcEnd)
Definition: zstd.c:15395
ZSTD_window_t::dictBase
BYTE const * dictBase
Definition: zstd.c:14565
ZSTDbss_compress
@ ZSTDbss_compress
Definition: zstd.c:20783
ZSTD_ROLL_HASH_CHAR_OFFSET
#define ZSTD_ROLL_HASH_CHAR_OFFSET
Definition: zstd.c:15243
ZSTD_symbolEncodingTypeStats_t
Definition: zstd.c:20328
ERR_STATIC
#define ERR_STATIC
Definition: zstd.c:1430
COVER_ctx_t::offsets
size_t * offsets
Definition: zstd.c:40761
HUF_repeat_valid
@ HUF_repeat_valid
Definition: zstd.c:2979
HUF_ReadDTableX2_Workspace::weightList
BYTE weightList[HUF_SYMBOLVALUE_MAX+1]
Definition: zstd.c:33992
ZSTD_hash8Ptr
static size_t ZSTD_hash8Ptr(const void *p, U32 h)
Definition: zstd.c:15189
ZSTD_DCtx_s::outBuff
char * outBuff
Definition: zstd.c:34952
ZSTD_blockSplitCtx::fullSeqStoreChunk
seqStore_t fullSeqStoreChunk
Definition: zstd.c:14758
ZSTD_compressBlock_lazy_extDict
size_t ZSTD_compressBlock_lazy_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28643
serialState_t::ldmWindow
ZSTD_window_t ldmWindow
Definition: zstd.c:31464
LLIMIT
#define LLIMIT
Definition: zstd.c:44715
HIST_isError
unsigned HIST_isError(size_t code)
Definition: zstd.c:11889
ZSTD_DCtx_s::inBuff
char * inBuff
Definition: zstd.c:34948
HIST_WKSP_SIZE
#define HIST_WKSP_SIZE
Definition: zstd.c:11223
ZSTD_entropyDTables_t::OFTable
ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]
Definition: zstd.c:34858
ZSTD_buildBlockEntropyStats_literals
static size_t ZSTD_buildBlockEntropyStats_literals(void *const src, size_t srcSize, const ZSTD_hufCTables_t *prevHuf, ZSTD_hufCTables_t *nextHuf, ZSTD_hufCTablesMetadata_t *hufMetadata, const int literalsCompressionIsDisabled, void *workspace, size_t wkspSize, int hufFlags)
Definition: zstd.c:21112
ZSTD_optLdm_t::startPosInBlock
U32 startPosInBlock
Definition: zstd.c:30420
ZSTD_copyCCtx
size_t ZSTD_copyCCtx(ZSTD_CCtx *dstCCtx, const ZSTD_CCtx *srcCCtx, unsigned long long pledgedSrcSize)
Definition: zstd.c:20173
XXH_errorcode
#define XXH_errorcode
XXH_PROCESS1
#define XXH_PROCESS1
ZSTD_c_dictIDFlag
@ ZSTD_c_dictIDFlag
Definition: zstd.h:429
ZSTDMT_CCtx_s::cMem
ZSTD_customMem cMem
Definition: zstd.c:31854
ZSTD_cwksp_mark_tables_dirty
MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp *ws)
Definition: zstd.c:14058
XXH32_canonical_t
Canonical (big endian) representation of XXH32_hash_t.
Definition: xxhash.h:204
ZSTD_CLEVEL_DEFAULT
#define ZSTD_CLEVEL_DEFAULT
Definition: zstd.h:129
ZSTD_localDict::cdict
ZSTD_CDict * cdict
Definition: zstd.c:14427
ZSTDMT_CCtx_s::rsync
rsyncState_t rsync
Definition: zstd.c:31845
HUF_decompress4X2_usingDTable_internal_body
FORCE_INLINE_TEMPLATE size_t HUF_decompress4X2_usingDTable_internal_body(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
Definition: zstd.c:34197
ZSTD_compressBlock_btlazy2_dictMatchState
size_t ZSTD_compressBlock_btlazy2_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28317
XXH64_createState
#define XXH64_createState
Definition: zstd.c:7448
RSYNC_MIN_BLOCK_SIZE
#define RSYNC_MIN_BLOCK_SIZE
Definition: zstd.c:31824
ZSTD_compressBegin_advanced
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize)
Definition: zstd.c:22706
ZSTD_cwksp_move
MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp *dst, ZSTD_cwksp *src)
Definition: zstd.c:14212
ZSTD_compressBegin_usingCDict_internal
static size_t ZSTD_compressBegin_usingCDict_internal(ZSTD_CCtx *const cctx, const ZSTD_CDict *const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
Definition: zstd.c:23222
HUF_TABLELOG_DEFAULT
#define HUF_TABLELOG_DEFAULT
Definition: zstd.c:2875
ZSTD_entropyDTables_t::workspace
U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32]
Definition: zstd.c:34862
ZSTD_decodingBufferSize_min
size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
Definition: zstd.c:37282
ZSTD_resetCCtx_byAttachingCDict
static size_t ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, ZSTD_CCtx_params params, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff)
Definition: zstd.c:19908
ZSTD_createCCtx_advanced
ZSTD_CCtx * ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
Definition: zstd.c:17752
ZDICT_fastCover_params_t::splitPoint
double splitPoint
Definition: zstd.c:40264
COVER_cmp
static int COVER_cmp(COVER_ctx_t *ctx, const void *lp, const void *rp)
Definition: zstd.c:40797
ZSTD_decompressDCtx
size_t ZSTD_decompressDCtx(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:36524
COVER_dictSelection::dictSize
size_t dictSize
Definition: zstd.c:40483
BUCKET_A
#define BUCKET_A(_c0)
Definition: zstd.c:41993
ZSTD_pthread_mutex_t
#define ZSTD_pthread_mutex_t
Definition: zstd.c:3904
ZSTD_BuildCTableWksp
Definition: zstd.c:16438
XXH_CPU_LITTLE_ENDIAN
#define XXH_CPU_LITTLE_ENDIAN
Whether the target is little endian.
Definition: zstd.c:6637
serialState_t::nextJobID
unsigned nextJobID
Definition: zstd.c:31458
ZSTD_CCtx_s::inBuffPos
size_t inBuffPos
Definition: zstd.c:14814
XXH64_state_s::reserved64
XXH64_hash_t reserved64
Definition: zstd.c:5917
ZSTDds_decodeBlockHeader
@ ZSTDds_decodeBlockHeader
Definition: zstd.c:34866
ZSTDMT_CCtx_s::cctxPool
ZSTDMT_CCtxPool * cctxPool
Definition: zstd.c:31836
ZSTD_CDictIndicesAreTagged
static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters *const cParams)
Definition: zstd.c:17944
ZSTD_pthread_mutex_destroy
#define ZSTD_pthread_mutex_destroy(a)
Definition: zstd.c:3906
ZSTD_MAX_FSE_HEADERS_SIZE
#define ZSTD_MAX_FSE_HEADERS_SIZE
Definition: zstd.c:10858
WILDCOPY_VECLEN
#define WILDCOPY_VECLEN
Definition: zstd.c:10941
HUF_CStream_t::ptr
BYTE * ptr
Definition: zstd.c:12863
MEM_swapST
MEM_STATIC size_t MEM_swapST(size_t in)
Definition: zstd.c:1125
XXH3_64bits_withSeed
#define XXH3_64bits_withSeed
XXH_rotl64
#define XXH_rotl64(x, r)
Definition: zstd.c:6678
ZSTD_GEN_DFAST_FN
#define ZSTD_GEN_DFAST_FN(dictMode, mls)
Definition: zstd.c:25341
ZSTD_cwksp_owns_buffer
MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp *ws, const void *ptr)
Definition: zstd.c:13881
POOL_add
void POOL_add(POOL_ctx *ctx, POOL_function function, void *opaque)
Definition: zstd.c:4567
ZSTD_CCtx_s::simpleApiParams
ZSTD_CCtx_params simpleApiParams
Definition: zstd.c:14782
ZSTD_MAX_PRICE
#define ZSTD_MAX_PRICE
Definition: zstd.c:29539
ZDICT_maxRep
static U32 ZDICT_maxRep(U32 const reps[ZSTD_REP_NUM])
Definition: zstd.c:45391
ZSTDMT_bufferPool_s::totalBuffers
unsigned totalBuffers
Definition: zstd.c:31097
ZSTD_error_parameter_combination_unsupported
@ ZSTD_error_parameter_combination_unsupported
Definition: zstd.c:1377
ZDICT_legacy_params_t::zParams
ZDICT_params_t zParams
Definition: zstd.c:40359
ZSTD_cwksp_check_too_large
MEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp *ws, size_t additionalNeededSpace)
Definition: zstd.c:14254
ZSTD_decompressionMargin
size_t ZSTD_decompressionMargin(void const *src, size_t srcSize)
Definition: zstd.c:36183
rsyncState_t
Definition: zstd.c:31826
MEM_readLE24
MEM_STATIC U32 MEM_readLE24(const void *memPtr)
Definition: zstd.c:1156
ZSTD_DCtx_s::xxhState
XXH64_state_t xxhState
Definition: zstd.c:34922
optState_t::litSum
U32 litSum
Definition: zstd.c:14544
LDM_HASH_RLOG
#define LDM_HASH_RLOG
Definition: zstd.c:28817
ZSTD_initStaticDCtx
ZSTD_DCtx * ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
Definition: zstd.c:35630
ZSTD_compressBlock_lazy2_dedicatedDictSearch_row
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28411
ZSTD_compressBlock_greedy_extDict
size_t ZSTD_compressBlock_greedy_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28636
ZSTD_llt_matchLength
@ ZSTD_llt_matchLength
Definition: zstd.c:11028
ZSTD_sizeof_matchState
static size_t ZSTD_sizeof_matchState(const ZSTD_compressionParameters *const cParams, const ZSTD_paramSwitch_e useRowMatchFinder, const U32 enableDedicatedDictSearch, const U32 forCCtx)
Definition: zstd.c:19237
ZSTD_compressBlock_btopt
size_t ZSTD_compressBlock_btopt(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30886
ZSTD_SWITCH_SEARCH_METHOD
#define ZSTD_SWITCH_SEARCH_METHOD(dictMode)
Definition: zstd.c:27957
ZSTD_clearAllDicts
static void ZSTD_clearAllDicts(ZSTD_CCtx *cctx)
Definition: zstd.c:17791
seqToBuffer
static buffer_t seqToBuffer(rawSeqStore_t seq)
Definition: zstd.c:31290
algoTime
static const algo_time_t algoTime[16][2]
Definition: zstd.c:34600
ZSTD_sequencePosition::idx
U32 idx
Definition: zstd.c:14518
DEFAULT_F
#define DEFAULT_F
Definition: zstd.c:43826
ZSTD_error_externalSequences_invalid
@ ZSTD_error_externalSequences_invalid
Definition: zstd.c:1398
MEM_writeBEST
MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val)
Definition: zstd.c:1257
XXH64_state_s::memsize
XXH32_hash_t memsize
Definition: zstd.c:5915
XXH_isLittleEndian
static int XXH_isLittleEndian(void)
Definition: zstd.c:6628
ZSTD_MAXWINDOWSIZE_DEFAULT
#define ZSTD_MAXWINDOWSIZE_DEFAULT
Definition: zstd.c:35322
HUF_COMPRESSBOUND
#define HUF_COMPRESSBOUND(size)
Definition: zstd.c:2890
HUF_CStream_t::startPtr
BYTE * startPtr
Definition: zstd.c:12862
XXH_readBE64
static xxh_u64 XXH_readBE64(const void *ptr)
Definition: zstd.c:7285
ZSTD_createCDict_advanced
ZSTD_CDict * ZSTD_createCDict_advanced(const void *dictBuffer, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
Definition: zstd.c:23041
FASTCOVER_tryParameters_data_s::ctx
const FASTCOVER_ctx_t * ctx
Definition: zstd.c:44241
COVER_ctx_t::d
unsigned d
Definition: zstd.c:40770
ZSTD_compressBegin_usingDict_deprecated
static size_t ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:22719
ss_mergebackward
static void ss_mergebackward(const unsigned char *T, const int *PA, int *first, int *middle, int *last, int *buf, int depth)
Definition: zstd.c:42550
ZSTDMT_jobDescription::job_mutex
ZSTD_pthread_mutex_t job_mutex
Definition: zstd.c:31638
HUF_ReadDTableX2_Workspace::rankVal
rankValCol_t rankVal[HUF_TABLELOG_MAX]
Definition: zstd.c:33988
HUF_decompress4X1_DCtx_wksp
static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:33747
ZSTD_cwksp_align
MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align)
Definition: zstd.c:13743
ZSTD_frameSizeInfo::compressedSize
size_t compressedSize
Definition: zstd.c:11083
FSE_PUBLIC_API
#define FSE_PUBLIC_API
Definition: zstd.c:1591
COPY16
#define COPY16(d, s)
Definition: zstd.c:10938
C
#define C(name, bit)
Definition: zstd.c:4811
ZSTD_createCDict_advanced_internal
static ZSTD_CDict * ZSTD_createCDict_advanced_internal(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_compressionParameters cParams, ZSTD_paramSwitch_e useRowMatchFinder, U32 enableDedicatedDictSearch, ZSTD_customMem customMem)
Definition: zstd.c:23005
ZSTD_localDict
Definition: zstd.c:14422
ZSTD_error_corruption_detected
@ ZSTD_error_corruption_detected
Definition: zstd.c:1370
FSE_CState_t::value
ptrdiff_t value
Definition: zstd.c:2491
ZSTD_getFrameContentSize
unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
Definition: zstd.c:35916
ZSTD_GEN_FAST_FN
#define ZSTD_GEN_FAST_FN(dictMode, mls, step)
Definition: zstd.c:25972
ZSTD_inBuffer_s::pos
size_t pos
Definition: zstd.h:668
range_t::start
void const * start
Definition: zstd.c:31447
ZSTD_copySequencesToSeqStoreExplicitBlockDelim
size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx *cctx, ZSTD_sequencePosition *seqPos, const ZSTD_Sequence *const inSeqs, size_t inSeqsSize, const void *src, size_t blockSize, ZSTD_paramSwitch_e externalRepSearch)
Definition: zstd.c:24032
ZSTD_cpuid_t::f7c
U32 f7c
Definition: zstd.c:4724
ZSTD_entropyCTables_t::huf
ZSTD_hufCTables_t huf
Definition: zstd.c:14445
XXH_PRIME64_4
#define XXH_PRIME64_4
Definition: zstd.c:7312
ZSTDMT_releaseCCtx
static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool *pool, ZSTD_CCtx *cctx)
Definition: zstd.c:31430
ZSTD_compressBlock_btlazy2
size_t ZSTD_compressBlock_btlazy2(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28289
COVER_segment_t::begin
U32 begin
Definition: zstd.c:40465
COVER_dictSelection_t
struct COVER_dictSelection COVER_dictSelection_t
OF_base
static const UNUSED_ATTR U32 OF_base[MaxOff+1]
Definition: zstd.c:34813
ZSTD_matchState_t::hashCache
U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]
Definition: zstd.c:14594
ZSTD_CCtx_s::ldmSequences
rawSeq * ldmSequences
Definition: zstd.c:14801
ZSTD_ldm_getMaxNbSeq
size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize)
Definition: zstd.c:28961
XXH64_canonicalFromHash
#define XXH64_canonicalFromHash
BIT_DStream_unfinished
@ BIT_DStream_unfinished
Definition: zstd.c:2090
S32
signed int S32
Definition: lz4.c:315
ZSTD_DCtx_selectFrameDDict
static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx *dctx)
Definition: zstd.c:35709
ZSTD_compressBegin_advanced_internal
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, ZSTD_dictTableLoadMethod_e dtlm, const ZSTD_CDict *cdict, const ZSTD_CCtx_params *params, unsigned long long pledgedSrcSize)
Definition: zstd.c:22686
isIncluded
static int isIncluded(const void *in, const void *container, size_t length)
Definition: zstd.c:44887
POOL_create
POOL_ctx * POOL_create(size_t numThreads, size_t queueSize)
Definition: zstd.c:4392
FSE_decompress_wksp_body_default
static size_t FSE_decompress_wksp_body_default(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workSpace, size_t wkspSize)
Definition: zstd.c:3779
ZSTD_STATIC_ASSERT
#define ZSTD_STATIC_ASSERT(c)
Definition: zstd.c:10784
POOL_create_advanced
POOL_ctx * POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem)
Definition: zstd.c:4396
ZSTD_invalidateMatchState
static void ZSTD_invalidateMatchState(ZSTD_matchState_t *ms)
Definition: zstd.c:19516
ZDICT_removeDictItem
static void ZDICT_removeDictItem(dictItem *table, U32 id)
Definition: zstd.c:44963
ZSTD_compressCCtx
size_t ZSTD_compressCCtx(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, int compressionLevel)
Definition: zstd.c:22888
optState_t::offCodeSumBasePrice
U32 offCodeSumBasePrice
Definition: zstd.c:14551
FASTCOVER_tryParameters
static void FASTCOVER_tryParameters(void *opaque)
Definition: zstd.c:44253
not_streaming
@ not_streaming
Definition: zstd.c:35388
FSE_readNCount_bmi2
FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short *normalizedCounter, unsigned *maxSymbolValuePtr, unsigned *tableLogPtr, const void *rBuffer, size_t rBuffSize, int bmi2)
Definition: zstd.c:3290
ZSTD_insertBlock
size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, size_t blockSize)
Definition: zstd.c:36232
FSE_CTable
unsigned FSE_CTable
Definition: zstd.c:1676
optState_t::litLengthSumBasePrice
U32 litLengthSumBasePrice
Definition: zstd.c:14549
ZSTD_CCtx_params_s::rsyncable
int rsyncable
Definition: zstd.c:14692
FSE_BUILD_CTABLE_WORKSPACE_SIZE
#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog)
Definition: zstd.c:2463
ZSTD_error_seekableIO
@ ZSTD_error_seekableIO
Definition: zstd.c:1394
ZSTD_seqSymbol
Definition: zstd.c:34843
ZSTD_rotateRight_U16
MEM_STATIC U16 ZSTD_rotateRight_U16(U16 const value, U32 count)
Definition: zstd.c:2015
set_basic
@ set_basic
Definition: zstd.c:10835
ZSTD_hufCTables_t::CTable
HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)]
Definition: zstd.c:14431
FSE_GETSYMBOL
#define FSE_GETSYMBOL(statePtr)
kNullRange
static const range_t kNullRange
Definition: zstd.c:31633
HUF_alignUpWorkspace
static void * HUF_alignUpWorkspace(void *workspace, size_t *workspaceSizePtr, size_t align)
Definition: zstd.c:12160
COVER_sum
size_t COVER_sum(const size_t *samplesSizes, unsigned nbSamples)
Definition: zstd.c:40783
HUF_DECOMPRESS_WORKSPACE_SIZE_U32
#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32
Definition: zstd.c:3060
ZSTD_DCtx_loadDictionary_advanced
size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx *dctx, const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:37023
FSE_DState_t::table
const void * table
Definition: zstd.c:2552
ZSTD_CCtx_s::outBuffFlushedSize
size_t outBuffFlushedSize
Definition: zstd.c:14819
ZSTD_c_checksumFlag
@ ZSTD_c_checksumFlag
Definition: zstd.h:428
ZSTD_compressBegin_internal
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_dictContentType_e dictContentType, ZSTD_dictTableLoadMethod_e dtlm, const ZSTD_CDict *cdict, const ZSTD_CCtx_params *params, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff)
Definition: zstd.c:22639
HUF_encodeSymbol
FORCE_INLINE_TEMPLATE void HUF_encodeSymbol(HUF_CStream_t *bitCPtr, U32 symbol, const HUF_CElt *CTable, int idx, int fast)
Definition: zstd.c:13000
ZSTD_CCtx_loadDictionary
size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx *cctx, const void *dict, size_t dictSize)
Definition: zstd.c:18947
ZSTD_rowMatchFinderSupported
static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy)
Definition: zstd.c:17861
ZSTD_dStage
ZSTD_dStage
Definition: zstd.c:34865
ZSTD_limitCopy
MEM_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:10989
ZSTDMT_getCCtx
static ZSTD_CCtx * ZSTDMT_getCCtx(ZSTDMT_CCtxPool *cctxPool)
Definition: zstd.c:31415
ZSTD_decompressFrame
static size_t ZSTD_decompressFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void **srcPtr, size_t *srcSizePtr)
Definition: zstd.c:36298
ZSTD_error_literals_headerWrong
@ ZSTD_error_literals_headerWrong
Definition: zstd.c:1372
ZSTD_DCtx_setParameter
size_t ZSTD_DCtx_setParameter(ZSTD_DCtx *dctx, ZSTD_dParameter dParam, int value)
Definition: zstd.c:37223
HUF_CTABLE_WORKSPACE_SIZE
#define HUF_CTABLE_WORKSPACE_SIZE
Definition: zstd.c:2999
HUF_CREATE_STATIC_CTABLE
#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue)
Definition: zstd.c:2897
ZSTD_cwksp::initOnceStart
void * initOnceStart
Definition: zstd.c:13701
ZSTDb_buffered
@ ZSTDb_buffered
Definition: zstd.c:14749
ZSTD_compress_advanced
size_t ZSTD_compress_advanced(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, ZSTD_parameters params)
Definition: zstd.c:22842
ZSTD_DDict_s::dictContent
const void * dictContent
Definition: zstd.c:35074
MEM_writeLE24
MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val)
Definition: zstd.c:1161
ZSTD_blockState_t::prevCBlock
ZSTD_compressedBlockState_t * prevCBlock
Definition: zstd.c:14626
GEAR_ITER_ONCE
#define GEAR_ITER_ONCE()
ZSTD_matchState_t::window
ZSTD_window_t window
Definition: zstd.c:14581
ZSTD_copyRawBlock
static size_t ZSTD_copyRawBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:36241
maybeSplitSequence
static rawSeq maybeSplitSequence(rawSeqStore_t *rawSeqStore, U32 const remaining, U32 const minMatch)
Definition: zstd.c:29415
FORWARD_IF_ERROR
#define FORWARD_IF_ERROR(err,...)
Definition: zstd.c:1532
MEM_swap64_fallback
MEM_STATIC U64 MEM_swap64_fallback(U64 in)
Definition: zstd.c:1101
ZSTDMT_flushProduced
static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx *mtctx, ZSTD_outBuffer *output, unsigned blockToFlush, ZSTD_EndDirective end)
Definition: zstd.c:32434
seqDef_s::mlBase
U16 mlBase
Definition: zstd.c:11021
ZSTD_cpuid_t::f7b
U32 f7b
Definition: zstd.c:4723
ZSTD_CCtx_params_s::outBufferMode
ZSTD_bufferMode_e outBufferMode
Definition: zstd.c:14702
ZSTD_CCtx_loadDictionary_advanced
size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:18909
FASTCOVER_MAX_ACCEL
#define FASTCOVER_MAX_ACCEL
Definition: zstd.c:43824
ZSTDMT_JOBLOG_MAX
#define ZSTDMT_JOBLOG_MAX
Definition: zstd.c:14321
ZSTD_compressBlock_lazy2_dedicatedDictSearch
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28346
MAP_EMPTY_VALUE
#define MAP_EMPTY_VALUE
Definition: zstd.c:40636
ZSTD_cwksp_clear
MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp *ws)
Definition: zstd.c:14136
HUF_DEltX1_set4
static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits)
Definition: zstd.c:33175
ZSTD_CCtx_s::frameEnded
U32 frameEnded
Definition: zstd.c:14821
ZSTD_row_nextCachedHash
FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32 *cache, U32 const *hashTable, BYTE const *tagTable, BYTE const *base, U32 idx, U32 const hashLog, U32 const rowLog, U32 const mls, U64 const hashSalt)
Definition: zstd.c:27378
ZSTD_updateStats
static void ZSTD_updateStats(optState_t *const optPtr, U32 litLength, const BYTE *literals, U32 offBase, U32 matchLength)
Definition: zstd.c:29874
ZSTD_compressBlock_btultra
size_t ZSTD_compressBlock_btultra(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30928
HUF_BLOCKSIZE_MAX
#define HUF_BLOCKSIZE_MAX
Definition: zstd.c:2862
B
#define B(name, bit)
ZSTD_DDictHashSet_addDDict
static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet *hashSet, const ZSTD_DDict *ddict, ZSTD_customMem customMem)
Definition: zstd.c:35560
ZSTD_rawLiteralsCost
static U32 ZSTD_rawLiteralsCost(const BYTE *const literals, U32 const litLength, const optState_t *const optPtr, int optLevel)
Definition: zstd.c:29785
ZSTD_externalMatchCtx::mFinder
ZSTD_sequenceProducer_F * mFinder
Definition: zstd.c:14771
ldmState_t::bucketOffsets
BYTE * bucketOffsets
Definition: zstd.c:14649
MAX_FSE_TABLELOG_FOR_HUFF_HEADER
#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER
Definition: zstd.c:12185
_trbudget_t::incval
int incval
Definition: zstd.c:42909
ZSTD_optimal_t::price
int price
Definition: zstd.c:14526
ip
#define ip
ZSTD_error_sequenceProducer_failed
@ ZSTD_error_sequenceProducer_failed
Definition: zstd.c:1397
ZSTD_resolveRowMatchFinderMode
static ZSTD_paramSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_paramSwitch_e mode, const ZSTD_compressionParameters *const cParams)
Definition: zstd.c:17874
ZSTD_pthread_cond_signal
#define ZSTD_pthread_cond_signal(a)
Definition: zstd.c:3914
prime3bytes
static const U32 prime3bytes
Definition: zstd.c:15162
ZSTD_getDictID_fromFrame
unsigned ZSTD_getDictID_fromFrame(const void *src, size_t srcSize)
Definition: zstd.c:36968
ZSTD_DCtx_s::format
ZSTD_format_e format
Definition: zstd.c:34924
rawSeqStore_t::seq
rawSeq * seq
Definition: zstd.c:14509
ZSTD_CCtx_s::consumedSrcSize
unsigned long long consumedSrcSize
Definition: zstd.c:14789
huffNodeTable
nodeElt huffNodeTable[2 *(HUF_SYMBOLVALUE_MAX+1)]
Definition: zstd.c:12528
ZSTD_CCtx_s::outBuff
char * outBuff
Definition: zstd.c:14816
S64
signed long long S64
Definition: zstd.c:921
HUF_buildCTable_wksp_tables::huffNodeTbl
huffNodeTable huffNodeTbl
Definition: zstd.c:12534
ZSTD_frameHeaderSize
size_t ZSTD_frameHeaderSize(const void *src, size_t srcSize)
Definition: zstd.c:35784
mqtt_test.data
dictionary data
Definition: mqtt_test.py:22
ZSTDMT_CCtx_s::consumed
unsigned long long consumed
Definition: zstd.c:31852
ZSTD_cwksp_reserve_failed
MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp *ws)
Definition: zstd.c:14226
HUF_flags_e
HUF_flags_e
Definition: zstd.c:2917
ZSTD_DCtx_getParameter
size_t ZSTD_DCtx_getParameter(ZSTD_DCtx *dctx, ZSTD_dParameter param, int *value)
Definition: zstd.c:37197
ZSTD_decompressBlock_deprecated
size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:39883
XXH3_generateSecret
#define XXH3_generateSecret
FASTCOVER_tryParameters_data_s::best
COVER_best_t * best
Definition: zstd.c:44242
HUF_buildCTable_wksp
size_t HUF_buildCTable_wksp(HUF_CElt *tree, const unsigned *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize)
Definition: zstd.c:12778
FSE_writeNCount
FSE_PUBLIC_API size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
Definition: zstd.c:11568
ZSTD_rowMatchFinderUsed
static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e mode)
Definition: zstd.c:17868
ZDICT_printHex
static void ZDICT_printHex(const void *ptr, size_t length)
Definition: zstd.c:44631
ZSTD_count
MEM_STATIC size_t ZSTD_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *const pInLimit)
Definition: zstd.c:15118
rankPos::base
U16 base
Definition: zstd.c:12524
ZSTD_matchState_t::prefetchCDictTables
int prefetchCDictTables
Definition: zstd.c:14615
ZSTD_pthread_cond_wait
#define ZSTD_pthread_cond_wait(a, b)
Definition: zstd.c:3913
ZSTDMT_JOBSIZE_MIN
#define ZSTDMT_JOBSIZE_MIN
Definition: zstd.c:14319
COVER_map_s::sizeLog
U32 sizeLog
Definition: zstd.c:40644
HUF_TABLELOG_MAX
#define HUF_TABLELOG_MAX
Definition: zstd.c:2874
ZSTD_checkOutBuffer
static size_t ZSTD_checkOutBuffer(ZSTD_DStream const *zds, ZSTD_outBuffer const *output)
Definition: zstd.c:37336
zcss_flush
@ zcss_flush
Definition: zstd.c:14414
ZSTD_symbolEncodingTypeStats_t::MLtype
U32 MLtype
Definition: zstd.c:20331
ZDICT_fastCover_params_t::nbThreads
unsigned nbThreads
Definition: zstd.c:40263
BIT_addBitsFast
MEM_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
Definition: zstd.c:2180
FSE_getErrorName
const FSE_PUBLIC_API char * FSE_getErrorName(size_t code)
Definition: zstd.c:3116
ZSTD_CCtx_s::xxhState
XXH64_state_t xxhState
Definition: zstd.c:14791
ZSTD_countSeqStoreMatchBytes
static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t *const seqStore)
Definition: zstd.c:21463
ZSTD_c_jobSize
@ ZSTD_c_jobSize
Definition: zstd.h:446
ZSTD_CCtx_params_s::srcSizeHint
int srcSizeHint
Definition: zstd.c:14681
HUF_DTABLE_SIZE
#define HUF_DTABLE_SIZE(maxTableLog)
Definition: zstd.c:2902
ZSTD_FOR_EACH_MLS_ROWLOG
#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode)
Definition: zstd.c:27909
HUF_mergeIndex1
FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t *bitC)
Definition: zstd.c:12936
COVER_best_s::cond
ZSTD_pthread_cond_t cond
Definition: zstd.c:40453
ZSTD_getDecompressedSize
unsigned long long ZSTD_getDecompressedSize(const void *src, size_t srcSize)
Definition: zstd.c:36037
HUF_CompressWeightsWksp
Definition: zstd.c:12187
POOL_ctx_s
Definition: zstd.c:4315
ZSTD_compressBlock_lazy
size_t ZSTD_compressBlock_lazy(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28303
ZSTD_DDict_s::entropy
ZSTD_entropyDTables_t entropy
Definition: zstd.c:35076
ZSTD_resetCStream
size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pss)
Definition: zstd.c:23368
ZSTD_CURRENT_MAX
#define ZSTD_CURRENT_MAX
Definition: zstd.c:15294
ZSTD_CCtx_s::blockState
ZSTD_blockState_t blockState
Definition: zstd.c:14804
FSE_repeat_valid
@ FSE_repeat_valid
Definition: zstd.c:2480
ZSTD_matchState_t::chainTable
U32 * chainTable
Definition: zstd.c:14600
ZSTD_CStreamInSize
size_t ZSTD_CStreamInSize(void)
Definition: zstd.c:23351
FASTCOVER_tryParameters_data_s
Definition: zstd.c:44240
ZSTD_hash3
static U32 ZSTD_hash3(U32 u, U32 h, U32 s)
Definition: zstd.c:15163
HUF_decompress1X2_DCtx_wksp
size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workSpace, size_t wkspSize, int flags)
Definition: zstd.c:34560
ZSTD_CCtx_setParams
size_t ZSTD_CCtx_setParams(ZSTD_CCtx *cctx, ZSTD_parameters params)
Definition: zstd.c:18844
ZSTD_nextSrcSizeToDecompressWithInputSize
static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx *dctx, size_t inputSize)
Definition: zstd.c:36563
range_t::size
size_t size
Definition: zstd.c:31448
ZSTD_matchState_t::ldmSeqStore
const rawSeqStore_t * ldmSeqStore
Definition: zstd.c:14610
ZSTD_div64
#define ZSTD_div64(dividend, divisor)
Definition: zstd.c:126
FASTCOVER_ctx_t::offsets
size_t * offsets
Definition: zstd.c:43909
param
T param(const std::string &param_name, const T &default_val)
ZSTD_CCtx_s::externalMatchCtx
ZSTD_externalMatchCtx externalMatchCtx
Definition: zstd.c:14847
POOL_ctx_s::customMem
ZSTD_customMem customMem
Definition: zstd.c:4316
ZSTD_DDict_s::entropyPresent
U32 entropyPresent
Definition: zstd.c:35078
ZSTD_insertDUBT1
static void ZSTD_insertDUBT1(const ZSTD_matchState_t *ms, U32 curr, const BYTE *inputEnd, U32 nbCompares, U32 btLow, const ZSTD_dictMode_e dictMode)
Definition: zstd.c:26597
ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
#define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
Definition: zstd.c:15351
ZSTD_estimateBlockSize_symbolType
static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type, const BYTE *codeTable, size_t nbSeq, unsigned maxCode, const FSE_CTable *fseCTable, const U8 *additionalBits, short const *defaultNorm, U32 defaultNormLog, U32 defaultMax, void *workspace, size_t wkspSize)
Definition: zstd.c:21336
COVER_strict_cmp8
static int WIN_CDECL COVER_strict_cmp8(const void *lp, const void *rp)
Definition: zstd.c:40830
bt_compressed
@ bt_compressed
Definition: zstd.c:10827
XXH_PRIME32_3
#define XXH_PRIME32_3
Definition: zstd.c:6784
ZSTD_error_frameIndex_tooLarge
@ ZSTD_error_frameIndex_tooLarge
Definition: zstd.c:1393
ZSTD_cwksp
Definition: zstd.c:13693
FSE_repeat_none
@ FSE_repeat_none
Definition: zstd.c:2478
ZSTDMT_CCtx_s::inBuff
inBuff_t inBuff
Definition: zstd.c:31842
XXH_versionNumber
#define XXH_versionNumber
Definition: zstd.c:6769
ZSTD_c_overlapLog
@ ZSTD_c_overlapLog
Definition: zstd.h:451
anchor
#define anchor
ZSTD_findDecompressedSize
unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize)
Definition: zstd.c:35990
XXH64_state_s::reserved32
XXH32_hash_t reserved32
Definition: zstd.c:5916
ZSTD_prefixDict_s::dict
const void * dict
Definition: zstd.c:14417
HUF_DEltX2::length
BYTE length
Definition: zstd.c:33770
BIT_CStream_t::ptr
char * ptr
Definition: zstd.c:2052
ZSTD_DCtx_s::ddictIsCold
int ddictIsCold
Definition: zstd.c:34940
FASTCOVER_ctx_t::nbTestSamples
size_t nbTestSamples
Definition: zstd.c:43913
ZSTD_DDictHashSet_emplaceDDict
static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet *hashSet, const ZSTD_DDict *ddict)
Definition: zstd.c:35456
HUF_WriteCTableWksp::huffWeight
BYTE huffWeight[HUF_SYMBOLVALUE_MAX]
Definition: zstd.c:12274
ZSTDds_decompressLastBlock
@ ZSTDds_decompressLastBlock
Definition: zstd.c:34867
ZSTD_estimateCStreamSize_usingCParams
size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
Definition: zstd.c:19414
XXH128_canonicalFromHash
#define XXH128_canonicalFromHash
FSE_TABLESTEP
#define FSE_TABLESTEP(tableSize)
Definition: zstd.c:2822
FSE_DState_t::state
size_t state
Definition: zstd.c:2551
ZSTD_cParam_getBounds
ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
Definition: zstd.c:18064
ZSTD_estimateCCtxSize_usingCParams
size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
Definition: zstd.c:19352
ZSTD_pthread_cond_broadcast
#define ZSTD_pthread_cond_broadcast(a)
Definition: zstd.c:3915
ZSTD_fseCTables_t
Definition: zstd.c:14435
HUF_DecompressUsingDTableFn
size_t(* HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
Definition: zstd.c:32953
ZSTDMT_freeJobsTable
static void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription *jobTable, U32 nbJobs, ZSTD_customMem cMem)
Definition: zstd.c:31860
OFFBASE_IS_OFFSET
#define OFFBASE_IS_OFFSET(o)
Definition: zstd.c:15006
ZSTD_CCtx_s::pledgedSrcSizePlusOne
unsigned long long pledgedSrcSizePlusOne
Definition: zstd.c:14788
ZSTD_isSkipFrame
static int ZSTD_isSkipFrame(ZSTD_DCtx *dctx)
Definition: zstd.c:36596
ZSTD_countTrailingZeros32_fallback
MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val)
Definition: zstd.c:1837
XXH3_128bits_reset_withSecretandSeed
#define XXH3_128bits_reset_withSecretandSeed
ZSTD_hash7PtrS
static size_t ZSTD_hash7PtrS(const void *p, U32 h, U64 s)
Definition: zstd.c:15185
ZSTD_ROW_HASH_CACHE_MASK
#define ZSTD_ROW_HASH_CACHE_MASK
Definition: zstd.c:27299
FSE_DECODE_TYPE
#define FSE_DECODE_TYPE
Definition: zstd.c:2802
BIT_DStream_t
Definition: zstd.c:2082
ZSTD_dedicatedDictSearch_isSupported
static int ZSTD_dedicatedDictSearch_isSupported(const ZSTD_compressionParameters *cParams)
Definition: zstd.c:24672
g_ZSTD_threading_useless_symbol
int g_ZSTD_threading_useless_symbol
Definition: zstd.c:3976
FSE_endOfDState
static unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr)
Definition: zstd.c:2763
ZSTD_DCtx_s::litExtraBuffer
BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE+WILDCOPY_OVERLENGTH]
Definition: zstd.c:34971
MIN
#define MIN(a, b)
Definition: zstd.c:10795
ZSTDcs_init
@ ZSTDcs_init
Definition: zstd.c:14413
ZSTDMT_jobDescription::params
ZSTD_CCtx_params params
Definition: zstd.c:31650
FSE_decompress_wksp_body
FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workSpace, size_t wkspSize, int bmi2)
Definition: zstd.c:3735
attachDictSizeCutoffs
static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1]
Definition: zstd.c:19879
ZDICT_cover_params_t::shrinkDict
unsigned shrinkDict
Definition: zstd.c:40253
ZSTD_optimal_t::mlen
U32 mlen
Definition: zstd.c:14528
COVER_map_t
struct COVER_map_s COVER_map_t
ZSTD_cwksp_alloc_size
MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size)
Definition: zstd.c:13761
FASTCOVER_MAX_F
#define FASTCOVER_MAX_F
Definition: zstd.c:43823
blockProperties_t
Definition: zstd.c:11098
XXH_ASSERT
#define XXH_ASSERT(c)
Definition: zstd.c:6436
ZSTD_compressStream2_simpleArgs
size_t ZSTD_compressStream2_simpleArgs(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, size_t *dstPos, const void *src, size_t srcSize, size_t *srcPos, ZSTD_EndDirective endOp)
Definition: zstd.c:23939
ZDICT_fastCover_params_t::shrinkDict
unsigned shrinkDict
Definition: zstd.c:40266
ZSTD_CCtx_setParametersUsingCCtxParams
size_t ZSTD_CCtx_setParametersUsingCCtxParams(ZSTD_CCtx *cctx, const ZSTD_CCtx_params *params)
Definition: zstd.c:18804
HUF_buildDEltX2
static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
Definition: zstd.c:33797
ZSTD_CDict_s::workspace
ZSTD_cwksp workspace
Definition: zstd.c:17723
XXH64_state_s::mem64
XXH64_hash_t mem64[4]
Definition: zstd.c:5914
ZSTD_compressBlock_targetCBlockSize
static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastBlock)
Definition: zstd.c:21979
ZSTD_compress_advanced_internal
size_t ZSTD_compress_advanced_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize, const ZSTD_CCtx_params *params)
Definition: zstd.c:22859
seqStore_t::maxNbLit
size_t maxNbLit
Definition: zstd.c:11040
XXH32_state_s::large_len
XXH32_hash_t large_len
Definition: zstd.c:5889
ZSTD_copyCCtx_internal
static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx *dstCCtx, const ZSTD_CCtx *srcCCtx, ZSTD_frameParameters fParams, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff)
Definition: zstd.c:20095
XXH3_64bits_reset_withSecret
#define XXH3_64bits_reset_withSecret
seqDef_s::litLength
U16 litLength
Definition: zstd.c:11020
ZSTD_blockSplitCtx::secondHalfSeqStore
seqStore_t secondHalfSeqStore
Definition: zstd.c:14760
buffer_s
Definition: zstd.c:31087
ZSTD_cwksp_available_space
MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp *ws)
Definition: zstd.c:14246
ZSTD_CCtx_s::cParamsChanged
int cParamsChanged
Definition: zstd.c:14778
ZSTD_CCtx_s::initialized
int initialized
Definition: zstd.c:14797
match
static const char * match(MatchState *ms, const char *s, const char *p)
Definition: lstrlib.c:570
serialState_t::ldmWindowCond
ZSTD_pthread_cond_t ldmWindowCond
Definition: zstd.c:31463
ZSTD_tableFillPurpose_e
ZSTD_tableFillPurpose_e
Definition: zstd.c:14851
ZSTD_CDict_s::useRowMatchFinder
ZSTD_paramSwitch_e useRowMatchFinder
Definition: zstd.c:17729
ZSTD_countLeadingZeros64
MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val)
Definition: zstd.c:1942
ZSTD_reduceTable_internal
FORCE_INLINE_TEMPLATE void ZSTD_reduceTable_internal(U32 *const table, U32 const size, U32 const reducerValue, int const preserveMark)
Definition: zstd.c:20195
COVER_segment_t::end
U32 end
Definition: zstd.c:40466
ZSTD_indexResetPolicy_e
ZSTD_indexResetPolicy_e
Definition: zstd.c:19543
ZSTD_litLocation_e
ZSTD_litLocation_e
Definition: zstd.c:34896
ZSTD_dParam_withinBounds
static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
Definition: zstd.c:37184
BIT_skipBits
MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t *bitD, U32 nbBits)
Definition: zstd.c:2340
ZSTD_row_nextIndex
FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE *const tagRow, U32 const rowMask)
Definition: zstd.c:27315
HIST_countFast_wksp
size_t HIST_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize, void *workSpace, size_t workSpaceSize)
Definition: zstd.c:12005
XXH3_state_t
#define XXH3_state_t
ZSTD_minGain
MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
Definition: zstd.c:14960
ZSTD_initStaticCStream
ZSTD_CStream * ZSTD_initStaticCStream(void *workspace, size_t workspaceSize)
Definition: zstd.c:23332
ZSTDMT_CCtx_s::factory
POOL_ctx * factory
Definition: zstd.c:31833
ZSTD_blockSplitCtx::entropyMetadata
ZSTD_entropyCTablesMetadata_t entropyMetadata
Definition: zstd.c:14765
sol::meta_function::length
@ length
POOL_sizeof
size_t POOL_sizeof(const POOL_ctx *ctx)
Definition: zstd.c:4487
DDICT_HASHSET_RESIZE_FACTOR
#define DDICT_HASHSET_RESIZE_FACTOR
Definition: zstd.c:35441
ZSTD_freeDDictHashSet
static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet *hashSet, ZSTD_customMem customMem)
Definition: zstd.c:35547
ZSTD_compressBlock_btopt_extDict
size_t ZSTD_compressBlock_btopt_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30978
rawSeq
Definition: zstd.c:14502
ZSTD_ldm_reduceTable
static void ZSTD_ldm_reduceTable(ldmEntry_t *const table, U32 const size, U32 const reducerValue)
Definition: zstd.c:29291
ZSTDMT_expandJobsTable
static size_t ZSTDMT_expandJobsTable(ZSTDMT_CCtx *mtctx, U32 nbWorkers)
Definition: zstd.c:31895
ZSTD_getFSEMaxSymbolValue
static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const *ctable)
Definition: zstd.c:16247
ZSTD_free
#define ZSTD_free(p)
Definition: zstd.c:112
ZSTD_sizeof_CCtx
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx *cctx)
Definition: zstd.c:17842
HUF_compress1X_usingCTable_internal_body
FORCE_INLINE_TEMPLATE size_t HUF_compress1X_usingCTable_internal_body(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable)
Definition: zstd.c:13071
XXH128
#define XXH128
ZSTDMT_createCCtx_advanced
ZSTDMT_CCtx * ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool *pool)
Definition: zstd.c:31958
HUF_WriteCTableWksp
Definition: zstd.c:12271
ZSTD_DCtx_s::litPtr
const BYTE * litPtr
Definition: zstd.c:34927
ZSTD_memcpy
#define ZSTD_memcpy(d, s, l)
Definition: zstd.c:92
ZSTD_cwksp::objectEnd
void * objectEnd
Definition: zstd.c:13697
ZSTD_ldm_getTableSize
size_t ZSTD_ldm_getTableSize(ldmParams_t params)
Definition: zstd.c:28951
XXH128_hash_t
#define XXH128_hash_t
ZSTD_DCtx_s::inPos
size_t inPos
Definition: zstd.c:34950
FSE_decode_t::nbBits
unsigned char nbBits
Definition: zstd.c:2713
COVER_map_clear
static void COVER_map_clear(COVER_map_t *map)
Definition: zstd.c:40652
tr_heapsort
static void tr_heapsort(const int *ISAd, int *SA, int size)
Definition: zstd.c:42827
ZSTD_CCtx_s::bufferedPolicy
ZSTD_buffered_policy_e bufferedPolicy
Definition: zstd.c:14808
BIT_endOfDStream
MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *bitD)
Definition: zstd.c:2417
ZSTD_compressionStage_e
ZSTD_compressionStage_e
Definition: zstd.c:14413
HUF_decodeStreamX1
HINT_INLINE size_t HUF_decodeStreamX1(BYTE *p, BIT_DStream_t *const bitDPtr, BYTE *const pEnd, const HUF_DEltX1 *const dt, const U32 dtLog)
Definition: zstd.c:33382
FASTCOVER_ctx_t::nbDmers
size_t nbDmers
Definition: zstd.c:43914
HUF_readStats_wksp
size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workspace, size_t wkspSize, int flags)
Definition: zstd.c:3411
POOL_ctx_s::threads
ZSTD_pthread_t * threads
Definition: zstd.c:4318
ZSTD_matchState_t::lazySkipping
int lazySkipping
Definition: zstd.c:14622
FASTCOVER_ctx_t::samplesSizes
const size_t * samplesSizes
Definition: zstd.c:43910
ZSTDMT_waitForAllJobsCompleted
static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:31995
ZSTDMT_jobDescription::serial
serialState_t * serial
Definition: zstd.c:31643
HUF_readCTable
size_t HUF_readCTable(HUF_CElt *CTable, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize, unsigned *hasZeroWeights)
Definition: zstd.c:12318
ZSTD_initDStream_usingDDict
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream *dctx, const ZSTD_DDict *ddict)
Definition: zstd.c:37085
HUF_READ_STATS_WORKSPACE_SIZE_U32
#define HUF_READ_STATS_WORKSPACE_SIZE_U32
Definition: zstd.c:3018
LL_bits
static const UNUSED_ATTR U8 LL_bits[MaxLL+1]
Definition: zstd.c:10860
rsyncState_t::primePower
U64 primePower
Definition: zstd.c:31829
ZSTD_initCStream_advanced
size_t ZSTD_initCStream_advanced(ZSTD_CStream *zcs, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pss)
Definition: zstd.c:23434
ZSTD_compressBlock_lazy2_row
size_t ZSTD_compressBlock_lazy2_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28368
header
const std::string header
ZSTDMT_jobDescription::frameChecksumNeeded
unsigned frameChecksumNeeded
Definition: zstd.c:31654
BIT_getMiddleBits
MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
Definition: zstd.c:2294
ZSTD_DCtx_s::LLTptr
const ZSTD_seqSymbol * LLTptr
Definition: zstd.c:34904
ZSTD_CCtx_s::pool
ZSTD_threadPool * pool
Definition: zstd.c:14793
ZSTD_cwksp_clean_tables
MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp *ws)
Definition: zstd.c:14100
blockProperties_t::lastBlock
U32 lastBlock
Definition: zstd.c:11100
ZSTD_scaleStats
static U32 ZSTD_scaleStats(unsigned *table, U32 lastEltIndex, U32 logTarget)
Definition: zstd.c:29642
CLAMP_TYPE
#define CLAMP_TYPE(cParam, val, type)
ZSTD_hash4
static U32 ZSTD_hash4(U32 u, U32 h, U32 s)
Definition: zstd.c:15168
HUF_flushBits
FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t *bitC, int kFast)
Definition: zstd.c:12952
FSE_CState_t::stateTable
const void * stateTable
Definition: zstd.c:2492
FASTCOVER_tryParameters_data_s::dictBufferCapacity
size_t dictBufferCapacity
Definition: zstd.c:44243
ZSTD_ldm_gear_reset
static void ZSTD_ldm_gear_reset(ldmRollingHashState_t *state, BYTE const *data, size_t minMatchLength)
Definition: zstd.c:28861
ZSTD_resetCCtx_byCopyingCDict
static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, ZSTD_CCtx_params params, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff)
Definition: zstd.c:19985
ZSTDMT_CCtx_s::doneJobID
unsigned doneJobID
Definition: zstd.c:31847
ZSTD_row_prefetch
FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const *hashTable, BYTE const *tagTable, U32 const relRow, U32 const rowLog)
Definition: zstd.c:27333
assert.h
ZSTD_reset_session_and_parameters
@ ZSTD_reset_session_and_parameters
Definition: zstd.h:557
ZSTD_CCtx_params_s::literalCompressionMode
ZSTD_paramSwitch_e literalCompressionMode
Definition: zstd.c:14686
COVER_ctx_destroy
static void COVER_ctx_destroy(COVER_ctx_t *ctx)
Definition: zstd.c:41059
ZSTD_decompress_usingDict
size_t ZSTD_decompress_usingDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize)
Definition: zstd.c:36498
ZSTD_rotateRight_U32
MEM_STATIC U32 ZSTD_rotateRight_U32(U32 const value, U32 count)
Definition: zstd.c:2008
ZSTDMT_CCtx_s::cdictLocal
ZSTD_CDict * cdictLocal
Definition: zstd.c:31855
FASTCOVER_ctx_t::f
unsigned f
Definition: zstd.c:43917
serialState_t::cond
ZSTD_pthread_cond_t cond
Definition: zstd.c:31454
ZSTD_estimateDDictSize
size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
Definition: zstd.c:35261
ZSTD_maybeRLE
static int ZSTD_maybeRLE(seqStore_t const *seqStore)
Definition: zstd.c:21077
findSynchronizationPoint
static syncPoint_t findSynchronizationPoint(ZSTDMT_CCtx const *mtctx, ZSTD_inBuffer const input)
Definition: zstd.c:32687
BITCOST_MULTIPLIER
#define BITCOST_MULTIPLIER
Definition: zstd.c:29558
XXH64_canonical_t
Definition: xxhash.h:239
next
#define next(ls)
Definition: llex.c:32
REPCODE1_TO_OFFBASE
#define REPCODE1_TO_OFFBASE
Definition: zstd.c:15001
ZSTD_compressContinue
size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22281
ZSTD_getCParams_internal
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode)
Definition: zstd.c:24733
ZSTDMT_NBWORKERS_MAX
#define ZSTDMT_NBWORKERS_MAX
Definition: zstd.c:14316
ZSTD_cwksp_reserve_object
MEM_STATIC void * ZSTD_cwksp_reserve_object(ZSTD_cwksp *ws, size_t bytes)
Definition: zstd.c:14019
ZSTDERRORLIB_API
#define ZSTDERRORLIB_API
Definition: zstd.c:1346
FSE_getMaxNbBits
MEM_STATIC U32 FSE_getMaxNbBits(const void *symbolTTPtr, U32 symbolValue)
Definition: zstd.c:2674
HUF_decompress4X1_usingDTable_internal_fast
static HUF_FAST_BMI2_ATTRS size_t HUF_decompress4X1_usingDTable_internal_fast(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable, HUF_DecompressFastLoopFn loopFn)
Definition: zstd.c:33661
ZSTD_HUFFDTABLE_CAPACITY_LOG
#define ZSTD_HUFFDTABLE_CAPACITY_LOG
Definition: zstd.c:34854
ZSTD_initCStream_usingDict
size_t ZSTD_initCStream_usingDict(ZSTD_CStream *zcs, const void *dict, size_t dictSize, int compressionLevel)
Definition: zstd.c:23452
ldmParams_t::minMatchLength
U32 minMatchLength
Definition: zstd.c:14658
ZSTDMT_jobDescription::cSize
size_t cSize
Definition: zstd.c:31637
HUF_addBits
FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t *bitC, HUF_CElt elt, int idx, int kFast)
Definition: zstd.c:12892
FSE_decode_t::symbol
unsigned char symbol
Definition: zstd.c:2712
ZSTD_hash4Ptr
static size_t ZSTD_hash4Ptr(const void *ptr, U32 h)
Definition: zstd.c:15169
FSE_readNCount_body_default
static size_t FSE_readNCount_body_default(short *normalizedCounter, unsigned *maxSVPtr, unsigned *tableLogPtr, const void *headerBuffer, size_t hbSize)
Definition: zstd.c:3274
ZSTD_MAGICNUMBER
#define ZSTD_MAGICNUMBER
Definition: zstd.h:137
ZDICT_fastCover_params_t::accel
unsigned accel
Definition: zstd.c:40265
MIN_LITERALS_FOR_4_STREAMS
#define MIN_LITERALS_FOR_4_STREAMS
Definition: zstd.c:10833
HUF_writeCTable_wksp
size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog, void *workspace, size_t workspaceSize)
Definition: zstd.c:12277
LDM_BATCH_SIZE
#define LDM_BATCH_SIZE
Definition: zstd.c:14643
OFFBASE_TO_OFFSET
#define OFFBASE_TO_OFFSET(o)
Definition: zstd.c:15008
tr_median5
static INLINE int * tr_median5(const int *ISAd, int *v1, int *v2, int *v3, int *v4, int *v5)
Definition: zstd.c:42865
FASTCOVER_hashPtrToIndex
static size_t FASTCOVER_hashPtrToIndex(const void *p, U32 f, unsigned d)
Definition: zstd.c:43872
HUF_readStats_body
FORCE_INLINE_TEMPLATE size_t HUF_readStats_body(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workSpace, size_t wkspSize, int bmi2)
Definition: zstd.c:3327
FORCE_INLINE_TEMPLATE
#define FORCE_INLINE_TEMPLATE
Definition: zstd.c:560
ZSTD_ldm_countBackwardsMatch_2segments
static size_t ZSTD_ldm_countBackwardsMatch_2segments(const BYTE *pIn, const BYTE *pAnchor, const BYTE *pMatch, const BYTE *pMatchBase, const BYTE *pExtDictStart, const BYTE *pExtDictEnd)
Definition: zstd.c:29010
ZSTD_getParams
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
Definition: zstd.c:24785
dst
char * dst
Definition: lz4.h:792
UNUSED_ATTR
#define UNUSED_ATTR
Definition: zstd.c:582
ZSTD_OptPrice_e
ZSTD_OptPrice_e
Definition: zstd.c:14533
algo_time_t::tableTime
U32 tableTime
Definition: zstd.c:34599
ZDICTLIB_API
#define ZDICTLIB_API
Definition: zstd.c:39989
ZSTD_pthread_mutex_lock
#define ZSTD_pthread_mutex_lock(a)
Definition: zstd.c:3907
ZSTD_fillHashTableForCCtx
static void ZSTD_fillHashTableForCCtx(ZSTD_matchState_t *ms, const void *const end, ZSTD_dictTableLoadMethod_e dtlm)
Definition: zstd.c:25617
ZSTD_CDict_s::dictContentSize
size_t dictContentSize
Definition: zstd.c:17720
bt_raw
@ bt_raw
Definition: zstd.c:10827
ZDICT_cover_params_t::steps
unsigned steps
Definition: zstd.c:40250
ZSTD_symbolEncodingTypeStats_t::size
size_t size
Definition: zstd.c:20332
HUF_getErrorName
const char * HUF_getErrorName(size_t code)
Definition: zstd.c:3119
ZSTD_deriveSeqStoreChunk
static void ZSTD_deriveSeqStoreChunk(seqStore_t *resultSeqStore, const seqStore_t *originalSeqStore, size_t startIdx, size_t endIdx)
Definition: zstd.c:21480
ZSTD_LLcode
MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
Definition: zstd.c:14886
ZSTDb_not_buffered
@ ZSTDb_not_buffered
Definition: zstd.c:14748
HUF_setMaxHeight
static U32 HUF_setMaxHeight(nodeElt *huffNode, U32 lastNonNull, U32 targetNbBits)
Definition: zstd.c:12399
ZSTD_cwksp_mark_tables_clean
MEM_STATIC void ZSTD_cwksp_mark_tables_clean(ZSTD_cwksp *ws)
Definition: zstd.c:14087
isQueueFull
static int isQueueFull(POOL_ctx const *ctx)
Definition: zstd.c:4542
ZSTD_allocateLiteralsBuffer
static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx *dctx, void *const dst, const size_t dstCapacity, const size_t litSize, const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
Definition: zstd.c:37782
ZSTD_CDict_s::dictContentType
ZSTD_dictContentType_e dictContentType
Definition: zstd.c:17721
BIT_DStream_t::limitPtr
const char * limitPtr
Definition: zstd.c:2087
seqStoreSplits
Definition: zstd.c:21653
ZSTD_resetSeqStore
void ZSTD_resetSeqStore(seqStore_t *ssPtr)
Definition: zstd.c:20710
ZSTDMT_bufferPool_s::nbBuffers
unsigned nbBuffers
Definition: zstd.c:31098
ZSTD_overlap_src_before_dst
@ ZSTD_overlap_src_before_dst
Definition: zstd.c:10945
U32
unsigned int U32
Definition: zstd.c:916
POOL_join
static void POOL_join(POOL_ctx *ctx)
Definition: zstd.c:4446
g_nullBuffer
static const buffer_t g_nullBuffer
Definition: zstd.c:31092
serialState_t::xxhState
XXH64_state_t xxhState
Definition: zstd.c:31457
ZSTD_ROW_HASH_MAX_ENTRIES
#define ZSTD_ROW_HASH_MAX_ENTRIES
Definition: zstd.c:27297
ZSTD_compressBlock_btopt_dictMatchState
size_t ZSTD_compressBlock_btopt_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:30964
XXH_PRIME64_2
#define XXH_PRIME64_2
Definition: zstd.c:7310
SeqCollector::seqIndex
size_t seqIndex
Definition: zstd.c:14666
BIT_lookBits
MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t *bitD, U32 nbBits)
Definition: zstd.c:2317
XXH64
#define XXH64
ZSTD_initStaticCDict
const ZSTD_CDict * ZSTD_initStaticCDict(void *workspace, size_t workspaceSize, const void *dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams)
Definition: zstd.c:23156
ZSTD_compressContinue_internal
static size_t ZSTD_compressContinue_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 frame, U32 lastFrameChunk)
Definition: zstd.c:22211
COVER_best_s::parameters
ZDICT_cover_params_t parameters
Definition: zstd.c:40457
ZSTD_LITFREQ_ADD
#define ZSTD_LITFREQ_ADD
Definition: zstd.c:29538
XXH3_generateSecret_fromSeed
#define XXH3_generateSecret_fromSeed
ZSTD_window_t::dictLimit
U32 dictLimit
Definition: zstd.c:14566
ZSTD_NbCommonBytes
MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val)
Definition: zstd.c:1973
XXH128_cmp
#define XXH128_cmp
ZSTD_UNREACHABLE
#define ZSTD_UNREACHABLE
Definition: zstd.c:672
ZSTD_freeThreadPool
void ZSTD_freeThreadPool(ZSTD_threadPool *pool)
Definition: zstd.c:4483
LDM_MIN_MATCH_LENGTH
#define LDM_MIN_MATCH_LENGTH
Definition: zstd.c:28816
HUF_DecompressFastArgs_init
static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs *args, void *dst, size_t dstSize, void const *src, size_t srcSize, const HUF_DTable *DTable)
Definition: zstd.c:33052
FSE_repeat_check
@ FSE_repeat_check
Definition: zstd.c:2479
ZSTD_estimateBlockSize_sequences
static size_t ZSTD_estimateBlockSize_sequences(const BYTE *ofCodeTable, const BYTE *llCodeTable, const BYTE *mlCodeTable, size_t nbSeq, const ZSTD_fseCTables_t *fseTables, const ZSTD_fseCTablesMetadata_t *fseMetadata, void *workspace, size_t wkspSize, int writeEntropy)
Definition: zstd.c:21374
ZSTD_compressBlock_deprecated
size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22302
ZSTD_isError
#define ZSTD_isError
Definition: zstd.c:10785
ZSTD_CCtx_params_s::fParams
ZSTD_frameParameters fParams
Definition: zstd.c:14673
XXH3_128bits
#define XXH3_128bits
HUF_fillDTableX2Level2
static void HUF_fillDTableX2Level2(HUF_DEltX2 *DTable, U32 targetLog, const U32 consumedBits, const U32 *rankVal, const int minWeight, const int maxWeight1, const sortedSymbol_t *sortedSymbols, U32 const *rankStart, U32 nbBitsBaseline, U16 baseSeq)
Definition: zstd.c:33886
ZSTD_indexTooCloseToMax
static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
Definition: zstd.c:19662
ZSTD_fseCTables_t::litlength_repeatMode
FSE_repeat litlength_repeatMode
Definition: zstd.c:14441
POOL_ctx_s::queueEmpty
int queueEmpty
Definition: zstd.c:4331
ZSTD_compressBlock_doubleFast_dictMatchState
size_t ZSTD_compressBlock_doubleFast_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:25380
nlohmann::detail::parse_event_t::key
@ key
the parser read a key of a value in an object
ZSTD_CCtx_params_s::cParams
ZSTD_compressionParameters cParams
Definition: zstd.c:14672
ZSTD_DCtx_s::stage
ZSTD_dStage stage
Definition: zstd.c:34919
ZSTD_insertBtAndGetAllMatches
FORCE_INLINE_TEMPLATE U32 ZSTD_insertBtAndGetAllMatches(ZSTD_match_t *matches, ZSTD_matchState_t *ms, U32 *nextToUpdate3, const BYTE *const ip, const BYTE *const iLimit, const ZSTD_dictMode_e dictMode, const U32 rep[ZSTD_REP_NUM], const U32 ll0, const U32 lengthToBeat, const U32 mls)
Definition: zstd.c:30101
XXH3_128bits_reset_withSecret
#define XXH3_128bits_reset_withSecret
ZSTD_compressEnd
size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
Definition: zstd.c:22835
ZSTD_initCDict_internal
static size_t ZSTD_initCDict_internal(ZSTD_CDict *cdict, const void *dictBuffer, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_CCtx_params params)
Definition: zstd.c:22952
ZSTD_getFrameHeader
size_t ZSTD_getFrameHeader(ZSTD_frameHeader *zfhPtr, const void *src, size_t srcSize)
Definition: zstd.c:35906
ZSTD_CCtx_reset
size_t ZSTD_CCtx_reset(ZSTD_CCtx *cctx, ZSTD_ResetDirective reset)
Definition: zstd.c:18993
FSE_CState_t::stateLog
unsigned stateLog
Definition: zstd.c:2494
DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT
#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT
Definition: zstd.c:35437
ZSTD_DCtx_s::workspace
U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]
Definition: zstd.c:34909
ZDICT_cover_params_t::shrinkDictMaxRegression
unsigned shrinkDictMaxRegression
Definition: zstd.c:40254
ZSTD_initDStream
size_t ZSTD_initDStream(ZSTD_DStream *zds)
Definition: zstd.c:37074
sol::table
table_core< false > table
Definition: forward.hpp:1126
ZDICT_MIN_SAMPLES_SIZE
#define ZDICT_MIN_SAMPLES_SIZE
Definition: zstd.c:44565
ZSTD_decompress_usingDDict
size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_DDict *ddict)
Definition: zstd.c:36980
SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO
#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO
Definition: zstd.c:13267
HUF_decompress4X2_usingDTable_internal
static size_t HUF_decompress4X2_usingDTable_internal(void *dst, size_t dstSize, void const *cSrc, size_t cSrcSize, HUF_DTable const *DTable, int flags)
Definition: zstd.c:34525
ZSTD_matchState_t::dictMatchState
const ZSTD_matchState_t * dictMatchState
Definition: zstd.c:14608
range_format::sequence
@ sequence
zcss_load
@ zcss_load
Definition: zstd.c:14414
ZSTD_frameSizeInfo::decompressedBound
unsigned long long decompressedBound
Definition: zstd.c:11084
ZSTD_decompressBegin_usingDict
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
Definition: zstd.c:36912
ZSTD_error_dstBuffer_wrong
@ ZSTD_error_dstBuffer_wrong
Definition: zstd.c:1395
DISPLAY
#define DISPLAY(...)
Definition: zstd.c:44625
ZSTD_fast
@ ZSTD_fast
Definition: zstd.h:317
ZSTD_initCStream_srcSize
size_t ZSTD_initCStream_srcSize(ZSTD_CStream *zcs, int compressionLevel, unsigned long long pss)
Definition: zstd.c:23461
ZSTD_cwksp::tableValidEnd
void * tableValidEnd
Definition: zstd.c:13699
roundBuff_t::capacity
size_t capacity
Definition: zstd.c:31805
BUCKET_B
#define BUCKET_B(_c0, _c1)
Definition: zstd.c:41995
ZSTD_error_checksum_wrong
@ ZSTD_error_checksum_wrong
Definition: zstd.c:1371
FASTCOVER_DEFAULT_SPLITPOINT
#define FASTCOVER_DEFAULT_SPLITPOINT
Definition: zstd.c:43825
ZSTD_DCtx_s::virtualStart
const void * virtualStart
Definition: zstd.c:34912
ZSTD_c_enableLongDistanceMatching
@ ZSTD_c_enableLongDistanceMatching
Definition: zstd.h:394
HUF_compress_internal
static size_t HUF_compress_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, HUF_nbStreams_e nbStreams, void *workSpace, size_t wkspSize, HUF_CElt *oldHufTable, HUF_repeat *repeat, int flags)
Definition: zstd.c:13346
ZSTD_error_srcSize_wrong
@ ZSTD_error_srcSize_wrong
Definition: zstd.c:1388
ML_defaultNorm
static const UNUSED_ATTR S16 ML_defaultNorm[MaxML+1]
Definition: zstd.c:10886
COMPRESS_LITERALS_SIZE_MIN
#define COMPRESS_LITERALS_SIZE_MIN
BIT_readBitsFast
MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, unsigned nbBits)
Definition: zstd.c:2358
ZSTD_rescaleFreqs
static void ZSTD_rescaleFreqs(optState_t *const optPtr, const BYTE *const src, size_t const srcSize, int const optLevel)
Definition: zstd.c:29660
ZSTD_estimateCCtxSize_usingCCtxParams_internal
static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(const ZSTD_compressionParameters *cParams, const ldmParams_t *ldmParams, const int isStatic, const ZSTD_paramSwitch_e useRowMatchFinder, const size_t buffInSize, const size_t buffOutSize, const U64 pledgedSrcSize, int useSequenceProducer, size_t maxBlockSize)
Definition: zstd.c:19285
COVER_best_init
void COVER_best_init(COVER_best_t *best)
Definition: zstd.c:41390
HUF_endMark
static HUF_CElt HUF_endMark(void)
Definition: zstd.c:12977
ZSTD_DCtx_loadDictionary_byReference
size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
Definition: zstd.c:37039
HUF_TABLELOG_ABSOLUTEMAX
#define HUF_TABLELOG_ABSOLUTEMAX
Definition: zstd.c:2878
ZSTD_CCtx_s::workspace
ZSTD_cwksp workspace
Definition: zstd.c:14786
ZSTD_MAX_HUF_HEADER_SIZE
#define ZSTD_MAX_HUF_HEADER_SIZE
Definition: zstd.c:10856
ZSTD_updateTree
void ZSTD_updateTree(ZSTD_matchState_t *ms, const BYTE *ip, const BYTE *iend)
Definition: zstd.c:30096
ZSTDMT_createCCtx_advanced_internal
MEM_STATIC ZSTDMT_CCtx * ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem, ZSTD_threadPool *pool)
Definition: zstd.c:31916
RETURN_ERROR
#define RETURN_ERROR(err,...)
Definition: zstd.c:1517
ZSTD_FOR_EACH_DICT_MODE
#define ZSTD_FOR_EACH_DICT_MODE(X,...)
Definition: zstd.c:27919
nodeElt_s::nbBits
BYTE nbBits
Definition: zstd.c:12099
dictItem::savings
U32 savings
Definition: zstd.c:44704
ZSTD_fseCTables_t::matchlength_repeatMode
FSE_repeat matchlength_repeatMode
Definition: zstd.c:14440
S8
signed char S8
Definition: zstd.c:907
ZSTD_CCtx_params_s::inBufferMode
ZSTD_bufferMode_e inBufferMode
Definition: zstd.c:14701
ZSTD_encodeSequences
size_t ZSTD_encodeSequences(void *dst, size_t dstCapacity, FSE_CTable const *CTable_MatchLength, BYTE const *mlCodeTable, FSE_CTable const *CTable_OffsetBits, BYTE const *ofCodeTable, FSE_CTable const *CTable_LitLength, BYTE const *llCodeTable, seqDef const *sequences, size_t nbSeq, int longOffsets, int bmi2)
Definition: zstd.c:16620
HUF_selectDecoder
U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize)
Definition: zstd.c:34627
MEM_32bits
MEM_STATIC unsigned MEM_32bits(void)
Definition: zstd.c:987
ZSTD_compressBlock_lazy2_extDict_row
size_t ZSTD_compressBlock_lazy2_extDict_row(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:28682
ZSTD_decompressStream
size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
Definition: zstd.c:37387
FSE_CTABLE_SIZE_U32
#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue)
Definition: zstd.c:2439
ZSTD_compressBlock_doubleFast_extDict_generic
static size_t ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize, U32 const mls)
Definition: zstd.c:25400
mqtt_test.ret
ret
Definition: mqtt_test.py:30
FSE_DTable
unsigned FSE_DTable
Definition: zstd.c:1752
repcodes_t
struct repcodes_s repcodes_t
ZSTD_CCtx_s::requestedParams
ZSTD_CCtx_params requestedParams
Definition: zstd.c:14780
ZSTD_buildSeqStore
static size_t ZSTD_buildSeqStore(ZSTD_CCtx *zc, const void *src, size_t srcSize)
Definition: zstd.c:20785
HUF_decompress4X2_usingDTable_internal_fast
static HUF_FAST_BMI2_ATTRS size_t HUF_decompress4X2_usingDTable_internal_fast(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable, HUF_DecompressFastLoopFn loopFn)
Definition: zstd.c:34476
ZSTD_fseCTablesMetadata_t::fseTablesSize
size_t fseTablesSize
Definition: zstd.c:14473
ZDICT_params_t::dictID
unsigned dictID
Definition: zstd.c:40159
ZSTD_assertEqualCParams
static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1, ZSTD_compressionParameters cParams2)
Definition: zstd.c:19487
XXH_alignment
XXH_alignment
Definition: zstd.c:6712
FSE_DecompressWksp
Definition: zstd.c:3729
ZSTD_hufCTablesMetadata_t::hType
symbolEncodingType_e hType
Definition: zstd.c:14460
ZSTD_compressBlock_fast_dictMatchState
size_t ZSTD_compressBlock_fast_dictMatchState(ZSTD_matchState_t *ms, seqStore_t *seqStore, U32 rep[ZSTD_REP_NUM], void const *src, size_t srcSize)
Definition: zstd.c:26231
g_debuglevel
int g_debuglevel
Definition: zstd.c:302
COVER_dictSelectionIsError
unsigned COVER_dictSelectionIsError(COVER_dictSelection_t selection)
Definition: zstd.c:41505
ZSTD_resetDStream
size_t ZSTD_resetDStream(ZSTD_DStream *dctx)
Definition: zstd.c:37096
ZSTD_optLdm_t::offset
U32 offset
Definition: zstd.c:30422
MEM_swap32_fallback
MEM_STATIC U32 MEM_swap32_fallback(U32 in)
Definition: zstd.c:1081
ZSTD_cwksp_used
MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp *ws)
Definition: zstd.c:14221
ZSTD_CCtx_params_s::blockDelimiters
ZSTD_sequenceFormat_e blockDelimiters
Definition: zstd.c:14705
ZSTD_buffered_policy_e
ZSTD_buffered_policy_e
Definition: zstd.c:14747
ZSTD_decompressSequences
static size_t ZSTD_decompressSequences(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, const int frame)
Definition: zstd.c:39632
ZSTD_CONTENTSIZE_ERROR
#define ZSTD_CONTENTSIZE_ERROR
Definition: zstd.h:192
HUF_getValueFast
static size_t HUF_getValueFast(HUF_CElt elt)
Definition: zstd.c:12251
ZSTDMT_CCtxPool::cMem
ZSTD_customMem cMem
Definition: zstd.c:31349
HUF_flags_optimalDepth
@ HUF_flags_optimalDepth
Definition: zstd.c:2927
ZSTD_CCtx_s::expectedInBuffer
ZSTD_inBuffer expectedInBuffer
Definition: zstd.c:14824
ZSTD_CCtx_s::bmi2
int bmi2
Definition: zstd.c:14779
ldmRollingHashState_t
Definition: zstd.c:28819
blockType_e
blockType_e
Definition: zstd.c:10827
FSE_encodeSymbol
static void FSE_encodeSymbol(BIT_CStream_t *bitC, FSE_CState_t *CStatePtr, unsigned symbol)
Definition: zstd.c:2653
MEM_isLittleEndian
MEM_STATIC unsigned MEM_isLittleEndian(void)
Definition: zstd.c:990
ZSTD_localDict::dict
void const * dict
Definition: zstd.c:14424
ZDICT_cover_params_t::zParams
ZDICT_params_t zParams
Definition: zstd.c:40255
ZSTD_reset_matchState
static size_t ZSTD_reset_matchState(ZSTD_matchState_t *ms, ZSTD_cwksp *ws, const ZSTD_compressionParameters *cParams, const ZSTD_paramSwitch_e useRowMatchFinder, const ZSTD_compResetPolicy_e crp, const ZSTD_indexResetPolicy_e forceResetIndex, const ZSTD_resetTarget_e forWho)
Definition: zstd.c:19568
HIST_countFast
size_t HIST_countFast(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize)
Definition: zstd.c:12033
HUF_CStream_t::bitContainer
size_t bitContainer[2]
Definition: zstd.c:12859
XXH128_hashFromCanonical
#define XXH128_hashFromCanonical
sol::detail::ptr
T * ptr(T &val)
Definition: sol.hpp:2106
ZSTD_CWKSP_ASAN_REDZONE_SIZE
#define ZSTD_CWKSP_ASAN_REDZONE_SIZE
Definition: zstd.c:13572
ZSTD_errorFrameSizeInfo
static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
Definition: zstd.c:36073
D
#define D(name, bit)
ZSTD_resolveRepcodeToRawOffset
static U32 ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, const U32 ll0)
Definition: zstd.c:21517
HIST_count_simple
unsigned HIST_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize)
Definition: zstd.c:11894
ZSTD_cwksp_init
MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp *ws, void *start, size_t size, ZSTD_cwksp_static_alloc_e isStatic)
Definition: zstd.c:14178
ZSTD_overlap_e
ZSTD_overlap_e
Definition: zstd.c:10943
ZSTD_deriveBlockSplitsHelper
static void ZSTD_deriveBlockSplitsHelper(seqStoreSplits *splits, size_t startIdx, size_t endIdx, ZSTD_CCtx *zc, const seqStore_t *origSeqStore)
Definition: zstd.c:21675
LIKELY
#define LIKELY(x)
Definition: zstd.c:665
ZSTD_loadEntropy_intoDDict
static size_t ZSTD_loadEntropy_intoDDict(ZSTD_DDict *ddict, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:35126
ZSTD_matchState_t
Definition: zstd.c:14580
ZSTD_CCtx_params_s::targetCBlockSize
size_t targetCBlockSize
Definition: zstd.c:14678
BIT_DStream_t::start
const char * start
Definition: zstd.c:2086
nodeElt
struct nodeElt_s nodeElt
inBuff_t
Definition: zstd.c:31793
HUF_buildDEltX2U32
static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level)
Definition: zstd.c:33778
ZSTD_cycleLog
U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
Definition: zstd.c:19051
HUF_CTABLE_SIZE_ST
#define HUF_CTABLE_SIZE_ST(maxSymbolValue)
Definition: zstd.c:2895
ZSTD_fseCTables_t::offcodeCTable
FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]
Definition: zstd.c:14436
ZSTD_selectEncodingType
symbolEncodingType_e ZSTD_selectEncodingType(FSE_repeat *repeatMode, unsigned const *count, unsigned const max, size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, FSE_CTable const *prevCTable, short const *defaultNorm, U32 defaultNormLog, ZSTD_defaultPolicy_e const isDefaultAllowed, ZSTD_strategy const strategy)
Definition: zstd.c:16358
ZSTD_rollingHash_primePower
MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length)
Definition: zstd.c:15271
ZSTD_wildcopy
MEM_STATIC FORCE_INLINE_ATTR void ZSTD_wildcopy(void *dst, const void *src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
Definition: zstd.c:10957
ZSTDMT_freeBufferPool
static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool *bufPool)
Definition: zstd.c:31119
RSYNC_MIN_BLOCK_LOG
#define RSYNC_MIN_BLOCK_LOG
Definition: zstd.c:31823
ZSTDMT_overlapLog_default
static int ZSTDMT_overlapLog_default(ZSTD_strategy strat)
Definition: zstd.c:32164
HUF_BITS_IN_CONTAINER
#define HUF_BITS_IN_CONTAINER
Definition: zstd.c:12856
OF_bits
static const UNUSED_ATTR U8 OF_bits[MaxOff+1]
Definition: zstd.c:34819
optState_t::symbolCosts
const ZSTD_entropyCTables_t * symbolCosts
Definition: zstd.c:14553
BIT_DStream_t::bitsConsumed
unsigned bitsConsumed
Definition: zstd.c:2084
ZSTD_copyCDictTableIntoCCtx
static void ZSTD_copyCDictTableIntoCCtx(U32 *dst, U32 const *src, size_t tableSize, ZSTD_compressionParameters const *cParams)
Definition: zstd.c:19969
HUF_compress_tables_t::buildCTable_wksp
HUF_buildCTable_wksp_tables buildCTable_wksp
Definition: zstd.c:13260
HUF_FAST_BMI2_ATTRS
#define HUF_FAST_BMI2_ATTRS
Definition: zstd.c:32921
XXH_PUBLIC_API
#define XXH_PUBLIC_API
XXH_PRIME64_3
#define XXH_PRIME64_3
Definition: zstd.c:7311
ZSTD_ROW_HASH_TAG_MASK
#define ZSTD_ROW_HASH_TAG_MASK
Definition: zstd.c:27296
NOISELENGTH
#define NOISELENGTH
Definition: zstd.c:44616
ZSTD_hash7
static size_t ZSTD_hash7(U64 u, U32 h, U64 s)
Definition: zstd.c:15183
seqStore_t::sequences
seqDef * sequences
Definition: zstd.c:11033
ZSTD_createDCtx
ZSTD_DCtx * ZSTD_createDCtx(void)
Definition: zstd.c:35659
nodeElt_s::count
U32 count
Definition: zstd.c:12096
SEQSYMBOL_TABLE_SIZE
#define SEQSYMBOL_TABLE_SIZE(log)
Definition: zstd.c:34850
HUF_flags_suspectUncompressible
@ HUF_flags_suspectUncompressible
Definition: zstd.c:2937
HUF_ReadDTableX2_Workspace::sortedSymbol
sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX+1]
Definition: zstd.c:33991
ZSTD_freeDStream
size_t ZSTD_freeDStream(ZSTD_DStream *zds)
Definition: zstd.c:37012
ZSTD_estimateSubBlockSize
static size_t ZSTD_estimateSubBlockSize(const BYTE *literals, size_t litSize, const BYTE *ofCodeTable, const BYTE *llCodeTable, const BYTE *mlCodeTable, size_t nbSeq, const ZSTD_entropyCTables_t *entropy, const ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, size_t wkspSize, int writeLitEntropy, int writeSeqEntropy)
Definition: zstd.c:17070
ZSTD_cwksp_dynamic_alloc
@ ZSTD_cwksp_dynamic_alloc
Definition: zstd.c:13595
ZSTD_cwksp_assert_internal_consistency
MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp *ws)
Definition: zstd.c:13716
ZSTD_allocateChainTable
static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e useRowMatchFinder, const U32 forDDSDict)
Definition: zstd.c:17900
ZDICT_params_t::notificationLevel
unsigned notificationLevel
Definition: zstd.c:40158
ZSTDMT_CCtx_s::serial
serialState_t serial
Definition: zstd.c:31844
ZSTDMT_bufferPool_s::bufferSize
size_t bufferSize
Definition: zstd.c:31096
HUF_compressCTable_internal
static size_t HUF_compressCTable_internal(BYTE *const ostart, BYTE *op, BYTE *const oend, const void *src, size_t srcSize, HUF_nbStreams_e nbStreams, const HUF_CElt *CTable, const int flags)
Definition: zstd.c:13239
STACK_SIZE
#define STACK_SIZE
g_selectivity_default
static const U32 g_selectivity_default
Definition: zstd.c:44618
ZSTDcs_created
@ ZSTDcs_created
Definition: zstd.c:14413
ZSTD_customCalloc
MEM_STATIC void * ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
Definition: zstd.c:4180
POOL_ctx_s::threadLimit
size_t threadLimit
Definition: zstd.c:4320
ZSTD_DCtx_updateOversizedDuration
static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream *zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
Definition: zstd.c:37322
ZSTD_c_searchLog
@ ZSTD_c_searchLog
Definition: zstd.h:369
ss_insertionsort
static void ss_insertionsort(const unsigned char *T, const int *PA, int *first, int *last, int depth)
Definition: zstd.c:42122
ZSTD_fseBitCost
size_t ZSTD_fseBitCost(FSE_CTable const *ctable, unsigned const *count, unsigned const max)
Definition: zstd.c:16305
ZSTD_checkDictValidity
MEM_STATIC void ZSTD_checkDictValidity(const ZSTD_window_t *window, const void *blockEnd, U32 maxDist, U32 *loadedDictEndPtr, const ZSTD_matchState_t **dictMatchStatePtr)
Definition: zstd.c:15562
ZSTD_compress
size_t ZSTD_compress(void *dst, size_t dstCapacity, const void *src, size_t srcSize, int compressionLevel)
Definition: zstd.c:22898
HUF_compress1X_usingCTable_internal
static size_t HUF_compress1X_usingCTable_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable, const int flags)
Definition: zstd.c:13167
allBytesIdentical
static int allBytesIdentical(const void *src, size_t srcSize)
Definition: zstd.c:15977
ZSTDMT_serialState_reset
static int ZSTDMT_serialState_reset(serialState_t *serialState, ZSTDMT_seqPool *seqPool, ZSTD_CCtx_params params, size_t jobSize, const void *dict, size_t const dictSize, ZSTD_dictContentType_e dictContentType)
Definition: zstd.c:31468
GEN_ZSTD_BT_SEARCH_FN
#define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls)
Definition: zstd.c:27873
ZSTD_CONTENTSIZE_UNKNOWN
#define ZSTD_CONTENTSIZE_UNKNOWN
Definition: zstd.h:191
ZSTD_crossEntropyCost
size_t ZSTD_crossEntropyCost(short const *norm, unsigned accuracyLog, unsigned const *count, unsigned const max)
Definition: zstd.c:16340
udp_client.args
args
Definition: udp_client.py:12
ZSTD_cpm_unknown
@ ZSTD_cpm_unknown
Definition: zstd.c:14873
ZSTD_DCtx_s::outEnd
size_t outEnd
Definition: zstd.c:34955
ZSTDMT_freeCCtx
size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx *mtctx)
Definition: zstd.c:32010
RANK_POSITION_LOG_BUCKETS_BEGIN
#define RANK_POSITION_LOG_BUCKETS_BEGIN
Definition: zstd.c:12547
ZSTD_DCtx_reset
size_t ZSTD_DCtx_reset(ZSTD_DCtx *dctx, ZSTD_ResetDirective reset)
Definition: zstd.c:37260
rawSeqStore_t::size
size_t size
Definition: zstd.c:14513
CHECK_DBOUNDS
#define CHECK_DBOUNDS(p, v)
Definition: zstd.c:37193
ZSTD_getCParamsFromCDict
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict *cdict)
Definition: zstd.c:23203
ZSTD_CCtx_s::inToCompress
size_t inToCompress
Definition: zstd.c:14813
ZSTD_copy4
static void ZSTD_copy4(void *dst, const void *src)
Definition: zstd.c:37756
ZSTD_ROW_HASH_CACHE_SIZE
#define ZSTD_ROW_HASH_CACHE_SIZE
Definition: zstd.c:14578
HUF_decompress4X2_usingDTable_internal_default
static size_t HUF_decompress4X2_usingDTable_internal_default(void *dst, size_t dstSize, void const *cSrc, size_t cSrcSize, HUF_DTable const *DTable)
Definition: zstd.c:34324
XXH_swap32
static xxh_u32 XXH_swap32(xxh_u32 x)
Definition: zstd.c:6694
MEM_readBE32
MEM_STATIC U32 MEM_readBE32(const void *memPtr)
Definition: zstd.c:1217
ZSTD_blockState_confirmRepcodesAndEntropyTables
static void ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t *const bs)
Definition: zstd.c:21086
ZSTD_refDictContent
static size_t ZSTD_refDictContent(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
Definition: zstd.c:36760
ZSTD_estimateDCtxSize
size_t ZSTD_estimateDCtxSize(void)
Definition: zstd.c:35580
ZSTD_selectSequenceCopier
static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
Definition: zstd.c:24243
ZSTD_error_prefix_unknown
@ ZSTD_error_prefix_unknown
Definition: zstd.c:1366
ZSTD_freeCCtxParams
size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params *params)
Definition: zstd.c:17991


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:27