annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/zdict.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
rev   line source
jpayne@69 1 /*
jpayne@69 2 * Copyright (c) Meta Platforms, Inc. and affiliates.
jpayne@69 3 * All rights reserved.
jpayne@69 4 *
jpayne@69 5 * This source code is licensed under both the BSD-style license (found in the
jpayne@69 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
jpayne@69 7 * in the COPYING file in the root directory of this source tree).
jpayne@69 8 * You may select, at your option, one of the above-listed licenses.
jpayne@69 9 */
jpayne@69 10
jpayne@69 11 #if defined (__cplusplus)
jpayne@69 12 extern "C" {
jpayne@69 13 #endif
jpayne@69 14
jpayne@69 15 #ifndef ZSTD_ZDICT_H
jpayne@69 16 #define ZSTD_ZDICT_H
jpayne@69 17
jpayne@69 18 /*====== Dependencies ======*/
jpayne@69 19 #include <stddef.h> /* size_t */
jpayne@69 20
jpayne@69 21
jpayne@69 22 /* ===== ZDICTLIB_API : control library symbols visibility ===== */
jpayne@69 23 #ifndef ZDICTLIB_VISIBLE
jpayne@69 24 /* Backwards compatibility with old macro name */
jpayne@69 25 # ifdef ZDICTLIB_VISIBILITY
jpayne@69 26 # define ZDICTLIB_VISIBLE ZDICTLIB_VISIBILITY
jpayne@69 27 # elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
jpayne@69 28 # define ZDICTLIB_VISIBLE __attribute__ ((visibility ("default")))
jpayne@69 29 # else
jpayne@69 30 # define ZDICTLIB_VISIBLE
jpayne@69 31 # endif
jpayne@69 32 #endif
jpayne@69 33
jpayne@69 34 #ifndef ZDICTLIB_HIDDEN
jpayne@69 35 # if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
jpayne@69 36 # define ZDICTLIB_HIDDEN __attribute__ ((visibility ("hidden")))
jpayne@69 37 # else
jpayne@69 38 # define ZDICTLIB_HIDDEN
jpayne@69 39 # endif
jpayne@69 40 #endif
jpayne@69 41
jpayne@69 42 #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
jpayne@69 43 # define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBLE
jpayne@69 44 #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
jpayne@69 45 # 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.*/
jpayne@69 46 #else
jpayne@69 47 # define ZDICTLIB_API ZDICTLIB_VISIBLE
jpayne@69 48 #endif
jpayne@69 49
jpayne@69 50 /*******************************************************************************
jpayne@69 51 * Zstd dictionary builder
jpayne@69 52 *
jpayne@69 53 * FAQ
jpayne@69 54 * ===
jpayne@69 55 * Why should I use a dictionary?
jpayne@69 56 * ------------------------------
jpayne@69 57 *
jpayne@69 58 * Zstd can use dictionaries to improve compression ratio of small data.
jpayne@69 59 * Traditionally small files don't compress well because there is very little
jpayne@69 60 * repetition in a single sample, since it is small. But, if you are compressing
jpayne@69 61 * many similar files, like a bunch of JSON records that share the same
jpayne@69 62 * structure, you can train a dictionary on ahead of time on some samples of
jpayne@69 63 * these files. Then, zstd can use the dictionary to find repetitions that are
jpayne@69 64 * present across samples. This can vastly improve compression ratio.
jpayne@69 65 *
jpayne@69 66 * When is a dictionary useful?
jpayne@69 67 * ----------------------------
jpayne@69 68 *
jpayne@69 69 * Dictionaries are useful when compressing many small files that are similar.
jpayne@69 70 * The larger a file is, the less benefit a dictionary will have. Generally,
jpayne@69 71 * we don't expect dictionary compression to be effective past 100KB. And the
jpayne@69 72 * smaller a file is, the more we would expect the dictionary to help.
jpayne@69 73 *
jpayne@69 74 * How do I use a dictionary?
jpayne@69 75 * --------------------------
jpayne@69 76 *
jpayne@69 77 * Simply pass the dictionary to the zstd compressor with
jpayne@69 78 * `ZSTD_CCtx_loadDictionary()`. The same dictionary must then be passed to
jpayne@69 79 * the decompressor, using `ZSTD_DCtx_loadDictionary()`. There are other
jpayne@69 80 * more advanced functions that allow selecting some options, see zstd.h for
jpayne@69 81 * complete documentation.
jpayne@69 82 *
jpayne@69 83 * What is a zstd dictionary?
jpayne@69 84 * --------------------------
jpayne@69 85 *
jpayne@69 86 * A zstd dictionary has two pieces: Its header, and its content. The header
jpayne@69 87 * contains a magic number, the dictionary ID, and entropy tables. These
jpayne@69 88 * entropy tables allow zstd to save on header costs in the compressed file,
jpayne@69 89 * which really matters for small data. The content is just bytes, which are
jpayne@69 90 * repeated content that is common across many samples.
jpayne@69 91 *
jpayne@69 92 * What is a raw content dictionary?
jpayne@69 93 * ---------------------------------
jpayne@69 94 *
jpayne@69 95 * A raw content dictionary is just bytes. It doesn't have a zstd dictionary
jpayne@69 96 * header, a dictionary ID, or entropy tables. Any buffer is a valid raw
jpayne@69 97 * content dictionary.
jpayne@69 98 *
jpayne@69 99 * How do I train a dictionary?
jpayne@69 100 * ----------------------------
jpayne@69 101 *
jpayne@69 102 * Gather samples from your use case. These samples should be similar to each
jpayne@69 103 * other. If you have several use cases, you could try to train one dictionary
jpayne@69 104 * per use case.
jpayne@69 105 *
jpayne@69 106 * Pass those samples to `ZDICT_trainFromBuffer()` and that will train your
jpayne@69 107 * dictionary. There are a few advanced versions of this function, but this
jpayne@69 108 * is a great starting point. If you want to further tune your dictionary
jpayne@69 109 * you could try `ZDICT_optimizeTrainFromBuffer_cover()`. If that is too slow
jpayne@69 110 * you can try `ZDICT_optimizeTrainFromBuffer_fastCover()`.
jpayne@69 111 *
jpayne@69 112 * If the dictionary training function fails, that is likely because you
jpayne@69 113 * either passed too few samples, or a dictionary would not be effective
jpayne@69 114 * for your data. Look at the messages that the dictionary trainer printed,
jpayne@69 115 * if it doesn't say too few samples, then a dictionary would not be effective.
jpayne@69 116 *
jpayne@69 117 * How large should my dictionary be?
jpayne@69 118 * ----------------------------------
jpayne@69 119 *
jpayne@69 120 * A reasonable dictionary size, the `dictBufferCapacity`, is about 100KB.
jpayne@69 121 * The zstd CLI defaults to a 110KB dictionary. You likely don't need a
jpayne@69 122 * dictionary larger than that. But, most use cases can get away with a
jpayne@69 123 * smaller dictionary. The advanced dictionary builders can automatically
jpayne@69 124 * shrink the dictionary for you, and select the smallest size that doesn't
jpayne@69 125 * hurt compression ratio too much. See the `shrinkDict` parameter.
jpayne@69 126 * A smaller dictionary can save memory, and potentially speed up
jpayne@69 127 * compression.
jpayne@69 128 *
jpayne@69 129 * How many samples should I provide to the dictionary builder?
jpayne@69 130 * ------------------------------------------------------------
jpayne@69 131 *
jpayne@69 132 * We generally recommend passing ~100x the size of the dictionary
jpayne@69 133 * in samples. A few thousand should suffice. Having too few samples
jpayne@69 134 * can hurt the dictionaries effectiveness. Having more samples will
jpayne@69 135 * only improve the dictionaries effectiveness. But having too many
jpayne@69 136 * samples can slow down the dictionary builder.
jpayne@69 137 *
jpayne@69 138 * How do I determine if a dictionary will be effective?
jpayne@69 139 * -----------------------------------------------------
jpayne@69 140 *
jpayne@69 141 * Simply train a dictionary and try it out. You can use zstd's built in
jpayne@69 142 * benchmarking tool to test the dictionary effectiveness.
jpayne@69 143 *
jpayne@69 144 * # Benchmark levels 1-3 without a dictionary
jpayne@69 145 * zstd -b1e3 -r /path/to/my/files
jpayne@69 146 * # Benchmark levels 1-3 with a dictionary
jpayne@69 147 * zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary
jpayne@69 148 *
jpayne@69 149 * When should I retrain a dictionary?
jpayne@69 150 * -----------------------------------
jpayne@69 151 *
jpayne@69 152 * You should retrain a dictionary when its effectiveness drops. Dictionary
jpayne@69 153 * effectiveness drops as the data you are compressing changes. Generally, we do
jpayne@69 154 * expect dictionaries to "decay" over time, as your data changes, but the rate
jpayne@69 155 * at which they decay depends on your use case. Internally, we regularly
jpayne@69 156 * retrain dictionaries, and if the new dictionary performs significantly
jpayne@69 157 * better than the old dictionary, we will ship the new dictionary.
jpayne@69 158 *
jpayne@69 159 * I have a raw content dictionary, how do I turn it into a zstd dictionary?
jpayne@69 160 * -------------------------------------------------------------------------
jpayne@69 161 *
jpayne@69 162 * If you have a raw content dictionary, e.g. by manually constructing it, or
jpayne@69 163 * using a third-party dictionary builder, you can turn it into a zstd
jpayne@69 164 * dictionary by using `ZDICT_finalizeDictionary()`. You'll also have to
jpayne@69 165 * provide some samples of the data. It will add the zstd header to the
jpayne@69 166 * raw content, which contains a dictionary ID and entropy tables, which
jpayne@69 167 * will improve compression ratio, and allow zstd to write the dictionary ID
jpayne@69 168 * into the frame, if you so choose.
jpayne@69 169 *
jpayne@69 170 * Do I have to use zstd's dictionary builder?
jpayne@69 171 * -------------------------------------------
jpayne@69 172 *
jpayne@69 173 * No! You can construct dictionary content however you please, it is just
jpayne@69 174 * bytes. It will always be valid as a raw content dictionary. If you want
jpayne@69 175 * a zstd dictionary, which can improve compression ratio, use
jpayne@69 176 * `ZDICT_finalizeDictionary()`.
jpayne@69 177 *
jpayne@69 178 * What is the attack surface of a zstd dictionary?
jpayne@69 179 * ------------------------------------------------
jpayne@69 180 *
jpayne@69 181 * Zstd is heavily fuzz tested, including loading fuzzed dictionaries, so
jpayne@69 182 * zstd should never crash, or access out-of-bounds memory no matter what
jpayne@69 183 * the dictionary is. However, if an attacker can control the dictionary
jpayne@69 184 * during decompression, they can cause zstd to generate arbitrary bytes,
jpayne@69 185 * just like if they controlled the compressed data.
jpayne@69 186 *
jpayne@69 187 ******************************************************************************/
jpayne@69 188
jpayne@69 189
jpayne@69 190 /*! ZDICT_trainFromBuffer():
jpayne@69 191 * Train a dictionary from an array of samples.
jpayne@69 192 * Redirect towards ZDICT_optimizeTrainFromBuffer_fastCover() single-threaded, with d=8, steps=4,
jpayne@69 193 * f=20, and accel=1.
jpayne@69 194 * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
jpayne@69 195 * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
jpayne@69 196 * The resulting dictionary will be saved into `dictBuffer`.
jpayne@69 197 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 198 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 199 * Note: Dictionary training will fail if there are not enough samples to construct a
jpayne@69 200 * dictionary, or if most of the samples are too small (< 8 bytes being the lower limit).
jpayne@69 201 * If dictionary training fails, you should use zstd without a dictionary, as the dictionary
jpayne@69 202 * would've been ineffective anyways. If you believe your samples would benefit from a dictionary
jpayne@69 203 * please open an issue with details, and we can look into it.
jpayne@69 204 * Note: ZDICT_trainFromBuffer()'s memory usage is about 6 MB.
jpayne@69 205 * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
jpayne@69 206 * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`.
jpayne@69 207 * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
jpayne@69 208 * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
jpayne@69 209 */
jpayne@69 210 ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
jpayne@69 211 const void* samplesBuffer,
jpayne@69 212 const size_t* samplesSizes, unsigned nbSamples);
jpayne@69 213
jpayne@69 214 typedef struct {
jpayne@69 215 int compressionLevel; /**< optimize for a specific zstd compression level; 0 means default */
jpayne@69 216 unsigned notificationLevel; /**< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
jpayne@69 217 unsigned dictID; /**< force dictID value; 0 means auto mode (32-bits random value)
jpayne@69 218 * NOTE: The zstd format reserves some dictionary IDs for future use.
jpayne@69 219 * You may use them in private settings, but be warned that they
jpayne@69 220 * may be used by zstd in a public dictionary registry in the future.
jpayne@69 221 * These dictionary IDs are:
jpayne@69 222 * - low range : <= 32767
jpayne@69 223 * - high range : >= (2^31)
jpayne@69 224 */
jpayne@69 225 } ZDICT_params_t;
jpayne@69 226
jpayne@69 227 /*! ZDICT_finalizeDictionary():
jpayne@69 228 * Given a custom content as a basis for dictionary, and a set of samples,
jpayne@69 229 * finalize dictionary by adding headers and statistics according to the zstd
jpayne@69 230 * dictionary format.
jpayne@69 231 *
jpayne@69 232 * Samples must be stored concatenated in a flat buffer `samplesBuffer`,
jpayne@69 233 * supplied with an array of sizes `samplesSizes`, providing the size of each
jpayne@69 234 * sample in order. The samples are used to construct the statistics, so they
jpayne@69 235 * should be representative of what you will compress with this dictionary.
jpayne@69 236 *
jpayne@69 237 * The compression level can be set in `parameters`. You should pass the
jpayne@69 238 * compression level you expect to use in production. The statistics for each
jpayne@69 239 * compression level differ, so tuning the dictionary for the compression level
jpayne@69 240 * can help quite a bit.
jpayne@69 241 *
jpayne@69 242 * You can set an explicit dictionary ID in `parameters`, or allow us to pick
jpayne@69 243 * a random dictionary ID for you, but we can't guarantee no collisions.
jpayne@69 244 *
jpayne@69 245 * The dstDictBuffer and the dictContent may overlap, and the content will be
jpayne@69 246 * appended to the end of the header. If the header + the content doesn't fit in
jpayne@69 247 * maxDictSize the beginning of the content is truncated to make room, since it
jpayne@69 248 * is presumed that the most profitable content is at the end of the dictionary,
jpayne@69 249 * since that is the cheapest to reference.
jpayne@69 250 *
jpayne@69 251 * `maxDictSize` must be >= max(dictContentSize, ZSTD_DICTSIZE_MIN).
jpayne@69 252 *
jpayne@69 253 * @return: size of dictionary stored into `dstDictBuffer` (<= `maxDictSize`),
jpayne@69 254 * or an error code, which can be tested by ZDICT_isError().
jpayne@69 255 * Note: ZDICT_finalizeDictionary() will push notifications into stderr if
jpayne@69 256 * instructed to, using notificationLevel>0.
jpayne@69 257 * NOTE: This function currently may fail in several edge cases including:
jpayne@69 258 * * Not enough samples
jpayne@69 259 * * Samples are uncompressible
jpayne@69 260 * * Samples are all exactly the same
jpayne@69 261 */
jpayne@69 262 ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dstDictBuffer, size_t maxDictSize,
jpayne@69 263 const void* dictContent, size_t dictContentSize,
jpayne@69 264 const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
jpayne@69 265 ZDICT_params_t parameters);
jpayne@69 266
jpayne@69 267
jpayne@69 268 /*====== Helper functions ======*/
jpayne@69 269 ZDICTLIB_API unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize); /**< extracts dictID; @return zero if error (not a valid dictionary) */
jpayne@69 270 ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize); /* returns dict header size; returns a ZSTD error code on failure */
jpayne@69 271 ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode);
jpayne@69 272 ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
jpayne@69 273
jpayne@69 274 #endif /* ZSTD_ZDICT_H */
jpayne@69 275
jpayne@69 276 #if defined(ZDICT_STATIC_LINKING_ONLY) && !defined(ZSTD_ZDICT_H_STATIC)
jpayne@69 277 #define ZSTD_ZDICT_H_STATIC
jpayne@69 278
jpayne@69 279 /* This can be overridden externally to hide static symbols. */
jpayne@69 280 #ifndef ZDICTLIB_STATIC_API
jpayne@69 281 # if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
jpayne@69 282 # define ZDICTLIB_STATIC_API __declspec(dllexport) ZDICTLIB_VISIBLE
jpayne@69 283 # elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
jpayne@69 284 # define ZDICTLIB_STATIC_API __declspec(dllimport) ZDICTLIB_VISIBLE
jpayne@69 285 # else
jpayne@69 286 # define ZDICTLIB_STATIC_API ZDICTLIB_VISIBLE
jpayne@69 287 # endif
jpayne@69 288 #endif
jpayne@69 289
jpayne@69 290 /* ====================================================================================
jpayne@69 291 * The definitions in this section are considered experimental.
jpayne@69 292 * They should never be used with a dynamic library, as they may change in the future.
jpayne@69 293 * They are provided for advanced usages.
jpayne@69 294 * Use them only in association with static linking.
jpayne@69 295 * ==================================================================================== */
jpayne@69 296
jpayne@69 297 #define ZDICT_DICTSIZE_MIN 256
jpayne@69 298 /* Deprecated: Remove in v1.6.0 */
jpayne@69 299 #define ZDICT_CONTENTSIZE_MIN 128
jpayne@69 300
jpayne@69 301 /*! ZDICT_cover_params_t:
jpayne@69 302 * k and d are the only required parameters.
jpayne@69 303 * For others, value 0 means default.
jpayne@69 304 */
jpayne@69 305 typedef struct {
jpayne@69 306 unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */
jpayne@69 307 unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */
jpayne@69 308 unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */
jpayne@69 309 unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */
jpayne@69 310 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 */
jpayne@69 311 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 */
jpayne@69 312 unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */
jpayne@69 313 ZDICT_params_t zParams;
jpayne@69 314 } ZDICT_cover_params_t;
jpayne@69 315
jpayne@69 316 typedef struct {
jpayne@69 317 unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */
jpayne@69 318 unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */
jpayne@69 319 unsigned f; /* log of size of frequency array : constraint: 0 < f <= 31 : 1 means default(20)*/
jpayne@69 320 unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */
jpayne@69 321 unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */
jpayne@69 322 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 */
jpayne@69 323 unsigned accel; /* Acceleration level: constraint: 0 < accel <= 10, higher means faster and less accurate, 0 means default(1) */
jpayne@69 324 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 */
jpayne@69 325 unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */
jpayne@69 326
jpayne@69 327 ZDICT_params_t zParams;
jpayne@69 328 } ZDICT_fastCover_params_t;
jpayne@69 329
jpayne@69 330 /*! ZDICT_trainFromBuffer_cover():
jpayne@69 331 * Train a dictionary from an array of samples using the COVER algorithm.
jpayne@69 332 * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
jpayne@69 333 * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
jpayne@69 334 * The resulting dictionary will be saved into `dictBuffer`.
jpayne@69 335 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 336 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 337 * See ZDICT_trainFromBuffer() for details on failure modes.
jpayne@69 338 * Note: ZDICT_trainFromBuffer_cover() requires about 9 bytes of memory for each input byte.
jpayne@69 339 * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
jpayne@69 340 * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`.
jpayne@69 341 * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
jpayne@69 342 * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
jpayne@69 343 */
jpayne@69 344 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover(
jpayne@69 345 void *dictBuffer, size_t dictBufferCapacity,
jpayne@69 346 const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
jpayne@69 347 ZDICT_cover_params_t parameters);
jpayne@69 348
jpayne@69 349 /*! ZDICT_optimizeTrainFromBuffer_cover():
jpayne@69 350 * The same requirements as above hold for all the parameters except `parameters`.
jpayne@69 351 * This function tries many parameter combinations and picks the best parameters.
jpayne@69 352 * `*parameters` is filled with the best parameters found,
jpayne@69 353 * dictionary constructed with those parameters is stored in `dictBuffer`.
jpayne@69 354 *
jpayne@69 355 * All of the parameters d, k, steps are optional.
jpayne@69 356 * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}.
jpayne@69 357 * if steps is zero it defaults to its default value.
jpayne@69 358 * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000].
jpayne@69 359 *
jpayne@69 360 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 361 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 362 * On success `*parameters` contains the parameters selected.
jpayne@69 363 * See ZDICT_trainFromBuffer() for details on failure modes.
jpayne@69 364 * Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread.
jpayne@69 365 */
jpayne@69 366 ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover(
jpayne@69 367 void* dictBuffer, size_t dictBufferCapacity,
jpayne@69 368 const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
jpayne@69 369 ZDICT_cover_params_t* parameters);
jpayne@69 370
jpayne@69 371 /*! ZDICT_trainFromBuffer_fastCover():
jpayne@69 372 * Train a dictionary from an array of samples using a modified version of COVER algorithm.
jpayne@69 373 * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
jpayne@69 374 * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
jpayne@69 375 * d and k are required.
jpayne@69 376 * All other parameters are optional, will use default values if not provided
jpayne@69 377 * The resulting dictionary will be saved into `dictBuffer`.
jpayne@69 378 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 379 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 380 * See ZDICT_trainFromBuffer() for details on failure modes.
jpayne@69 381 * Note: ZDICT_trainFromBuffer_fastCover() requires 6 * 2^f bytes of memory.
jpayne@69 382 * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
jpayne@69 383 * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`.
jpayne@69 384 * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
jpayne@69 385 * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
jpayne@69 386 */
jpayne@69 387 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer,
jpayne@69 388 size_t dictBufferCapacity, const void *samplesBuffer,
jpayne@69 389 const size_t *samplesSizes, unsigned nbSamples,
jpayne@69 390 ZDICT_fastCover_params_t parameters);
jpayne@69 391
jpayne@69 392 /*! ZDICT_optimizeTrainFromBuffer_fastCover():
jpayne@69 393 * The same requirements as above hold for all the parameters except `parameters`.
jpayne@69 394 * This function tries many parameter combinations (specifically, k and d combinations)
jpayne@69 395 * and picks the best parameters. `*parameters` is filled with the best parameters found,
jpayne@69 396 * dictionary constructed with those parameters is stored in `dictBuffer`.
jpayne@69 397 * All of the parameters d, k, steps, f, and accel are optional.
jpayne@69 398 * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}.
jpayne@69 399 * if steps is zero it defaults to its default value.
jpayne@69 400 * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000].
jpayne@69 401 * If f is zero, default value of 20 is used.
jpayne@69 402 * If accel is zero, default value of 1 is used.
jpayne@69 403 *
jpayne@69 404 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 405 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 406 * On success `*parameters` contains the parameters selected.
jpayne@69 407 * See ZDICT_trainFromBuffer() for details on failure modes.
jpayne@69 408 * Note: ZDICT_optimizeTrainFromBuffer_fastCover() requires about 6 * 2^f bytes of memory for each thread.
jpayne@69 409 */
jpayne@69 410 ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer,
jpayne@69 411 size_t dictBufferCapacity, const void* samplesBuffer,
jpayne@69 412 const size_t* samplesSizes, unsigned nbSamples,
jpayne@69 413 ZDICT_fastCover_params_t* parameters);
jpayne@69 414
jpayne@69 415 typedef struct {
jpayne@69 416 unsigned selectivityLevel; /* 0 means default; larger => select more => larger dictionary */
jpayne@69 417 ZDICT_params_t zParams;
jpayne@69 418 } ZDICT_legacy_params_t;
jpayne@69 419
jpayne@69 420 /*! ZDICT_trainFromBuffer_legacy():
jpayne@69 421 * Train a dictionary from an array of samples.
jpayne@69 422 * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
jpayne@69 423 * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
jpayne@69 424 * The resulting dictionary will be saved into `dictBuffer`.
jpayne@69 425 * `parameters` is optional and can be provided with values set to 0 to mean "default".
jpayne@69 426 * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
jpayne@69 427 * or an error code, which can be tested with ZDICT_isError().
jpayne@69 428 * See ZDICT_trainFromBuffer() for details on failure modes.
jpayne@69 429 * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
jpayne@69 430 * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`.
jpayne@69 431 * In general, it's recommended to provide a few thousands samples, though this can vary a lot.
jpayne@69 432 * It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
jpayne@69 433 * Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0.
jpayne@69 434 */
jpayne@69 435 ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy(
jpayne@69 436 void* dictBuffer, size_t dictBufferCapacity,
jpayne@69 437 const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
jpayne@69 438 ZDICT_legacy_params_t parameters);
jpayne@69 439
jpayne@69 440
jpayne@69 441 /* Deprecation warnings */
jpayne@69 442 /* It is generally possible to disable deprecation warnings from compiler,
jpayne@69 443 for example with -Wno-deprecated-declarations for gcc
jpayne@69 444 or _CRT_SECURE_NO_WARNINGS in Visual.
jpayne@69 445 Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */
jpayne@69 446 #ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS
jpayne@69 447 # define ZDICT_DEPRECATED(message) /* disable deprecation warnings */
jpayne@69 448 #else
jpayne@69 449 # define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
jpayne@69 450 # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
jpayne@69 451 # define ZDICT_DEPRECATED(message) [[deprecated(message)]]
jpayne@69 452 # elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405)
jpayne@69 453 # define ZDICT_DEPRECATED(message) __attribute__((deprecated(message)))
jpayne@69 454 # elif (ZDICT_GCC_VERSION >= 301)
jpayne@69 455 # define ZDICT_DEPRECATED(message) __attribute__((deprecated))
jpayne@69 456 # elif defined(_MSC_VER)
jpayne@69 457 # define ZDICT_DEPRECATED(message) __declspec(deprecated(message))
jpayne@69 458 # else
jpayne@69 459 # pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler")
jpayne@69 460 # define ZDICT_DEPRECATED(message)
jpayne@69 461 # endif
jpayne@69 462 #endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */
jpayne@69 463
jpayne@69 464 ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead")
jpayne@69 465 ZDICTLIB_STATIC_API
jpayne@69 466 size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
jpayne@69 467 const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
jpayne@69 468
jpayne@69 469
jpayne@69 470 #endif /* ZSTD_ZDICT_H_STATIC */
jpayne@69 471
jpayne@69 472 #if defined (__cplusplus)
jpayne@69 473 }
jpayne@69 474 #endif