diff options
Diffstat (limited to 'src/common/pg_lzcompress.c')
-rw-r--r-- | src/common/pg_lzcompress.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c index 988b3987d04..3adad62d9a4 100644 --- a/src/common/pg_lzcompress.c +++ b/src/common/pg_lzcompress.c @@ -771,3 +771,40 @@ pglz_decompress(const char *source, int32 slen, char *dest, */ return (char *) dp - dest; } + + +/* ---------- + * pglz_max_compressed_size - + * + * Calculate the maximum compressed size for a given amount of raw data. + * Return the maximum size, or total compressed size if maximum size is + * larger than total compressed size. + * + * We can't use PGLZ_MAX_OUTPUT for this purpose, because that's used to size + * the compression buffer (and abort the compression). It does not really say + * what's the maximum compressed size for an input of a given length, and it + * may happen that while the whole value is compressible (and thus fits into + * PGLZ_MAX_OUTPUT nicely), the prefix is not compressible at all. + * ---------- + */ +int32 +pglz_maximum_compressed_size(int32 rawsize, int32 total_compressed_size) +{ + int32 compressed_size; + + /* + * pglz uses one control bit per byte, so we need (rawsize * 9) bits. We + * care about bytes though, so we add 7 to make sure we include the last + * incomplete byte (integer division rounds down). + * + * XXX Use int64 to prevent overflow during calculation. + */ + compressed_size = (int32) ((int64) rawsize * 9 + 7) / 8; + + /* + * Maximum compressed size can't be larger than total compressed size. + */ + compressed_size = Min(compressed_size, total_compressed_size); + + return compressed_size; +} |