From: Regina Obe Date: Mon, 1 Jul 2019 18:15:25 +0000 (+0000) Subject: fix for 32-bit hash X-Git-Tag: 3.0.0alpha4~80 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e015bdf510ba46b1024b453f33d96931ec3334cd;p=postgis fix for 32-bit hash Closes #4433 Closes https://github.com/postgis/postgis/pull/429 git-svn-id: http://svn.osgeo.org/postgis/trunk@17575 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/NEWS b/NEWS index e1afbd5d3..032eee844 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,11 @@ PostGIS 3.0.0alpha4 -comming next +2019/xx/xx +For full changes and enhancements, refer to PostGIS 3.0.0. +This version requires PostgreSQL 9.5+-12 and GEOS >= 3.6+ +Additional features enabled if you are running Proj6+ and PostgreSQL 12 + +* Major highlights * + - #4433 32-bit hash fix (requires reindexing your data if on 32-bit OS) (Raúl Marín) PostGIS 3.0.0alpha3 diff --git a/liblwgeom/gserialized.c b/liblwgeom/gserialized.c index 213bbecd6..6998f13cc 100644 --- a/liblwgeom/gserialized.c +++ b/liblwgeom/gserialized.c @@ -110,7 +110,8 @@ uint32_t gserialized_max_header_size(void) * in the GSERIALIZED. Ignores metadata like flags and optional * boxes, etc. */ -uint64_t gserialized_hash(const GSERIALIZED *g) +int32_t +gserialized_hash(const GSERIALIZED *g) { if (GFLAGS_GET_VERSION(g->gflags)) return gserialized2_hash(g); diff --git a/liblwgeom/gserialized.h b/liblwgeom/gserialized.h index 66847fd2b..a9d48c8bc 100644 --- a/liblwgeom/gserialized.h +++ b/liblwgeom/gserialized.h @@ -75,7 +75,7 @@ extern uint32_t gserialized_max_header_size(void); * in the GSERIALIZED. Ignores metadata like flags and optional * boxes, etc. */ -extern uint64_t gserialized_hash(const GSERIALIZED *g); +extern int32_t gserialized_hash(const GSERIALIZED *g); /** * Extract the SRID from the serialized form (it is packed into diff --git a/liblwgeom/gserialized1.c b/liblwgeom/gserialized1.c index 69b1a24ed..e0a30188d 100644 --- a/liblwgeom/gserialized1.c +++ b/liblwgeom/gserialized1.c @@ -221,11 +221,11 @@ int gserialized1_is_empty(const GSERIALIZED *g) /* pb = IN: secondary initval, OUT: secondary hash */ void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); - -uint64_t gserialized1_hash(const GSERIALIZED *g1) +int32_t +gserialized1_hash(const GSERIALIZED *g1) { - uint64_t hval; - uint32_t pb = 0, pc = 0; + int32_t hval; + int32_t pb = 0, pc = 0; /* Point to just the type/coordinate part of buffer */ size_t hsz1 = gserialized1_header_size(g1); uint8_t *b1 = (uint8_t*)g1 + hsz1; @@ -241,9 +241,9 @@ uint64_t gserialized1_hash(const GSERIALIZED *g1) /* Copy type/coordinates into rest of combined buffer */ memcpy(b2+sizeof(int), b1, bsz1); /* Hash combined buffer */ - hashlittle2(b2, bsz1, &pb, &pc); + hashlittle2(b2, bsz2, (uint32_t *)&pb, (uint32_t *)&pc); lwfree(b2); - hval = pc + (((uint64_t)pb)<<32); + hval = pb ^ pc; return hval; } diff --git a/liblwgeom/gserialized1.h b/liblwgeom/gserialized1.h index 04c9d6302..0f792b8ae 100644 --- a/liblwgeom/gserialized1.h +++ b/liblwgeom/gserialized1.h @@ -86,7 +86,7 @@ uint32_t gserialized1_max_header_size(void); * in the GSERIALIZED. Ignores metadata like flags and optional * boxes, etc. */ -uint64_t gserialized1_hash(const GSERIALIZED *g); +int32_t gserialized1_hash(const GSERIALIZED *g); /** * Extract the SRID from the serialized form (it is packed into diff --git a/liblwgeom/gserialized2.c b/liblwgeom/gserialized2.c index 9280ca058..3e2e65a0b 100644 --- a/liblwgeom/gserialized2.c +++ b/liblwgeom/gserialized2.c @@ -252,19 +252,19 @@ int gserialized2_is_empty(const GSERIALIZED *g) /* pb = IN: secondary initval, OUT: secondary hash */ void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb); - -uint64_t gserialized2_hash(const GSERIALIZED *g) +int32_t +gserialized2_hash(const GSERIALIZED *g1) { - uint64_t hval; - uint32_t pb = 0, pc = 0; + int32_t hval; + int32_t pb = 0, pc = 0; /* Point to just the type/coordinate part of buffer */ - size_t hsz1 = gserialized2_header_size(g); - uint8_t *b1 = (uint8_t*)g + hsz1; + size_t hsz1 = gserialized2_header_size(g1); + uint8_t *b1 = (uint8_t *)g1 + hsz1; /* Calculate size of type/coordinate buffer */ - size_t sz1 = SIZE_GET(g->size); + size_t sz1 = SIZE_GET(g1->size); size_t bsz1 = sz1 - hsz1; /* Calculate size of srid/type/coordinate buffer */ - int32_t srid = gserialized2_get_srid(g); + int32_t srid = gserialized2_get_srid(g1); size_t bsz2 = bsz1 + sizeof(int); uint8_t *b2 = lwalloc(bsz2); /* Copy srid into front of combined buffer */ @@ -272,9 +272,9 @@ uint64_t gserialized2_hash(const GSERIALIZED *g) /* Copy type/coordinates into rest of combined buffer */ memcpy(b2+sizeof(int), b1, bsz1); /* Hash combined buffer */ - hashlittle2(b2, bsz1, &pb, &pc); + hashlittle2(b2, bsz2, (uint32_t *)&pb, (uint32_t *)&pc); lwfree(b2); - hval = pc + (((uint64_t)pb)<<32); + hval = pb ^ pc; return hval; } diff --git a/liblwgeom/gserialized2.h b/liblwgeom/gserialized2.h index b8d8834d6..2685bbee0 100644 --- a/liblwgeom/gserialized2.h +++ b/liblwgeom/gserialized2.h @@ -93,7 +93,7 @@ uint32_t gserialized2_max_header_size(void); * in the GSERIALIZED. Ignores metadata like flags and optional * boxes, etc. */ -uint64_t gserialized2_hash(const GSERIALIZED *g); +int32_t gserialized2_hash(const GSERIALIZED *g); /** * Extract the SRID from the serialized form (it is packed into diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in index 9032f5c27..68fb5f6ea 100644 --- a/liblwgeom/liblwgeom.h.in +++ b/liblwgeom/liblwgeom.h.in @@ -735,7 +735,7 @@ extern uint32_t gserialized_max_header_size(void); * in the GSERIALIZED. Ignores metadata like flags and optional * boxes, etc. */ -extern uint64_t gserialized_hash(const GSERIALIZED *g); +extern int32_t gserialized_hash(const GSERIALIZED *g); /** * Extract the SRID from the serialized form (it is packed into diff --git a/postgis/lwgeom_btree.c b/postgis/lwgeom_btree.c index 66c1573e0..6c11445ed 100644 --- a/postgis/lwgeom_btree.c +++ b/postgis/lwgeom_btree.c @@ -131,9 +131,9 @@ PG_FUNCTION_INFO_V1(lwgeom_hash); Datum lwgeom_hash(PG_FUNCTION_ARGS) { GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0); - uint64_t hval = gserialized_hash(g1); + int32_t hval = gserialized_hash(g1); PG_FREE_IF_COPY(g1, 0); - PG_RETURN_DATUM(Int64GetDatum(hval)); + PG_RETURN_INT32(hval); }