index 0b4f2ebadb6c85216786f1c55acf198faa1d020a..e8e0eab655213c47c2e490ea176d266bd4b5e33a 100644 (file)
if (entry->matchBitmap)
{
if (entry->matchIterator)
- tbm_end_iterate(entry->matchIterator);
+ tbm_end_private_iterate(entry->matchIterator);
entry->matchIterator = NULL;
tbm_free(entry->matchBitmap);
entry->matchBitmap = NULL;
if (entry->matchBitmap && !tbm_is_empty(entry->matchBitmap))
{
- entry->matchIterator = tbm_begin_iterate(entry->matchBitmap);
+ entry->matchIterator =
+ tbm_begin_private_iterate(entry->matchBitmap);
entry->isFinished = false;
}
}
@@ -832,12 +833,13 @@ entryGetItem(GinState *ginstate, GinScanEntry entry,
(ItemPointerIsLossyPage(&advancePast) &&
entry->matchResult->blockno == advancePastBlk))
{
- entry->matchResult = tbm_iterate(entry->matchIterator);
+ entry->matchResult =
+ tbm_private_iterate(entry->matchIterator);
if (entry->matchResult == NULL)
{
ItemPointerSetInvalid(&entry->curItem);
- tbm_end_iterate(entry->matchIterator);
+ tbm_end_private_iterate(entry->matchIterator);
entry->matchIterator = NULL;
entry->isFinished = true;
break;
index f2fd62afbbfd91c8d512d58ccc1172f7088ad9e4..2c6631c914d974fbd2b4f8011e3a14ab39769c43 100644 (file)
if (entry->list)
pfree(entry->list);
if (entry->matchIterator)
- tbm_end_iterate(entry->matchIterator);
+ tbm_end_private_iterate(entry->matchIterator);
if (entry->matchBitmap)
tbm_free(entry->matchBitmap);
}
index 689773ff2397a615597bc5c2b95877d64ecc0378..adf968df42bae93e6d89985c8d7ddcf13c52b79c 100644 (file)
@@ -2138,7 +2138,7 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
if (scan->st.bitmap.rs_shared_iterator)
tbmres = tbm_shared_iterate(scan->st.bitmap.rs_shared_iterator);
else
- tbmres = tbm_iterate(scan->st.bitmap.rs_iterator);
+ tbmres = tbm_private_iterate(scan->st.bitmap.rs_iterator);
if (tbmres == NULL)
return false;
index 689bde16dd2c17e1f7c38ff924243f3b01c50455..d9e7a516a078cd8a1f257fca8f2cffef10f95422 100644 (file)
@@ -95,7 +95,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
*/
if (!node->initialized)
{
- TBMIterator *tbmiterator = NULL;
+ TBMPrivateIterator *tbmiterator = NULL;
TBMSharedIterator *shared_tbmiterator = NULL;
if (!pstate)
elog(ERROR, "unrecognized result from subplan");
node->tbm = tbm;
- tbmiterator = tbm_begin_iterate(tbm);
+ tbmiterator = tbm_begin_private_iterate(tbm);
#ifdef USE_PREFETCH
if (node->prefetch_maximum > 0)
{
- node->prefetch_iterator = tbm_begin_iterate(tbm);
+ node->prefetch_iterator = tbm_begin_private_iterate(tbm);
node->prefetch_pages = 0;
node->prefetch_target = -1;
}
@@ -332,7 +332,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
if (pstate == NULL)
{
- TBMIterator *prefetch_iterator = node->prefetch_iterator;
+ TBMPrivateIterator *prefetch_iterator = node->prefetch_iterator;
if (node->prefetch_pages > 0)
{
@@ -341,7 +341,7 @@ BitmapAdjustPrefetchIterator(BitmapHeapScanState *node)
}
else if (prefetch_iterator)
{
- tbmpre = tbm_iterate(prefetch_iterator);
+ tbmpre = tbm_private_iterate(prefetch_iterator);
node->prefetch_blockno = tbmpre ? tbmpre->blockno :
InvalidBlockNumber;
}
@@ -446,19 +446,20 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
if (pstate == NULL)
{
- TBMIterator *prefetch_iterator = node->prefetch_iterator;
+ TBMPrivateIterator *prefetch_iterator = node->prefetch_iterator;
if (prefetch_iterator)
{
while (node->prefetch_pages < node->prefetch_target)
{
- TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
+ TBMIterateResult *tbmpre;
bool skip_fetch;
+ tbmpre = tbm_private_iterate(prefetch_iterator);
if (tbmpre == NULL)
{
/* No more pages to prefetch */
- tbm_end_iterate(prefetch_iterator);
+ tbm_end_private_iterate(prefetch_iterator);
node->prefetch_iterator = NULL;
break;
}
@@ -594,7 +595,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
if (scan->st.bitmap.rs_iterator)
{
- tbm_end_iterate(scan->st.bitmap.rs_iterator);
+ tbm_end_private_iterate(scan->st.bitmap.rs_iterator);
scan->st.bitmap.rs_iterator = NULL;
}
@@ -604,7 +605,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
/* release bitmaps and buffers if any */
if (node->prefetch_iterator)
- tbm_end_iterate(node->prefetch_iterator);
+ tbm_end_private_iterate(node->prefetch_iterator);
if (node->shared_prefetch_iterator)
tbm_end_shared_iterate(node->shared_prefetch_iterator);
if (node->tbm)
@@ -685,7 +686,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
if (scanDesc->st.bitmap.rs_iterator)
{
- tbm_end_iterate(scanDesc->st.bitmap.rs_iterator);
+ tbm_end_private_iterate(scanDesc->st.bitmap.rs_iterator);
scanDesc->st.bitmap.rs_iterator = NULL;
}
@@ -699,7 +700,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
* release bitmaps and buffers if any
*/
if (node->prefetch_iterator)
- tbm_end_iterate(node->prefetch_iterator);
+ tbm_end_private_iterate(node->prefetch_iterator);
if (node->tbm)
tbm_free(node->tbm);
if (node->shared_prefetch_iterator)
index e8ab5d78fcc7ceaa2d3f4a32681fdcb74ec7d47c..687d6f1763632820a136a0f151324bb7aea5b426 100644 (file)
};
/*
- * When iterating over a bitmap in sorted order, a TBMIterator is used to
- * track our progress. There can be several iterators scanning the same
- * bitmap concurrently. Note that the bitmap becomes read-only as soon as
- * any iterator is created.
+ * When iterating over a backend-local bitmap in sorted order, a
+ * TBMPrivateIterator is used to track our progress. There can be several
+ * iterators scanning the same bitmap concurrently. Note that the bitmap
+ * becomes read-only as soon as any iterator is created.
*/
-struct TBMIterator
+struct TBMPrivateIterator
{
TIDBitmap *tbm; /* TIDBitmap we're iterating over */
int spageptr; /* next spages index */
} PTIterationArray;
/*
- * same as TBMIterator, but it is used for joint iteration, therefore this
- * also holds a reference to the shared state.
+ * same as TBMPrivateIterator, but it is used for joint iteration, therefore
+ * this also holds a reference to the shared state.
*/
struct TBMSharedIterator
{
}
/*
- * tbm_begin_iterate - prepare to iterate through a TIDBitmap
+ * tbm_begin_private_iterate - prepare to iterate through a TIDBitmap
*
- * The TBMIterator struct is created in the caller's memory context.
- * For a clean shutdown of the iteration, call tbm_end_iterate; but it's
- * okay to just allow the memory context to be released, too. It is caller's
- * responsibility not to touch the TBMIterator anymore once the TIDBitmap
- * is freed.
+ * The TBMPrivateIterator struct is created in the caller's memory context.
+ * For a clean shutdown of the iteration, call tbm_end_private_iterate; but
+ * it's okay to just allow the memory context to be released, too. It is
+ * caller's responsibility not to touch the TBMPrivateIterator anymore once
+ * the TIDBitmap is freed.
*
* NB: after this is called, it is no longer allowed to modify the contents
* of the bitmap. However, you can call this multiple times to scan the
* contents repeatedly, including parallel scans.
*/
-TBMIterator *
-tbm_begin_iterate(TIDBitmap *tbm)
+TBMPrivateIterator *
+tbm_begin_private_iterate(TIDBitmap *tbm)
{
- TBMIterator *iterator;
+ TBMPrivateIterator *iterator;
Assert(tbm->iterating != TBM_ITERATING_SHARED);
/*
- * Create the TBMIterator struct, with enough trailing space to serve the
- * needs of the TBMIterateResult sub-struct.
+ * Create the TBMPrivateIterator struct, with enough trailing space to
+ * serve the needs of the TBMIterateResult sub-struct.
*/
- iterator = (TBMIterator *) palloc(sizeof(TBMIterator) +
- MAX_TUPLES_PER_PAGE * sizeof(OffsetNumber));
+ iterator = (TBMPrivateIterator *) palloc(sizeof(TBMPrivateIterator) +
+ MAX_TUPLES_PER_PAGE *
+ sizeof(OffsetNumber));
iterator->tbm = tbm;
/*
@@ -878,7 +879,7 @@ tbm_prepare_shared_iterate(TIDBitmap *tbm)
ptchunks = dsa_get_address(tbm->dsa, tbm->ptchunks);
/*
- * For every shared iterator, referring to pagetable and iterator array,
+ * For every shared iterator referring to pagetable and iterator array,
* increase the refcount by 1 so that while freeing the shared iterator we
* don't free pagetable and iterator array until its refcount becomes 0.
*/
@@ -956,7 +957,7 @@ tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp)
}
/*
- * tbm_iterate - scan through next page of a TIDBitmap
+ * tbm_private_iterate - scan through next page of a TIDBitmap
*
* Returns a TBMIterateResult representing one page, or NULL if there are
* no more pages to scan. Pages are guaranteed to be delivered in numerical
@@ -968,7 +969,7 @@ tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp)
* testing, recheck is always set true when ntuples < 0.)
*/
TBMIterateResult *
-tbm_iterate(TBMIterator *iterator)
+tbm_private_iterate(TBMPrivateIterator *iterator)
{
TIDBitmap *tbm = iterator->tbm;
TBMIterateResult *output = &(iterator->output);
}
/*
- * tbm_end_iterate - finish an iteration over a TIDBitmap
+ * tbm_end_private_iterate - finish an iteration over a TIDBitmap
*
* Currently this is just a pfree, but it might do more someday. (For
* instance, it could be useful to count open iterators and allow the
* bitmap to return to read/write status when there are no more iterators.)
*/
void
-tbm_end_iterate(TBMIterator *iterator)
+tbm_end_private_iterate(TBMPrivateIterator *iterator)
{
pfree(iterator);
}
return nbuckets;
}
+
+/*
+ * Create a shared or private bitmap iterator and start iteration.
+ *
+ * `tbm` is only used to create the private iterator and dsa and dsp are only
+ * used to create the shared iterator.
+ *
+ * Before invoking tbm_begin_iterate() to create a shared iterator, one
+ * process must already have invoked tbm_prepare_shared_iterate() to create
+ * and set up the TBMSharedIteratorState.
+ */
+TBMIterator
+tbm_begin_iterate(TIDBitmap *tbm, dsa_area *dsa, dsa_pointer dsp)
+{
+ TBMIterator iterator = {0};
+
+ /* Allocate a private iterator and attach the shared state to it */
+ if (DsaPointerIsValid(dsp))
+ {
+ iterator.shared = true;
+ iterator.i.shared_iterator = tbm_attach_shared_iterate(dsa, dsp);
+ }
+ else
+ {
+ iterator.shared = false;
+ iterator.i.private_iterator = tbm_begin_private_iterate(tbm);
+ }
+
+ return iterator;
+}
+
+/*
+ * Clean up shared or private bitmap iterator.
+ */
+void
+tbm_end_iterate(TBMIterator *iterator)
+{
+ Assert(iterator);
+
+ if (iterator->shared)
+ tbm_end_shared_iterate(iterator->i.shared_iterator);
+ else
+ tbm_end_private_iterate(iterator->i.private_iterator);
+
+ *iterator = (TBMIterator)
+ {
+ 0
+ };
+}
+
+/*
+ * Get the next TBMIterateResult from the shared or private bitmap iterator.
+ */
+TBMIterateResult *
+tbm_iterate(TBMIterator *iterator)
+{
+ Assert(iterator);
+
+ if (iterator->shared)
+ return tbm_shared_iterate(iterator->i.shared_iterator);
+ else
+ return tbm_private_iterate(iterator->i.private_iterator);
+}
index 3013a44bae1c2c506153876e11ec202bfc7a5a15..788005093677535bd8222752fe1243efead63916 100644 (file)
/* for a partial-match or full-scan query, we accumulate all TIDs here */
TIDBitmap *matchBitmap;
- TBMIterator *matchIterator;
+ TBMPrivateIterator *matchIterator;
TBMIterateResult *matchResult;
/* used for Posting list and one page in Posting tree */
index e1884acf493cc4ce3041e3b2527d38d6ca87add4..153561addc0fe6e10fd135b90e85a23a0e59699d 100644 (file)
struct ParallelTableScanDescData;
-struct TBMIterator;
+struct TBMPrivateIterator;
struct TBMSharedIterator;
/*
@@ -48,7 +48,7 @@ typedef struct TableScanDescData
/* Iterators for Bitmap Table Scans */
struct
{
- struct TBMIterator *rs_iterator;
+ struct TBMPrivateIterator *rs_iterator;
struct TBMSharedIterator *rs_shared_iterator;
} bitmap;
index 7f71b7625df7c9656e7975162849172fc1bf9993..f0b5fa421ca9299cad2b81dc0c27c5db30cbfbd9 100644 (file)
TIDBitmap *tbm;
Buffer pvmbuffer;
BitmapHeapScanInstrumentation stats;
- TBMIterator *prefetch_iterator;
+ TBMPrivateIterator *prefetch_iterator;
int prefetch_pages;
int prefetch_target;
int prefetch_maximum;
index 1945f0639bf15667878ab58916667a23fc10a5b4..d746963976489c91b390cc3403cec5e2bfc6382e 100644 (file)
*/
typedef struct TIDBitmap TIDBitmap;
-/* Likewise, TBMIterator is private */
-typedef struct TBMIterator TBMIterator;
+/* Likewise, TBMPrivateIterator is private */
+typedef struct TBMPrivateIterator TBMPrivateIterator;
typedef struct TBMSharedIterator TBMSharedIterator;
+/*
+ * Callers with both private and shared implementations can use this unified
+ * API.
+ */
+typedef struct TBMIterator
+{
+ bool shared;
+ union
+ {
+ TBMPrivateIterator *private_iterator;
+ TBMSharedIterator *shared_iterator;
+ } i;
+} TBMIterator;
+
/* Result structure for tbm_iterate */
typedef struct TBMIterateResult
{
@@ -62,14 +76,20 @@ extern void tbm_intersect(TIDBitmap *a, const TIDBitmap *b);
extern bool tbm_is_empty(const TIDBitmap *tbm);
-extern TBMIterator *tbm_begin_iterate(TIDBitmap *tbm);
+extern TBMPrivateIterator *tbm_begin_private_iterate(TIDBitmap *tbm);
extern dsa_pointer tbm_prepare_shared_iterate(TIDBitmap *tbm);
-extern TBMIterateResult *tbm_iterate(TBMIterator *iterator);
+extern TBMIterateResult *tbm_private_iterate(TBMPrivateIterator *iterator);
extern TBMIterateResult *tbm_shared_iterate(TBMSharedIterator *iterator);
-extern void tbm_end_iterate(TBMIterator *iterator);
+extern void tbm_end_private_iterate(TBMPrivateIterator *iterator);
extern void tbm_end_shared_iterate(TBMSharedIterator *iterator);
extern TBMSharedIterator *tbm_attach_shared_iterate(dsa_area *dsa,
dsa_pointer dp);
extern long tbm_calculate_entries(double maxbytes);
+extern TBMIterator tbm_begin_iterate(TIDBitmap *tbm,
+ dsa_area *dsa, dsa_pointer dsp);
+extern void tbm_end_iterate(TBMIterator *iterator);
+
+extern TBMIterateResult *tbm_iterate(TBMIterator *iterator);
+
#endif /* TIDBITMAP_H */
index ce33e55bf1d3a8beb19de27fdc174a019a306daa..cda21239cbc1091687cb5ced31c42b156fed57b8 100644 (file)
TBMIterateResult
TBMIteratingState
TBMIterator
+TBMPrivateIterator
TBMSharedIterator
TBMSharedIteratorState
TBMStatus