| 323 | } |
| 324 | |
| 325 | void CacheInputStream::loadPosition() { |
| 326 | auto offset = region_.offset; |
| 327 | if (pin_.empty()) { |
| 328 | auto load = bufferedInput_->coalescedLoad(this); |
| 329 | if (load) { |
| 330 | folly::SemiFuture<bool> waitFuture(false); |
| 331 | uint64_t usec = 0; |
| 332 | { |
| 333 | MicrosecondTimer timer(&usec); |
| 334 | try { |
| 335 | if (!load->loadOrFuture(&waitFuture)) { |
| 336 | auto& exec = folly::QueuedImmediateExecutor::instance(); |
| 337 | std::move(waitFuture).via(&exec).wait(); |
| 338 | } |
| 339 | } catch (const std::exception& e) { |
| 340 | // Log the error and continue. The error, if it persists, will be hit |
| 341 | // again in looking up the specific entry and thrown from there. |
| 342 | LOG(ERROR) << "IOERR: error in coalesced load " << e.what(); |
| 343 | } |
| 344 | } |
| 345 | ioStats_->queryThreadIoLatency().increment(usec); |
| 346 | } |
| 347 | auto loadRegion = region_; |
| 348 | // Quantize position to previous multiple of 'loadQuantum_'. |
| 349 | loadRegion.offset += (position_ / loadQuantum_) * loadQuantum_; |
| 350 | // Set length to be the lesser of 'loadQuantum_' and distance to end of |
| 351 | // 'region_' |
| 352 | loadRegion.length = std::min<int32_t>( |
| 353 | loadQuantum_, region_.length - (loadRegion.offset - region_.offset)); |
| 354 | loadSync(loadRegion); |
| 355 | } |
| 356 | auto* entry = pin_.checkedEntry(); |
| 357 | uint64_t positionInFile = offset + position_; |
| 358 | if (entry->offset() <= positionInFile && |
| 359 | entry->offset() + entry->size() > positionInFile) { |
| 360 | // The position is inside the range of 'entry'. |
| 361 | auto offsetInEntry = positionInFile - entry->offset(); |
| 362 | if (entry->data().numPages() == 0) { |
| 363 | run_ = reinterpret_cast<uint8_t*>(entry->tinyData()); |
| 364 | runSize_ = entry->size(); |
| 365 | offsetInRun_ = offsetInEntry; |
| 366 | offsetOfRun_ = 0; |
| 367 | } else { |
| 368 | entry->data().findRun(offsetInEntry, &runIndex_, &offsetInRun_); |
| 369 | offsetOfRun_ = offsetInEntry - offsetInRun_; |
| 370 | auto run = entry->data().runAt(runIndex_); |
| 371 | run_ = run.data(); |
| 372 | runSize_ = run.numPages() * memory::AllocationTraits::kPageSize; |
| 373 | if (offsetOfRun_ + runSize_ > entry->size()) { |
| 374 | runSize_ = entry->size() - offsetOfRun_; |
| 375 | } |
| 376 | } |
| 377 | } else { |
| 378 | pin_.clear(); |
| 379 | loadPosition(); |
| 380 | } |
| 381 | } |
| 382 | } // namespace bytedance::bolt::dwio::common |
nothing calls this directly
no test coverage detected