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 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 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 (void)argc; 74 (void)argv; 75 76 if (!buffer || !out || !roundtrip || !cctx || !dctx) { 77 fprintf(stderr, "Allocation failure\n"); 78 return 1; 79 } 80 81 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 31))) 82 return 1; 83 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 1))) 84 return 1; 85 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_overlapLog, 9))) 86 return 1; 87 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1))) 88 return 1; 89 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, ZSTD_btopt))) 90 return 1; 91 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, 7))) 92 return 1; 93 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 7))) 94 return 1; 95 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, 1))) 96 return 1; 97 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, 10))) 98 return 1; 99 if (ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, 10))) 100 return 1; 101 102 if (ZSTD_isError(ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, 31))) 103 return 1; 104 105 RDG_genBuffer(buffer, bufferSize, 1.0, 0.0, 0xbeefcafe); 106 107 /* Compress 30 GB */ 108 { 109 int i; 110 for (i = 0; i < 10; ++i) { 111 fprintf(stderr, "Compressing 1 GB\n"); 112 if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_continue)) 113 return 1; 114 } 115 } 116 fprintf(stderr, "Compressing 1 GB\n"); 117 if (compress(cctx, dctx, out, outSize, buffer, dataSize, roundtrip, ZSTD_e_end)) 118 return 1; 119 120 fprintf(stderr, "Success!\n"); 121 122 free(roundtrip); 123 free(out); 124 free(buffer); 125 ZSTD_freeDCtx(dctx); 126 ZSTD_freeCCtx(cctx); 127 return 0; 128 } 129