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

Method ProcessBlock

be/src/util/decompress.cc:149–245  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

147}
148
149Status GzipDecompressor::ProcessBlock(bool output_preallocated, int64_t input_length,
150 const uint8_t* input, int64_t* output_length, uint8_t** output) {
151 int64_t output_length_local = *output_length;
152 *output_length = 0;
153 if (UNLIKELY(output_preallocated && output_length_local == 0)) {
154 // The zlib library does not allow *output to be nullptr, even when output_length is 0
155 // (inflate() will return Z_STREAM_ERROR). We don't consider this an error, so bail
156 // early if no output is expected. Note that we don't signal an error if the input
157 // actually contains compressed data.
158 return Status::OK();
159 }
160
161 bool use_temp = false;
162 if (!output_preallocated) {
163 if (!reuse_buffer_ || out_buffer_ == nullptr) {
164 // guess that we will need 2x the input length.
165 buffer_length_ = input_length * 2;
166 out_buffer_ = temp_memory_pool_->TryAllocate(buffer_length_);
167 if (UNLIKELY(out_buffer_ == nullptr)) {
168 string details = Substitute(DECOMPRESSOR_MEM_LIMIT_EXCEEDED, "Gzip",
169 buffer_length_);
170 return temp_memory_pool_->mem_tracker()->MemLimitExceeded(
171 nullptr, details, buffer_length_);
172 }
173 }
174 use_temp = true;
175 *output = out_buffer_;
176 output_length_local = buffer_length_;
177 }
178
179 // Reset the stream for this block
180 int ret = inflateReset(&stream_);
181 if (ret != Z_OK) {
182 return Status(TErrorCode::COMPRESSED_FILE_DECOMPRESSOR_ERROR, "Gzip",
183 "inflateReset()", ret);
184 }
185
186 // We only support the non-streaming use case where we present it the entire
187 // compressed input and a buffer big enough to contain the entire decompressed
188 // output. In the case where we don't know the output, we just make a bigger
189 // buffer and try the non-streaming mode from the beginning again.
190 // TODO: IMPALA-3073 Verify if compressed block could be multistream. If yes, we need
191 // to support it and shouldn't stop decompressing while ret == Z_STREAM_END.
192 while (ret != Z_STREAM_END) {
193 stream_.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(input));
194 stream_.avail_in = input_length;
195 stream_.next_out = reinterpret_cast<Bytef*>(*output);
196 stream_.avail_out = output_length_local;
197
198 if (use_temp) {
199 // We don't know the output size, so this might fail.
200 ret = inflate(&stream_, Z_PARTIAL_FLUSH);
201 } else {
202 // We know the output size. In this case, we can use Z_FINISH
203 // which is more efficient.
204 ret = inflate(&stream_, Z_FINISH);
205 }
206 if (ret == Z_STREAM_END || ret != Z_OK) break;

Callers

nothing calls this directly

Calls 11

OKFunction · 0.85
SubstituteFunction · 0.85
SnappyBlockDecompressFunction · 0.85
AcquireDataMethod · 0.80
StatusClass · 0.70
getMethod · 0.65
TryAllocateMethod · 0.45
MemLimitExceededMethod · 0.45
mem_trackerMethod · 0.45
strMethod · 0.45
ClearMethod · 0.45

Tested by

no test coverage detected