1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-11 10:01:57 +03:00

Added another single byte oriented decompressor, useful for

comparision functions.

Added all lztext comparision functions, operators and a default
operator class for nbtree on lztext.

Jan
This commit is contained in:
Jan Wieck
1999-11-25 01:28:07 +00:00
parent 4ae43c84c3
commit 4069d48aa7
9 changed files with 435 additions and 9 deletions

View File

@ -1,7 +1,7 @@
/* ----------
* pg_lzcompress.c -
*
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.2 1999/11/17 22:18:45 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.3 1999/11/25 01:28:04 wieck Exp $
*
* This is an implementation of LZ compression for PostgreSQL.
* It uses a simple history table and generates 2-3 byte tags
@ -671,3 +671,167 @@ pglz_decompress (PGLZ_Header *source, char *dest)
}
/* ----------
* pglz_get_next_decomp_char_from_lzdata -
*
* Reads the next character from a decompression state if the
* input data to pglz_decomp_init() was in compressed format.
* ----------
*/
int
pglz_get_next_decomp_char_from_lzdata(PGLZ_DecompState *dstate)
{
unsigned char retval;
if (dstate->tocopy > 0)
{
/* ----------
* Copy one byte from output to output until we did it
* for the length specified by the last tag. Return that
* byte.
* ----------
*/
dstate->tocopy--;
return (*(dstate->cp_out++) = *(dstate->cp_copy++));
}
if (dstate->ctrl_count == 0)
{
/* ----------
* Get the next control byte if we need to, but check
* for EOF before.
* ----------
*/
if (dstate->cp_in == dstate->cp_end)
{
return EOF;
}
/* ----------
* This decompression method saves time only, if we stop near
* the beginning of the data (maybe because we're called by a
* comparision function and a difference occurs early). Otherwise,
* all the checks, needed here, cause too much overhead.
*
* Thus we decompress the entire rest at once into the temporary
* buffer and change the decomp state to return the prepared
* data from the buffer by the more simple calls to
* pglz_get_next_decomp_char_from_plain().
* ----------
*/
if (dstate->cp_out - dstate->temp_buf >= 256)
{
unsigned char *cp_in = dstate->cp_in;
unsigned char *cp_out = dstate->cp_out;
unsigned char *cp_end = dstate->cp_end;
unsigned char *cp_copy;
unsigned char ctrl;
int off;
int len;
int i;
while (cp_in < cp_end)
{
ctrl = *cp_in++;
for (i = 0; i < 8; i++)
{
if (cp_in == cp_end)
break;
if (ctrl & 0x01)
{
len = (cp_in[0] & 0x0f) + 3;
off = ((cp_in[0] & 0xf0) << 4) | cp_in[1];
cp_in += 2;
if (len == 18)
len += *cp_in++;
cp_copy = cp_out - off;
while(len--)
*cp_out++ = *cp_copy++;
} else {
*cp_out++ = *cp_in++;
}
ctrl >>= 1;
}
}
dstate->cp_in = dstate->cp_out;
dstate->cp_end = cp_out;
dstate->next_char = pglz_get_next_decomp_char_from_plain;
return (int)(*(dstate->cp_in++));
}
/* ----------
* Not yet, get next control byte into decomp state.
* ----------
*/
dstate->ctrl = (unsigned char)(*(dstate->cp_in++));
dstate->ctrl_count = 8;
}
/* ----------
* Check for EOF in tag/literal byte data.
* ----------
*/
if (dstate->cp_in == dstate->cp_end)
{
return EOF;
}
/* ----------
* Handle next control bit.
* ----------
*/
dstate->ctrl_count--;
if (dstate->ctrl & 0x01)
{
/* ----------
* Bit is set, so tag is following. Setup copy information
* and do the copy for the first byte as above.
* ----------
*/
int off;
dstate->tocopy = (dstate->cp_in[0] & 0x0f) + 3;
off = ((dstate->cp_in[0] & 0xf0) << 4) | dstate->cp_in[1];
dstate->cp_in += 2;
if (dstate->tocopy == 18)
dstate->tocopy += *(dstate->cp_in++);
dstate->cp_copy = dstate->cp_out - off;
dstate->tocopy--;
retval = (*(dstate->cp_out++) = *(dstate->cp_copy++));
} else {
/* ----------
* Bit is unset, so literal byte follows.
* ----------
*/
retval = (int)(*(dstate->cp_out++) = *(dstate->cp_in++));
}
dstate->ctrl >>= 1;
return (int)retval;
}
/* ----------
* pglz_get_next_decomp_char_from_plain -
*
* The input data to pglz_decomp_init() was stored in uncompressed
* format. So we don't have a temporary output buffer and simply
* return bytes from the input until EOF.
* ----------
*/
int
pglz_get_next_decomp_char_from_plain(PGLZ_DecompState *dstate)
{
if (dstate->cp_in >= dstate->cp_end)
return EOF;
return (int)(*(dstate->cp_in++));
}