648db22b |
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 | */ |
9 | extern "C" { |
10 | #include "datagen.h" |
11 | } |
12 | #include "Options.h" |
13 | #include "test/RoundTrip.h" |
14 | #include "utils/ScopeGuard.h" |
15 | |
16 | #include <cstddef> |
17 | #include <cstdio> |
18 | #include <cstdlib> |
19 | #include <memory> |
20 | #include <random> |
21 | |
22 | using namespace std; |
23 | using namespace pzstd; |
24 | |
25 | namespace { |
26 | string |
27 | writeData(size_t size, double matchProba, double litProba, unsigned seed) { |
28 | std::unique_ptr<uint8_t[]> buf(new uint8_t[size]); |
29 | RDG_genBuffer(buf.get(), size, matchProba, litProba, seed); |
30 | string file = tmpnam(nullptr); |
31 | auto fd = std::fopen(file.c_str(), "wb"); |
32 | auto guard = makeScopeGuard([&] { std::fclose(fd); }); |
33 | auto bytesWritten = std::fwrite(buf.get(), 1, size, fd); |
34 | if (bytesWritten != size) { |
35 | std::abort(); |
36 | } |
37 | return file; |
38 | } |
39 | |
40 | template <typename Generator> |
41 | string generateInputFile(Generator& gen) { |
42 | // Use inputs ranging from 1 Byte to 2^16 Bytes |
43 | std::uniform_int_distribution<size_t> size{1, 1 << 16}; |
44 | std::uniform_real_distribution<> prob{0, 1}; |
45 | return writeData(size(gen), prob(gen), prob(gen), gen()); |
46 | } |
47 | |
48 | template <typename Generator> |
49 | Options generateOptions(Generator& gen, const string& inputFile) { |
50 | Options options; |
51 | options.inputFiles = {inputFile}; |
52 | options.overwrite = true; |
53 | |
54 | std::uniform_int_distribution<unsigned> numThreads{1, 32}; |
55 | std::uniform_int_distribution<unsigned> compressionLevel{1, 10}; |
56 | |
57 | options.numThreads = numThreads(gen); |
58 | options.compressionLevel = compressionLevel(gen); |
59 | |
60 | return options; |
61 | } |
62 | } |
63 | |
64 | int main() { |
65 | std::mt19937 gen(std::random_device{}()); |
66 | |
67 | auto newlineGuard = makeScopeGuard([] { std::fprintf(stderr, "\n"); }); |
68 | for (unsigned i = 0; i < 10000; ++i) { |
69 | if (i % 100 == 0) { |
70 | std::fprintf(stderr, "Progress: %u%%\r", i / 100); |
71 | } |
72 | auto inputFile = generateInputFile(gen); |
73 | auto inputGuard = makeScopeGuard([&] { std::remove(inputFile.c_str()); }); |
74 | for (unsigned i = 0; i < 10; ++i) { |
75 | auto options = generateOptions(gen, inputFile); |
76 | if (!roundTrip(options)) { |
77 | std::fprintf(stderr, "numThreads: %u\n", options.numThreads); |
78 | std::fprintf(stderr, "level: %u\n", options.compressionLevel); |
79 | std::fprintf(stderr, "decompress? %u\n", (unsigned)options.decompress); |
80 | std::fprintf(stderr, "file: %s\n", inputFile.c_str()); |
81 | return 1; |
82 | } |
83 | } |
84 | } |
85 | return 0; |
86 | } |