Add 32-byte hash support

This commit is contained in:
simon987 2020-04-11 21:08:51 -04:00
parent 82291d600d
commit ab3fb7191e
2 changed files with 58 additions and 12 deletions

View File

@ -58,6 +58,35 @@ Datum hash_is_within_distance8(PG_FUNCTION_ARGS) {
PG_RETURN_BOOL(true); PG_RETURN_BOOL(true);
} }
PG_FUNCTION_INFO_V1(hash_is_within_distance32);
Datum hash_is_within_distance32(PG_FUNCTION_ARGS) {
char *h1 = VARDATA(PG_GETARG_BYTEA_P(0));
char *h2 = VARDATA(PG_GETARG_BYTEA_P(1));
int32 max_distance = PG_GETARG_INT32(2);
int distance = 0;
distance += __builtin_popcountll(*((uint64 *) h1) ^ *((uint64 *) h2));
if (distance > max_distance) {
PG_RETURN_BOOL(false);
}
distance += __builtin_popcountll(*((uint64 *) h1 + 1) ^ *((uint64 *) h2 + 1));
if (distance > max_distance) {
PG_RETURN_BOOL(false);
}
distance += __builtin_popcountll(*((uint64 *) h1 + 2) ^ *((uint64 *) h2 + 2));
if (distance > max_distance) {
PG_RETURN_BOOL(false);
}
distance += __builtin_popcountll(*((uint64 *) h1 + 3) ^ *((uint64 *) h2 + 3));
if (distance > max_distance) {
PG_RETURN_BOOL(false);
}
PG_RETURN_BOOL(distance <= max_distance);
}
PG_FUNCTION_INFO_V1(hash_distance8); PG_FUNCTION_INFO_V1(hash_distance8);
Datum hash_distance8(PG_FUNCTION_ARGS) { Datum hash_distance8(PG_FUNCTION_ARGS) {
@ -68,6 +97,21 @@ Datum hash_distance8(PG_FUNCTION_ARGS) {
PG_RETURN_INT32(distance); PG_RETURN_INT32(distance);
} }
PG_FUNCTION_INFO_V1(hash_distance32);
Datum hash_distance32(PG_FUNCTION_ARGS) {
char *h1 = VARDATA(PG_GETARG_BYTEA_P(0));
char *h2 = VARDATA(PG_GETARG_BYTEA_P(1));
int distance = 0;
distance += __builtin_popcountll(*((uint64 *) h1) ^ *((uint64 *) h2));
distance += __builtin_popcountll(*((uint64 *) h1 + 1) ^ *((uint64 *) h2 + 1));
distance += __builtin_popcountll(*((uint64 *) h1 + 2) ^ *((uint64 *) h2 + 2));
distance += __builtin_popcountll(*((uint64 *) h1 + 3) ^ *((uint64 *) h2 + 3));
PG_RETURN_INT32(distance);
}
PG_FUNCTION_INFO_V1(hash_distance18); PG_FUNCTION_INFO_V1(hash_distance18);
/** /**
@ -89,15 +133,9 @@ Datum hash_distance18(PG_FUNCTION_ARGS) {
int distance = 0; int distance = 0;
distance += __builtin_popcountll( distance += __builtin_popcountll(*((uint64 *) h1) ^ *((uint64 *) h2));
*((uint64 *) h1) ^ *((uint64 *) h2) distance += __builtin_popcountll(*((uint64 *) h1 + 1) ^ *((uint64 *) h2 + 1));
); distance += __builtin_popcount(*((uint16 *) h1 + 8) ^ *((uint16 *) h2 + 8));
distance += __builtin_popcountll(
*((uint64 *) h1 + 1) ^ *((uint64 *) h2 + 1)
);
distance += __builtin_popcount(
*((uint16 *) h1 + 8) ^ *((uint16 *) h2 + 8)
);
PG_RETURN_INT32(distance); PG_RETURN_INT32(distance);
} }

14
install.sh Normal file → Executable file
View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
USER=dbuser mv libhamming.so /usr/lib/
DATABASE=dbname
LIB_PATH='/path/to/libhamming.so' USER=postgres
DATABASE=imhashdb
LIB_PATH="'/usr/lib/libhamming.so'"
psql -U $USER $DATABASE <<EOF psql -U $USER $DATABASE <<EOF
CREATE OR REPLACE FUNCTION hash_is_within_distance18(bytea, bytea, integer) RETURNS boolean CREATE OR REPLACE FUNCTION hash_is_within_distance18(bytea, bytea, integer) RETURNS boolean
@ -11,6 +13,9 @@ CREATE OR REPLACE FUNCTION hash_is_within_distance18(bytea, bytea, integer) RETU
CREATE OR REPLACE FUNCTION hash_is_within_distance8(bytea, bytea, integer) RETURNS boolean CREATE OR REPLACE FUNCTION hash_is_within_distance8(bytea, bytea, integer) RETURNS boolean
AS $LIB_PATH, 'hash_is_within_distance8' AS $LIB_PATH, 'hash_is_within_distance8'
LANGUAGE C STRICT; LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION hash_is_within_distance32(bytea, bytea, integer) RETURNS boolean
AS $LIB_PATH, 'hash_is_within_distance32'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION hash_distance18(bytea, bytea) RETURNS integer CREATE OR REPLACE FUNCTION hash_distance18(bytea, bytea) RETURNS integer
AS $LIB_PATH, 'hash_distance18' AS $LIB_PATH, 'hash_distance18'
@ -18,6 +23,9 @@ CREATE OR REPLACE FUNCTION hash_distance18(bytea, bytea) RETURNS integer
CREATE OR REPLACE FUNCTION hash_distance8(bytea, bytea) RETURNS integer CREATE OR REPLACE FUNCTION hash_distance8(bytea, bytea) RETURNS integer
AS $LIB_PATH, 'hash_distance8' AS $LIB_PATH, 'hash_distance8'
LANGUAGE C STRICT; LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION hash_distance32(bytea, bytea) RETURNS integer
AS $LIB_PATH, 'hash_distance32'
LANGUAGE C STRICT;
CREATE OR REPLACE FUNCTION hash_is_within_distance18_any(bytea, bytea, integer) RETURNS bool CREATE OR REPLACE FUNCTION hash_is_within_distance18_any(bytea, bytea, integer) RETURNS bool
AS $LIB_PATH, 'hash_is_within_distance18_any' AS $LIB_PATH, 'hash_is_within_distance18_any'