mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	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.
		
			
				
	
	
		
			43 lines
		
	
	
		
			731 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			43 lines
		
	
	
		
			731 B
		
	
	
	
		
			C
		
	
	
	
	
	
| /* contrib/ltree/crc32.c */
 | |
| 
 | |
| /*
 | |
|  * 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!
 | |
|  */
 | |
| 
 | |
| #include "postgres.h"
 | |
| 
 | |
| #include <sys/types.h>
 | |
| #include <stdio.h>
 | |
| #include <sys/types.h>
 | |
| 
 | |
| #ifdef LOWER_NODE
 | |
| #include <ctype.h>
 | |
| #define TOLOWER(x)	tolower((unsigned char) (x))
 | |
| #else
 | |
| #define TOLOWER(x)	(x)
 | |
| #endif
 | |
| 
 | |
| #include "utils/pg_crc.h"
 | |
| #include "crc32.h"
 | |
| 
 | |
| unsigned int
 | |
| ltree_crc32_sz(char *buf, int size)
 | |
| {
 | |
| 	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;
 | |
| }
 |