7
7
// Use of this source code is governed by a BSD-style license that can be
8
8
// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
9
10
+ #define __STDC_FORMAT_MACROS
10
11
#include " db/version_set.h"
11
12
13
+ #include < inttypes.h>
12
14
#include < algorithm>
13
15
#include < climits>
14
16
#include < stdio.h>
@@ -1435,6 +1437,7 @@ VersionSet::VersionSet(const std::string& dbname, const Options* options,
1435
1437
icmp_(*cmp),
1436
1438
next_file_number_(2 ),
1437
1439
manifest_file_number_(0 ), // Filled by Recover()
1440
+ pending_manifest_file_number_(0 ),
1438
1441
last_sequence_(0 ),
1439
1442
log_number_(0 ),
1440
1443
prev_log_number_(0 ),
@@ -1527,22 +1530,17 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
1527
1530
1528
1531
// Initialize new descriptor log file if necessary by creating
1529
1532
// a temporary file that contains a snapshot of the current version.
1530
- std::string new_manifest_filename;
1531
1533
uint64_t new_manifest_file_size = 0 ;
1532
1534
Status s;
1533
- // we will need this if we are creating new manifest
1534
- uint64_t old_manifest_file_number = manifest_file_number_;
1535
1535
1536
- // No need to perform this check if a new Manifest is being created anyways.
1536
+ assert (pending_manifest_file_number_ == 0 );
1537
1537
if (!descriptor_log_ ||
1538
1538
manifest_file_size_ > options_->max_manifest_file_size ) {
1539
+ pending_manifest_file_number_ = NewFileNumber ();
1540
+ batch_edits.back ()->SetNextFile (next_file_number_);
1539
1541
new_descriptor_log = true ;
1540
- manifest_file_number_ = NewFileNumber (); // Change manifest file no.
1541
- }
1542
-
1543
- if (new_descriptor_log) {
1544
- new_manifest_filename = DescriptorFileName (dbname_, manifest_file_number_);
1545
- edit->SetNextFile (next_file_number_);
1542
+ } else {
1543
+ pending_manifest_file_number_ = manifest_file_number_;
1546
1544
}
1547
1545
1548
1546
// Unlock during expensive operations. New writes cannot get here
@@ -1562,10 +1560,11 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
1562
1560
1563
1561
// This is fine because everything inside of this block is serialized --
1564
1562
// only one thread can be here at the same time
1565
- if (!new_manifest_filename. empty () ) {
1563
+ if (new_descriptor_log ) {
1566
1564
unique_ptr<WritableFile> descriptor_file;
1567
- s = env_->NewWritableFile (new_manifest_filename, &descriptor_file,
1568
- storage_options_.AdaptForLogWrite ());
1565
+ s = env_->NewWritableFile (
1566
+ DescriptorFileName (dbname_, pending_manifest_file_number_),
1567
+ &descriptor_file, storage_options_.AdaptForLogWrite ());
1569
1568
if (s.ok ()) {
1570
1569
descriptor_log_.reset (new log ::Writer (std::move (descriptor_file)));
1571
1570
s = WriteSnapshot (descriptor_log_.get ());
@@ -1604,7 +1603,7 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
1604
1603
for (auto & e : batch_edits) {
1605
1604
std::string record;
1606
1605
e->EncodeTo (&record);
1607
- if (!ManifestContains (record)) {
1606
+ if (!ManifestContains (pending_manifest_file_number_, record)) {
1608
1607
all_records_in = false ;
1609
1608
break ;
1610
1609
}
@@ -1621,17 +1620,16 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
1621
1620
1622
1621
// If we just created a new descriptor file, install it by writing a
1623
1622
// new CURRENT file that points to it.
1624
- if (s.ok () && !new_manifest_filename. empty () ) {
1625
- s = SetCurrentFile (env_, dbname_, manifest_file_number_ );
1626
- if (s.ok () && old_manifest_file_number < manifest_file_number_) {
1623
+ if (s.ok () && new_descriptor_log ) {
1624
+ s = SetCurrentFile (env_, dbname_, pending_manifest_file_number_ );
1625
+ if (s.ok () && pending_manifest_file_number_ > manifest_file_number_) {
1627
1626
// delete old manifest file
1628
1627
Log (options_->info_log ,
1629
- " Deleting manifest %lu current manifest %lu\n " ,
1630
- (unsigned long )old_manifest_file_number,
1631
- (unsigned long )manifest_file_number_);
1628
+ " Deleting manifest %" PRIu64 " current manifest %" PRIu64 " \n " ,
1629
+ manifest_file_number_, pending_manifest_file_number_);
1632
1630
// we don't care about an error here, PurgeObsoleteFiles will take care
1633
1631
// of it later
1634
- env_->DeleteFile (DescriptorFileName (dbname_, old_manifest_file_number ));
1632
+ env_->DeleteFile (DescriptorFileName (dbname_, manifest_file_number_ ));
1635
1633
}
1636
1634
if (!options_->disableDataSync && db_directory != nullptr ) {
1637
1635
db_directory->Fsync ();
@@ -1649,23 +1647,25 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
1649
1647
1650
1648
// Install the new version
1651
1649
if (s.ok ()) {
1650
+ manifest_file_number_ = pending_manifest_file_number_;
1652
1651
manifest_file_size_ = new_manifest_file_size;
1653
1652
AppendVersion (v);
1654
1653
if (max_log_number_in_batch != 0 ) {
1655
1654
assert (log_number_ < max_log_number_in_batch);
1656
1655
log_number_ = max_log_number_in_batch;
1657
1656
}
1658
1657
prev_log_number_ = edit->prev_log_number_ ;
1659
-
1660
1658
} else {
1661
1659
Log (options_->info_log , " Error in committing version %lu" ,
1662
1660
(unsigned long )v->GetVersionNumber ());
1663
1661
delete v;
1664
- if (!new_manifest_filename. empty () ) {
1662
+ if (new_descriptor_log ) {
1665
1663
descriptor_log_.reset ();
1666
- env_->DeleteFile (new_manifest_filename);
1664
+ env_->DeleteFile (
1665
+ DescriptorFileName (dbname_, pending_manifest_file_number_));
1667
1666
}
1668
1667
}
1668
+ pending_manifest_file_number_ = 0 ;
1669
1669
1670
1670
// wake up all the waiting writers
1671
1671
while (true ) {
@@ -2103,8 +2103,10 @@ Status VersionSet::WriteSnapshot(log::Writer* log) {
2103
2103
2104
2104
// Opens the mainfest file and reads all records
2105
2105
// till it finds the record we are looking for.
2106
- bool VersionSet::ManifestContains (const std::string& record) const {
2107
- std::string fname = DescriptorFileName (dbname_, manifest_file_number_);
2106
+ bool VersionSet::ManifestContains (uint64_t manifest_file_number,
2107
+ const std::string& record) const {
2108
+ std::string fname =
2109
+ DescriptorFileName (dbname_, manifest_file_number);
2108
2110
Log (options_->info_log , " ManifestContains: checking %s\n " , fname.c_str ());
2109
2111
unique_ptr<SequentialFile> file;
2110
2112
Status s = env_->NewSequentialFile (fname, &file, storage_options_);
0 commit comments