1 /*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11 #include <assert.h>
12 #include <stdio.h>
13 #include <stddef.h>
14 #include <stdlib.h>
15 #include <stdint.h>
16 #include "datagen.h"
17 #include "mem.h"
18 #define ZSTD_STATIC_LINKING_ONLY
19 #include "zstd.h"
20
21 static int
compress(ZSTD_CCtx * cctx,ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,void const * src,size_t srcSize,void * roundtrip,ZSTD_EndDirective end)22 compress(ZSTD_CCtx* cctx, ZSTD_DCtx* dctx,
23 void* dst, size_t dstCapacity,
24 void const* src, size_t srcSize,
25 void* roundtrip, ZSTD_EndDirective end)
26 {
27 ZSTD_inBuffer in = {src, srcSize, 0};
28 ZSTD_outBuffer out = {dst, dstCapacity, 0};
29 int ended = 0;
30
31 while (!ended && (in.pos < in.size || out.pos > 0)) {
32 size_t rc;
33 out.pos = 0;
34 rc = ZSTD_compressStream2(cctx, &out, &in, end);
35 if (ZSTD_isError(rc))
36 return 1;
37 if (end == ZSTD_e_end && rc == 0)
38 ended = 1;
39 {
40 ZSTD_inBuffer rtIn = {dst, out.pos, 0};
41 ZSTD_outBuffer rtOut = {roundtrip, srcSize, 0};
42 rc = 1;
43 while (rtIn.pos < rtIn.size || rtOut.pos > 0) {
44 rtOut.pos = 0;
45 rc = ZSTD_decompressStream(dctx, &rtOut, &rtIn);
46 if (ZSTD_isError(rc)) {
47 fprintf(stderr, "Decompression error: %s\n", ZSTD_getErrorName(rc));
48 return 1;
49 }
50 if (rc == 0)
51 break;
52 }
53 if (ended && rc != 0) {
54 fprintf(stderr, "Frame not finished!\n");
55 return 1;
56 }
57 }
58 }
59
60 return 0;
61 }
62
main(int argc,const char ** argv)63 int main(int argc, const char** argv)
64 {
65 ZSTD_CCtx* cctx = ZSTD_createCCtx();
66 ZSTD_DCtx* dctx = ZSTD_createDCtx();
67 const size_t dataSize = (size_t)1 << 30;
68 const size_t outSize = ZSTD_compressBound(dataSize);
69 const size_t bufferSize = (size_t)1 << 31;
70 char* buffer = (char*)malloc(bufferSize);
71 void* out = malloc(outSize);
72 void* roundtrip = malloc(dataSize);
73 int _exit_code = 0;
74 (void)argc;
75 (void)argv;
76
77 if (!buffer || !out || !roundtrip || !cctx || !dctx) {
78 fprintf(stderr, "Allocation failure\n");
79 _exit_code = 1;
80 goto cleanup;
81 }
82
83 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 31)))
84 return 1;
85 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1)))
86 return 1;
87 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_overlapLog, 9)))
88 return 1;
89 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1)))
90 return 1;
91 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btopt)))
92 return 1;
93 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, 7)))
94 return 1;
95 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7)))
96 return 1;
97 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, 1)))
98 return 1;
99 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, 10)))
100 return 1;
101 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, 10)))
102 return 1;
103
104 if (ZSTD_isError(ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 31)))
105 return 1;
106
107 RDG_genBuffer(buffer, bufferSize, 1.0, 0.0, 0xbeefcafe);
108
109 /* Compress 30 GB */
110 {
111 int i;
112 for (i = 0; i < 10; ++i) {
113 fprintf(stderr, "Compressing 1 GB\n");
114 if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_continue))
115 return 1;
116 }
117 }
118 fprintf(stderr, "Compressing 1 GB\n");
119 if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_end))
120 return 1;
121
122 fprintf(stderr, "Success!\n");
123
124 goto cleanup;
125
126 cleanup:
127 free(roundtrip);
128 free(out);
129 free(buffer);
130 ZSTD_freeCCtx(cctx);
131 ZSTD_freeDCtx(dctx);
132 return _exit_code;
133 }
134