51
51
#include " util/auto_roll_logger.h"
52
52
#include " util/build_version.h"
53
53
#include " util/coding.h"
54
+ #include " util/hash_skiplist_rep.h"
54
55
#include " util/logging.h"
55
56
#include " util/mutexlock.h"
56
57
#include " util/perf_context_imp.h"
@@ -163,10 +164,10 @@ Options SanitizeOptions(const std::string& dbname,
163
164
Log (result.info_log , " Compaction filter specified, ignore factory" );
164
165
}
165
166
if (result.prefix_extractor ) {
166
- // If a prefix extractor has been supplied and a PrefixHashRepFactory is
167
+ // If a prefix extractor has been supplied and a HashSkipListRepFactory is
167
168
// being used, make sure that the latter uses the former as its transform
168
169
// function.
169
- auto factory = dynamic_cast <PrefixHashRepFactory *>(
170
+ auto factory = dynamic_cast <HashSkipListRepFactory *>(
170
171
result.memtable_factory .get ());
171
172
if (factory &&
172
173
factory->GetTransform () != result.prefix_extractor ) {
@@ -236,7 +237,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
236
237
mutex_(options.use_adaptive_mutex),
237
238
shutting_down_(nullptr ),
238
239
bg_cv_(&mutex_),
239
- mem_rep_factory_(options_.memtable_factory),
240
+ mem_rep_factory_(options_.memtable_factory.get() ),
240
241
mem_(new MemTable(internal_comparator_, mem_rep_factory_,
241
242
NumberLevels (), options_)),
242
243
logfile_number_(0 ),
@@ -516,6 +517,19 @@ void DBImpl::FindObsoleteFiles(DeletionState& deletion_state,
516
517
// files in sst_delete_files and log_delete_files.
517
518
// It is not necessary to hold the mutex when invoking this method.
518
519
void DBImpl::PurgeObsoleteFiles (DeletionState& state) {
520
+
521
+ // free pending memtables
522
+ for (auto m : state.memtables_to_free ) {
523
+ delete m;
524
+ }
525
+
526
+ // check if there is anything to do
527
+ if (!state.all_files .size () &&
528
+ !state.sst_delete_files .size () &&
529
+ !state.log_delete_files .size ()) {
530
+ return ;
531
+ }
532
+
519
533
// this checks if FindObsoleteFiles() was run before. If not, don't do
520
534
// PurgeObsoleteFiles(). If FindObsoleteFiles() was run, we need to also
521
535
// run PurgeObsoleteFiles(), even if disable_delete_obsolete_files_ is true
@@ -1170,7 +1184,7 @@ Status DBImpl::FlushMemTableToOutputFile(bool* madeProgress,
1170
1184
// Replace immutable memtable with the generated Table
1171
1185
s = imm_.InstallMemtableFlushResults (
1172
1186
mems, versions_.get (), s, &mutex_, options_.info_log .get (),
1173
- file_number, pending_outputs_);
1187
+ file_number, pending_outputs_, &deletion_state. memtables_to_free );
1174
1188
1175
1189
if (s.ok ()) {
1176
1190
if (madeProgress) {
@@ -1656,7 +1670,7 @@ Status DBImpl::BackgroundFlush(bool* madeProgress,
1656
1670
1657
1671
void DBImpl::BackgroundCallFlush () {
1658
1672
bool madeProgress = false ;
1659
- DeletionState deletion_state;
1673
+ DeletionState deletion_state (options_. max_write_buffer_number ) ;
1660
1674
assert (bg_flush_scheduled_);
1661
1675
MutexLock l (&mutex_);
1662
1676
@@ -1702,7 +1716,7 @@ void DBImpl::TEST_PurgeObsoleteteWAL() {
1702
1716
1703
1717
void DBImpl::BackgroundCallCompaction () {
1704
1718
bool madeProgress = false ;
1705
- DeletionState deletion_state;
1719
+ DeletionState deletion_state (options_. max_write_buffer_number ) ;
1706
1720
1707
1721
MaybeDumpStats ();
1708
1722
@@ -1732,6 +1746,7 @@ void DBImpl::BackgroundCallCompaction() {
1732
1746
// FindObsoleteFiles(). This is because deletion_state does not catch
1733
1747
// all created files if compaction failed.
1734
1748
FindObsoleteFiles (deletion_state, !s.ok ());
1749
+
1735
1750
// delete unnecessary files if any, this is done outside the mutex
1736
1751
if (deletion_state.HaveSomethingToDelete ()) {
1737
1752
mutex_.Unlock ();
@@ -2492,25 +2507,20 @@ struct IterState {
2492
2507
2493
2508
static void CleanupIteratorState (void * arg1, void * arg2) {
2494
2509
IterState* state = reinterpret_cast <IterState*>(arg1);
2495
- std::vector<MemTable*> to_delete;
2496
- to_delete. reserve (state-> mem . size () );
2510
+ DBImpl::DeletionState deletion_state (state-> db -> GetOptions ().
2511
+ max_write_buffer_number );
2497
2512
state->mu ->Lock ();
2498
2513
for (unsigned int i = 0 ; i < state->mem .size (); i++) {
2499
2514
MemTable* m = state->mem [i]->Unref ();
2500
2515
if (m != nullptr ) {
2501
- to_delete .push_back (m);
2516
+ deletion_state. memtables_to_free .push_back (m);
2502
2517
}
2503
2518
}
2504
2519
state->version ->Unref ();
2505
- // delete only the sst obsolete files
2506
- DBImpl::DeletionState deletion_state;
2507
2520
// fast path FindObsoleteFiles
2508
2521
state->db ->FindObsoleteFiles (deletion_state, false , true );
2509
2522
state->mu ->Unlock ();
2510
2523
state->db ->PurgeObsoleteFiles (deletion_state);
2511
-
2512
- // delete obsolete memtables outside the db-mutex
2513
- for (MemTable* m : to_delete) delete m;
2514
2524
delete state;
2515
2525
}
2516
2526
} // namespace
@@ -2612,8 +2622,10 @@ Status DBImpl::GetImpl(const ReadOptions& options,
2612
2622
BumpPerfTime (&perf_context.get_snapshot_time , &snapshot_timer);
2613
2623
if (mem->Get (lkey, value, &s, merge_context, options_)) {
2614
2624
// Done
2625
+ RecordTick (options_.statistics .get (), MEMTABLE_HIT);
2615
2626
} else if (imm.Get (lkey, value, &s, merge_context, options_)) {
2616
2627
// Done
2628
+ RecordTick (options_.statistics .get (), MEMTABLE_HIT);
2617
2629
} else {
2618
2630
StopWatchNano from_files_timer (env_, false );
2619
2631
StartPerfTimer (&from_files_timer);
@@ -2622,6 +2634,7 @@ Status DBImpl::GetImpl(const ReadOptions& options,
2622
2634
options_, value_found);
2623
2635
have_stat_update = true ;
2624
2636
BumpPerfTime (&perf_context.get_from_output_files_time , &from_files_timer);
2637
+ RecordTick (options_.statistics .get (), MEMTABLE_MISS);
2625
2638
}
2626
2639
2627
2640
StopWatchNano post_process_timer (env_, false );
@@ -3514,6 +3527,33 @@ void DBImpl::GetLiveFilesMetaData(std::vector<LiveFileMetaData> *metadata) {
3514
3527
return versions_->GetLiveFilesMetaData (metadata);
3515
3528
}
3516
3529
3530
+ Status DBImpl::GetDbIdentity (std::string& identity) {
3531
+ std::string idfilename = IdentityFileName (dbname_);
3532
+ unique_ptr<SequentialFile> idfile;
3533
+ const EnvOptions soptions;
3534
+ Status s = env_->NewSequentialFile (idfilename, &idfile, soptions);
3535
+ if (!s.ok ()) {
3536
+ return s;
3537
+ }
3538
+ uint64_t file_size;
3539
+ s = env_->GetFileSize (idfilename, &file_size);
3540
+ if (!s.ok ()) {
3541
+ return s;
3542
+ }
3543
+ char buffer[file_size];
3544
+ Slice id;
3545
+ s = idfile->Read (file_size, &id, buffer);
3546
+ if (!s.ok ()) {
3547
+ return s;
3548
+ }
3549
+ identity.assign (id.ToString ());
3550
+ // If last character is '\n' remove it from identity
3551
+ if (identity.size () > 0 && identity.back () == ' \n ' ) {
3552
+ identity.pop_back ();
3553
+ }
3554
+ return s;
3555
+ }
3556
+
3517
3557
// Default implementations of convenience methods that subclasses of DB
3518
3558
// can call if they wish
3519
3559
Status DB::Put (const WriteOptions& opt, const Slice& key, const Slice& value) {
0 commit comments