| 465 | } |
| 466 | |
| 467 | void BufferPool::Client::DestroyPageInternal( |
| 468 | PageHandle* handle, BufferHandle* out_buffer) { |
| 469 | DCHECK(handle->is_pinned() || out_buffer == NULL); |
| 470 | Page* page = handle->page_; |
| 471 | // Remove the page from the list that it is currently present in (if any). |
| 472 | { |
| 473 | unique_lock<mutex> cl(lock_); |
| 474 | // First try to remove from the pinned or dirty unpinned lists. |
| 475 | if (!pinned_pages_.Remove(page) && !dirty_unpinned_pages_.Remove(page)) { |
| 476 | // The page either has a write in flight, is clean, or is evicted. |
| 477 | // Let the write complete, if in flight. |
| 478 | WaitForWrite(&cl, page); |
| 479 | // If clean, remove it from the clean pages list. If evicted, this is a no-op. |
| 480 | pool_->allocator_->RemoveCleanPage(cl, out_buffer != nullptr, page); |
| 481 | } |
| 482 | DCHECK(!page->in_queue()); |
| 483 | --num_pages_; |
| 484 | } |
| 485 | |
| 486 | if (page->write_handle != NULL) { |
| 487 | // Discard any on-disk data. |
| 488 | file_group_->DestroyWriteHandle(move(page->write_handle)); |
| 489 | } |
| 490 | if (out_buffer != NULL) { |
| 491 | DCHECK(page->buffer.is_open()); |
| 492 | *out_buffer = std::move(page->buffer); |
| 493 | buffers_allocated_bytes_ += out_buffer->len(); |
| 494 | } else if (page->buffer.is_open()) { |
| 495 | pool_->allocator_->Free(move(page->buffer)); |
| 496 | } |
| 497 | delete page; |
| 498 | handle->Reset(); |
| 499 | } |
| 500 | |
| 501 | void BufferPool::Client::MoveToDirtyUnpinned(Page* page) { |
| 502 | // Only valid to unpin pages if spilling is enabled. |
no test coverage detected