Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/tidstore.c63
-rw-r--r--src/backend/access/heap/vacuumlazy.c9
2 files changed, 36 insertions, 36 deletions
diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c
index fb3949d69f6..a7179759d67 100644
--- a/src/backend/access/common/tidstore.c
+++ b/src/backend/access/common/tidstore.c
@@ -147,9 +147,6 @@ struct TidStoreIter
TidStoreIterResult output;
};
-static void tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
- BlocktableEntry *page);
-
/*
* Create a TidStore. The TidStore will live in the memory context that is
* CurrentMemoryContext at the time of this call. The TID storage, backed
@@ -486,13 +483,6 @@ TidStoreBeginIterate(TidStore *ts)
iter = palloc0(sizeof(TidStoreIter));
iter->ts = ts;
- /*
- * We start with an array large enough to contain at least the offsets
- * from one completely full bitmap element.
- */
- iter->output.max_offset = 2 * BITS_PER_BITMAPWORD;
- iter->output.offsets = palloc(sizeof(OffsetNumber) * iter->output.max_offset);
-
if (TidStoreIsShared(ts))
iter->tree_iter.shared = shared_ts_begin_iterate(ts->tree.shared);
else
@@ -503,9 +493,9 @@ TidStoreBeginIterate(TidStore *ts)
/*
- * Scan the TidStore and return the TIDs of the next block. The offsets in
- * each iteration result are ordered, as are the block numbers over all
- * iterations.
+ * Return a result that contains the next block number and that can be used to
+ * obtain the set of offsets by calling TidStoreGetBlockOffsets(). The result
+ * is copyable.
*/
TidStoreIterResult *
TidStoreIterateNext(TidStoreIter *iter)
@@ -521,8 +511,8 @@ TidStoreIterateNext(TidStoreIter *iter)
if (page == NULL)
return NULL;
- /* Collect TIDs from the key-value pair */
- tidstore_iter_extract_tids(iter, (BlockNumber) key, page);
+ iter->output.blkno = key;
+ iter->output.internal_page = page;
return &(iter->output);
}
@@ -540,7 +530,6 @@ TidStoreEndIterate(TidStoreIter *iter)
else
local_ts_end_iterate(iter->tree_iter.local);
- pfree(iter->output.offsets);
pfree(iter);
}
@@ -575,24 +564,32 @@ TidStoreGetHandle(TidStore *ts)
return (dsa_pointer) shared_ts_get_handle(ts->tree.shared);
}
-/* Extract TIDs from the given key-value pair */
-static void
-tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
- BlocktableEntry *page)
+/*
+ * Given a TidStoreIterResult returned by TidStoreIterateNext(), extract the
+ * offset numbers. Returns the number of offsets filled in, if <=
+ * max_offsets. Otherwise, fills in as much as it can in the given space, and
+ * returns the size of the buffer that would be needed.
+ */
+int
+TidStoreGetBlockOffsets(TidStoreIterResult *result,
+ OffsetNumber *offsets,
+ int max_offsets)
{
- TidStoreIterResult *result = (&iter->output);
+ BlocktableEntry *page = result->internal_page;
+ int num_offsets = 0;
int wordnum;
- result->num_offsets = 0;
- result->blkno = blkno;
-
if (page->header.nwords == 0)
{
/* we have offsets in the header */
for (int i = 0; i < NUM_FULL_OFFSETS; i++)
{
if (page->header.full_offsets[i] != InvalidOffsetNumber)
- result->offsets[result->num_offsets++] = page->header.full_offsets[i];
+ {
+ if (num_offsets < max_offsets)
+ offsets[num_offsets] = page->header.full_offsets[i];
+ num_offsets++;
+ }
}
}
else
@@ -602,21 +599,19 @@ tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
bitmapword w = page->words[wordnum];
int off = wordnum * BITS_PER_BITMAPWORD;
- /* Make sure there is enough space to add offsets */
- if ((result->num_offsets + BITS_PER_BITMAPWORD) > result->max_offset)
- {
- result->max_offset *= 2;
- result->offsets = repalloc(result->offsets,
- sizeof(OffsetNumber) * result->max_offset);
- }
-
while (w != 0)
{
if (w & 1)
- result->offsets[result->num_offsets++] = (OffsetNumber) off;
+ {
+ if (num_offsets < max_offsets)
+ offsets[num_offsets] = (OffsetNumber) off;
+ num_offsets++;
+ }
off++;
w >>= 1;
}
}
}
+
+ return num_offsets;
}
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index abb47ae5960..835b53415d0 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -2126,12 +2126,17 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
Buffer buf;
Page page;
Size freespace;
+ OffsetNumber offsets[MaxOffsetNumber];
+ int num_offsets;
vacuum_delay_point();
blkno = iter_result->blkno;
vacrel->blkno = blkno;
+ num_offsets = TidStoreGetBlockOffsets(iter_result, offsets, lengthof(offsets));
+ Assert(num_offsets <= lengthof(offsets));
+
/*
* Pin the visibility map page in case we need to mark the page
* all-visible. In most cases this will be very cheap, because we'll
@@ -2143,8 +2148,8 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
buf = ReadBufferExtended(vacrel->rel, MAIN_FORKNUM, blkno, RBM_NORMAL,
vacrel->bstrategy);
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
- lazy_vacuum_heap_page(vacrel, blkno, buf, iter_result->offsets,
- iter_result->num_offsets, vmbuffer);
+ lazy_vacuum_heap_page(vacrel, blkno, buf, offsets,
+ num_offsets, vmbuffer);
/* Now that we've vacuumed the page, record its available space */
page = BufferGetPage(buf);