diff --git a/src/test/modules/test_popcount/Makefile b/src/test/modules/test_popcount/Makefile new file mode 100644 index 0000000000..8a49d1ccfc --- /dev/null +++ b/src/test/modules/test_popcount/Makefile @@ -0,0 +1,21 @@ +MODULE_big = test_popcount +OBJS = test_popcount.o +PGFILEDESC = "test" +EXTENSION = test_popcount +DATA = test_popcount--1.0.sql + +first: all + +# needed? +test_popcount.o: test_popcount.c + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_popcount +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_popcount/test_popcount--1.0.sql b/src/test/modules/test_popcount/test_popcount--1.0.sql new file mode 100644 index 0000000000..a5975e54cd --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount--1.0.sql @@ -0,0 +1,2 @@ +CREATE FUNCTION drive_popcount (count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C; +CREATE FUNCTION drive_popcount64(count int, num int) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_popcount/test_popcount.c b/src/test/modules/test_popcount/test_popcount.c new file mode 100644 index 0000000000..0030ed142f --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount.c @@ -0,0 +1,71 @@ +/* select drive_popcount(1000000, 1024); */ + +#include "postgres.h" + +#include "fmgr.h" + +#include "port/pg_bitutils.h" + +PG_MODULE_MAGIC; + +#ifndef PG_POPCOUNT64 +#define PG_POPCOUNT32(word) pg_popcount32(word) +#define PG_POPCOUNT64(word) pg_popcount64(word) +#endif + + +/* + * drive_popcount64(count int, num int) returns bigint + * + * num is the number of 64-bit words to use + */ +PG_FUNCTION_INFO_V1(drive_popcount64); +Datum +drive_popcount64(PG_FUNCTION_ARGS) +{ + + int count = PG_GETARG_INT32(0); + int num = PG_GETARG_INT32(1); + + int len = num * sizeof(uint64); + uint64 *words = palloc(len); + int64 popcount; + + for (int i = 0; i < num; i++) + words[i] = i; + + while (count--) + { + popcount = 0; + for (int i = 0; i < num; i++) + popcount += PG_POPCOUNT64(words[i]); + } + + PG_RETURN_INT64(popcount); +} + +/* + * drive_popcount(count int, len int) returns bigint + * + * num is the number of 64-bit words to use + */ +PG_FUNCTION_INFO_V1(drive_popcount); +Datum +drive_popcount(PG_FUNCTION_ARGS) +{ + + int count = PG_GETARG_INT32(0); + int num = PG_GETARG_INT32(1); + + int len = num * sizeof(uint64); + uint64 *words = palloc(len); + int64 popcount; + + for (int i = 0; i < num; i++) + words[i] = i; + + while (count--) + popcount = pg_popcount((const char*) words, len); + + PG_RETURN_INT64(popcount); +} diff --git a/src/test/modules/test_popcount/test_popcount.control b/src/test/modules/test_popcount/test_popcount.control new file mode 100644 index 0000000000..6837d724b4 --- /dev/null +++ b/src/test/modules/test_popcount/test_popcount.control @@ -0,0 +1,4 @@ +comment = 'test' +default_version = '1.0' +module_pathname = '$libdir/test_popcount' +relocatable = true