Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf6bef36

Browse files
committed
Refactor tidstore.c iterator buffering.
Previously, TidStoreIterateNext() would expand the set of offsets foreach block into an internal buffer that it overwrote each time. Inorder to be able to collect the offsets for multiple blocks beforeworking with them, change the contract. Now, the offsets are obtainedby a separate call to TidStoreGetBlockOffsets(), which can be called ata later time. TidStoreIteratorResult objects are safe to copy and storein a queue.Reviewed-by: Noah Misch <noah@leadboat.com>Discussion:https://postgr.es/m/CAAKRu_bbkmwAzSBgnezancgJeXrQZXy4G4kBTd+5=cr86H5yew@mail.gmail.com
1 parent1462aad commitf6bef36

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

‎src/backend/access/common/tidstore.c

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,6 @@ struct TidStoreIter
147147
TidStoreIterResultoutput;
148148
};
149149

150-
staticvoidtidstore_iter_extract_tids(TidStoreIter*iter,BlockNumberblkno,
151-
BlocktableEntry*page);
152-
153150
/*
154151
* Create a TidStore. The TidStore will live in the memory context that is
155152
* CurrentMemoryContext at the time of this call. The TID storage, backed
@@ -486,13 +483,6 @@ TidStoreBeginIterate(TidStore *ts)
486483
iter=palloc0(sizeof(TidStoreIter));
487484
iter->ts=ts;
488485

489-
/*
490-
* We start with an array large enough to contain at least the offsets
491-
* from one completely full bitmap element.
492-
*/
493-
iter->output.max_offset=2*BITS_PER_BITMAPWORD;
494-
iter->output.offsets=palloc(sizeof(OffsetNumber)*iter->output.max_offset);
495-
496486
if (TidStoreIsShared(ts))
497487
iter->tree_iter.shared=shared_ts_begin_iterate(ts->tree.shared);
498488
else
@@ -503,9 +493,9 @@ TidStoreBeginIterate(TidStore *ts)
503493

504494

505495
/*
506-
*Scan the TidStore and return theTIDs of the next block. The offsets in
507-
*each iteration result are ordered, as are the block numbers over all
508-
*iterations.
496+
*Return a result that contains thenext block number and that can be used to
497+
*obtain the set of offsets by calling TidStoreGetBlockOffsets(). The result
498+
*is copyable.
509499
*/
510500
TidStoreIterResult*
511501
TidStoreIterateNext(TidStoreIter*iter)
@@ -521,8 +511,8 @@ TidStoreIterateNext(TidStoreIter *iter)
521511
if (page==NULL)
522512
returnNULL;
523513

524-
/* Collect TIDs from the key-value pair */
525-
tidstore_iter_extract_tids(iter, (BlockNumber)key,page);
514+
iter->output.blkno=key;
515+
iter->output.internal_page=page;
526516

527517
return&(iter->output);
528518
}
@@ -540,7 +530,6 @@ TidStoreEndIterate(TidStoreIter *iter)
540530
else
541531
local_ts_end_iterate(iter->tree_iter.local);
542532

543-
pfree(iter->output.offsets);
544533
pfree(iter);
545534
}
546535

@@ -575,24 +564,32 @@ TidStoreGetHandle(TidStore *ts)
575564
return (dsa_pointer)shared_ts_get_handle(ts->tree.shared);
576565
}
577566

578-
/* Extract TIDs from the given key-value pair */
579-
staticvoid
580-
tidstore_iter_extract_tids(TidStoreIter*iter,BlockNumberblkno,
581-
BlocktableEntry*page)
567+
/*
568+
* Given a TidStoreIterResult returned by TidStoreIterateNext(), extract the
569+
* offset numbers. Returns the number of offsets filled in, if <=
570+
* max_offsets. Otherwise, fills in as much as it can in the given space, and
571+
* returns the size of the buffer that would be needed.
572+
*/
573+
int
574+
TidStoreGetBlockOffsets(TidStoreIterResult*result,
575+
OffsetNumber*offsets,
576+
intmax_offsets)
582577
{
583-
TidStoreIterResult*result= (&iter->output);
578+
BlocktableEntry*page=result->internal_page;
579+
intnum_offsets=0;
584580
intwordnum;
585581

586-
result->num_offsets=0;
587-
result->blkno=blkno;
588-
589582
if (page->header.nwords==0)
590583
{
591584
/* we have offsets in the header */
592585
for (inti=0;i<NUM_FULL_OFFSETS;i++)
593586
{
594587
if (page->header.full_offsets[i]!=InvalidOffsetNumber)
595-
result->offsets[result->num_offsets++]=page->header.full_offsets[i];
588+
{
589+
if (num_offsets<max_offsets)
590+
offsets[num_offsets]=page->header.full_offsets[i];
591+
num_offsets++;
592+
}
596593
}
597594
}
598595
else
@@ -602,21 +599,19 @@ tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
602599
bitmapwordw=page->words[wordnum];
603600
intoff=wordnum*BITS_PER_BITMAPWORD;
604601

605-
/* Make sure there is enough space to add offsets */
606-
if ((result->num_offsets+BITS_PER_BITMAPWORD)>result->max_offset)
607-
{
608-
result->max_offset *=2;
609-
result->offsets=repalloc(result->offsets,
610-
sizeof(OffsetNumber)*result->max_offset);
611-
}
612-
613602
while (w!=0)
614603
{
615604
if (w&1)
616-
result->offsets[result->num_offsets++]= (OffsetNumber)off;
605+
{
606+
if (num_offsets<max_offsets)
607+
offsets[num_offsets]= (OffsetNumber)off;
608+
num_offsets++;
609+
}
617610
off++;
618611
w >>=1;
619612
}
620613
}
621614
}
615+
616+
returnnum_offsets;
622617
}

‎src/backend/access/heap/vacuumlazy.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,12 +2126,17 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
21262126
Bufferbuf;
21272127
Pagepage;
21282128
Sizefreespace;
2129+
OffsetNumberoffsets[MaxOffsetNumber];
2130+
intnum_offsets;
21292131

21302132
vacuum_delay_point();
21312133

21322134
blkno=iter_result->blkno;
21332135
vacrel->blkno=blkno;
21342136

2137+
num_offsets=TidStoreGetBlockOffsets(iter_result,offsets,lengthof(offsets));
2138+
Assert(num_offsets <=lengthof(offsets));
2139+
21352140
/*
21362141
* Pin the visibility map page in case we need to mark the page
21372142
* all-visible. In most cases this will be very cheap, because we'll
@@ -2143,8 +2148,8 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
21432148
buf=ReadBufferExtended(vacrel->rel,MAIN_FORKNUM,blkno,RBM_NORMAL,
21442149
vacrel->bstrategy);
21452150
LockBuffer(buf,BUFFER_LOCK_EXCLUSIVE);
2146-
lazy_vacuum_heap_page(vacrel,blkno,buf,iter_result->offsets,
2147-
iter_result->num_offsets,vmbuffer);
2151+
lazy_vacuum_heap_page(vacrel,blkno,buf,offsets,
2152+
num_offsets,vmbuffer);
21482153

21492154
/* Now that we've vacuumed the page, record its available space */
21502155
page=BufferGetPage(buf);

‎src/include/access/tidstore.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
typedefstructTidStoreTidStore;
2121
typedefstructTidStoreIterTidStoreIter;
2222

23-
/* Result struct for TidStoreIterateNext */
23+
/*
24+
* Result struct for TidStoreIterateNext. This is copyable, but should be
25+
* treated as opaque. Call TidStoreGetOffsets() to obtain the offsets.
26+
*/
2427
typedefstructTidStoreIterResult
2528
{
2629
BlockNumberblkno;
27-
intmax_offset;
28-
intnum_offsets;
29-
OffsetNumber*offsets;
30+
void*internal_page;
3031
}TidStoreIterResult;
3132

3233
externTidStore*TidStoreCreateLocal(size_tmax_bytes,boolinsert_only);
@@ -42,6 +43,9 @@ extern void TidStoreSetBlockOffsets(TidStore *ts, BlockNumber blkno, OffsetNumbe
4243
externboolTidStoreIsMember(TidStore*ts,ItemPointertid);
4344
externTidStoreIter*TidStoreBeginIterate(TidStore*ts);
4445
externTidStoreIterResult*TidStoreIterateNext(TidStoreIter*iter);
46+
externintTidStoreGetBlockOffsets(TidStoreIterResult*result,
47+
OffsetNumber*offsets,
48+
intmax_offsets);
4549
externvoidTidStoreEndIterate(TidStoreIter*iter);
4650
externsize_tTidStoreMemoryUsage(TidStore*ts);
4751
externdsa_pointerTidStoreGetHandle(TidStore*ts);

‎src/test/modules/test_tidstore/test_tidstore.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,14 @@ check_set_block_offsets(PG_FUNCTION_ARGS)
267267
iter=TidStoreBeginIterate(tidstore);
268268
while ((iter_result=TidStoreIterateNext(iter))!=NULL)
269269
{
270-
for (inti=0;i<iter_result->num_offsets;i++)
270+
OffsetNumberoffsets[MaxOffsetNumber];
271+
intnum_offsets;
272+
273+
num_offsets=TidStoreGetBlockOffsets(iter_result,offsets,lengthof(offsets));
274+
Assert(num_offsets <=lengthof(offsets));
275+
for (inti=0;i<num_offsets;i++)
271276
ItemPointerSet(&(items.iter_tids[num_iter_tids++]),iter_result->blkno,
272-
iter_result->offsets[i]);
277+
offsets[i]);
273278
}
274279
TidStoreEndIterate(iter);
275280
TidStoreUnlock(tidstore);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp