PostgreSQL Source Code: src/common/compression.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifndef FRONTEND
26#else
28#endif
29
30#ifdef USE_ZSTD
31#include <zstd.h>
32#endif
33#ifdef HAVE_LIBZ
34#include <zlib.h>
35#endif
36
38
43
44
45
46
47
48bool
50{
51 if (strcmp(name, "none") == 0)
53 else if (strcmp(name, "gzip") == 0)
55 else if (strcmp(name, "lz4") == 0)
57 else if (strcmp(name, "zstd") == 0)
59 else
60 return false;
61 return true;
62}
63
64
65
66
67
68const char *
70{
71 switch (algorithm)
72 {
74 return "none";
76 return "gzip";
78 return "lz4";
80 return "zstd";
81
82 }
84 return "???";
85}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106void
109{
110 int bare_level;
111 char *bare_level_endp;
112
113
117
118
119
120
121
123 {
125 result->level = 0;
126 break;
128#ifdef USE_LZ4
129 result->level = 0;
130#else
132 psprintf(_("this build does not support compression with %s"),
133 "LZ4");
134#endif
135 break;
137#ifdef USE_ZSTD
138 result->level = ZSTD_CLEVEL_DEFAULT;
139#else
141 psprintf(_("this build does not support compression with %s"),
142 "ZSTD");
143#endif
144 break;
146#ifdef HAVE_LIBZ
147 result->level = Z_DEFAULT_COMPRESSION;
148#else
150 psprintf(_("this build does not support compression with %s"),
151 "gzip");
152#endif
153 break;
154 }
155
156
157 if (specification == NULL)
158 return;
159
160
161 bare_level = strtol(specification, &bare_level_endp, 10);
162 if (specification != bare_level_endp && *bare_level_endp == '\0')
163 {
164 result->level = bare_level;
165 return;
166 }
167
168
169 while (1)
170 {
171 char *kwstart;
172 char *kwend;
173 char *vstart;
174 char *vend;
175 int kwlen;
176 int vlen;
177 bool has_value;
178 char *keyword;
180
181
182 kwstart = kwend = specification;
183 while (*kwend != '\0' && *kwend != ',' && *kwend != '=')
184 ++kwend;
185 kwlen = kwend - kwstart;
186 if (*kwend != '=')
187 {
188 vstart = vend = NULL;
189 vlen = 0;
190 has_value = false;
191 }
192 else
193 {
194 vstart = vend = kwend + 1;
195 while (*vend != '\0' && *vend != ',')
196 ++vend;
197 vlen = vend - vstart;
198 has_value = true;
199 }
200
201
202 if (kwlen == 0)
203 {
205 pstrdup(_("found empty string where a compression option was expected"));
206 break;
207 }
208
209
210 keyword = palloc(kwlen + 1);
211 memcpy(keyword, kwstart, kwlen);
212 keyword[kwlen] = '\0';
213 if (!has_value)
215 else
216 {
218 memcpy(value, vstart, vlen);
219 value[vlen] = '\0';
220 }
221
222
223 if (strcmp(keyword, "level") == 0)
224 {
226
227
228
229
230
231 }
232 else if (strcmp(keyword, "workers") == 0)
233 {
236 }
237 else if (strcmp(keyword, "long") == 0)
238 {
241 }
242 else
244 psprintf(_("unrecognized compression option: \"%s\""), keyword);
245
246
248 if (value != NULL)
250
251
252
253
254
255
256
257
258
260 (vend == NULL ? *kwend == '\0' : *vend == '\0'))
261 break;
262
263
264 specification = vend == NULL ? kwend + 1 : vend + 1;
265 }
266}
267
268
269
270
271
272
273
274static int
276{
277 int ivalue;
278 char *ivalue_endp;
279
280 if (value == NULL)
281 {
283 psprintf(_("compression option \"%s\" requires a value"),
284 keyword);
285 return -1;
286 }
287
288 ivalue = strtol(value, &ivalue_endp, 10);
289 if (ivalue_endp == value || *ivalue_endp != '\0')
290 {
292 psprintf(_("value for compression option \"%s\" must be an integer"),
293 keyword);
294 return -1;
295 }
296 return ivalue;
297}
298
299
300
301
302
303
304
305
306
307
308
309
310static bool
312{
313 if (value == NULL)
314 return true;
315
317 return true;
319 return true;
321 return true;
322
324 return false;
326 return false;
328 return false;
329
331 psprintf(_("value for compression option \"%s\" must be a Boolean value"),
332 keyword);
333 return false;
334}
335
336
337
338
339
340
341
342
343char *
345{
346 int min_level = 1;
347 int max_level = 1;
348 int default_level = 0;
349
350
353
354
355
356
357
359 {
361 max_level = 9;
362#ifdef HAVE_LIBZ
363 default_level = Z_DEFAULT_COMPRESSION;
364#endif
365 break;
367 max_level = 12;
368 default_level = 0;
369 break;
371#ifdef USE_ZSTD
372 max_level = ZSTD_maxCLevel();
373 min_level = ZSTD_minCLevel();
374 default_level = ZSTD_CLEVEL_DEFAULT;
375#endif
376 break;
378 if (spec->level != 0)
379 return psprintf(_("compression algorithm \"%s\" does not accept a compression level"),
381 break;
382 }
383
384 if ((spec->level < min_level || spec->level > max_level) &&
385 spec->level != default_level)
386 return psprintf(_("compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"),
388 min_level, max_level, default_level);
389
390
391
392
393
396 {
397 return psprintf(_("compression algorithm \"%s\" does not accept a worker count"),
399 }
400
401
402
403
404
407 {
408 return psprintf(_("compression algorithm \"%s\" does not support long-distance mode"),
410 }
411
412 return NULL;
413}
414
415#ifdef FRONTEND
416
417
418
419
420
421
422
423
424
425void
427{
428 char *sep;
429 char *endp;
430 long result;
431
432
433
434
435
436
437
438 result = strtol(option, &endp, 10);
439 if (*endp == '\0')
440 {
441 if (result == 0)
442 {
443 *algorithm = pstrdup("none");
444 *detail = NULL;
445 }
446 else
447 {
448 *algorithm = pstrdup("gzip");
450 }
451 return;
452 }
453
454
455
456
457
458 sep = strchr(option, ':');
459 if (sep == NULL)
460 {
462 *detail = NULL;
463 }
464 else
465 {
466 char *alg;
467
470 alg[sep - option] = '\0';
471
472 *algorithm = alg;
473 *detail = pstrdup(sep + 1);
474 }
475}
476#endif
static bool expect_boolean_value(char *keyword, char *value, pg_compress_specification *result)
const char * get_compress_algorithm_name(pg_compress_algorithm algorithm)
char * validate_compress_specification(pg_compress_specification *spec)
bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
static int expect_integer_value(char *keyword, char *value, pg_compress_specification *result)
void parse_compress_specification(pg_compress_algorithm algorithm, char *specification, pg_compress_specification *result)
#define PG_COMPRESSION_OPTION_WORKERS
#define PG_COMPRESSION_OPTION_LONG_DISTANCE
void parse_compress_options(const char *option, char **algorithm, char **detail)
Assert(PointerIsAligned(start, uint64))
char * pstrdup(const char *in)
void pfree(void *pointer)
int pg_strcasecmp(const char *s1, const char *s2)
char * psprintf(const char *fmt,...)
pg_compress_algorithm algorithm