@@ -91,6 +91,7 @@ extern ReadStream *read_stream_begin_relation(int flags,
91
91
extern Buffer read_stream_next_buffer (ReadStream * stream , void * * per_buffer_data );
92
92
extern BlockNumber read_stream_next_block (ReadStream * stream ,
93
93
BufferAccessStrategy * strategy );
94
+ extern size_t read_stream_per_buffer_data_size (ReadStream * stream );
94
95
extern ReadStream * read_stream_begin_smgr_relation (int flags ,
95
96
BufferAccessStrategy strategy ,
96
97
SMgrRelation smgr ,
@@ -102,4 +103,67 @@ extern ReadStream *read_stream_begin_smgr_relation(int flags,
102
103
extern void read_stream_reset (ReadStream * stream );
103
104
extern void read_stream_end (ReadStream * stream );
104
105
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
+
105
169
#endif /* READ_STREAM_H */
0 commit comments