Skip to content

Commit aa9a2a7

Browse files
author
Commitfest Bot
committed
[CF 5617] v2 - Beautify read stream "per buffer data" APIs
This branch was automatically generated by a robot using es from an email thread registered at: https://commitfest.postgresql.org//5617 The branch will be overwritten each time a new version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. (es): https://www.postgresql.org/message-id/CA+hUKGLa7ba7USyT+JR7uRiawWeCVJ96wyRsoEXk7r2gngPv=A@mail.gmail.com Author(s): Thomas Munro
2 parents 43b8e6c + c480724 commit aa9a2a7

File tree

8 files changed

+90
-16
lines changed

8 files changed

+90
-16
lines changed

‎contrib/pg_prewarm/pg_prewarm.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,11 @@ pg_prewarm(PG_FUNCTION_ARGS)
216216
Buffer buf;
217217

218218
CHECK_FOR_INTERRUPTS();
219-
buf = read_stream_next_buffer(stream, NULL);
219+
buf = read_stream_get_buffer(stream);
220220
ReleaseBuffer(buf);
221221
++blocks_done;
222222
}
223-
Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer);
223+
Assert(read_stream_get_buffer(stream) == InvalidBuffer);
224224
read_stream_end(stream);
225225
}
226226

‎contrib/pg_visibility/pg_visibility.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ collect_visibility_data(Oid relid, bool include_pd)
565565
Buffer buffer;
566566
Page page;
567567

568-
buffer = read_stream_next_buffer(stream, NULL);
568+
buffer = read_stream_get_buffer(stream);
569569
LockBuffer(buffer, BUFFER_LOCK_SHARE);
570570

571571
page = BufferGetPage(buffer);
@@ -578,7 +578,7 @@ collect_visibility_data(Oid relid, bool include_pd)
578578

579579
if (include_pd)
580580
{
581-
Assert(read_stream_next_buffer(stream, NULL) == InvalidBuffer);
581+
Assert(read_stream_get_buffer(stream) == InvalidBuffer);
582582
read_stream_end(stream);
583583
}
584584

@@ -761,7 +761,7 @@ collect_corrupt_items(Oid relid, bool all_visible, bool all_frozen)
761761
0);
762762

763763
/* Loop over every block in the relation. */
764-
while ((buffer = read_stream_next_buffer(stream, NULL)) != InvalidBuffer)
764+
while ((buffer = read_stream_get_buffer(stream)) != InvalidBuffer)
765765
{
766766
bool check_frozen = all_frozen;
767767
bool check_visible = all_visible;

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ heap_fetch_next_buffer(HeapScanDesc scan, ScanDirection dir)
651651

652652
scan->rs_dir = dir;
653653

654-
scan->rs_cbuf = read_stream_next_buffer(scan->rs_read_stream, NULL);
654+
scan->rs_cbuf = read_stream_get_buffer(scan->rs_read_stream);
655655
if (BufferIsValid(scan->rs_cbuf))
656656
scan->rs_cblock = BufferGetBlockNumber(scan->rs_cbuf);
657657
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ heapam_scan_analyze_next_block(TableScanDesc scan, ReadStream *stream)
10141014
* re-acquire sharelock for each tuple, but since we aren't doing much
10151015
* work per tuple, the extra lock traffic is probably better avoided.
10161016
*/
1017-
hscan->rs_cbuf = read_stream_next_buffer(stream, NULL);
1017+
hscan->rs_cbuf = read_stream_get_buffer(stream);
10181018
if (!BufferIsValid(hscan->rs_cbuf))
10191019
return false;
10201020

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

+5-7
Original file line numberDiff line numberDiff line change
@@ -1245,7 +1245,6 @@ lazy_scan_heap(LVRelState *vacrel)
12451245
Page page;
12461246
uint8 blk_info = 0;
12471247
bool has_lpdead_items;
1248-
void *per_buffer_data = NULL;
12491248
bool vm_page_frozen = false;
12501249
bool got_cleanup_lock = false;
12511250

@@ -1305,13 +1304,12 @@ lazy_scan_heap(LVRelState *vacrel)
13051304
PROGRESS_VACUUM_PHASE_SCAN_HEAP);
13061305
}
13071306

1308-
buf = read_stream_next_buffer(stream, &per_buffer_data);
1307+
buf = read_stream_get_buffer_and_value(stream, &blk_info);
13091308

13101309
/* The relation is exhausted. */
13111310
if (!BufferIsValid(buf))
13121311
break;
13131312

1314-
blk_info = *((uint8 *) per_buffer_data);
13151313
CheckBufferIsPinnedOnce(buf);
13161314
page = BufferGetPage(buf);
13171315
blkno = BufferGetBlockNumber(buf);
@@ -1632,7 +1630,7 @@ heap_vac_scan_next_block(ReadStream *stream,
16321630
*/
16331631
vacrel->current_block = next_block;
16341632
blk_info |= VAC_BLK_ALL_VISIBLE_ACCORDING_TO_VM;
1635-
*((uint8 *) per_buffer_data) = blk_info;
1633+
read_stream_put_value(stream, per_buffer_data, blk_info);
16361634
return vacrel->current_block;
16371635
}
16381636
else
@@ -1648,7 +1646,7 @@ heap_vac_scan_next_block(ReadStream *stream,
16481646
blk_info |= VAC_BLK_ALL_VISIBLE_ACCORDING_TO_VM;
16491647
if (vacrel->next_unskippable_eager_scanned)
16501648
blk_info |= VAC_BLK_WAS_EAGER_SCANNED;
1651-
*((uint8 *) per_buffer_data) = blk_info;
1649+
read_stream_put_value(stream, per_buffer_data, blk_info);
16521650
return vacrel->current_block;
16531651
}
16541652
}
@@ -2693,7 +2691,7 @@ vacuum_reap_lp_read_stream_next(ReadStream *stream,
26932691
* Save the TidStoreIterResult for later, so we can extract the offsets.
26942692
* It is safe to copy the result, according to TidStoreIterateNext().
26952693
*/
2696-
memcpy(per_buffer_data, iter_result, sizeof(*iter_result));
2694+
read_stream_put_value(stream, per_buffer_data, *iter_result);
26972695

26982696
return iter_result->blkno;
26992697
}
@@ -2768,7 +2766,7 @@ lazy_vacuum_heap_rel(LVRelState *vacrel)
27682766

27692767
vacuum_delay_point(false);
27702768

2771-
buf = read_stream_next_buffer(stream, (void **) &iter_result);
2769+
buf = read_stream_get_buffer_and_pointer(stream, &iter_result);
27722770

27732771
/* The relation is exhausted */
27742772
if (!BufferIsValid(buf))

‎src/backend/storage/aio/read_stream.c

+12
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,9 @@ read_stream_begin_smgr_relation(int flags,
762762
* valid until the next call to read_stream_next_buffer(). When the stream
763763
* runs out of data, InvalidBuffer is returned. The caller may decide to end
764764
* the stream early at any time by calling read_stream_end().
765+
*
766+
* See read_stream.h for read_stream_get_buffer() and variants that provide
767+
* some degree of type safety for the per_buffer_data argument.
765768
*/
766769
Buffer
767770
read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
@@ -997,6 +1000,15 @@ read_stream_next_block(ReadStream *stream, BufferAccessStrategy *strategy)
9971000
return read_stream_get_block(stream, NULL);
9981001
}
9991002

1003+
/*
1004+
* Return the configured per-buffer data size, for use in assertions.
1005+
*/
1006+
size_t
1007+
read_stream_per_buffer_data_size(ReadStream *stream)
1008+
{
1009+
return stream->per_buffer_data_size;
1010+
}
1011+
10001012
/*
10011013
* Reset a read stream by releasing any queued up buffers, allowing the stream
10021014
* to be used again for different blocks. This can be used to clear an

‎src/backend/storage/buffer/bufmgr.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -5117,7 +5117,7 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
51175117
CHECK_FOR_INTERRUPTS();
51185118

51195119
/* Read block from source relation. */
5120-
srcBuf = read_stream_next_buffer(src_stream, NULL);
5120+
srcBuf = read_stream_get_buffer(src_stream);
51215121
LockBuffer(srcBuf, BUFFER_LOCK_SHARE);
51225122
srcPage = BufferGetPage(srcBuf);
51235123

@@ -5142,7 +5142,7 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
51425142
UnlockReleaseBuffer(dstBuf);
51435143
UnlockReleaseBuffer(srcBuf);
51445144
}
5145-
Assert(read_stream_next_buffer(src_stream, NULL) == InvalidBuffer);
5145+
Assert(read_stream_get_buffer(src_stream) == InvalidBuffer);
51465146
read_stream_end(src_stream);
51475147

51485148
FreeAccessStrategy(bstrategy_src);

‎src/include/storage/read_stream.h

+64
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ extern ReadStream *read_stream_begin_relation(int flags,
9191
extern Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data);
9292
extern BlockNumber read_stream_next_block(ReadStream *stream,
9393
BufferAccessStrategy *strategy);
94+
extern size_t read_stream_per_buffer_data_size(ReadStream *stream);
9495
extern ReadStream *read_stream_begin_smgr_relation(int flags,
9596
BufferAccessStrategy strategy,
9697
SMgrRelation smgr,
@@ -102,4 +103,67 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags,
102103
extern void read_stream_reset(ReadStream *stream);
103104
extern void read_stream_end(ReadStream *stream);
104105

106+
/*
107+
* Get the next buffer from a stream that is not using per-buffer data.
108+
*/
109+
static inline Buffer
110+
read_stream_get_buffer(ReadStream *stream)
111+
{
112+
Assert(read_stream_per_buffer_data_size(stream) == 0);
113+
return read_stream_next_buffer(stream, NULL);
114+
}
115+
116+
/*
117+
* Helper for read_stream_get_buffer_and_value().
118+
*/
119+
static inline Buffer
120+
read_stream_get_buffer_and_value_with_size(ReadStream *stream,
121+
void *output_data,
122+
size_t output_data_size)
123+
{
124+
Buffer buffer;
125+
void *per_buffer_data;
126+
127+
Assert(read_stream_per_buffer_data_size(stream) == output_data_size);
128+
buffer = read_stream_next_buffer(stream, &per_buffer_data);
129+
if (buffer != InvalidBuffer)
130+
memcpy(output_data, per_buffer_data, output_data_size);
131+
132+
return buffer;
133+
}
134+
135+
/*
136+
* Get the next buffer and a copy of the associated per-buffer data.
137+
* InvalidBuffer means end-of-stream, and in that case the per-buffer data is
138+
* undefined. Example of use:
139+
*
140+
* int my_int;
141+
*
142+
* buf = read_stream_get_buffer_and_value(stream, &my_int);
143+
*/
144+
#define read_stream_get_buffer_and_value(stream, vp) \
145+
read_stream_get_buffer_and_value_with_size((stream), (vp), sizeof(*(vp)))
146+
147+
/*
148+
* Get the next buffer and a pointer to the associated per-buffer data. This
149+
* avoids casts in the calling code, and asserts that we received a pointer to
150+
* a pointer to a type that doesn't exceed the storage size. For example:
151+
*
152+
* int *my_int_p;
153+
*
154+
* buf = read_stream_get_buffer_and_pointer(stream, &my_int_p);
155+
*/
156+
#define read_stream_get_buffer_and_pointer(stream, pointer) \
157+
(AssertMacro(sizeof(**(pointer)) <= read_stream_per_buffer_data_size(stream)), \
158+
read_stream_next_buffer((stream), ((void **) (pointer))))
159+
160+
/*
161+
* Set the per-buffer data by value. This can be called from inside a
162+
* callback that is returning block numbers. It asserts that the value's size
163+
* matches the available space.
164+
*/
165+
#define read_stream_put_value(stream, per_buffer_data, value) \
166+
(AssertMacro(sizeof(value) == read_stream_per_buffer_data_size(stream)), \
167+
memcpy((per_buffer_data), &(value), sizeof(value)))
168+
105169
#endif /* READ_STREAM_H */

0 commit comments

Comments
 (0)