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{
202202 struct PGLZ_HistEntry * next ;
203+ struct PGLZ_HistEntry * prev ;
203204 char * 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 are nott
213+ 256 , /* Data chunks smaller 256 bytes are not
213214 * compressed */
214215 6144 , /* 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 ) { \
280287 int __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
462481 unsigned char * bp = ((unsigned char * ) dest ) + sizeof (PGLZ_Header );
463482 unsigned char * 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 */
531550 memset ((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
588602 pglz_out_tag (ctrlp , ctrlb , ctrl , bp , match_len , match_off );
589603 while (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 );
592606 dp ++ ; /* 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 */
602616 pglz_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 );
604618 dp ++ ; /* 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
0 commit comments