@@ -91,6 +91,7 @@ extern ReadStream *read_stream_begin_relation(int flags,
9191extern Buffer read_stream_next_buffer (ReadStream * stream , void * * per_buffer_data );
9292extern BlockNumber read_stream_next_block (ReadStream * stream ,
9393 BufferAccessStrategy * strategy );
94+ extern size_t read_stream_per_buffer_data_size (ReadStream * stream );
9495extern 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,
102103extern void read_stream_reset (ReadStream * stream );
103104extern 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