2010-09-21 04:08:53 +08:00
|
|
|
/* contrib/ltree/crc32.c */
|
2006-03-11 12:38:42 +08:00
|
|
|
|
Switch to CRC-32C in WAL and other places.
The old algorithm was found to not be the usual CRC-32 algorithm, used by
Ethernet et al. We were using a non-reflected lookup table with code meant
for a reflected lookup table. That's a strange combination that AFAICS does
not correspond to any bit-wise CRC calculation, which makes it difficult to
reason about its properties. Although it has worked well in practice, seems
safer to use a well-known algorithm.
Since we're changing the algorithm anyway, we might as well choose a
different polynomial. The Castagnoli polynomial has better error-correcting
properties than the traditional CRC-32 polynomial, even if we had
implemented it correctly. Another reason for picking that is that some new
CPUs have hardware support for calculating CRC-32C, but not CRC-32, let
alone our strange variant of it. This patch doesn't add any support for such
hardware, but a future patch could now do that.
The old algorithm is kept around for tsquery and pg_trgm, which use the
values in indexes that need to remain compatible so that pg_upgrade works.
While we're at it, share the old lookup table for CRC-32 calculation
between hstore, ltree and core. They all use the same table, so might as
well.
2014-11-04 17:35:15 +08:00
|
|
|
/*
|
|
|
|
* Implements CRC-32, as used in ltree.
|
|
|
|
*
|
|
|
|
* Note that the CRC is used in the on-disk format of GiST indexes, so we
|
|
|
|
* must stay backwards-compatible!
|
|
|
|
*/
|
|
|
|
|
2011-08-27 09:16:24 +08:00
|
|
|
#include "postgres.h"
|
|
|
|
|
2002-07-31 00:40:34 +08:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#ifdef LOWER_NODE
|
|
|
|
#include <ctype.h>
|
2006-09-23 05:39:58 +08:00
|
|
|
#define TOLOWER(x) tolower((unsigned char) (x))
|
2002-07-31 00:40:34 +08:00
|
|
|
#else
|
|
|
|
#define TOLOWER(x) (x)
|
|
|
|
#endif
|
|
|
|
|
2015-04-14 22:03:42 +08:00
|
|
|
#include "utils/pg_crc.h"
|
2002-07-31 00:40:34 +08:00
|
|
|
#include "crc32.h"
|
|
|
|
|
|
|
|
unsigned int
|
2002-08-11 04:46:24 +08:00
|
|
|
ltree_crc32_sz(char *buf, int size)
|
2002-07-31 00:40:34 +08:00
|
|
|
{
|
Switch to CRC-32C in WAL and other places.
The old algorithm was found to not be the usual CRC-32 algorithm, used by
Ethernet et al. We were using a non-reflected lookup table with code meant
for a reflected lookup table. That's a strange combination that AFAICS does
not correspond to any bit-wise CRC calculation, which makes it difficult to
reason about its properties. Although it has worked well in practice, seems
safer to use a well-known algorithm.
Since we're changing the algorithm anyway, we might as well choose a
different polynomial. The Castagnoli polynomial has better error-correcting
properties than the traditional CRC-32 polynomial, even if we had
implemented it correctly. Another reason for picking that is that some new
CPUs have hardware support for calculating CRC-32C, but not CRC-32, let
alone our strange variant of it. This patch doesn't add any support for such
hardware, but a future patch could now do that.
The old algorithm is kept around for tsquery and pg_trgm, which use the
values in indexes that need to remain compatible so that pg_upgrade works.
While we're at it, share the old lookup table for CRC-32 calculation
between hstore, ltree and core. They all use the same table, so might as
well.
2014-11-04 17:35:15 +08:00
|
|
|
pg_crc32 crc;
|
|
|
|
char *p = buf;
|
|
|
|
|
|
|
|
INIT_TRADITIONAL_CRC32(crc);
|
|
|
|
while (size > 0)
|
|
|
|
{
|
|
|
|
char c = (char) TOLOWER(*p);
|
|
|
|
COMP_TRADITIONAL_CRC32(crc, &c, 1);
|
|
|
|
size--;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
FIN_TRADITIONAL_CRC32(crc);
|
|
|
|
return (unsigned int) crc;
|
2002-07-31 00:40:34 +08:00
|
|
|
}
|