| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 390a9dc commit 8e697d1
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1081,6 +1081,9 @@ Each Zstd-based class takes an `options` object. All options are optional. | |||
| 1081 | 1081 | * `maxOutputLength` {integer} Limits output size when using | |
| 1082 | 1082 | [convenience methods][]. **Default:** [`buffer.kMaxLength`][] | |
| 1083 | 1083 | * `info` {boolean} If `true`, returns an object with `buffer` and `engine`. **Default:** `false` | |
| 1084 | + * `dictionary` {Buffer} Optional dictionary used to | ||
| 1085 | + improve compression efficiency when compressing or decompressing data that | ||
| 1086 | + shares common patterns with the dictionary. | ||
| 1084 | 1087 | ||
| 1085 | 1088 | For example: | |
| 1086 | 1089 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -891,12 +891,15 @@ class Zstd extends ZlibBase { | |||
| 891 | 891 | const pledgedSrcSize = opts?.pledgedSrcSize ?? undefined; | |
| 892 | 892 | ||
| 893 | 893 | const writeState = new Uint32Array(2); | |
| 894 | + | ||
| 894 | 895 | handle.init( | |
| 895 | 896 | initParamsArray, | |
| 896 | 897 | pledgedSrcSize, | |
| 897 | 898 | writeState, | |
| 898 | 899 | processCallback, | |
| 900 | + opts?.dictionary && isArrayBufferView(opts.dictionary) ? opts.dictionary : undefined, | ||
| 899 | 901 | ); | |
| 902 | + | ||
| 900 | 903 | super(opts, mode, handle, zstdDefaultOpts); | |
| 901 | 904 | this._writeState = writeState; | |
| 902 | 905 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -324,7 +324,8 @@ class ZstdCompressContext final : public ZstdContext { | |||
| 324 | 324 | CompressionError ResetStream(); | |
| 325 | 325 | ||
| 326 | 326 | // Zstd specific: | |
| 327 | - CompressionError Init(uint64_t pledged_src_size); | ||
| 327 | + CompressionError Init(uint64_t pledged_src_size, | ||
| 328 | + std::string_view dictionary = {}); | ||
| 328 | 329 | CompressionError SetParameter(int key, int value); | |
| 329 | 330 | ||
| 330 | 331 | // Wrap ZSTD_freeCCtx to remove the return type. | |
@@ -349,7 +350,9 @@ class ZstdDecompressContext final : public ZstdContext { | |||
| 349 | 350 | CompressionError ResetStream(); | |
| 350 | 351 | ||
| 351 | 352 | // Zstd specific: | |
| 352 | - CompressionError Init(uint64_t pledged_src_size); | ||
| 353 | + CompressionError Init(uint64_t pledged_src_size, | ||
| 354 | + std::string_view dictionary = {}); | ||
| 355 | + | ||
| 353 | 356 | CompressionError SetParameter(int key, int value); | |
| 354 | 357 | ||
| 355 | 358 | // Wrap ZSTD_freeDCtx to remove the return type. | |
@@ -874,8 +877,10 @@ class ZstdStream final : public CompressionStream<CompressionContext> { | |||
| 874 | 877 | Environment* env = Environment::GetCurrent(args); | |
| 875 | 878 | Local<Context> context = env->context(); | |
| 876 | 879 | ||
| 877 | - CHECK(args.Length() == 4 && | ||
| 878 | - "init(params, pledgedSrcSize, writeResult, writeCallback)"); | ||
| 880 | + CHECK((args.Length() == 4 || args.Length() == 5) && | ||
| 881 | + "init(params, pledgedSrcSize, writeResult, writeCallback[, " | ||
| 882 | + "dictionary])"); | ||
| 883 | + | ||
| 879 | 884 | ZstdStream* wrap; | |
| 880 | 885 | ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This()); | |
| 881 | 886 | ||
@@ -903,7 +908,19 @@ class ZstdStream final : public CompressionStream<CompressionContext> { | |||
| 903 | 908 | } | |
| 904 | 909 | ||
| 905 | 910 | AllocScope alloc_scope(wrap); | |
| 906 | - CompressionError err = wrap->context()->Init(pledged_src_size); | ||
| 911 | + std::string_view dictionary; | ||
| 912 | + ArrayBufferViewContents<char> contents; | ||
| 913 | + if (args.Length() == 5 && !args[4]->IsUndefined()) { | ||
| 914 | + if (!args[4]->IsArrayBufferView()) { | ||
| 915 | + THROW_ERR_INVALID_ARG_TYPE( | ||
| 916 | + wrap->env(), "dictionary must be an ArrayBufferView if provided"); | ||
| 917 | + return; | ||
| 918 | + } | ||
| 919 | + contents.ReadValue(args[4]); | ||
| 920 | + dictionary = std::string_view(contents.data(), contents.length()); | ||
| 921 | + } | ||
| 922 | + | ||
| 923 | + CompressionError err = wrap->context()->Init(pledged_src_size, dictionary); | ||
| 907 | 924 | if (err.IsError()) { | |
| 908 | 925 | wrap->EmitError(err); | |
| 909 | 926 | THROW_ERR_ZLIB_INITIALIZATION_FAILED(wrap->env(), err.message); | |
@@ -1508,14 +1525,26 @@ CompressionError ZstdCompressContext::SetParameter(int key, int value) { | |||
| 1508 | 1525 | return {}; | |
| 1509 | 1526 | } | |
| 1510 | 1527 | ||
| 1511 | - CompressionError ZstdCompressContext::Init(uint64_t pledged_src_size) { | ||
| 1528 | + CompressionError ZstdCompressContext::Init(uint64_t pledged_src_size, | ||
| 1529 | + std::string_view dictionary) { | ||
| 1512 | 1530 | pledged_src_size_ = pledged_src_size; | |
| 1513 | 1531 | cctx_.reset(ZSTD_createCCtx()); | |
| 1514 | 1532 | if (!cctx_) { | |
| 1515 | 1533 | return CompressionError("Could not initialize zstd instance", | |
| 1516 | 1534 | "ERR_ZLIB_INITIALIZATION_FAILED", | |
| 1517 | 1535 | -1); | |
| 1518 | 1536 | } | |
| 1537 | + | ||
| 1538 | + if (!dictionary.empty()) { | ||
| 1539 | + size_t ret = ZSTD_CCtx_loadDictionary( | ||
| 1540 | + cctx_.get(), dictionary.data(), dictionary.size()); | ||
| 1541 | + if (ZSTD_isError(ret)) { | ||
| 1542 | + return CompressionError("Failed to load zstd dictionary", | ||
| 1543 | + "ERR_ZLIB_DICTIONARY_LOAD_FAILED", | ||
| 1544 | + -1); | ||
| 1545 | + } | ||
| 1546 | + } | ||
| 1547 | + | ||
| 1519 | 1548 | size_t result = ZSTD_CCtx_setPledgedSrcSize(cctx_.get(), pledged_src_size); | |
| 1520 | 1549 | if (ZSTD_isError(result)) { | |
| 1521 | 1550 | return CompressionError( | |
@@ -1548,13 +1577,24 @@ CompressionError ZstdDecompressContext::SetParameter(int key, int value) { | |||
| 1548 | 1577 | return {}; | |
| 1549 | 1578 | } | |
| 1550 | 1579 | ||
| 1551 | - CompressionError ZstdDecompressContext::Init(uint64_t pledged_src_size) { | ||
| 1580 | + CompressionError ZstdDecompressContext::Init(uint64_t pledged_src_size, | ||
| 1581 | + std::string_view dictionary) { | ||
| 1552 | 1582 | dctx_.reset(ZSTD_createDCtx()); | |
| 1553 | 1583 | if (!dctx_) { | |
| 1554 | 1584 | return CompressionError("Could not initialize zstd instance", | |
| 1555 | 1585 | "ERR_ZLIB_INITIALIZATION_FAILED", | |
| 1556 | 1586 | -1); | |
| 1557 | 1587 | } | |
| 1588 | + | ||
| 1589 | + if (!dictionary.empty()) { | ||
| 1590 | + size_t ret = ZSTD_DCtx_loadDictionary( | ||
| 1591 | + dctx_.get(), dictionary.data(), dictionary.size()); | ||
| 1592 | + if (ZSTD_isError(ret)) { | ||
| 1593 | + return CompressionError("Failed to load zstd dictionary", | ||
| 1594 | + "ERR_ZLIB_DICTIONARY_LOAD_FAILED", | ||
| 1595 | + -1); | ||
| 1596 | + } | ||
| 1597 | + } | ||
| 1558 | 1598 | return {}; | |
| 1559 | 1599 | } | |
| 1560 | 1600 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,26 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const zlib = require('zlib'); | ||
| 6 | + | ||
| 7 | + const dictionary = Buffer.from( | ||
| 8 | + `Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
| 9 | + Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
| 10 | + Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.` | ||
| 11 | + ); | ||
| 12 | + | ||
| 13 | + const input = Buffer.from( | ||
| 14 | + `Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
| 15 | + Lorem ipsum dolor sit amet, consectetur adipiscing elit. | ||
| 16 | + Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
| 17 | + Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. | ||
| 18 | + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.` | ||
| 19 | + ); | ||
| 20 | + | ||
| 21 | + zlib.zstdCompress(input, { dictionary }, common.mustSucceed((compressed) => { | ||
| 22 | + assert(compressed.length < input.length); | ||
| 23 | + zlib.zstdDecompress(compressed, { dictionary }, common.mustSucceed((decompressed) => { | ||
| 24 | + assert.strictEqual(decompressed.toString(), input.toString()); | ||
| 25 | + })); | ||
| 26 | + })); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments