Commit 378c79dc authored by Tom Lane's avatar Tom Lane

Cleanup for pglz_compress code: remove dead code, const-ify API of

remaining functions, simplify pglz_compress's API to not require a useless
data copy when compression fails.  Also add a check in pglz_decompress that
the expected amount of data was decompressed.
parent e378f82e
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.65 2006/10/04 00:29:48 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.66 2006/10/05 23:33:33 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -100,15 +100,12 @@ heap_tuple_untoast_attr(varattrib *attr) ...@@ -100,15 +100,12 @@ heap_tuple_untoast_attr(varattrib *attr)
* Fetch it from the toast heap and decompress. * Fetch it from the toast heap and decompress.
* ---------- * ----------
*/ */
varattrib *tmp; PGLZ_Header *tmp;
tmp = toast_fetch_datum(attr);
result = (varattrib *) palloc(attr->va_content.va_external.va_rawsize
+ VARHDRSZ);
VARATT_SIZEP(result) = attr->va_content.va_external.va_rawsize
+ VARHDRSZ;
pglz_decompress((PGLZ_Header *) tmp, VARATT_DATA(result));
tmp = (PGLZ_Header *) toast_fetch_datum(attr);
result = (varattrib *) palloc(PGLZ_RAW_SIZE(tmp) + VARHDRSZ);
VARATT_SIZEP(result) = PGLZ_RAW_SIZE(tmp) + VARHDRSZ;
pglz_decompress(tmp, VARATT_DATA(result));
pfree(tmp); pfree(tmp);
} }
else else
...@@ -124,11 +121,11 @@ heap_tuple_untoast_attr(varattrib *attr) ...@@ -124,11 +121,11 @@ heap_tuple_untoast_attr(varattrib *attr)
/* /*
* This is a compressed value inside of the main tuple * This is a compressed value inside of the main tuple
*/ */
result = (varattrib *) palloc(attr->va_content.va_compressed.va_rawsize PGLZ_Header *tmp = (PGLZ_Header *) attr;
+ VARHDRSZ);
VARATT_SIZEP(result) = attr->va_content.va_compressed.va_rawsize result = (varattrib *) palloc(PGLZ_RAW_SIZE(tmp) + VARHDRSZ);
+ VARHDRSZ; VARATT_SIZEP(result) = PGLZ_RAW_SIZE(tmp) + VARHDRSZ;
pglz_decompress((PGLZ_Header *) attr, VARATT_DATA(result)); pglz_decompress(tmp, VARATT_DATA(result));
} }
else else
...@@ -157,19 +154,18 @@ heap_tuple_untoast_attr_slice(varattrib *attr, int32 sliceoffset, int32 slicelen ...@@ -157,19 +154,18 @@ heap_tuple_untoast_attr_slice(varattrib *attr, int32 sliceoffset, int32 slicelen
if (VARATT_IS_COMPRESSED(attr)) if (VARATT_IS_COMPRESSED(attr))
{ {
varattrib *tmp; PGLZ_Header *tmp;
if (VARATT_IS_EXTERNAL(attr)) if (VARATT_IS_EXTERNAL(attr))
tmp = toast_fetch_datum(attr); tmp = (PGLZ_Header *) toast_fetch_datum(attr);
else else
tmp = attr; /* compressed in main tuple */ tmp = (PGLZ_Header *) attr; /* compressed in main tuple */
preslice = (varattrib *) palloc(attr->va_content.va_external.va_rawsize preslice = (varattrib *) palloc(PGLZ_RAW_SIZE(tmp) + VARHDRSZ);
+ VARHDRSZ); VARATT_SIZEP(preslice) = PGLZ_RAW_SIZE(tmp) + VARHDRSZ;
VARATT_SIZEP(preslice) = attr->va_content.va_external.va_rawsize + VARHDRSZ; pglz_decompress(tmp, VARATT_DATA(preslice));
pglz_decompress((PGLZ_Header *) tmp, VARATT_DATA(preslice));
if (tmp != attr) if (tmp != (PGLZ_Header *) attr)
pfree(tmp); pfree(tmp);
} }
else else
...@@ -948,12 +944,12 @@ Datum ...@@ -948,12 +944,12 @@ Datum
toast_compress_datum(Datum value) toast_compress_datum(Datum value)
{ {
varattrib *tmp; varattrib *tmp;
int32 valsize = VARATT_SIZE(value) - VARHDRSZ;
tmp = (varattrib *) palloc(sizeof(PGLZ_Header) + VARATT_SIZE(value)); tmp = (varattrib *) palloc(PGLZ_MAX_OUTPUT(valsize));
pglz_compress(VARATT_DATA(value), VARATT_SIZE(value) - VARHDRSZ, if (pglz_compress(VARATT_DATA(value), valsize,
(PGLZ_Header *) tmp, (PGLZ_Header *) tmp, PGLZ_strategy_default) &&
PGLZ_strategy_default); VARATT_SIZE(tmp) < VARATT_SIZE(value))
if (VARATT_SIZE(tmp) < VARATT_SIZE(value))
{ {
/* successful compression */ /* successful compression */
VARATT_SIZEP(tmp) |= VARATT_FLAG_COMPRESSED; VARATT_SIZEP(tmp) |= VARATT_FLAG_COMPRESSED;
......
This diff is collapsed.
/* ---------- /* ----------
* pg_lzcompress.h - * pg_lzcompress.h -
* *
* $PostgreSQL: pgsql/src/include/utils/pg_lzcompress.h,v 1.12 2006/07/13 16:49:20 momjian Exp $
*
* Definitions for the builtin LZ compressor * Definitions for the builtin LZ compressor
*
* $PostgreSQL: pgsql/src/include/utils/pg_lzcompress.h,v 1.13 2006/10/05 23:33:33 tgl Exp $
* ---------- * ----------
*/ */
...@@ -29,15 +29,11 @@ typedef struct PGLZ_Header ...@@ -29,15 +29,11 @@ typedef struct PGLZ_Header
/* ---------- /* ----------
* PGLZ_MAX_OUTPUT - * PGLZ_MAX_OUTPUT -
* *
* Macro to compute the maximum buffer required for the * Macro to compute the buffer size required by pglz_compress().
* compression output. It is larger than the input, because * We allow 4 bytes for overrun before detecting compression failure.
* in the worst case, we cannot write out one single tag but
* need one control byte per 8 literal data bytes plus the
* EOF mark at the end.
* ---------- * ----------
*/ */
#define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + (((_dlen) | 0x07) >> 3) \ #define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + 4 + sizeof(PGLZ_Header))
+ sizeof(PGLZ_Header))
/* ---------- /* ----------
* PGLZ_RAW_SIZE - * PGLZ_RAW_SIZE -
...@@ -48,26 +44,6 @@ typedef struct PGLZ_Header ...@@ -48,26 +44,6 @@ typedef struct PGLZ_Header
*/ */
#define PGLZ_RAW_SIZE(_lzdata) ((_lzdata)->rawsize) #define PGLZ_RAW_SIZE(_lzdata) ((_lzdata)->rawsize)
/* ----------
* PGLZ_IS_COMPRESSED -
*
* Macro to determine if the data itself is stored as raw
* uncompressed data.
* ----------
*/
#define PGLZ_IS_COMPRESSED(_lzdata) ((_lzdata)->varsize != \
e (_lzdata)->rawsize + e \
sizeof(PGLZ_Header))
/* ----------
* PGLZ_RAW_DATA -
*
* Macro to get access to the plain compressed or uncompressed
* data. Useful if PGLZ_IS_COMPRESSED returns false.
* ----------
*/
#define PGLZ_RAW_DATA(_lzdata) (((char *)(_lzdata)) + \
sizeof(PGLZ_Header))
/* ---------- /* ----------
* PGLZ_Strategy - * PGLZ_Strategy -
...@@ -112,27 +88,6 @@ typedef struct PGLZ_Strategy ...@@ -112,27 +88,6 @@ typedef struct PGLZ_Strategy
} PGLZ_Strategy; } PGLZ_Strategy;
/* ----------
* PGLZ_DecompState -
*
* Decompression state variable for byte-per-byte decompression
* using pglz_decomp_getchar() macro.
* ----------
*/
typedef struct PGLZ_DecompState
{
unsigned char *temp_buf;
unsigned char *cp_in;
unsigned char *cp_end;
unsigned char *cp_out;
unsigned char *cp_copy;
int (*next_char) (struct PGLZ_DecompState *dstate);
int tocopy;
int ctrl_count;
unsigned char ctrl;
} PGLZ_DecompState;
/* ---------- /* ----------
* The standard strategies * The standard strategies
* *
...@@ -151,83 +106,18 @@ typedef struct PGLZ_DecompState ...@@ -151,83 +106,18 @@ typedef struct PGLZ_DecompState
* small input and does fallback to * small input and does fallback to
* uncompressed storage only if output * uncompressed storage only if output
* would be larger than input. * would be larger than input.
*
* PGLZ_strategy_never Force pglz_compress to act as a custom
* interface for memcpy(). Only useful
* for generic interfacing.
* ----------
*/
extern PGLZ_Strategy *PGLZ_strategy_default;
extern PGLZ_Strategy *PGLZ_strategy_always;
extern PGLZ_Strategy *PGLZ_strategy_never;
/* ----------
* pglz_decomp_getchar -
*
* Get next character (or EOF) from decompressor.
* The status variable must be initialized before and deinitialized
* after compression with the next two macros below.
* ---------- * ----------
*/ */
#define pglz_decomp_getchar(_ds) \ extern const PGLZ_Strategy * const PGLZ_strategy_default;
((*((_ds)->next_char))((_ds))) extern const PGLZ_Strategy * const PGLZ_strategy_always;
/* ----------
* pglz_decomp_init -
*
* Initialize a decomp state from a compressed input.
* ----------
*/
#define pglz_decomp_init(_ds,_lz) \
do { \
(_ds)->cp_in = ((unsigned char *)(_lz)) \
+ sizeof(PGLZ_Header); \
(_ds)->cp_end = (_ds)->cp_in + (_lz)->varsize \
- sizeof(PGLZ_Header); \
if (PGLZ_IS_COMPRESSED((_lz))) { \
(_ds)->temp_buf = (unsigned char *) \
palloc(PGLZ_RAW_SIZE((_lz))); \
(_ds)->cp_out = (_ds)->temp_buf; \
(_ds)->next_char = pglz_get_next_decomp_char_from_lzdata; \
(_ds)->tocopy = 0; \
(_ds)->ctrl_count = 0; \
} else { \
(_ds)->temp_buf = NULL; \
(_ds)->next_char = pglz_get_next_decomp_char_from_plain; \
} \
} while (0)
/* ----------
* pglz_decomp_end -
*
* Deallocate resources after decompression.
* ----------
*/
#define pglz_decomp_end(_ds) \
do { \
if ((_ds)->temp_buf != NULL) \
pfree((void *)((_ds)->temp_buf)); \
} while (0)
/* ---------- /* ----------
* Global function declarations * Global function declarations
* ---------- * ----------
*/ */
int pglz_compress(char *source, int32 slen, PGLZ_Header *dest, extern bool pglz_compress(const char *source, int32 slen, PGLZ_Header *dest,
PGLZ_Strategy *strategy); const PGLZ_Strategy *strategy);
int pglz_decompress(PGLZ_Header *source, char *dest); extern void pglz_decompress(const PGLZ_Header *source, char *dest);
/* ----------
* Functions used by pglz_decomp_getchar().
* Internal use only.
* ----------
*/
extern int pglz_get_next_decomp_char_from_lzdata(PGLZ_DecompState *dstate);
extern int pglz_get_next_decomp_char_from_plain(PGLZ_DecompState *dstate);
#endif /* _PG_LZCOMPRESS_H_ */ #endif /* _PG_LZCOMPRESS_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment