1999-11-17 22:21:51 +01:00
|
|
|
/* ----------
|
|
|
|
* pg_lzcompress.h -
|
|
|
|
*
|
2006-07-13 18:49:20 +02:00
|
|
|
* $PostgreSQL: pgsql/src/include/utils/pg_lzcompress.h,v 1.12 2006/07/13 16:49:20 momjian Exp $
|
1999-11-17 22:21:51 +01:00
|
|
|
*
|
|
|
|
* Definitions for the builtin LZ compressor
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _PG_LZCOMPRESS_H_
|
|
|
|
#define _PG_LZCOMPRESS_H_
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_Header -
|
|
|
|
*
|
2000-04-12 19:17:23 +02:00
|
|
|
* The information at the top of the compressed data.
|
1999-11-17 22:21:51 +01:00
|
|
|
* The varsize must be kept the same data type as the value
|
|
|
|
* in front of all variable size data types in PostgreSQL.
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
typedef struct PGLZ_Header
|
|
|
|
{
|
|
|
|
int32 varsize;
|
|
|
|
int32 rawsize;
|
1999-11-17 22:21:51 +01:00
|
|
|
} PGLZ_Header;
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_MAX_OUTPUT -
|
|
|
|
*
|
|
|
|
* Macro to compute the maximum buffer required for the
|
|
|
|
* compression output. It is larger than the input, because
|
|
|
|
* 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) \
|
|
|
|
+ sizeof(PGLZ_Header))
|
1999-11-17 23:18:46 +01:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_RAW_SIZE -
|
|
|
|
*
|
|
|
|
* Macro to determine the uncompressed data size contained
|
|
|
|
* in the entry.
|
|
|
|
* ----------
|
|
|
|
*/
|
2005-05-25 23:40:43 +02:00
|
|
|
#define PGLZ_RAW_SIZE(_lzdata) ((_lzdata)->rawsize)
|
1999-11-17 23:18:46 +01:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_IS_COMPRESSED -
|
|
|
|
*
|
|
|
|
* Macro to determine if the data itself is stored as raw
|
|
|
|
* uncompressed data.
|
|
|
|
* ----------
|
|
|
|
*/
|
2005-05-25 23:40:43 +02:00
|
|
|
#define PGLZ_IS_COMPRESSED(_lzdata) ((_lzdata)->varsize != \
|
|
|
|
e (_lzdata)->rawsize + e \
|
2000-04-12 19:17:23 +02:00
|
|
|
sizeof(PGLZ_Header))
|
1999-11-17 23:18:46 +01:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_RAW_DATA -
|
|
|
|
*
|
|
|
|
* Macro to get access to the plain compressed or uncompressed
|
|
|
|
* data. Useful if PGLZ_IS_COMPRESSED returns false.
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
#define PGLZ_RAW_DATA(_lzdata) (((char *)(_lzdata)) + \
|
1999-11-17 23:18:46 +01:00
|
|
|
sizeof(PGLZ_Header))
|
1999-11-17 22:21:51 +01:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* PGLZ_Strategy -
|
|
|
|
*
|
|
|
|
* Some values that control the compression algorithm.
|
|
|
|
*
|
|
|
|
* min_input_size Minimum input data size to start compression.
|
|
|
|
*
|
|
|
|
* force_input_size Input data size at which compressed storage is
|
|
|
|
* forced even if the compression rate drops below
|
|
|
|
* min_comp_rate (but not below 0).
|
|
|
|
*
|
|
|
|
* min_comp_rate Minimum compression rate (0-99%), the output
|
|
|
|
* must be smaller than the input. If that isn't
|
2000-01-05 19:23:54 +01:00
|
|
|
* the case, the compressor will throw away its
|
1999-11-17 22:21:51 +01:00
|
|
|
* output and copy the original, uncompressed data
|
|
|
|
* to the output buffer.
|
|
|
|
*
|
|
|
|
* match_size_good The initial GOOD match size when starting history
|
|
|
|
* lookup. When looking up the history to find a
|
|
|
|
* match that could be expressed as a tag, the
|
2002-11-23 04:59:09 +01:00
|
|
|
* algorithm does not always walk back entirely.
|
2000-04-12 19:17:23 +02:00
|
|
|
* A good match fast is usually better than the
|
1999-11-17 22:21:51 +01:00
|
|
|
* best possible one very late. For each iteration
|
|
|
|
* in the lookup, this value is lowered so the
|
|
|
|
* longer the lookup takes, the smaller matches
|
|
|
|
* are considered good.
|
|
|
|
*
|
|
|
|
* match_size_drop The percentage, match_size_good is lowered
|
|
|
|
* at each history check. Allowed values are
|
|
|
|
* 0 (no change until end) to 100 (only check
|
|
|
|
* latest history entry at all).
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
typedef struct PGLZ_Strategy
|
|
|
|
{
|
1999-11-17 22:21:51 +01:00
|
|
|
int32 min_input_size;
|
|
|
|
int32 force_input_size;
|
|
|
|
int32 min_comp_rate;
|
|
|
|
int32 match_size_good;
|
|
|
|
int32 match_size_drop;
|
|
|
|
} PGLZ_Strategy;
|
|
|
|
|
|
|
|
|
1999-11-25 02:28:07 +01:00
|
|
|
/* ----------
|
|
|
|
* PGLZ_DecompState -
|
|
|
|
*
|
|
|
|
* Decompression state variable for byte-per-byte decompression
|
|
|
|
* using pglz_decomp_getchar() macro.
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
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;
|
1999-11-25 02:28:07 +01:00
|
|
|
} PGLZ_DecompState;
|
|
|
|
|
|
|
|
|
1999-11-17 22:21:51 +01:00
|
|
|
/* ----------
|
|
|
|
* The standard strategies
|
|
|
|
*
|
|
|
|
* PGLZ_strategy_default Starts compression only if input is
|
|
|
|
* at least 256 bytes large. Stores output
|
|
|
|
* uncompressed if compression does not
|
|
|
|
* gain at least 20% size reducture but
|
|
|
|
* input does not exceed 6K. Stops history
|
|
|
|
* lookup if at least a 128 byte long
|
|
|
|
* match has been found.
|
|
|
|
*
|
|
|
|
* This is the default strategy if none
|
|
|
|
* is given to pglz_compress().
|
|
|
|
*
|
2002-11-23 04:59:09 +01:00
|
|
|
* PGLZ_strategy_always Starts compression on any infinitely
|
1999-11-17 22:21:51 +01:00
|
|
|
* small input and does fallback to
|
|
|
|
* uncompressed storage only if output
|
|
|
|
* would be larger than input.
|
|
|
|
*
|
|
|
|
* PGLZ_strategy_never Force pglz_compress to act as a custom
|
|
|
|
* interface for memcpy(). Only useful
|
|
|
|
* for generic interfacing.
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
extern PGLZ_Strategy *PGLZ_strategy_default;
|
2002-11-23 04:59:09 +01:00
|
|
|
extern PGLZ_Strategy *PGLZ_strategy_always;
|
2000-04-12 19:17:23 +02:00
|
|
|
extern PGLZ_Strategy *PGLZ_strategy_never;
|
1999-11-17 22:21:51 +01:00
|
|
|
|
|
|
|
|
1999-11-25 02:28:07 +01:00
|
|
|
/* ----------
|
|
|
|
* 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) \
|
|
|
|
((*((_ds)->next_char))((_ds)))
|
|
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* pglz_decomp_init -
|
|
|
|
*
|
|
|
|
* Initialize a decomp state from a compressed input.
|
|
|
|
* ----------
|
|
|
|
*/
|
2006-07-13 18:49:20 +02:00
|
|
|
#define pglz_decomp_init(_ds,_lz) \
|
|
|
|
do { \
|
2000-04-12 19:17:23 +02:00
|
|
|
(_ds)->cp_in = ((unsigned char *)(_lz)) \
|
1999-11-25 02:28:07 +01:00
|
|
|
+ sizeof(PGLZ_Header); \
|
2000-04-12 19:17:23 +02:00
|
|
|
(_ds)->cp_end = (_ds)->cp_in + (_lz)->varsize \
|
1999-11-25 02:28:07 +01:00
|
|
|
- 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; \
|
|
|
|
} \
|
2000-04-12 19:17:23 +02:00
|
|
|
} while (0)
|
1999-11-25 02:28:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* pglz_decomp_end -
|
|
|
|
*
|
|
|
|
* Deallocate resources after decompression.
|
|
|
|
* ----------
|
|
|
|
*/
|
2006-07-13 18:49:20 +02:00
|
|
|
#define pglz_decomp_end(_ds) \
|
|
|
|
do { \
|
1999-11-25 02:28:07 +01:00
|
|
|
if ((_ds)->temp_buf != NULL) \
|
|
|
|
pfree((void *)((_ds)->temp_buf)); \
|
2000-04-12 19:17:23 +02:00
|
|
|
} while (0)
|
1999-11-25 02:28:07 +01:00
|
|
|
|
|
|
|
|
1999-11-17 22:21:51 +01:00
|
|
|
/* ----------
|
|
|
|
* Global function declarations
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
int pglz_compress(char *source, int32 slen, PGLZ_Header *dest,
|
|
|
|
PGLZ_Strategy *strategy);
|
|
|
|
int pglz_decompress(PGLZ_Header *source, char *dest);
|
1999-11-17 22:21:51 +01:00
|
|
|
|
|
|
|
|
1999-11-25 02:28:07 +01:00
|
|
|
/* ----------
|
|
|
|
* Functions used by pglz_decomp_getchar().
|
|
|
|
* Internal use only.
|
|
|
|
* ----------
|
|
|
|
*/
|
2000-04-12 19:17:23 +02:00
|
|
|
extern int pglz_get_next_decomp_char_from_lzdata(PGLZ_DecompState *dstate);
|
|
|
|
extern int pglz_get_next_decomp_char_from_plain(PGLZ_DecompState *dstate);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
2001-11-05 18:46:40 +01:00
|
|
|
#endif /* _PG_LZCOMPRESS_H_ */
|