| 415 | } |
| 416 | |
| 417 | void AsyncDataCacheTest::loadBatch( |
| 418 | uint64_t fileNum, |
| 419 | std::vector<Request>& requests, |
| 420 | bool injectError, |
| 421 | Semaphore* semaphore) { |
| 422 | // Pattern for loading a set of buffers from a file: Divide the requested |
| 423 | // ranges between already loaded and loadable from storage. |
| 424 | std::vector<Request*> fromStorage; |
| 425 | std::vector<Request*> fromSsd; |
| 426 | for (auto& request : requests) { |
| 427 | RawFileCacheKey key{fileNum, request.offset}; |
| 428 | if (cache_->exists(key)) { |
| 429 | continue; |
| 430 | } |
| 431 | // Schedule a CoalescedLoad with other keys that need loading from the same |
| 432 | // source. |
| 433 | if (cache_->ssdCache() != nullptr) { |
| 434 | auto& file = cache_->ssdCache()->file(key.fileNum); |
| 435 | request.ssdPin = file.find(key); |
| 436 | if (!request.ssdPin.empty()) { |
| 437 | fromSsd.push_back(&request); |
| 438 | continue; |
| 439 | } |
| 440 | } |
| 441 | fromStorage.push_back(&request); |
| 442 | } |
| 443 | |
| 444 | // Make CoalescedLoads for pins from different sources. |
| 445 | if (!fromStorage.empty()) { |
| 446 | std::vector<RawFileCacheKey> keys; |
| 447 | std::vector<int32_t> sizes; |
| 448 | for (auto request : fromStorage) { |
| 449 | keys.push_back(RawFileCacheKey{fileNum, request->offset}); |
| 450 | sizes.push_back(request->size); |
| 451 | } |
| 452 | auto load = std::make_shared<TestingCoalescedLoad>( |
| 453 | std::move(keys), std::move(sizes), cache_, injectError); |
| 454 | executor()->add([load, semaphore]() { |
| 455 | try { |
| 456 | load->loadOrFuture(nullptr); |
| 457 | } catch (const std::exception& e) { |
| 458 | // Expecting error, ignore. |
| 459 | }; |
| 460 | if (semaphore) { |
| 461 | semaphore->release(); |
| 462 | } |
| 463 | }); |
| 464 | } else if (semaphore) { |
| 465 | semaphore->release(); |
| 466 | } |
| 467 | |
| 468 | if (!fromSsd.empty()) { |
| 469 | std::vector<SsdPin> ssdPins; |
| 470 | std::vector<RawFileCacheKey> keys; |
| 471 | std::vector<int32_t> sizes; |
| 472 | for (auto* request : fromSsd) { |
| 473 | keys.push_back(RawFileCacheKey{fileNum, request->offset}); |
| 474 | sizes.push_back(request->size); |