aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-11-04 11:35:15 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-11-04 11:39:48 +0200
commit5028f22f6eb0579890689655285a4778b4ffc460 (patch)
treeed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/utils
parent404bc51cde9dce1c674abe4695635612f08fe27e (diff)
downloadpostgresql-5028f22f6eb0579890689655285a4778b4ffc460.tar.gz
postgresql-5028f22f6eb0579890689655285a4778b4ffc460.zip
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.
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/tsgistidx.c6
-rw-r--r--src/backend/utils/adt/tsquery.c12
-rw-r--r--src/backend/utils/cache/relmapper.c16
3 files changed, 17 insertions, 17 deletions
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index 80039189c3f..e9cff4ffb69 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -201,9 +201,9 @@ gtsvector_compress(PG_FUNCTION_ARGS)
{
pg_crc32 c;
- INIT_CRC32(c);
- COMP_CRC32(c, words + ptr->pos, ptr->len);
- FIN_CRC32(c);
+ INIT_LEGACY_CRC32(c);
+ COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
+ FIN_LEGACY_CRC32(c);
*arr = *(int32 *) &c;
arr++;
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index c8011a8ea92..5226bae2d17 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -280,9 +280,9 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
errmsg("word is too long in tsquery: \"%s\"",
state->buffer)));
- INIT_CRC32(valcrc);
- COMP_CRC32(valcrc, strval, lenval);
- FIN_CRC32(valcrc);
+ INIT_LEGACY_CRC32(valcrc);
+ COMP_LEGACY_CRC32(valcrc, strval, lenval);
+ FIN_LEGACY_CRC32(valcrc);
pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix);
/* append the value string to state.op, enlarging buffer if needed first */
@@ -883,9 +883,9 @@ tsqueryrecv(PG_FUNCTION_ARGS)
/* Looks valid. */
- INIT_CRC32(valcrc);
- COMP_CRC32(valcrc, val, val_len);
- FIN_CRC32(valcrc);
+ INIT_LEGACY_CRC32(valcrc);
+ COMP_LEGACY_CRC32(valcrc, val, val_len);
+ FIN_LEGACY_CRC32(valcrc);
item->qoperand.weight = weight;
item->qoperand.prefix = (prefix) ? true : false;
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 95a2689fd42..b6b13308773 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -84,7 +84,7 @@ typedef struct RelMapFile
int32 magic; /* always RELMAPPER_FILEMAGIC */
int32 num_mappings; /* number of valid RelMapping entries */
RelMapping mappings[MAX_MAPPINGS];
- int32 crc; /* CRC of all above */
+ pg_crc32 crc; /* CRC of all above */
int32 pad; /* to make the struct size be 512 exactly */
} RelMapFile;
@@ -673,11 +673,11 @@ load_relmap_file(bool shared)
mapfilename)));
/* verify the CRC */
- INIT_CRC32(crc);
- COMP_CRC32(crc, (char *) map, offsetof(RelMapFile, crc));
- FIN_CRC32(crc);
+ INIT_CRC32C(crc);
+ COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
+ FIN_CRC32C(crc);
- if (!EQ_CRC32(crc, map->crc))
+ if (!EQ_CRC32C(crc, map->crc))
ereport(FATAL,
(errmsg("relation mapping file \"%s\" contains incorrect checksum",
mapfilename)));
@@ -719,9 +719,9 @@ write_relmap_file(bool shared, RelMapFile *newmap,
if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
elog(ERROR, "attempt to write bogus relation mapping");
- INIT_CRC32(newmap->crc);
- COMP_CRC32(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
- FIN_CRC32(newmap->crc);
+ INIT_CRC32C(newmap->crc);
+ COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
+ FIN_CRC32C(newmap->crc);
/*
* Open the target file. We prefer to do this before entering the