4 * $Header: /cvsroot/pgsql/src/include/utils/pg_lzcompress.h,v 1.8 2001/11/05 17:46:36 momjian Exp $
6 * Definitions for the builtin LZ compressor
10 #ifndef _PG_LZCOMPRESS_H_
11 #define _PG_LZCOMPRESS_H_
17 * The information at the top of the compressed data.
18 * The varsize must be kept the same data type as the value
19 * in front of all variable size data types in PostgreSQL.
22 typedef struct PGLZ_Header
32 * Macro to compute the maximum buffer required for the
33 * compression output. It is larger than the input, because
34 * in the worst case, we cannot write out one single tag but
35 * need one control byte per 8 literal data bytes plus the
36 * EOF mark at the end.
39 #define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + (((_dlen) | 0x07) >> 3) \
40 + sizeof(PGLZ_Header))
45 * Macro to determine the uncompressed data size contained
49 #define PGLZ_RAW_SIZE(_lzdata) (_lzdata->rawsize)
52 * PGLZ_IS_COMPRESSED -
54 * Macro to determine if the data itself is stored as raw
58 #define PGLZ_IS_COMPRESSED(_lzdata) (_lzdata->varsize != \
65 * Macro to get access to the plain compressed or uncompressed
66 * data. Useful if PGLZ_IS_COMPRESSED returns false.
69 #define PGLZ_RAW_DATA(_lzdata) (((char *)(_lzdata)) + \
75 * Some values that control the compression algorithm.
77 * min_input_size Minimum input data size to start compression.
79 * force_input_size Input data size at which compressed storage is
80 * forced even if the compression rate drops below
81 * min_comp_rate (but not below 0).
83 * min_comp_rate Minimum compression rate (0-99%), the output
84 * must be smaller than the input. If that isn't
85 * the case, the compressor will throw away its
86 * output and copy the original, uncompressed data
87 * to the output buffer.
89 * match_size_good The initial GOOD match size when starting history
90 * lookup. When looking up the history to find a
91 * match that could be expressed as a tag, the
92 * algorithm does not allways walk back entirely.
93 * A good match fast is usually better than the
94 * best possible one very late. For each iteration
95 * in the lookup, this value is lowered so the
96 * longer the lookup takes, the smaller matches
97 * are considered good.
99 * match_size_drop The percentage, match_size_good is lowered
100 * at each history check. Allowed values are
101 * 0 (no change until end) to 100 (only check
102 * latest history entry at all).
105 typedef struct PGLZ_Strategy
107 int32 min_input_size;
108 int32 force_input_size;
110 int32 match_size_good;
111 int32 match_size_drop;
118 * Decompression state variable for byte-per-byte decompression
119 * using pglz_decomp_getchar() macro.
122 typedef struct PGLZ_DecompState
124 unsigned char *temp_buf;
125 unsigned char *cp_in;
126 unsigned char *cp_end;
127 unsigned char *cp_out;
128 unsigned char *cp_copy;
129 int (*next_char) (struct PGLZ_DecompState *dstate);
137 * The standard strategies
139 * PGLZ_strategy_default Starts compression only if input is
140 * at least 256 bytes large. Stores output
141 * uncompressed if compression does not
142 * gain at least 20% size reducture but
143 * input does not exceed 6K. Stops history
144 * lookup if at least a 128 byte long
145 * match has been found.
147 * This is the default strategy if none
148 * is given to pglz_compress().
150 * PGLZ_strategy_allways Starts compression on any infinitely
151 * small input and does fallback to
152 * uncompressed storage only if output
153 * would be larger than input.
155 * PGLZ_strategy_never Force pglz_compress to act as a custom
156 * interface for memcpy(). Only useful
157 * for generic interfacing.
160 extern PGLZ_Strategy *PGLZ_strategy_default;
161 extern PGLZ_Strategy *PGLZ_strategy_allways;
162 extern PGLZ_Strategy *PGLZ_strategy_never;
166 * pglz_decomp_getchar -
168 * Get next character (or EOF) from decompressor.
169 * The status variable must be initialized before and deinitialized
170 * after compression with the next two macros below.
173 #define pglz_decomp_getchar(_ds) \
174 ((*((_ds)->next_char))((_ds)))
180 * Initialize a decomp state from a compressed input.
183 #define pglz_decomp_init(_ds,_lz) do { \
184 (_ds)->cp_in = ((unsigned char *)(_lz)) \
185 + sizeof(PGLZ_Header); \
186 (_ds)->cp_end = (_ds)->cp_in + (_lz)->varsize \
187 - sizeof(PGLZ_Header); \
188 if (PGLZ_IS_COMPRESSED((_lz))) { \
189 (_ds)->temp_buf = (unsigned char *) \
190 palloc(PGLZ_RAW_SIZE((_lz))); \
191 (_ds)->cp_out = (_ds)->temp_buf; \
192 (_ds)->next_char = pglz_get_next_decomp_char_from_lzdata; \
194 (_ds)->ctrl_count = 0; \
196 (_ds)->temp_buf = NULL; \
197 (_ds)->next_char = pglz_get_next_decomp_char_from_plain; \
205 * Deallocate resources after decompression.
208 #define pglz_decomp_end(_ds) do { \
209 if ((_ds)->temp_buf != NULL) \
210 pfree((void *)((_ds)->temp_buf)); \
215 * Global function declarations
218 int pglz_compress(char *source, int32 slen, PGLZ_Header *dest,
219 PGLZ_Strategy *strategy);
220 int pglz_decompress(PGLZ_Header *source, char *dest);
224 * Functions used by pglz_decomp_getchar().
228 extern int pglz_get_next_decomp_char_from_lzdata(PGLZ_DecompState *dstate);
229 extern int pglz_get_next_decomp_char_from_plain(PGLZ_DecompState *dstate);
231 #endif /* _PG_LZCOMPRESS_H_ */