MCPcopy Create free account
hub / github.com/apache/impala / GetBytesInternal

Method GetBytesInternal

be/src/exec/scanner-context.cc:263–324  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

261}
262
263Status ScannerContext::Stream::GetBytesInternal(int64_t requested_len,
264 uint8_t** out_buffer, bool peek, int64_t* out_len) {
265 DCHECK_GT(requested_len, boundary_buffer_bytes_left_);
266 DCHECK(output_buffer_bytes_left_ != &io_buffer_bytes_left_
267 || requested_len > io_buffer_bytes_left_) << "All bytes in output buffer "
268 << requested_len << " " << io_buffer_bytes_left_;
269 *out_buffer = nullptr;
270
271 if (boundary_buffer_bytes_left_ == 0) boundary_buffer_->Clear();
272 DCHECK(ValidateBufferPointers());
273
274 // First this loop ensures, by reading I/O buffers one-by-one, that we've got all of
275 // the requested bytes in 'boundary_buffer_', 'io_buffer_', or split between the two.
276 // We may not be able to get all of the bytes if we hit eof.
277 while (boundary_buffer_bytes_left_ + io_buffer_bytes_left_ < requested_len) {
278 if (io_buffer_bytes_left_ > 0) {
279 // Copy the remainder of 'io_buffer_' to 'boundary_buffer_' before getting the next
280 // 'io_buffer_'. Preallocate 'boundary_buffer_' to avoid unnecessary resizes for
281 // large reads.
282 RETURN_IF_ERROR(boundary_buffer_->GrowBuffer(requested_len));
283 RETURN_IF_ERROR(CopyIoToBoundary(io_buffer_bytes_left_));
284 }
285 int64_t remaining_requested_len = requested_len - boundary_buffer_bytes_left_;
286 RETURN_IF_ERROR(GetNextBuffer(remaining_requested_len));
287 if (UNLIKELY(parent_->cancelled())) return CONTEXT_CANCELLED;
288 // No more bytes (i.e. EOF).
289 if (io_buffer_bytes_left_ == 0) break;
290 }
291
292 // We have read the full 'requested_len' bytes or hit eof.
293 // We can assemble the contiguous bytes in two ways:
294 // 1. if the the read range falls entirely with an I/O buffer, we return a pointer into
295 // that I/O buffer.
296 // 2. if the read straddles I/O buffers, we append the data to 'boundary_buffer_'.
297 // 'boundary_buffer_' may already contain some of the data that we need if we did a
298 // "peek" earlier.
299 int64_t requested_bytes_left = requested_len - boundary_buffer_bytes_left_;
300 DCHECK_GE(requested_bytes_left, 0);
301 int64_t num_bytes_left_to_copy = min(io_buffer_bytes_left_, requested_bytes_left);
302 *out_len = boundary_buffer_bytes_left_ + num_bytes_left_to_copy;
303 DCHECK_LE(*out_len, requested_len);
304 if (boundary_buffer_bytes_left_ == 0) {
305 // Case 1: return a pointer into the I/O buffer.
306 output_buffer_pos_ = &io_buffer_pos_;
307 output_buffer_bytes_left_ = &io_buffer_bytes_left_;
308 } else {
309 // Case 2: return a pointer into the boundary buffer, after copying any required
310 // data from the I/O buffer.
311 DCHECK_EQ(output_buffer_pos_, &boundary_buffer_pos_);
312 DCHECK_EQ(output_buffer_bytes_left_, &boundary_buffer_bytes_left_);
313 if (io_buffer_bytes_left_ > 0) {
314 RETURN_IF_ERROR(CopyIoToBoundary(num_bytes_left_to_copy));
315 }
316 }
317 *out_buffer = *output_buffer_pos_;
318 if (!peek) {
319 total_bytes_returned_ += *out_len;
320 AdvanceBufferPos(*out_len, output_buffer_pos_, output_buffer_bytes_left_);

Callers

nothing calls this directly

Calls 5

minFunction · 0.85
OKFunction · 0.85
GrowBufferMethod · 0.80
ClearMethod · 0.45
cancelledMethod · 0.45

Tested by

no test coverage detected