11/* ----------
22 * pg_lzcompress.c -
33 *
4- * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.7 2000/07/06 21:02:07 wieck Exp $
4+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.8 2000/07/20 14:23:28 wieck Exp $
55 *
66 *This is an implementation of LZ compression for PostgreSQL.
77 *It uses a simple history table and generates 2-3 byte tags
185185 * Local definitions
186186 * ----------
187187 */
188- #define PGLZ_HISTORY_SIZE 8192
188+ #define PGLZ_HISTORY_LISTS 8192
189189#define PGLZ_HISTORY_MASK 0x1fff
190- #define PGLZ_HISTORY_PREALLOC 8192
190+ #define PGLZ_HISTORY_SIZE 4096
191191#define PGLZ_MAX_MATCH 273
192192
193193
200200typedef struct PGLZ_HistEntry
201201{
202202struct PGLZ_HistEntry * next ;
203+ struct PGLZ_HistEntry * prev ;
203204char * pos ;
204205}PGLZ_HistEntry ;
205206
@@ -209,7 +210,7 @@ typedef struct PGLZ_HistEntry
209210 * ----------
210211 */
211212static PGLZ_Strategy strategy_default_data = {
212- 256 ,/* Data chunks smaller 256 bytes arenott
213+ 256 ,/* Data chunks smaller 256 bytes arenot
213214 * compressed */
2142156144 ,/* Data chunks greater equal 6K force
215216 * compression */
@@ -247,6 +248,12 @@ static PGLZ_Strategy strategy_never_data = {
247248};
248249PGLZ_Strategy * PGLZ_strategy_never = & strategy_never_data ;
249250
251+ /* ----------
252+ * Global arrays for history
253+ * ----------
254+ */
255+ static PGLZ_HistEntry * hist_start [PGLZ_HISTORY_LISTS ];
256+ static PGLZ_HistEntry hist_entries [PGLZ_HISTORY_SIZE ];
250257
251258
252259/* ----------
@@ -276,11 +283,26 @@ PGLZ_Strategy *PGLZ_strategy_never = &strategy_never_data;
276283 *Adds a new entry to the history table.
277284 * ----------
278285 */
279- #define pglz_hist_add (_hs ,_hn ,_s ,_e ) { \
286+ #define pglz_hist_add (_hs ,_he , _hn ,_s ,_e ) {\
280287int __hindex = pglz_hist_idx((_s),(_e));\
281- (_hn)->next = (_hs)[__hindex];\
282- (_hn)->pos= (_s);\
283- (_hs)[__hindex] = (_hn)++;\
288+ if ((_he)[(_hn)].prev == NULL) {\
289+ (_hs)[__hindex] = (_he)[(_hn)].next;\
290+ } else {\
291+ (_he)[(_hn)].prev->next = (_he)[(_hn)].next;\
292+ }\
293+ if ((_he)[(_hn)].next != NULL) {\
294+ (_he)[(_hn)].next->prev = (_he)[(_hn)].prev;\
295+ }\
296+ (_he)[(_hn)].next = (_hs)[__hindex];\
297+ (_he)[(_hn)].prev = NULL;\
298+ (_he)[(_hn)].pos = (_s);\
299+ if ((_hs)[__hindex] != NULL) {\
300+ (_hs)[__hindex]->prev = &((_he)[(_hn)]);\
301+ }\
302+ (_hs)[__hindex] = &((_he)[(_hn)]);\
303+ if (++(_hn) >= PGLZ_HISTORY_SIZE) {\
304+ (_hn) = 0;\
305+ }\
284306}
285307
286308
@@ -454,10 +476,7 @@ pglz_find_match(PGLZ_HistEntry **hstart, char *input, char *end,
454476int
455477pglz_compress (char * source ,int slen ,PGLZ_Header * dest ,PGLZ_Strategy * strategy )
456478{
457- PGLZ_HistEntry * hist_start [PGLZ_HISTORY_SIZE ];
458- PGLZ_HistEntry * hist_alloc ;
459- PGLZ_HistEntry hist_prealloc [PGLZ_HISTORY_PREALLOC ];
460- PGLZ_HistEntry * hist_next ;
479+ int hist_next = 0 ;
461480
462481unsignedchar * bp = ((unsignedchar * )dest )+ sizeof (PGLZ_Header );
463482unsignedchar * bstart = bp ;
@@ -524,17 +543,12 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
524543
525544/* ----------
526545 * Initialize the history tables. For inputs smaller than
527- *PGLZ_HISTORY_PREALLOC , we already have a big enough history
546+ *PGLZ_HISTORY_SIZE , we already have a big enough history
528547 * table on the stack frame.
529548 * ----------
530549 */
531550memset ((void * )hist_start ,0 ,sizeof (hist_start ));
532- if (slen + 1 <=PGLZ_HISTORY_PREALLOC )
533- hist_alloc = hist_prealloc ;
534- else
535- hist_alloc = (PGLZ_HistEntry * )
536- palloc (sizeof (PGLZ_HistEntry )* (slen + 1 ));
537- hist_next = hist_alloc ;
551+ memset ((void * )hist_entries ,0 ,sizeof (hist_entries ));
538552
539553/* ----------
540554 * Compute the maximum result size allowed by the strategy.
@@ -588,7 +602,7 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
588602pglz_out_tag (ctrlp ,ctrlb ,ctrl ,bp ,match_len ,match_off );
589603while (match_len -- )
590604{
591- pglz_hist_add (hist_start ,hist_next ,dp ,dend );
605+ pglz_hist_add (hist_start ,hist_entries , hist_next ,dp ,dend );
592606dp ++ ;/* Do not do this ++ in the line above!*/
593607/* The macro would do it four times - Jan.*/
594608}
@@ -600,19 +614,12 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
600614 * ----------
601615 */
602616pglz_out_literal (ctrlp ,ctrlb ,ctrl ,bp ,* dp );
603- pglz_hist_add (hist_start ,hist_next ,dp ,dend );
617+ pglz_hist_add (hist_start ,hist_entries , hist_next ,dp ,dend );
604618dp ++ ;/* Do not do this ++ in the line above!*/
605619/* The macro would do it four times - Jan.*/
606620}
607621}
608622
609- /* ----------
610- * Get rid of the history (if allocated)
611- * ----------
612- */
613- if (hist_alloc != hist_prealloc )
614- pfree ((void * )hist_alloc );
615-
616623/* ----------
617624 * If we are still in compressing mode, write out the last
618625 * control byte and determine if the compression gained the