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