PinnedBlock KeepFileBlockSource::NextBlock() { if (current_block_ >= file_.num_blocks() && fetching_blocks_.empty()) return PinnedBlock(); if (prefetch_size_ == 0) { // operate without prefetching return NextUnpinnedBlock().PinWait(local_worker_id_); } else { // prefetch #desired bytes while (fetching_bytes_ < prefetch_size_ && current_block_ < file_.num_blocks()) { Block b = NextUnpinnedBlock(); fetching_bytes_ += b.size(); fetching_blocks_.emplace_back(b.Pin(local_worker_id_)); } // this might block if the prefetching is not finished PinnedBlock b = fetching_blocks_.front()->Wait(); fetching_bytes_ -= b.size(); fetching_blocks_.pop_front(); return b; } }
void KeepFileBlockSource::Prefetch(size_t prefetch_size) { if (prefetch_size >= prefetch_size_) { prefetch_size_ = prefetch_size; // prefetch #desired bytes while (fetching_bytes_ < prefetch_size_ && current_block_ < file_.num_blocks()) { Block b = NextUnpinnedBlock(); fetching_bytes_ += b.size(); fetching_blocks_.emplace_back(b.Pin(local_worker_id_)); } } else if (prefetch_size < prefetch_size_) { prefetch_size_ = prefetch_size; // cannot discard prefetched Blocks } }