diff options
| author | Heikki Linnakangas | 2014-11-04 09:35:15 +0000 |
|---|---|---|
| committer | Heikki Linnakangas | 2014-11-04 09:39:48 +0000 |
| commit | 5028f22f6eb0579890689655285a4778b4ffc460 (patch) | |
| tree | ed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/utils/cache | |
| parent | 404bc51cde9dce1c674abe4695635612f08fe27e (diff) | |
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/cache')
| -rw-r--r-- | src/backend/utils/cache/relmapper.c | 16 |
1 files changed, 8 insertions, 8 deletions
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 |
