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

Method WriteDirtyPagesAsync

be/src/runtime/bufferpool/buffer-pool.cc:719–768  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

717}
718
719void BufferPool::Client::WriteDirtyPagesAsync(int64_t min_bytes_to_write) {
720 DCHECK_GE(min_bytes_to_write, 0) << DebugStringLocked();
721 DCHECK_LE(min_bytes_to_write, dirty_unpinned_pages_.bytes()) << DebugStringLocked();
722 if (file_group_ == NULL) {
723 // Spilling disabled - there should be no unpinned pages to write.
724 DCHECK_EQ(0, min_bytes_to_write);
725 DCHECK_EQ(0, dirty_unpinned_pages_.bytes());
726 return;
727 }
728 // No point in starting writes if an error occurred because future operations for the
729 // client will fail regardless.
730 if (!write_status_.ok()) return;
731
732 // Compute the ideal amount of writes to start. We use a simple heuristic based on the
733 // total number of writes. The FileGroup's allocation should spread the writes across
734 // disks somewhat, but doesn't guarantee we're fully using all available disks. In
735 // future we could track the # of writes per-disk.
736 const int64_t target_writes = FLAGS_concurrent_scratch_ios_per_device
737 * file_group_->tmp_file_mgr()->NumActiveTmpDevices();
738
739 int64_t bytes_written = 0;
740 while (!dirty_unpinned_pages_.empty()
741 && (bytes_written < min_bytes_to_write
742 || in_flight_write_pages_.size() < target_writes)) {
743 Page* page = dirty_unpinned_pages_.tail(); // LIFO.
744 DCHECK(page != NULL) << "Should have been enough dirty unpinned pages";
745 {
746 lock_guard<SpinLock> pl(page->buffer_lock);
747 DCHECK(file_group_ != NULL);
748 DCHECK(page->buffer.is_open());
749 Status status = file_group_->Write(page->buffer.mem_range(),
750 [this, page](
751 const Status& write_status) { WriteCompleteCallback(page, write_status); },
752 &page->write_handle, &counters_);
753 // Exit early on error: there is no point in starting more writes because future
754 /// operations for this client will fail regardless.
755 if (!status.ok()) {
756 write_status_.MergeStatus(status);
757 return;
758 }
759 COUNTER_ADD(counters().bytes_written, page->write_handle->on_disk_len());
760 COUNTER_ADD(counters().write_io_ops, 1);
761 }
762 // Now that the write is in flight, update all the state
763 Page* tmp = dirty_unpinned_pages_.PopBack();
764 DCHECK_EQ(tmp, page);
765 in_flight_write_pages_.Enqueue(page);
766 bytes_written += page->len;
767 }
768}
769
770void BufferPool::Client::WriteCompleteCallback(Page* page, const Status& write_status) {
771#ifndef NDEBUG

Callers

nothing calls this directly

Calls 14

bytesMethod · 0.80
NumActiveTmpDevicesMethod · 0.80
mem_rangeMethod · 0.80
MergeStatusMethod · 0.80
on_disk_lenMethod · 0.80
okMethod · 0.45
tmp_file_mgrMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45
tailMethod · 0.45
is_openMethod · 0.45
WriteMethod · 0.45

Tested by

no test coverage detected