]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/test-compress-benchmark.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / journal / test-compress-benchmark.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
fd53fee0
ZJS
2/***
3 This file is part of systemd
4
5 Copyright 2014 Zbigniew Jędrzejewski-Szmek
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
b5efdb8a 21#include "alloc-util.h"
fd53fee0 22#include "compress.h"
245d3d3c 23#include "env-util.h"
fd53fee0 24#include "macro.h"
6bedfcbb 25#include "parse-util.h"
9f35e8b4 26#include "random-util.h"
07630cea
LP
27#include "string-util.h"
28#include "util.h"
fd53fee0 29
5d6f46b6
ZJS
30typedef int (compress_t)(const void *src, uint64_t src_size, void *dst,
31 size_t dst_alloc_size, size_t *dst_size);
fd53fee0 32typedef int (decompress_t)(const void *src, uint64_t src_size,
fa1c4b51 33 void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max);
fd53fee0 34
349cc4a5 35#if HAVE_XZ || HAVE_LZ4
ccc717fa 36
245d3d3c 37static usec_t arg_duration;
c4291c15
ZJS
38static size_t arg_start;
39
fd53fee0 40#define MAX_SIZE (1024*1024LU)
c4291c15
ZJS
41#define PRIME 1048571 /* A prime close enough to one megabyte that mod 4 == 3 */
42
43static size_t _permute(size_t x) {
44 size_t residue;
45
46 if (x >= PRIME)
47 return x;
48
49 residue = x*x % PRIME;
50 if (x <= PRIME / 2)
51 return residue;
52 else
53 return PRIME - residue;
54}
55
56static size_t permute(size_t x) {
57 return _permute((_permute(x) + arg_start) % MAX_SIZE ^ 0xFF345);
58}
fd53fee0 59
9f35e8b4 60static char* make_buf(size_t count, const char *type) {
fd53fee0
ZJS
61 char *buf;
62 size_t i;
63
64 buf = malloc(count);
0c0cdb06 65 assert_se(buf);
fd53fee0 66
9f35e8b4
ZJS
67 if (streq(type, "zeros"))
68 memzero(buf, count);
69 else if (streq(type, "simple"))
70 for (i = 0; i < count; i++)
71 buf[i] = 'a' + i % ('z' - 'a' + 1);
72 else if (streq(type, "random")) {
0036b0bf
ZJS
73 size_t step = count / 10;
74
75 random_bytes(buf, step);
76 memzero(buf + 1*step, step);
77 random_bytes(buf + 2*step, step);
78 memzero(buf + 3*step, step);
79 random_bytes(buf + 4*step, step);
80 memzero(buf + 5*step, step);
81 random_bytes(buf + 6*step, step);
82 memzero(buf + 7*step, step);
83 random_bytes(buf + 8*step, step);
84 memzero(buf + 9*step, step);
9f35e8b4
ZJS
85 } else
86 assert_not_reached("here");
fd53fee0
ZJS
87
88 return buf;
89}
90
9f35e8b4 91static void test_compress_decompress(const char* label, const char* type,
fd53fee0 92 compress_t compress, decompress_t decompress) {
da2e1c71 93 usec_t n, n2 = 0;
fd53fee0
ZJS
94 float dt;
95
96 _cleanup_free_ char *text, *buf;
97 _cleanup_free_ void *buf2 = NULL;
fa1c4b51 98 size_t buf2_allocated = 0;
fd53fee0
ZJS
99 size_t skipped = 0, compressed = 0, total = 0;
100
9f35e8b4 101 text = make_buf(MAX_SIZE, type);
fd53fee0 102 buf = calloc(MAX_SIZE + 1, 1);
0c0cdb06 103 assert_se(text && buf);
fd53fee0
ZJS
104
105 n = now(CLOCK_MONOTONIC);
106
c4291c15
ZJS
107 for (size_t i = 0; i <= MAX_SIZE; i++) {
108 size_t j = 0, k = 0, size;
fd53fee0
ZJS
109 int r;
110
c4291c15 111 size = permute(i);
15b947fb
ZJS
112 if (size == 0)
113 continue;
c4291c15
ZJS
114
115 log_debug("%s %zu %zu", type, i, size);
116
117 memzero(buf, MIN(size + 1000, MAX_SIZE));
118
5d6f46b6
ZJS
119 r = compress(text, size, buf, size, &j);
120 /* assume compression must be successful except for small or random inputs */
c4291c15 121 assert_se(r == 0 || (size < 2048 && r == -ENOBUFS) || streq(type, "random"));
9f35e8b4 122
fd53fee0 123 /* check for overwrites */
c4291c15 124 assert_se(buf[size] == 0);
fd53fee0 125 if (r != 0) {
c4291c15 126 skipped += size;
fd53fee0
ZJS
127 continue;
128 }
129
0c0cdb06 130 assert_se(j > 0);
c4291c15
ZJS
131 if (j >= size)
132 log_error("%s \"compressed\" %zu -> %zu", label, size, j);
fd53fee0
ZJS
133
134 r = decompress(buf, j, &buf2, &buf2_allocated, &k, 0);
0c0cdb06
RC
135 assert_se(r == 0);
136 assert_se(buf2_allocated >= k);
c4291c15 137 assert_se(k == size);
fd53fee0 138
c4291c15 139 assert_se(memcmp(text, buf2, size) == 0);
fd53fee0 140
c4291c15 141 total += size;
fd53fee0
ZJS
142 compressed += j;
143
144 n2 = now(CLOCK_MONOTONIC);
c4291c15 145 if (n2 - n > arg_duration)
fd53fee0
ZJS
146 break;
147 }
148
149 dt = (n2-n) / 1e6;
150
9f35e8b4 151 log_info("%s/%s: compressed & decompressed %zu bytes in %.2fs (%.2fMiB/s), "
fd53fee0 152 "mean compresion %.2f%%, skipped %zu bytes",
9f35e8b4 153 label, type, total, dt,
fd53fee0
ZJS
154 total / 1024. / 1024 / dt,
155 100 - compressed * 100. / total,
156 skipped);
157}
ccc717fa 158#endif
fd53fee0
ZJS
159
160int main(int argc, char *argv[]) {
349cc4a5 161#if HAVE_XZ || HAVE_LZ4
9f35e8b4 162 const char *i;
245d3d3c 163 int r;
fd53fee0 164
c4291c15
ZJS
165 log_set_max_level(LOG_INFO);
166
167 if (argc >= 2) {
168 unsigned x;
169
170 assert_se(safe_atou(argv[1], &x) >= 0);
171 arg_duration = x * USEC_PER_SEC;
245d3d3c
ZJS
172 } else {
173 bool slow;
174
175 r = getenv_bool("SYSTEMD_SLOW_TESTS");
176 slow = r >= 0 ? r : SYSTEMD_SLOW_TESTS_DEFAULT;
177
178 arg_duration = slow ? 2 * USEC_PER_SEC : USEC_PER_SEC / 50;
c4291c15 179 }
245d3d3c 180
c4291c15 181 if (argc == 3)
7c2da2ca 182 (void) safe_atozu(argv[2], &arg_start);
c4291c15 183 else
df0ff127 184 arg_start = getpid_cached();
fd53fee0 185
9f35e8b4 186 NULSTR_FOREACH(i, "zeros\0simple\0random\0") {
349cc4a5 187#if HAVE_XZ
9f35e8b4 188 test_compress_decompress("XZ", i, compress_blob_xz, decompress_blob_xz);
fd53fee0 189#endif
349cc4a5 190#if HAVE_LZ4
9f35e8b4 191 test_compress_decompress("LZ4", i, compress_blob_lz4, decompress_blob_lz4);
fd53fee0 192#endif
9f35e8b4 193 }
fd53fee0 194 return 0;
ccc717fa
ZJS
195#else
196 return EXIT_TEST_SKIP;
197#endif
fd53fee0 198}