diff --git a/src/backend/utils/adt/pg_lzcompress.c b/src/backend/utils/adt/pg_lzcompress.c index 66c64c1..b4a8b8b 100644 --- a/src/backend/utils/adt/pg_lzcompress.c +++ b/src/backend/utils/adt/pg_lzcompress.c @@ -198,9 +198,9 @@ */ typedef struct PGLZ_HistEntry { - struct PGLZ_HistEntry *next; /* links for my hash key's list */ - struct PGLZ_HistEntry *prev; - int hindex; /* my current hash key */ + int16 next; /* links for my hash key's list */ + int16 prev; + uint32 hindex; /* my current hash key */ const char *pos; /* my input position */ } PGLZ_HistEntry; @@ -241,9 +241,11 @@ const PGLZ_Strategy *const PGLZ_strategy_always = &strategy_always_data; * Statically allocated work arrays for history * ---------- */ -static PGLZ_HistEntry *hist_start[PGLZ_HISTORY_LISTS]; -static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE]; +static int16 hist_start[PGLZ_HISTORY_LISTS]; +static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE + 1]; +/* Element 0 in hist_entries is unused, and means 'invalid'. */ +#define INVALID_ENTRY 0 /* ---------- * pglz_hist_idx - @@ -279,25 +281,25 @@ static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE]; #define pglz_hist_add(_hs,_he,_hn,_recycle,_s,_e) \ do { \ int __hindex = pglz_hist_idx((_s),(_e)); \ - PGLZ_HistEntry **__myhsp = &(_hs)[__hindex]; \ + int16 *__myhsp = &(_hs)[__hindex]; \ PGLZ_HistEntry *__myhe = &(_he)[_hn]; \ if (_recycle) { \ - if (__myhe->prev == NULL) \ + if (__myhe->prev == INVALID_ENTRY) \ (_hs)[__myhe->hindex] = __myhe->next; \ else \ - __myhe->prev->next = __myhe->next; \ - if (__myhe->next != NULL) \ - __myhe->next->prev = __myhe->prev; \ + (_he)[__myhe->prev].next = __myhe->next; \ + if (__myhe->next != INVALID_ENTRY) \ + (_he)[__myhe->next].prev = __myhe->prev; \ } \ __myhe->next = *__myhsp; \ - __myhe->prev = NULL; \ + __myhe->prev = INVALID_ENTRY; \ __myhe->hindex = __hindex; \ __myhe->pos = (_s); \ - if (*__myhsp != NULL) \ - (*__myhsp)->prev = __myhe; \ - *__myhsp = __myhe; \ - if (++(_hn) >= PGLZ_HISTORY_SIZE) { \ - (_hn) = 0; \ + if (*__myhsp != INVALID_ENTRY) \ + (_he)[(*__myhsp)].prev = _hn; \ + *__myhsp = _hn; \ + if (++(_hn) >= PGLZ_HISTORY_SIZE + 1) { \ + (_hn) = 1; \ (_recycle) = true; \ } \ } while (0) @@ -372,19 +374,20 @@ do { \ * ---------- */ static inline int -pglz_find_match(PGLZ_HistEntry **hstart, const char *input, const char *end, +pglz_find_match(int16 *hstart, const char *input, const char *end, int *lenp, int *offp, int good_match, int good_drop) { - PGLZ_HistEntry *hent; + int16 hentno; int32 len = 0; int32 off = 0; /* * Traverse the linked history list until a good enough match is found. */ - hent = hstart[pglz_hist_idx(input, end)]; - while (hent) + hentno = hstart[pglz_hist_idx(input, end)]; + while (hentno != INVALID_ENTRY) { + PGLZ_HistEntry *hent = &hist_entries[hentno]; const char *ip = input; const char *hp = hent->pos; int32 thisoff; @@ -443,13 +446,13 @@ pglz_find_match(PGLZ_HistEntry **hstart, const char *input, const char *end, /* * Advance to the next history entry */ - hent = hent->next; + hentno = hent->next; /* * Be happy with lesser good matches the more entries we visited. But * no point in doing calculation if we're at end of list. */ - if (hent) + if (hentno != INVALID_ENTRY) { if (len >= good_match) break; @@ -484,7 +487,7 @@ pglz_compress(const char *source, int32 slen, PGLZ_Header *dest, { unsigned char *bp = ((unsigned char *) dest) + sizeof(PGLZ_Header); unsigned char *bstart = bp; - int hist_next = 0; + int hist_next = 1; bool hist_recycle = false; const char *dp = source; const char *dend = source + slen;