mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +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:
@@ -1,7 +1,7 @@
|
||||
/* ----------
|
||||
* lztext.c -
|
||||
*
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/lztext.c,v 1.3 1999/11/24 03:45:12 ishii Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/lztext.c,v 1.4 1999/11/25 01:28:04 wieck Exp $
|
||||
*
|
||||
* Text type with internal LZ compressed representation. Uses the
|
||||
* standard PostgreSQL compression method.
|
||||
@@ -290,3 +290,146 @@ lztext_text(lztext *lz)
|
||||
}
|
||||
|
||||
|
||||
/* ----------
|
||||
* lztext_cmp -
|
||||
*
|
||||
* Comparision function for two lztext datum's.
|
||||
*
|
||||
* Returns -1, 0 or 1.
|
||||
* ----------
|
||||
*/
|
||||
int32
|
||||
lztext_cmp(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
#ifdef USE_LOCALE
|
||||
|
||||
char *cp1;
|
||||
char *cp2;
|
||||
int result;
|
||||
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return (int32)0;
|
||||
|
||||
cp1 = lztextout(lz1);
|
||||
cp2 = lztextout(lz2);
|
||||
|
||||
result = strcoll(cp1, cp2);
|
||||
|
||||
pfree(cp1);
|
||||
pfree(cp2);
|
||||
|
||||
return result;
|
||||
|
||||
#else /* !USE_LOCALE */
|
||||
|
||||
PGLZ_DecompState ds1;
|
||||
PGLZ_DecompState ds2;
|
||||
int c1;
|
||||
int c2;
|
||||
int32 result = (int32)0;
|
||||
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return (int32)0;
|
||||
|
||||
pglz_decomp_init(&ds1, lz1);
|
||||
pglz_decomp_init(&ds2, lz2);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
c1 = pglz_decomp_getchar(&ds1);
|
||||
c2 = pglz_decomp_getchar(&ds2);
|
||||
|
||||
if (c1 == EOF)
|
||||
{
|
||||
if (c2 != EOF)
|
||||
result = (int32)-1;
|
||||
break;
|
||||
} else {
|
||||
if (c2 == EOF)
|
||||
{
|
||||
result = (int32)1;
|
||||
}
|
||||
}
|
||||
if (c1 != c2)
|
||||
{
|
||||
result = (int32)(c1 - c2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pglz_decomp_end(&ds1);
|
||||
pglz_decomp_end(&ds2);
|
||||
|
||||
return result;
|
||||
|
||||
#endif /* USE_LOCALE */
|
||||
}
|
||||
|
||||
|
||||
/* ----------
|
||||
* lztext_eq ... -
|
||||
*
|
||||
* =, !=, >, >=, < and <= operator functions for two
|
||||
* lztext datums.
|
||||
* ----------
|
||||
*/
|
||||
bool
|
||||
lztext_eq(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) == 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
lztext_ne(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) != 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
lztext_gt(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) > 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
lztext_ge(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) >= 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
lztext_lt(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) < 0);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
lztext_le(lztext *lz1, lztext *lz2)
|
||||
{
|
||||
if (lz1 == NULL || lz2 == NULL)
|
||||
return false;
|
||||
|
||||
return (bool)(lztext_cmp(lz1, lz2) <= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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++));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user