summaryrefslogtreecommitdiff
path: root/src/backend/access/common/tidstore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/common/tidstore.c')
-rw-r--r--src/backend/access/common/tidstore.c63
1 files changed, 29 insertions, 34 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;
}