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

Commitde1f586

Browse files
committed
Fix a bug with building rtree_gist indexes.
Patch from Teodor Sigaev.
1 parenta71a530 commitde1f586

File tree

1 file changed

+65
-20
lines changed

1 file changed

+65
-20
lines changed

‎contrib/rtree_gist/rtree_gist.c

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
*$Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/rtree_gist.c,v 1.4 2001/10/25 05:49:20 momjian Exp $
10+
*$Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/rtree_gist.c,v 1.5 2002/05/28 15:24:53 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -161,6 +161,22 @@ gbox_penalty(PG_FUNCTION_ARGS)
161161
PG_RETURN_POINTER(result);
162162
}
163163

164+
typedefstruct {
165+
BOX*key;
166+
intpos;
167+
}KBsort;
168+
169+
staticint
170+
compare_KB(constvoid*a,constvoid*b) {
171+
BOX*abox= ((KBsort*)a)->key;
172+
BOX*bbox= ((KBsort*)b)->key;
173+
floatsa= (abox->high.x-abox->low.x)* (abox->high.y-abox->low.y);
174+
floatsb= (bbox->high.x-bbox->low.x)* (bbox->high.y-bbox->low.y);
175+
176+
if (sa==sb )return0;
177+
return (sa>sb ) ?1 :-1;
178+
}
179+
164180
/*
165181
** The GiST PickSplit method
166182
** New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree',
@@ -201,26 +217,22 @@ gbox_picksplit(PG_FUNCTION_ARGS)
201217
for (i=OffsetNumberNext(FirstOffsetNumber);i <=maxoff;i=OffsetNumberNext(i))
202218
{
203219
cur=DatumGetBoxP(((GISTENTRY*)VARDATA(entryvec))[i].key);
204-
if (pageunion.high.x<cur->high.x)
205-
{
220+
if (allisequal== true&& (
221+
pageunion.high.x!=cur->high.x||
222+
pageunion.high.y!=cur->high.y||
223+
pageunion.low.x!=cur->low.x||
224+
pageunion.low.y!=cur->low.y
225+
) )
206226
allisequal= false;
227+
228+
if (pageunion.high.x<cur->high.x)
207229
pageunion.high.x=cur->high.x;
208-
}
209230
if (pageunion.low.x>cur->low.x)
210-
{
211-
allisequal= false;
212231
pageunion.low.x=cur->low.x;
213-
}
214232
if (pageunion.high.y<cur->high.y)
215-
{
216-
allisequal= false;
217233
pageunion.high.y=cur->high.y;
218-
}
219234
if (pageunion.low.y>cur->low.y)
220-
{
221-
allisequal= false;
222235
pageunion.low.y=cur->low.y;
223-
}
224236
}
225237

226238
nbytes= (maxoff+2)*sizeof(OffsetNumber);
@@ -264,7 +276,7 @@ gbox_picksplit(PG_FUNCTION_ARGS)
264276
unionB= (BOX*)palloc(sizeof(BOX));
265277
unionT= (BOX*)palloc(sizeof(BOX));
266278

267-
#defineADDLIST(list,unionD,pos ) do { \
279+
#defineADDLIST(list,unionD,pos,num ) do { \
268280
if ( pos ) { \
269281
if ( unionD->high.x < cur->high.x ) unionD->high.x= cur->high.x; \
270282
if ( unionD->low.x> cur->low.x ) unionD->low.x= cur->low.x; \
@@ -273,25 +285,58 @@ gbox_picksplit(PG_FUNCTION_ARGS)
273285
} else { \
274286
memcpy( (void*)unionD, (void*) cur, sizeof( BOX ) ); \
275287
} \
276-
list[pos] =i; \
288+
list[pos] =num; \
277289
(pos)++; \
278290
} while(0)
279291

280292
for (i=FirstOffsetNumber;i <=maxoff;i=OffsetNumberNext(i))
281293
{
282294
cur=DatumGetBoxP(((GISTENTRY*)VARDATA(entryvec))[i].key);
283295
if (cur->low.x-pageunion.low.x<pageunion.high.x-cur->high.x)
284-
ADDLIST(listL,unionL,posL);
296+
ADDLIST(listL,unionL,posL,i);
285297
else
286-
ADDLIST(listR,unionR,posR);
298+
ADDLIST(listR,unionR,posR,i);
287299
if (cur->low.y-pageunion.low.y<pageunion.high.y-cur->high.y)
288-
ADDLIST(listB,unionB,posB);
300+
ADDLIST(listB,unionB,posB,i);
289301
else
290-
ADDLIST(listT,unionT,posT);
302+
ADDLIST(listT,unionT,posT,i);
291303
}
292304

293-
/* which split more optimal? */
305+
/* bad disposition, sort by ascending and resplit */
306+
if ( (posR==0||posL==0)&& (posT==0||posB==0) ) {
307+
KBsort*arr= (KBsort*)palloc(sizeof(KBsort)*maxoff );
308+
posL=posR=posB=posT=0;
309+
for (i=FirstOffsetNumber;i <=maxoff;i=OffsetNumberNext(i)) {
310+
arr[i-1].key=DatumGetBoxP(((GISTENTRY*)VARDATA(entryvec))[i].key);
311+
arr[i-1].pos=i;
312+
}
313+
qsort(arr,maxoff,sizeof(KBsort),compare_KB );
314+
for (i=FirstOffsetNumber;i <=maxoff;i=OffsetNumberNext(i)) {
315+
cur=arr[i-1].key;
316+
if (cur->low.x-pageunion.low.x<pageunion.high.x-cur->high.x)
317+
ADDLIST(listL,unionL,posL,arr[i-1].pos);
318+
elseif (cur->low.x-pageunion.low.x==pageunion.high.x-cur->high.x ) {
319+
if (posL>posR )
320+
ADDLIST(listR,unionR,posR,arr[i-1].pos);
321+
else
322+
ADDLIST(listL,unionL,posL,arr[i-1].pos);
323+
}else
324+
ADDLIST(listR,unionR,posR,arr[i-1].pos);
325+
326+
if (cur->low.y-pageunion.low.y<pageunion.high.y-cur->high.y)
327+
ADDLIST(listB,unionB,posB,arr[i-1].pos);
328+
elseif (cur->low.y-pageunion.low.y==pageunion.high.y-cur->high.y ) {
329+
if (posB>posT )
330+
ADDLIST(listT,unionT,posT,arr[i-1].pos);
331+
else
332+
ADDLIST(listB,unionB,posB,arr[i-1].pos);
333+
}else
334+
ADDLIST(listT,unionT,posT,arr[i-1].pos);
335+
}
336+
pfree(arr);
337+
}
294338

339+
/* which split more optimal? */
295340
if (Max(posL,posR)<Max(posB,posT))
296341
direction='x';
297342
elseif (Max(posL,posR)>Max(posB,posT))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp