Skip to content

Commit 43a57cf

Browse files
committed
Revise the TIDBitmap API to support multiple concurrent iterations over a
bitmap. This is extracted from Greg Stark's posix_fadvise patch; it seems worth committing separately, since it's potentially useful independently of posix_fadvise.
1 parent 3b34e98 commit 43a57cf

File tree

7 files changed

+143
-80
lines changed

7 files changed

+143
-80
lines changed

src/backend/access/gin/ginget.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.21 2009/01/01 17:23:34 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.22 2009/01/10 21:08:36 tgl Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414

@@ -290,6 +290,7 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
290290
entry->list = NULL;
291291
entry->nlist = 0;
292292
entry->partialMatch = NULL;
293+
entry->partialMatchIterator = NULL;
293294
entry->partialMatchResult = NULL;
294295
entry->reduceResult = FALSE;
295296
entry->predictNumberResult = 0;
@@ -311,6 +312,9 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
311312
*/
312313
if ( entry->partialMatch )
313314
{
315+
if (entry->partialMatchIterator)
316+
tbm_end_iterate(entry->partialMatchIterator);
317+
entry->partialMatchIterator = NULL;
314318
tbm_free( entry->partialMatch );
315319
entry->partialMatch = NULL;
316320
}
@@ -323,7 +327,7 @@ startScanEntry(Relation index, GinState *ginstate, GinScanEntry entry)
323327

324328
if ( entry->partialMatch && !tbm_is_empty(entry->partialMatch) )
325329
{
326-
tbm_begin_iterate(entry->partialMatch);
330+
entry->partialMatchIterator = tbm_begin_iterate(entry->partialMatch);
327331
entry->isFinished = FALSE;
328332
}
329333
}
@@ -534,11 +538,13 @@ entryGetItem(Relation index, GinScanEntry entry)
534538
{
535539
if ( entry->partialMatchResult == NULL || entry->offset >= entry->partialMatchResult->ntuples )
536540
{
537-
entry->partialMatchResult = tbm_iterate( entry->partialMatch );
541+
entry->partialMatchResult = tbm_iterate( entry->partialMatchIterator );
538542

539543
if ( entry->partialMatchResult == NULL )
540544
{
541545
ItemPointerSet(&entry->curItem, InvalidBlockNumber, InvalidOffsetNumber);
546+
tbm_end_iterate(entry->partialMatchIterator);
547+
entry->partialMatchIterator = NULL;
542548
entry->isFinished = TRUE;
543549
break;
544550
}

src/backend/access/gin/ginscan.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/gin/ginscan.c,v 1.20 2009/01/01 17:23:34 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/gin/ginscan.c,v 1.21 2009/01/10 21:08:36 tgl Exp $
1212
*-------------------------------------------------------------------------
1313
*/
1414

@@ -61,6 +61,8 @@ fillScanKey(GinState *ginstate, GinScanKey key, OffsetNumber attnum, Datum query
6161
key->scanEntry[i].offset = InvalidOffsetNumber;
6262
key->scanEntry[i].buffer = InvalidBuffer;
6363
key->scanEntry[i].partialMatch = NULL;
64+
key->scanEntry[i].partialMatchIterator = NULL;
65+
key->scanEntry[i].partialMatchResult = NULL;
6466
key->scanEntry[i].strategy = strategy;
6567
key->scanEntry[i].list = NULL;
6668
key->scanEntry[i].nlist = 0;
@@ -107,6 +109,7 @@ resetScanKeys(GinScanKey keys, uint32 nkeys)
107109
key->scanEntry[j].list = NULL;
108110
key->scanEntry[j].nlist = 0;
109111
key->scanEntry[j].partialMatch = NULL;
112+
key->scanEntry[j].partialMatchIterator = NULL;
110113
key->scanEntry[j].partialMatchResult = NULL;
111114
}
112115
}
@@ -132,6 +135,8 @@ freeScanKeys(GinScanKey keys, uint32 nkeys)
132135
ReleaseBuffer(key->scanEntry[j].buffer);
133136
if (key->scanEntry[j].list)
134137
pfree(key->scanEntry[j].list);
138+
if (key->scanEntry[j].partialMatchIterator)
139+
tbm_end_iterate(key->scanEntry[j].partialMatchIterator);
135140
if (key->scanEntry[j].partialMatch)
136141
tbm_free(key->scanEntry[j].partialMatch);
137142
}

src/backend/executor/nodeBitmapHeapscan.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*
2222
*
2323
* IDENTIFICATION
24-
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.31 2009/01/01 17:23:41 momjian Exp $
24+
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.32 2009/01/10 21:08:36 tgl Exp $
2525
*
2626
*-------------------------------------------------------------------------
2727
*/
@@ -65,6 +65,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
6565
HeapScanDesc scan;
6666
Index scanrelid;
6767
TIDBitmap *tbm;
68+
TBMIterator *tbmiterator;
6869
TBMIterateResult *tbmres;
6970
OffsetNumber targoffset;
7071
TupleTableSlot *slot;
@@ -78,6 +79,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
7879
scan = node->ss.ss_currentScanDesc;
7980
scanrelid = ((BitmapHeapScan *) node->ss.ps.plan)->scan.scanrelid;
8081
tbm = node->tbm;
82+
tbmiterator = node->tbmiterator;
8183
tbmres = node->tbmres;
8284

8385
/*
@@ -111,7 +113,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
111113

112114
/*
113115
* If we haven't yet performed the underlying index scan, do it, and
114-
* prepare the bitmap to be iterated over.
116+
* begin the iteration over the bitmap.
115117
*/
116118
if (tbm == NULL)
117119
{
@@ -121,9 +123,8 @@ BitmapHeapNext(BitmapHeapScanState *node)
121123
elog(ERROR, "unrecognized result from subplan");
122124

123125
node->tbm = tbm;
126+
node->tbmiterator = tbmiterator = tbm_begin_iterate(tbm);
124127
node->tbmres = tbmres = NULL;
125-
126-
tbm_begin_iterate(tbm);
127128
}
128129

129130
for (;;)
@@ -136,7 +137,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
136137
*/
137138
if (tbmres == NULL)
138139
{
139-
node->tbmres = tbmres = tbm_iterate(tbm);
140+
node->tbmres = tbmres = tbm_iterate(tbmiterator);
140141
if (tbmres == NULL)
141142
{
142143
/* no more entries in the bitmap */
@@ -376,9 +377,12 @@ ExecBitmapHeapReScan(BitmapHeapScanState *node, ExprContext *exprCtxt)
376377
/* rescan to release any page pin */
377378
heap_rescan(node->ss.ss_currentScanDesc, NULL);
378379

380+
if (node->tbmiterator)
381+
tbm_end_iterate(node->tbmiterator);
379382
if (node->tbm)
380383
tbm_free(node->tbm);
381384
node->tbm = NULL;
385+
node->tbmiterator = NULL;
382386
node->tbmres = NULL;
383387

384388
/*
@@ -423,6 +427,8 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
423427
/*
424428
* release bitmap if any
425429
*/
430+
if (node->tbmiterator)
431+
tbm_end_iterate(node->tbmiterator);
426432
if (node->tbm)
427433
tbm_free(node->tbm);
428434

@@ -466,6 +472,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
466472
scanstate->ss.ps.state = estate;
467473

468474
scanstate->tbm = NULL;
475+
scanstate->tbmiterator = NULL;
469476
scanstate->tbmres = NULL;
470477

471478
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy