35
35
* Portions Copyright (c) 1994, Regents of the University of California
36
36
*
37
37
* IDENTIFICATION
38
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.56 2000/07/21 22:14:09 tgl Exp $
38
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.57 2000/08/10 02:33:20 inoue Exp $
39
39
*
40
40
*-------------------------------------------------------------------------
41
41
*/
@@ -95,7 +95,7 @@ static void _bt_sortaddtup(Page page, Size itemsize,
95
95
BTItem btitem , OffsetNumber itup_off );
96
96
static void _bt_buildadd (Relation index , BTPageState * state , BTItem bti );
97
97
static void _bt_uppershutdown (Relation index , BTPageState * state );
98
- static void _bt_load (Relation index , BTSpool * btspool );
98
+ static void _bt_load (Relation index , BTSpool * btspool , BTSpool * btspool2 );
99
99
100
100
101
101
/*
@@ -153,7 +153,7 @@ _bt_spool(BTItem btitem, BTSpool *btspool)
153
153
* create an entire btree.
154
154
*/
155
155
void
156
- _bt_leafbuild (BTSpool * btspool )
156
+ _bt_leafbuild (BTSpool * btspool , BTSpool * btspool2 )
157
157
{
158
158
#ifdef BTREE_BUILD_STATS
159
159
if (Show_btree_build_stats )
@@ -165,7 +165,9 @@ _bt_leafbuild(BTSpool *btspool)
165
165
#endif /* BTREE_BUILD_STATS */
166
166
tuplesort_performsort (btspool -> sortstate );
167
167
168
- _bt_load (btspool -> index , btspool );
168
+ if (btspool2 )
169
+ tuplesort_performsort (btspool2 -> sortstate );
170
+ _bt_load (btspool -> index , btspool , btspool2 );
169
171
}
170
172
171
173
@@ -523,28 +525,106 @@ _bt_uppershutdown(Relation index, BTPageState *state)
523
525
* btree leaves.
524
526
*/
525
527
static void
526
- _bt_load (Relation index , BTSpool * btspool )
528
+ _bt_load (Relation index , BTSpool * btspool , BTSpool * btspool2 )
527
529
{
528
530
BTPageState * state = NULL ;
529
-
530
- for (;;)
531
+ bool merge = (btspool2 != NULL );
532
+ BTItem bti , bti2 = NULL ;
533
+ bool should_free , should_free2 , load1 ;
534
+ TupleDesc tupdes = RelationGetDescr (index );
535
+ int i , keysz = RelationGetNumberOfAttributes (index );
536
+ ScanKey indexScanKey = NULL ;
537
+
538
+ if (merge )
531
539
{
532
- BTItem bti ;
533
- bool should_free ;
534
-
535
- bti = (BTItem ) tuplesort_getindextuple (btspool -> sortstate , true,
536
- & should_free );
537
- if (bti == (BTItem ) NULL )
538
- break ;
539
-
540
- /* When we see first tuple, create first index page */
541
- if (state == NULL )
542
- state = _bt_pagestate (index , BTP_LEAF , 0 );
543
-
544
- _bt_buildadd (index , state , bti );
540
+ /*
541
+ * Another BTSpool for dead tuples exists.
542
+ * Now we have to merge btspool and btspool2.
543
+ */
544
+ ScanKey entry ;
545
+ Datum attrDatum1 , attrDatum2 ;
546
+ bool isFirstNull , isSecondNull ;
547
+ int32 compare ;
548
+
549
+ /* the preparation of merge */
550
+ bti = (BTItem ) tuplesort_getindextuple (btspool -> sortstate , true, & should_free );
551
+ bti2 = (BTItem ) tuplesort_getindextuple (btspool2 -> sortstate , true, & should_free2 );
552
+ indexScanKey = _bt_mkscankey_nodata (index );
553
+ for (;;)
554
+ {
555
+ load1 = true; /* load BTSpool next ? */
556
+ if (NULL == bti2 )
557
+ {
558
+ if (NULL == bti )
559
+ break ;
560
+ }
561
+ else if (NULL != bti )
562
+ {
563
+
564
+ for (i = 1 ; i <= keysz ; i ++ )
565
+ {
566
+ entry = indexScanKey + i - 1 ;
567
+ attrDatum1 = index_getattr ((IndexTuple )bti , i , tupdes , & isFirstNull );
568
+ attrDatum2 = index_getattr ((IndexTuple )bti2 , i , tupdes , & isSecondNull );
569
+ if (isFirstNull )
570
+ {
571
+ if (!isSecondNull )
572
+ {
573
+ load1 = false;
574
+ break ;
575
+ }
576
+ }
577
+ else if (isSecondNull )
578
+ break ;
579
+ else
580
+ {
581
+ compare = DatumGetInt32 (FunctionCall2 (& entry -> sk_func , attrDatum1 , attrDatum2 ));
582
+ if (compare > 0 )
583
+ {
584
+ load1 = false;
585
+ break ;
586
+ }
587
+ else if (compare < 0 )
588
+ break ;
589
+ }
590
+ }
591
+ }
592
+ else
593
+ load1 = false;
594
+
595
+ /* When we see first tuple, create first index page */
596
+ if (state == NULL )
597
+ state = _bt_pagestate (index , BTP_LEAF , 0 );
598
+
599
+ if (load1 )
600
+ {
601
+ _bt_buildadd (index , state , bti );
602
+ if (should_free )
603
+ pfree ((void * ) bti );
604
+ bti = (BTItem ) tuplesort_getindextuple (btspool -> sortstate , true, & should_free );
605
+ }
606
+ else
607
+ {
608
+ _bt_buildadd (index , state , bti2 );
609
+ if (should_free2 )
610
+ pfree ((void * ) bti2 );
611
+ bti2 = (BTItem ) tuplesort_getindextuple (btspool2 -> sortstate , true, & should_free2 );
612
+ }
613
+ }
614
+ _bt_freeskey (indexScanKey );
615
+ }
616
+ else /* merge is unnecessary */
617
+ {
618
+ while (bti = (BTItem ) tuplesort_getindextuple (btspool -> sortstate , true, & should_free ), bti != (BTItem ) NULL )
619
+ {
620
+ /* When we see first tuple, create first index page */
621
+ if (state == NULL )
622
+ state = _bt_pagestate (index , BTP_LEAF , 0 );
545
623
546
- if (should_free )
547
- pfree ((void * ) bti );
624
+ _bt_buildadd (index , state , bti );
625
+ if (should_free )
626
+ pfree ((void * ) bti );
627
+ }
548
628
}
549
629
550
630
/* Close down final pages, if we had any data at all */
0 commit comments