1
1
/* ----------
2
2
* pg_lzcompress.c -
3
3
*
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 $
5
5
*
6
6
*This is an implementation of LZ compression for PostgreSQL.
7
7
*It uses a simple history table and generates 2-3 byte tags
185
185
* Local definitions
186
186
* ----------
187
187
*/
188
- #define PGLZ_HISTORY_SIZE 8192
188
+ #define PGLZ_HISTORY_LISTS 8192
189
189
#define PGLZ_HISTORY_MASK 0x1fff
190
- #define PGLZ_HISTORY_PREALLOC 8192
190
+ #define PGLZ_HISTORY_SIZE 4096
191
191
#define PGLZ_MAX_MATCH 273
192
192
193
193
200
200
typedef struct PGLZ_HistEntry
201
201
{
202
202
struct PGLZ_HistEntry * next ;
203
+ struct PGLZ_HistEntry * prev ;
203
204
char * pos ;
204
205
}PGLZ_HistEntry ;
205
206
@@ -209,7 +210,7 @@ typedef struct PGLZ_HistEntry
209
210
* ----------
210
211
*/
211
212
static PGLZ_Strategy strategy_default_data = {
212
- 256 ,/* Data chunks smaller 256 bytes arenott
213
+ 256 ,/* Data chunks smaller 256 bytes arenot
213
214
* compressed */
214
215
6144 ,/* Data chunks greater equal 6K force
215
216
* compression */
@@ -247,6 +248,12 @@ static PGLZ_Strategy strategy_never_data = {
247
248
};
248
249
PGLZ_Strategy * PGLZ_strategy_never = & strategy_never_data ;
249
250
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 ];
250
257
251
258
252
259
/* ----------
@@ -276,11 +283,26 @@ PGLZ_Strategy *PGLZ_strategy_never = &strategy_never_data;
276
283
*Adds a new entry to the history table.
277
284
* ----------
278
285
*/
279
- #define pglz_hist_add (_hs ,_hn ,_s ,_e ) { \
286
+ #define pglz_hist_add (_hs ,_he , _hn ,_s ,_e ) {\
280
287
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
+ }\
284
306
}
285
307
286
308
@@ -454,10 +476,7 @@ pglz_find_match(PGLZ_HistEntry **hstart, char *input, char *end,
454
476
int
455
477
pglz_compress (char * source ,int slen ,PGLZ_Header * dest ,PGLZ_Strategy * strategy )
456
478
{
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 ;
461
480
462
481
unsignedchar * bp = ((unsignedchar * )dest )+ sizeof (PGLZ_Header );
463
482
unsignedchar * bstart = bp ;
@@ -524,17 +543,12 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
524
543
525
544
/* ----------
526
545
* 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
528
547
* table on the stack frame.
529
548
* ----------
530
549
*/
531
550
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 ));
538
552
539
553
/* ----------
540
554
* 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
588
602
pglz_out_tag (ctrlp ,ctrlb ,ctrl ,bp ,match_len ,match_off );
589
603
while (match_len -- )
590
604
{
591
- pglz_hist_add (hist_start ,hist_next ,dp ,dend );
605
+ pglz_hist_add (hist_start ,hist_entries , hist_next ,dp ,dend );
592
606
dp ++ ;/* Do not do this ++ in the line above!*/
593
607
/* The macro would do it four times - Jan.*/
594
608
}
@@ -600,19 +614,12 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
600
614
* ----------
601
615
*/
602
616
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 );
604
618
dp ++ ;/* Do not do this ++ in the line above!*/
605
619
/* The macro would do it four times - Jan.*/
606
620
}
607
621
}
608
622
609
- /* ----------
610
- * Get rid of the history (if allocated)
611
- * ----------
612
- */
613
- if (hist_alloc != hist_prealloc )
614
- pfree ((void * )hist_alloc );
615
-
616
623
/* ----------
617
624
* If we are still in compressing mode, write out the last
618
625
* control byte and determine if the compression gained the