Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7815e7e

Browse files
committed
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 whereappropriate.Author: Thomas MunroReviewed-by: Tom Lane (in an earlier version)Discussion:https://postgr.es/m/CAEepm%3D2vmFTNpAmwbGGD2WaryM6T3hSDVKQPfUwjdD_5XY6vAA%40mail.gmail.com
1 parent3feb6ac commit7815e7e

File tree

13 files changed

+115
-208
lines changed

13 files changed

+115
-208
lines changed

‎contrib/hstore/hstore_io.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen)
322322
}
323323

324324
qsort((void*)a,l,sizeof(Pairs),comparePairs);
325+
326+
/*
327+
* We can't use qunique here because we have some clean-up code to run on
328+
* removed elements.
329+
*/
325330
ptr=a+1;
326331
res=a;
327332
while (ptr-a<l)

‎contrib/intarray/_int_tool.c

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include"_int.h"
99
#include"catalog/pg_type.h"
10+
#include"lib/qunique.h"
1011

1112
/* arguments are assumed sorted & unique-ified */
1213
bool
@@ -308,23 +309,13 @@ internal_size(int *a, int len)
308309
ArrayType*
309310
_int_unique(ArrayType*r)
310311
{
311-
int*tmp,
312-
*dr,
313-
*data;
314312
intnum=ARRNELEMS(r);
313+
boolduplicates_found;/* not used */
315314

316-
if (num<2)
317-
returnr;
315+
num=qunique_arg(ARRPTR(r),num,sizeof(int),isort_cmp,
316+
&duplicates_found);
318317

319-
data=tmp=dr=ARRPTR(r);
320-
while (tmp-data<num)
321-
{
322-
if (*tmp!=*dr)
323-
*(++dr)=*tmp++;
324-
else
325-
tmp++;
326-
}
327-
returnresize_intArrayType(r,dr+1-ARRPTR(r));
318+
returnresize_intArrayType(r,num);
328319
}
329320

330321
void

‎contrib/pg_trgm/trgm_op.c

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include<ctype.h>
77

88
#include"catalog/pg_type.h"
9+
#include"lib/qunique.h"
910
#include"trgm.h"
1011
#include"tsearch/ts_locale.h"
1112
#include"utils/lsyscache.h"
@@ -162,26 +163,6 @@ comp_trgm(const void *a, const void *b)
162163
returnCMPTRGM(a,b);
163164
}
164165

165-
staticint
166-
unique_array(trgm*a,intlen)
167-
{
168-
trgm*curend,
169-
*tmp;
170-
171-
curend=tmp=a;
172-
while (tmp-a<len)
173-
if (CMPTRGM(tmp,curend))
174-
{
175-
curend++;
176-
CPTRGM(curend,tmp);
177-
tmp++;
178-
}
179-
else
180-
tmp++;
181-
182-
returncurend+1-a;
183-
}
184-
185166
/*
186167
* Finds first word in string, returns pointer to the word,
187168
* endword points to the character after word
@@ -394,7 +375,7 @@ generate_trgm(char *str, int slen)
394375
if (len>1)
395376
{
396377
qsort((void*)GETARR(trg),len,sizeof(trgm),comp_trgm);
397-
len=unique_array(GETARR(trg),len);
378+
len=qunique(GETARR(trg),len,sizeof(trgm),comp_trgm);
398379
}
399380

400381
SET_VARSIZE(trg,CALCGTSIZE(ARRKEY,len));
@@ -942,7 +923,7 @@ generate_wildcard_trgm(const char *str, int slen)
942923
if (len>1)
943924
{
944925
qsort((void*)GETARR(trg),len,sizeof(trgm),comp_trgm);
945-
len=unique_array(GETARR(trg),len);
926+
len=qunique(GETARR(trg),len,sizeof(trgm),comp_trgm);
946927
}
947928

948929
SET_VARSIZE(trg,CALCGTSIZE(ARRKEY,len));

‎src/backend/access/nbtree/nbtutils.c

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include"access/reloptions.h"
2222
#include"access/relscan.h"
2323
#include"commands/progress.h"
24+
#include"lib/qunique.h"
2425
#include"miscadmin.h"
2526
#include"utils/array.h"
2627
#include"utils/datum.h"
@@ -435,8 +436,6 @@ _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey,
435436
Oidelemtype;
436437
RegProcedurecmp_proc;
437438
BTSortArrayContextcxt;
438-
intlast_non_dup;
439-
inti;
440439

441440
if (nelems <=1)
442441
returnnelems;/* no work to do */
@@ -475,20 +474,8 @@ _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey,
475474
_bt_compare_array_elements, (void*)&cxt);
476475

477476
/* Now scan the sorted elements and remove duplicates */
478-
last_non_dup=0;
479-
for (i=1;i<nelems;i++)
480-
{
481-
int32compare;
482-
483-
compare=DatumGetInt32(FunctionCall2Coll(&cxt.flinfo,
484-
cxt.collation,
485-
elems[last_non_dup],
486-
elems[i]));
487-
if (compare!=0)
488-
elems[++last_non_dup]=elems[i];
489-
}
490-
491-
returnlast_non_dup+1;
477+
returnqunique_arg(elems,nelems,sizeof(Datum),
478+
_bt_compare_array_elements,&cxt);
492479
}
493480

494481
/*

‎src/backend/executor/nodeTidscan.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include"catalog/pg_type.h"
2828
#include"executor/execdebug.h"
2929
#include"executor/nodeTidscan.h"
30+
#include"lib/qunique.h"
3031
#include"miscadmin.h"
3132
#include"nodes/nodeFuncs.h"
3233
#include"storage/bufmgr.h"
@@ -260,21 +261,13 @@ TidListEval(TidScanState *tidstate)
260261
*/
261262
if (numTids>1)
262263
{
263-
intlastTid;
264-
inti;
265-
266264
/* CurrentOfExpr could never appear OR'd with something else */
267265
Assert(!tidstate->tss_isCurrentOf);
268266

269267
qsort((void*)tidList,numTids,sizeof(ItemPointerData),
270268
itemptr_comparator);
271-
lastTid=0;
272-
for (i=1;i<numTids;i++)
273-
{
274-
if (!ItemPointerEquals(&tidList[lastTid],&tidList[i]))
275-
tidList[++lastTid]=tidList[i];
276-
}
277-
numTids=lastTid+1;
269+
numTids=qunique(tidList,numTids,sizeof(ItemPointerData),
270+
itemptr_comparator);
278271
}
279272

280273
tidstate->tss_TidList=tidList;

‎src/backend/utils/adt/acl.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include"commands/tablespace.h"
2929
#include"foreign/foreign.h"
3030
#include"funcapi.h"
31+
#include"lib/qunique.h"
3132
#include"miscadmin.h"
3233
#include"utils/acl.h"
3334
#include"utils/array.h"
@@ -1475,8 +1476,7 @@ aclmembers(const Acl *acl, Oid **roleids)
14751476
Oid*list;
14761477
constAclItem*acldat;
14771478
inti,
1478-
j,
1479-
k;
1479+
j;
14801480

14811481
if (acl==NULL||ACL_NUM(acl)==0)
14821482
{
@@ -1508,21 +1508,14 @@ aclmembers(const Acl *acl, Oid **roleids)
15081508
/* Sort the array */
15091509
qsort(list,j,sizeof(Oid),oid_cmp);
15101510

1511-
/* Remove duplicates from the array */
1512-
k=0;
1513-
for (i=1;i<j;i++)
1514-
{
1515-
if (list[k]!=list[i])
1516-
list[++k]=list[i];
1517-
}
1518-
15191511
/*
15201512
* We could repalloc the array down to minimum size, but it's hardly worth
15211513
* it since it's only transient memory.
15221514
*/
15231515
*roleids=list;
15241516

1525-
returnk+1;
1517+
/* Remove duplicates from the array */
1518+
returnqunique(list,j,sizeof(Oid),oid_cmp);
15261519
}
15271520

15281521

‎src/backend/utils/adt/tsgistidx.c

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include"access/gist.h"
1818
#include"access/heaptoast.h"
19+
#include"lib/qunique.h"
1920
#include"port/pg_bitutils.h"
2021
#include"tsearch/ts_utils.h"
2122
#include"utils/builtins.h"
@@ -122,31 +123,6 @@ compareint(const void *va, const void *vb)
122123
return (a>b) ?1 :-1;
123124
}
124125

125-
/*
126-
* Removes duplicates from an array of int32. 'l' is
127-
* size of the input array. Returns the new size of the array.
128-
*/
129-
staticint
130-
uniqueint(int32*a,int32l)
131-
{
132-
int32*ptr,
133-
*res;
134-
135-
if (l <=1)
136-
returnl;
137-
138-
ptr=res=a;
139-
140-
qsort((void*)a,l,sizeof(int32),compareint);
141-
142-
while (ptr-a<l)
143-
if (*ptr!=*res)
144-
*(++res)=*ptr++;
145-
else
146-
ptr++;
147-
returnres+1-a;
148-
}
149-
150126
staticvoid
151127
makesign(BITVECPsign,SignTSVector*a)
152128
{
@@ -193,7 +169,8 @@ gtsvector_compress(PG_FUNCTION_ARGS)
193169
ptr++;
194170
}
195171

196-
len=uniqueint(GETARR(res),val->size);
172+
qsort(GETARR(res),val->size,sizeof(int),compareint);
173+
len=qunique(GETARR(res),val->size,sizeof(int),compareint);
197174
if (len!=val->size)
198175
{
199176
/*

‎src/backend/utils/adt/tsquery_op.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include"postgres.h"
1616

17+
#include"lib/qunique.h"
1718
#include"tsearch/ts_utils.h"
1819
#include"utils/builtins.h"
1920

@@ -302,29 +303,6 @@ cmp_string(const void *a, const void *b)
302303
returnstrcmp(sa,sb);
303304
}
304305

305-
staticint
306-
remove_duplicates(char**strings,intn)
307-
{
308-
if (n <=1)
309-
returnn;
310-
else
311-
{
312-
inti;
313-
char*prev=strings[0];
314-
intnew_n=1;
315-
316-
for (i=1;i<n;i++)
317-
{
318-
if (strcmp(strings[i],prev)!=0)
319-
{
320-
strings[new_n++]=strings[i];
321-
prev=strings[i];
322-
}
323-
}
324-
returnnew_n;
325-
}
326-
}
327-
328306
Datum
329307
tsq_mcontains(PG_FUNCTION_ARGS)
330308
{
@@ -342,9 +320,10 @@ tsq_mcontains(PG_FUNCTION_ARGS)
342320

343321
/* Sort and remove duplicates from both arrays */
344322
qsort(query_values,query_nvalues,sizeof(char*),cmp_string);
345-
query_nvalues=remove_duplicates(query_values,query_nvalues);
323+
query_nvalues=qunique(query_values,query_nvalues,sizeof(char*),
324+
cmp_string);
346325
qsort(ex_values,ex_nvalues,sizeof(char*),cmp_string);
347-
ex_nvalues=remove_duplicates(ex_values,ex_nvalues);
326+
ex_nvalues=qunique(ex_values,ex_nvalues,sizeof(char*),cmp_string);
348327

349328
if (ex_nvalues>query_nvalues)
350329
result= false;

‎src/backend/utils/adt/tsvector.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ compareWordEntryPos(const void *a, const void *b)
4141
}
4242

4343
/*
44-
* Removes duplicate pos entries. If there's two entries with same pos
45-
* but different weight, the higher weight is retained.
44+
* Removes duplicate pos entries. If there's two entries with same pos but
45+
* different weight, the higher weight is retained, so we can't use
46+
* qunique here.
4647
*
4748
* Returns new length.
4849
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp