| 593 | } |
| 594 | |
| 595 | void DBImpl::TEST_CompactRange(int level, const Slice* begin, |
| 596 | const Slice* end) { |
| 597 | assert(level >= 0); |
| 598 | assert(level + 1 < config::kNumLevels); |
| 599 | |
| 600 | InternalKey begin_storage, end_storage; |
| 601 | |
| 602 | ManualCompaction manual; |
| 603 | manual.level = level; |
| 604 | manual.done = false; |
| 605 | if (begin == nullptr) { |
| 606 | manual.begin = nullptr; |
| 607 | } else { |
| 608 | begin_storage = InternalKey(*begin, kMaxSequenceNumber, kValueTypeForSeek); |
| 609 | manual.begin = &begin_storage; |
| 610 | } |
| 611 | if (end == nullptr) { |
| 612 | manual.end = nullptr; |
| 613 | } else { |
| 614 | end_storage = InternalKey(*end, 0, static_cast<ValueType>(0)); |
| 615 | manual.end = &end_storage; |
| 616 | } |
| 617 | |
| 618 | MutexLock l(&mutex_); |
| 619 | while (!manual.done && !shutting_down_.load(std::memory_order_acquire) && |
| 620 | bg_error_.ok()) { |
| 621 | if (manual_compaction_ == nullptr) { // Idle |
| 622 | manual_compaction_ = &manual; |
| 623 | MaybeScheduleCompaction(); |
| 624 | } else { // Running either my compaction or another compaction. |
| 625 | background_work_finished_signal_.Wait(); |
| 626 | } |
| 627 | } |
| 628 | if (manual_compaction_ == &manual) { |
| 629 | // Cancel my manual compaction since we aborted early for some reason. |
| 630 | manual_compaction_ = nullptr; |
| 631 | } |
| 632 | } |
| 633 | |
| 634 | Status DBImpl::TEST_CompactMemTable() { |
| 635 | // nullptr batch means just wait for earlier writes to be done |