diff options
-rw-r--r-- | src/backend/access/gin/ginget.c | 10 | ||||
-rw-r--r-- | src/backend/access/gin/ginscan.c | 2 | ||||
-rw-r--r-- | src/backend/access/heap/heapam_handler.c | 2 | ||||
-rw-r--r-- | src/backend/executor/nodeBitmapHeapscan.c | 25 | ||||
-rw-r--r-- | src/backend/nodes/tidbitmap.c | 114 | ||||
-rw-r--r-- | src/include/access/gin_private.h | 2 | ||||
-rw-r--r-- | src/include/access/relscan.h | 4 | ||||
-rw-r--r-- | src/include/nodes/execnodes.h | 2 | ||||
-rw-r--r-- | src/include/nodes/tidbitmap.h | 30 | ||||
-rw-r--r-- | src/tools/pgindent/typedefs.list | 1 |
10 files changed, 140 insertions, 52 deletions
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 0b4f2ebadb6..e8e0eab6552 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -373,7 +373,7 @@ restartScanEntry: 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; @@ -385,7 +385,8 @@ restartScanEntry: 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; diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index f2fd62afbbf..2c6631c914d 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -246,7 +246,7 @@ ginFreeScanKeys(GinScanOpaque so) 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); } diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 689773ff239..adf968df42b 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -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; diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 689bde16dd2..d9e7a516a07 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -95,7 +95,7 @@ BitmapHeapNext(BitmapHeapScanState *node) */ if (!node->initialized) { - TBMIterator *tbmiterator = NULL; + TBMPrivateIterator *tbmiterator = NULL; TBMSharedIterator *shared_tbmiterator = NULL; if (!pstate) @@ -106,12 +106,12 @@ BitmapHeapNext(BitmapHeapScanState *node) 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) diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index e8ab5d78fcc..687d6f17636 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -170,12 +170,12 @@ struct TIDBitmap }; /* - * 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 */ @@ -213,8 +213,8 @@ typedef struct PTIterationArray } 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 { @@ -673,31 +673,32 @@ tbm_is_empty(const TIDBitmap *tbm) } /* - * 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); @@ -1136,14 +1137,14 @@ tbm_shared_iterate(TBMSharedIterator *iterator) } /* - * 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); } @@ -1556,3 +1557,66 @@ tbm_calculate_entries(double maxbytes) 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); +} diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index 3013a44bae1..78800509367 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -352,7 +352,7 @@ typedef struct GinScanEntryData /* 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 */ diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index e1884acf493..153561addc0 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -25,7 +25,7 @@ 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; diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 7f71b7625df..f0b5fa421ca 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1853,7 +1853,7 @@ typedef struct BitmapHeapScanState TIDBitmap *tbm; Buffer pvmbuffer; BitmapHeapScanInstrumentation stats; - TBMIterator *prefetch_iterator; + TBMPrivateIterator *prefetch_iterator; int prefetch_pages; int prefetch_target; int prefetch_maximum; diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h index 1945f0639bf..d7469639764 100644 --- a/src/include/nodes/tidbitmap.h +++ b/src/include/nodes/tidbitmap.h @@ -32,10 +32,24 @@ */ 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 */ diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index ce33e55bf1d..cda21239cbc 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2812,6 +2812,7 @@ TAR_MEMBER TBMIterateResult TBMIteratingState TBMIterator +TBMPrivateIterator TBMSharedIterator TBMSharedIteratorState TBMStatus |