| 149 | } |
| 150 | |
| 151 | ReadOutcome ScanRange::DoReadInternal(DiskQueue* queue, int disk_id, bool use_local_buff, |
| 152 | bool use_mem_buffer, shared_lock<shared_mutex>* local_file_lock) { |
| 153 | int64_t bytes_remaining = bytes_to_read_ - bytes_read_; |
| 154 | DCHECK_GT(bytes_remaining, 0); |
| 155 | // Can't be set to true together. |
| 156 | DCHECK(!(use_local_buff && use_mem_buffer)); |
| 157 | |
| 158 | unique_ptr<BufferDescriptor> buffer_desc; |
| 159 | FileReader* file_reader = nullptr; |
| 160 | { |
| 161 | unique_lock<mutex> lock(lock_); |
| 162 | DCHECK(!read_in_flight_); |
| 163 | if (!cancel_status_.ok()) return ReadOutcome::CANCELLED; |
| 164 | |
| 165 | if (buffer_manager_->is_client_buffer()) { |
| 166 | buffer_desc = unique_ptr<BufferDescriptor>(new BufferDescriptor( |
| 167 | this, client_buffer_.data, client_buffer_.len)); |
| 168 | } else { |
| 169 | DCHECK(buffer_manager_->is_internal_buffer()) |
| 170 | << "This code path does not handle other buffer types, i.e. HDFS cache. " |
| 171 | << "Buffer tag = " |
| 172 | << static_cast<int>(buffer_manager_->buffer_tag()); |
| 173 | buffer_desc = buffer_manager_->GetUnusedBuffer(lock); |
| 174 | if (buffer_desc == nullptr) { |
| 175 | // No buffer available - the range will be rescheduled when a buffer is added. |
| 176 | blocked_on_buffer_ = true; |
| 177 | return ReadOutcome::BLOCKED_ON_BUFFER; |
| 178 | } |
| 179 | buffer_manager_->add_iomgr_buffer_cumulative_bytes_used(buffer_desc->buffer_len()); |
| 180 | } |
| 181 | read_in_flight_ = true; |
| 182 | // Set the correct reader to read the range if the memory buffer is not available. |
| 183 | if (!use_mem_buffer) { |
| 184 | if (use_local_buff) { |
| 185 | file_reader = local_buffer_reader_.get(); |
| 186 | file_ = disk_buffer_file_->path(); |
| 187 | } else { |
| 188 | file_reader = file_reader_.get(); |
| 189 | } |
| 190 | use_local_buffer_ = use_local_buff; |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | bool eof = false; |
| 195 | Status read_status = Status::OK(); |
| 196 | |
| 197 | if (use_mem_buffer) { |
| 198 | // The only scenario to use the memory buffer is for the temporary files, the range |
| 199 | // is supposed to be read in one round. |
| 200 | // For the efficiency consideration, don't have the lock of the memory block, the |
| 201 | // safety is implicitly guaranteed by the physical lock of the disk file, which is |
| 202 | // required while removing the disk file and the memory blocks. The other case of |
| 203 | // removing the memory block is when all of the pages have been read, and that could |
| 204 | // only happen after this read. |
| 205 | DCHECK(local_file_lock != nullptr); |
| 206 | read_status = disk_buffer_file_->ReadFromMemBuffer( |
| 207 | offset_, bytes_to_read_, buffer_desc->buffer_, *local_file_lock); |
| 208 | if (read_status.ok()) { |
nothing calls this directly
no test coverage detected