@@ -147,9 +147,6 @@ struct TidStoreIter
147
147
TidStoreIterResult output ;
148
148
};
149
149
150
- static void tidstore_iter_extract_tids (TidStoreIter * iter , BlockNumber blkno ,
151
- BlocktableEntry * page );
152
-
153
150
/*
154
151
* Create a TidStore. The TidStore will live in the memory context that is
155
152
* CurrentMemoryContext at the time of this call. The TID storage, backed
@@ -486,13 +483,6 @@ TidStoreBeginIterate(TidStore *ts)
486
483
iter = palloc0 (sizeof (TidStoreIter ));
487
484
iter -> ts = ts ;
488
485
489
- /*
490
- * We start with an array large enough to contain at least the offsets
491
- * from one completely full bitmap element.
492
- */
493
- iter -> output .max_offset = 2 * BITS_PER_BITMAPWORD ;
494
- iter -> output .offsets = palloc (sizeof (OffsetNumber ) * iter -> output .max_offset );
495
-
496
486
if (TidStoreIsShared (ts ))
497
487
iter -> tree_iter .shared = shared_ts_begin_iterate (ts -> tree .shared );
498
488
else
@@ -503,9 +493,9 @@ TidStoreBeginIterate(TidStore *ts)
503
493
504
494
505
495
/*
506
- * Scan the TidStore and return the TIDs of the next block. The offsets in
507
- * each iteration result are ordered, as are the block numbers over all
508
- * iterations .
496
+ * Return a result that contains the next block number and that can be used to
497
+ * obtain the set of offsets by calling TidStoreGetBlockOffsets(). The result
498
+ * is copyable .
509
499
*/
510
500
TidStoreIterResult *
511
501
TidStoreIterateNext (TidStoreIter * iter )
@@ -521,8 +511,8 @@ TidStoreIterateNext(TidStoreIter *iter)
521
511
if (page == NULL )
522
512
return NULL ;
523
513
524
- /* Collect TIDs from the key-value pair */
525
- tidstore_iter_extract_tids ( iter , ( BlockNumber ) key , page ) ;
514
+ iter -> output . blkno = key ;
515
+ iter -> output . internal_page = page ;
526
516
527
517
return & (iter -> output );
528
518
}
@@ -540,7 +530,6 @@ TidStoreEndIterate(TidStoreIter *iter)
540
530
else
541
531
local_ts_end_iterate (iter -> tree_iter .local );
542
532
543
- pfree (iter -> output .offsets );
544
533
pfree (iter );
545
534
}
546
535
@@ -575,24 +564,32 @@ TidStoreGetHandle(TidStore *ts)
575
564
return (dsa_pointer ) shared_ts_get_handle (ts -> tree .shared );
576
565
}
577
566
578
- /* Extract TIDs from the given key-value pair */
579
- static void
580
- tidstore_iter_extract_tids (TidStoreIter * iter , BlockNumber blkno ,
581
- BlocktableEntry * page )
567
+ /*
568
+ * Given a TidStoreIterResult returned by TidStoreIterateNext(), extract the
569
+ * offset numbers. Returns the number of offsets filled in, if <=
570
+ * max_offsets. Otherwise, fills in as much as it can in the given space, and
571
+ * returns the size of the buffer that would be needed.
572
+ */
573
+ int
574
+ TidStoreGetBlockOffsets (TidStoreIterResult * result ,
575
+ OffsetNumber * offsets ,
576
+ int max_offsets )
582
577
{
583
- TidStoreIterResult * result = (& iter -> output );
578
+ BlocktableEntry * page = result -> internal_page ;
579
+ int num_offsets = 0 ;
584
580
int wordnum ;
585
581
586
- result -> num_offsets = 0 ;
587
- result -> blkno = blkno ;
588
-
589
582
if (page -> header .nwords == 0 )
590
583
{
591
584
/* we have offsets in the header */
592
585
for (int i = 0 ; i < NUM_FULL_OFFSETS ; i ++ )
593
586
{
594
587
if (page -> header .full_offsets [i ] != InvalidOffsetNumber )
595
- result -> offsets [result -> num_offsets ++ ] = page -> header .full_offsets [i ];
588
+ {
589
+ if (num_offsets < max_offsets )
590
+ offsets [num_offsets ] = page -> header .full_offsets [i ];
591
+ num_offsets ++ ;
592
+ }
596
593
}
597
594
}
598
595
else
@@ -602,21 +599,19 @@ tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
602
599
bitmapword w = page -> words [wordnum ];
603
600
int off = wordnum * BITS_PER_BITMAPWORD ;
604
601
605
- /* Make sure there is enough space to add offsets */
606
- if ((result -> num_offsets + BITS_PER_BITMAPWORD ) > result -> max_offset )
607
- {
608
- result -> max_offset *= 2 ;
609
- result -> offsets = repalloc (result -> offsets ,
610
- sizeof (OffsetNumber ) * result -> max_offset );
611
- }
612
-
613
602
while (w != 0 )
614
603
{
615
604
if (w & 1 )
616
- result -> offsets [result -> num_offsets ++ ] = (OffsetNumber ) off ;
605
+ {
606
+ if (num_offsets < max_offsets )
607
+ offsets [num_offsets ] = (OffsetNumber ) off ;
608
+ num_offsets ++ ;
609
+ }
617
610
off ++ ;
618
611
w >>= 1 ;
619
612
}
620
613
}
621
614
}
615
+
616
+ return num_offsets ;
622
617
}
0 commit comments