summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorThomas Munro2019-11-07 03:51:04 +0000
committerThomas Munro2019-11-07 04:00:48 +0000
commit7815e7efdb4ce9575b5d8460beb0dd2569d7ca3a (patch)
treedc3d1795259ab8c2dafc371cbd89725b43abc2da /contrib
parent3feb6ace7cfe8edbf6db702de06dc9295f307a8e (diff)
Add reusable routine for making arrays unique.
Introduce qunique() and qunique_arg(), which can be used after qsort() and qsort_arg() respectively to remove duplicate values. Use it where appropriate. Author: Thomas Munro Reviewed-by: Tom Lane (in an earlier version) Discussion: https://postgr.es/m/CAEepm%3D2vmFTNpAmwbGGD2WaryM6T3hSDVKQPfUwjdD_5XY6vAA%40mail.gmail.com
Diffstat (limited to 'contrib')
-rw-r--r--contrib/hstore/hstore_io.c5
-rw-r--r--contrib/intarray/_int_tool.c19
-rw-r--r--contrib/pg_trgm/trgm_op.c25
3 files changed, 13 insertions, 36 deletions
diff --git a/contrib/hstore/hstore_io.c b/contrib/hstore/hstore_io.c
index be3cce4f740..10ec392775e 100644
--- a/contrib/hstore/hstore_io.c
+++ b/contrib/hstore/hstore_io.c
@@ -322,6 +322,11 @@ hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
}
qsort((void *) a, l, sizeof(Pairs), comparePairs);
+
+ /*
+ * We can't use qunique here because we have some clean-up code to run on
+ * removed elements.
+ */
ptr = a + 1;
res = a;
while (ptr - a < l)
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index efff81d77dc..e5f4bd40643 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -7,6 +7,7 @@
#include "_int.h"
#include "catalog/pg_type.h"
+#include "lib/qunique.h"
/* arguments are assumed sorted & unique-ified */
bool
@@ -308,23 +309,13 @@ internal_size(int *a, int len)
ArrayType *
_int_unique(ArrayType *r)
{
- int *tmp,
- *dr,
- *data;
int num = ARRNELEMS(r);
+ bool duplicates_found; /* not used */
- if (num < 2)
- return r;
+ num = qunique_arg(ARRPTR(r), num, sizeof(int), isort_cmp,
+ &duplicates_found);
- data = tmp = dr = ARRPTR(r);
- while (tmp - data < num)
- {
- if (*tmp != *dr)
- *(++dr) = *tmp++;
- else
- tmp++;
- }
- return resize_intArrayType(r, dr + 1 - ARRPTR(r));
+ return resize_intArrayType(r, num);
}
void
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index 07a31803786..c9c8cbc7342 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -6,6 +6,7 @@
#include <ctype.h>
#include "catalog/pg_type.h"
+#include "lib/qunique.h"
#include "trgm.h"
#include "tsearch/ts_locale.h"
#include "utils/lsyscache.h"
@@ -162,26 +163,6 @@ comp_trgm(const void *a, const void *b)
return CMPTRGM(a, b);
}
-static int
-unique_array(trgm *a, int len)
-{
- trgm *curend,
- *tmp;
-
- curend = tmp = a;
- while (tmp - a < len)
- if (CMPTRGM(tmp, curend))
- {
- curend++;
- CPTRGM(curend, tmp);
- tmp++;
- }
- else
- tmp++;
-
- return curend + 1 - a;
-}
-
/*
* Finds first word in string, returns pointer to the word,
* endword points to the character after word
@@ -394,7 +375,7 @@ generate_trgm(char *str, int slen)
if (len > 1)
{
qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
- len = unique_array(GETARR(trg), len);
+ len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
}
SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));
@@ -942,7 +923,7 @@ generate_wildcard_trgm(const char *str, int slen)
if (len > 1)
{
qsort((void *) GETARR(trg), len, sizeof(trgm), comp_trgm);
- len = unique_array(GETARR(trg), len);
+ len = qunique(GETARR(trg), len, sizeof(trgm), comp_trgm);
}
SET_VARSIZE(trg, CALCGTSIZE(ARRKEY, len));