Release leveldb 1.11
Fixes issues 161 174 178 As well as the issue reported by edouarda14@gmail.com about MissingSSTFile unit test failing on windows.
This commit is contained in:
parent
28dad918f2
commit
7b094f12e4
6
Makefile
6
Makefile
@ -42,6 +42,7 @@ TESTS = \
|
|||||||
env_test \
|
env_test \
|
||||||
filename_test \
|
filename_test \
|
||||||
filter_block_test \
|
filter_block_test \
|
||||||
|
issue178_test \
|
||||||
log_test \
|
log_test \
|
||||||
memenv_test \
|
memenv_test \
|
||||||
skiplist_test \
|
skiplist_test \
|
||||||
@ -69,7 +70,7 @@ SHARED = $(SHARED1)
|
|||||||
else
|
else
|
||||||
# Update db.h if you change these.
|
# Update db.h if you change these.
|
||||||
SHARED_MAJOR = 1
|
SHARED_MAJOR = 1
|
||||||
SHARED_MINOR = 10
|
SHARED_MINOR = 11
|
||||||
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
|
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
|
||||||
SHARED2 = $(SHARED1).$(SHARED_MAJOR)
|
SHARED2 = $(SHARED1).$(SHARED_MAJOR)
|
||||||
SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
|
SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
|
||||||
@ -146,6 +147,9 @@ filename_test: db/filename_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
|||||||
filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
||||||
$(CXX) $(LDFLAGS) table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
|
$(CXX) $(LDFLAGS) table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
|
||||||
|
|
||||||
|
issue178_test: issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
||||||
|
$(CXX) $(LDFLAGS) issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
|
||||||
|
|
||||||
log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
|
||||||
$(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
|
$(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
|
const int kNumNonTableCacheFiles = 10;
|
||||||
|
|
||||||
// Information kept for every waiting writer
|
// Information kept for every waiting writer
|
||||||
struct DBImpl::Writer {
|
struct DBImpl::Writer {
|
||||||
Status status;
|
Status status;
|
||||||
@ -92,9 +94,9 @@ Options SanitizeOptions(const std::string& dbname,
|
|||||||
Options result = src;
|
Options result = src;
|
||||||
result.comparator = icmp;
|
result.comparator = icmp;
|
||||||
result.filter_policy = (src.filter_policy != NULL) ? ipolicy : NULL;
|
result.filter_policy = (src.filter_policy != NULL) ? ipolicy : NULL;
|
||||||
ClipToRange(&result.max_open_files, 20, 50000);
|
ClipToRange(&result.max_open_files, 64 + kNumNonTableCacheFiles, 50000);
|
||||||
ClipToRange(&result.write_buffer_size, 64<<10, 1<<30);
|
ClipToRange(&result.write_buffer_size, 64<<10, 1<<30);
|
||||||
ClipToRange(&result.block_size, 1<<10, 4<<20);
|
ClipToRange(&result.block_size, 1<<10, 4<<20);
|
||||||
if (result.info_log == NULL) {
|
if (result.info_log == NULL) {
|
||||||
// Open a log file in the same directory as the db
|
// Open a log file in the same directory as the db
|
||||||
src.env->CreateDir(dbname); // In case it does not exist
|
src.env->CreateDir(dbname); // In case it does not exist
|
||||||
@ -130,12 +132,13 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
|
|||||||
log_(NULL),
|
log_(NULL),
|
||||||
tmp_batch_(new WriteBatch),
|
tmp_batch_(new WriteBatch),
|
||||||
bg_compaction_scheduled_(false),
|
bg_compaction_scheduled_(false),
|
||||||
manual_compaction_(NULL) {
|
manual_compaction_(NULL),
|
||||||
|
consecutive_compaction_errors_(0) {
|
||||||
mem_->Ref();
|
mem_->Ref();
|
||||||
has_imm_.Release_Store(NULL);
|
has_imm_.Release_Store(NULL);
|
||||||
|
|
||||||
// Reserve ten files or so for other uses and give the rest to TableCache.
|
// Reserve ten files or so for other uses and give the rest to TableCache.
|
||||||
const int table_cache_size = options.max_open_files - 10;
|
const int table_cache_size = options.max_open_files - kNumNonTableCacheFiles;
|
||||||
table_cache_ = new TableCache(dbname_, &options_, table_cache_size);
|
table_cache_ = new TableCache(dbname_, &options_, table_cache_size);
|
||||||
|
|
||||||
versions_ = new VersionSet(dbname_, &options_, table_cache_,
|
versions_ = new VersionSet(dbname_, &options_, table_cache_,
|
||||||
@ -619,6 +622,7 @@ void DBImpl::BackgroundCall() {
|
|||||||
Status s = BackgroundCompaction();
|
Status s = BackgroundCompaction();
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
// Success
|
// Success
|
||||||
|
consecutive_compaction_errors_ = 0;
|
||||||
} else if (shutting_down_.Acquire_Load()) {
|
} else if (shutting_down_.Acquire_Load()) {
|
||||||
// Error most likely due to shutdown; do not wait
|
// Error most likely due to shutdown; do not wait
|
||||||
} else {
|
} else {
|
||||||
@ -630,7 +634,12 @@ void DBImpl::BackgroundCall() {
|
|||||||
Log(options_.info_log, "Waiting after background compaction error: %s",
|
Log(options_.info_log, "Waiting after background compaction error: %s",
|
||||||
s.ToString().c_str());
|
s.ToString().c_str());
|
||||||
mutex_.Unlock();
|
mutex_.Unlock();
|
||||||
env_->SleepForMicroseconds(1000000);
|
++consecutive_compaction_errors_;
|
||||||
|
int seconds_to_sleep = 1;
|
||||||
|
for (int i = 0; i < 3 && i < consecutive_compaction_errors_ - 1; ++i) {
|
||||||
|
seconds_to_sleep *= 2;
|
||||||
|
}
|
||||||
|
env_->SleepForMicroseconds(seconds_to_sleep * 1000000);
|
||||||
mutex_.Lock();
|
mutex_.Lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +163,7 @@ class DBImpl : public DB {
|
|||||||
|
|
||||||
// Have we encountered a background error in paranoid mode?
|
// Have we encountered a background error in paranoid mode?
|
||||||
Status bg_error_;
|
Status bg_error_;
|
||||||
|
int consecutive_compaction_errors_;
|
||||||
|
|
||||||
// Per level compaction stats. stats_[level] stores the stats for
|
// Per level compaction stats. stats_[level] stores the stats for
|
||||||
// compactions that produced data for the specified "level".
|
// compactions that produced data for the specified "level".
|
||||||
|
@ -33,8 +33,11 @@ class AtomicCounter {
|
|||||||
public:
|
public:
|
||||||
AtomicCounter() : count_(0) { }
|
AtomicCounter() : count_(0) { }
|
||||||
void Increment() {
|
void Increment() {
|
||||||
|
IncrementBy(1);
|
||||||
|
}
|
||||||
|
void IncrementBy(int count) {
|
||||||
MutexLock l(&mu_);
|
MutexLock l(&mu_);
|
||||||
count_++;
|
count_ += count;
|
||||||
}
|
}
|
||||||
int Read() {
|
int Read() {
|
||||||
MutexLock l(&mu_);
|
MutexLock l(&mu_);
|
||||||
@ -45,6 +48,10 @@ class AtomicCounter {
|
|||||||
count_ = 0;
|
count_ = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void DelayMilliseconds(int millis) {
|
||||||
|
Env::Default()->SleepForMicroseconds(millis * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special Env used to delay background operations
|
// Special Env used to delay background operations
|
||||||
@ -69,6 +76,7 @@ class SpecialEnv : public EnvWrapper {
|
|||||||
AtomicCounter random_read_counter_;
|
AtomicCounter random_read_counter_;
|
||||||
|
|
||||||
AtomicCounter sleep_counter_;
|
AtomicCounter sleep_counter_;
|
||||||
|
AtomicCounter sleep_time_counter_;
|
||||||
|
|
||||||
explicit SpecialEnv(Env* base) : EnvWrapper(base) {
|
explicit SpecialEnv(Env* base) : EnvWrapper(base) {
|
||||||
delay_sstable_sync_.Release_Store(NULL);
|
delay_sstable_sync_.Release_Store(NULL);
|
||||||
@ -103,7 +111,7 @@ class SpecialEnv : public EnvWrapper {
|
|||||||
Status Flush() { return base_->Flush(); }
|
Status Flush() { return base_->Flush(); }
|
||||||
Status Sync() {
|
Status Sync() {
|
||||||
while (env_->delay_sstable_sync_.Acquire_Load() != NULL) {
|
while (env_->delay_sstable_sync_.Acquire_Load() != NULL) {
|
||||||
env_->SleepForMicroseconds(100000);
|
DelayMilliseconds(100);
|
||||||
}
|
}
|
||||||
return base_->Sync();
|
return base_->Sync();
|
||||||
}
|
}
|
||||||
@ -174,8 +182,9 @@ class SpecialEnv : public EnvWrapper {
|
|||||||
|
|
||||||
virtual void SleepForMicroseconds(int micros) {
|
virtual void SleepForMicroseconds(int micros) {
|
||||||
sleep_counter_.Increment();
|
sleep_counter_.Increment();
|
||||||
target()->SleepForMicroseconds(micros);
|
sleep_time_counter_.IncrementBy(micros);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DBTest {
|
class DBTest {
|
||||||
@ -625,7 +634,7 @@ TEST(DBTest, GetEncountersEmptyLevel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Wait for compaction to finish
|
// Step 4: Wait for compaction to finish
|
||||||
env_->SleepForMicroseconds(1000000);
|
DelayMilliseconds(1000);
|
||||||
|
|
||||||
ASSERT_EQ(NumTableFilesAtLevel(0), 0);
|
ASSERT_EQ(NumTableFilesAtLevel(0), 0);
|
||||||
} while (ChangeOptions());
|
} while (ChangeOptions());
|
||||||
@ -1309,7 +1318,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_a) {
|
|||||||
Reopen();
|
Reopen();
|
||||||
Reopen();
|
Reopen();
|
||||||
ASSERT_EQ("(a->v)", Contents());
|
ASSERT_EQ("(a->v)", Contents());
|
||||||
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
||||||
ASSERT_EQ("(a->v)", Contents());
|
ASSERT_EQ("(a->v)", Contents());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1325,7 +1334,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_b) {
|
|||||||
Put("","");
|
Put("","");
|
||||||
Reopen();
|
Reopen();
|
||||||
Put("","");
|
Put("","");
|
||||||
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
||||||
Reopen();
|
Reopen();
|
||||||
Put("d","dv");
|
Put("d","dv");
|
||||||
Reopen();
|
Reopen();
|
||||||
@ -1335,7 +1344,7 @@ TEST(DBTest, L0_CompactionBug_Issue44_b) {
|
|||||||
Delete("b");
|
Delete("b");
|
||||||
Reopen();
|
Reopen();
|
||||||
ASSERT_EQ("(->)(c->cv)", Contents());
|
ASSERT_EQ("(->)(c->cv)", Contents());
|
||||||
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
|
DelayMilliseconds(1000); // Wait for compaction to finish
|
||||||
ASSERT_EQ("(->)(c->cv)", Contents());
|
ASSERT_EQ("(->)(c->cv)", Contents());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1520,6 +1529,30 @@ TEST(DBTest, NoSpace) {
|
|||||||
ASSERT_GE(env_->sleep_counter_.Read(), 5);
|
ASSERT_GE(env_->sleep_counter_.Read(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DBTest, ExponentialBackoff) {
|
||||||
|
Options options = CurrentOptions();
|
||||||
|
options.env = env_;
|
||||||
|
Reopen(&options);
|
||||||
|
|
||||||
|
ASSERT_OK(Put("foo", "v1"));
|
||||||
|
ASSERT_EQ("v1", Get("foo"));
|
||||||
|
Compact("a", "z");
|
||||||
|
env_->non_writable_.Release_Store(env_); // Force errors for new files
|
||||||
|
env_->sleep_counter_.Reset();
|
||||||
|
env_->sleep_time_counter_.Reset();
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
dbfull()->TEST_CompactRange(2, NULL, NULL);
|
||||||
|
}
|
||||||
|
env_->non_writable_.Release_Store(NULL);
|
||||||
|
|
||||||
|
// Wait for compaction to finish
|
||||||
|
DelayMilliseconds(1000);
|
||||||
|
|
||||||
|
ASSERT_GE(env_->sleep_counter_.Read(), 5);
|
||||||
|
ASSERT_LT(env_->sleep_counter_.Read(), 10);
|
||||||
|
ASSERT_GE(env_->sleep_time_counter_.Read(), 10e6);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(DBTest, NonWritableFileSystem) {
|
TEST(DBTest, NonWritableFileSystem) {
|
||||||
Options options = CurrentOptions();
|
Options options = CurrentOptions();
|
||||||
options.write_buffer_size = 1000;
|
options.write_buffer_size = 1000;
|
||||||
@ -1533,7 +1566,7 @@ TEST(DBTest, NonWritableFileSystem) {
|
|||||||
fprintf(stderr, "iter %d; errors %d\n", i, errors);
|
fprintf(stderr, "iter %d; errors %d\n", i, errors);
|
||||||
if (!Put("foo", big).ok()) {
|
if (!Put("foo", big).ok()) {
|
||||||
errors++;
|
errors++;
|
||||||
env_->SleepForMicroseconds(100000);
|
DelayMilliseconds(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_GT(errors, 0);
|
ASSERT_GT(errors, 0);
|
||||||
@ -1589,6 +1622,7 @@ TEST(DBTest, MissingSSTFile) {
|
|||||||
dbfull()->TEST_CompactMemTable();
|
dbfull()->TEST_CompactMemTable();
|
||||||
ASSERT_EQ("bar", Get("foo"));
|
ASSERT_EQ("bar", Get("foo"));
|
||||||
|
|
||||||
|
Close();
|
||||||
ASSERT_TRUE(DeleteAnSSTFile());
|
ASSERT_TRUE(DeleteAnSSTFile());
|
||||||
Options options = CurrentOptions();
|
Options options = CurrentOptions();
|
||||||
options.paranoid_checks = true;
|
options.paranoid_checks = true;
|
||||||
@ -1742,13 +1776,13 @@ TEST(DBTest, MultiThreaded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Let them run for a while
|
// Let them run for a while
|
||||||
env_->SleepForMicroseconds(kTestSeconds * 1000000);
|
DelayMilliseconds(kTestSeconds * 1000);
|
||||||
|
|
||||||
// Stop the threads and wait for them to finish
|
// Stop the threads and wait for them to finish
|
||||||
mt.stop.Release_Store(&mt);
|
mt.stop.Release_Store(&mt);
|
||||||
for (int id = 0; id < kNumThreads; id++) {
|
for (int id = 0; id < kNumThreads; id++) {
|
||||||
while (mt.thread_done[id].Acquire_Load() == NULL) {
|
while (mt.thread_done[id].Acquire_Load() == NULL) {
|
||||||
env_->SleepForMicroseconds(100000);
|
DelayMilliseconds(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (ChangeOptions());
|
} while (ChangeOptions());
|
||||||
|
@ -70,7 +70,7 @@ TEST(FileNameTest, Parse) {
|
|||||||
for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) {
|
for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) {
|
||||||
std::string f = errors[i];
|
std::string f = errors[i];
|
||||||
ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f;
|
ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FileNameTest, Construction) {
|
TEST(FileNameTest, Construction) {
|
||||||
|
@ -1331,14 +1331,19 @@ Compaction* VersionSet::CompactRange(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid compacting too much in one shot in case the range is large.
|
// Avoid compacting too much in one shot in case the range is large.
|
||||||
const uint64_t limit = MaxFileSizeForLevel(level);
|
// But we cannot do this for level-0 since level-0 files can overlap
|
||||||
uint64_t total = 0;
|
// and we must not pick one file and drop another older file if the
|
||||||
for (size_t i = 0; i < inputs.size(); i++) {
|
// two files overlap.
|
||||||
uint64_t s = inputs[i]->file_size;
|
if (level > 0) {
|
||||||
total += s;
|
const uint64_t limit = MaxFileSizeForLevel(level);
|
||||||
if (total >= limit) {
|
uint64_t total = 0;
|
||||||
inputs.resize(i + 1);
|
for (size_t i = 0; i < inputs.size(); i++) {
|
||||||
break;
|
uint64_t s = inputs[i]->file_size;
|
||||||
|
total += s;
|
||||||
|
if (total >= limit) {
|
||||||
|
inputs.resize(i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace leveldb {
|
|||||||
|
|
||||||
// Update Makefile if you change these
|
// Update Makefile if you change these
|
||||||
static const int kMajorVersion = 1;
|
static const int kMajorVersion = 1;
|
||||||
static const int kMinorVersion = 10;
|
static const int kMinorVersion = 11;
|
||||||
|
|
||||||
struct Options;
|
struct Options;
|
||||||
struct ReadOptions;
|
struct ReadOptions;
|
||||||
|
88
issues/issue178_test.cc
Normal file
88
issues/issue178_test.cc
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Test for issue 178: a manual compaction causes deleted data to reappear.
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "leveldb/db.h"
|
||||||
|
#include "leveldb/write_batch.h"
|
||||||
|
#include "util/testharness.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const int kNumKeys = 1100000;
|
||||||
|
|
||||||
|
std::string Key1(int i) {
|
||||||
|
char buf[100];
|
||||||
|
snprintf(buf, sizeof(buf), "my_key_%d", i);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Key2(int i) {
|
||||||
|
return Key1(i) + "_xxx";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Issue178 { };
|
||||||
|
|
||||||
|
TEST(Issue178, Test) {
|
||||||
|
// Get rid of any state from an old run.
|
||||||
|
std::string dbpath = leveldb::test::TmpDir() + "/leveldb_cbug_test";
|
||||||
|
DestroyDB(dbpath, leveldb::Options());
|
||||||
|
|
||||||
|
// Open database. Disable compression since it affects the creation
|
||||||
|
// of layers and the code below is trying to test against a very
|
||||||
|
// specific scenario.
|
||||||
|
leveldb::DB* db;
|
||||||
|
leveldb::Options db_options;
|
||||||
|
db_options.create_if_missing = true;
|
||||||
|
db_options.compression = leveldb::kNoCompression;
|
||||||
|
ASSERT_OK(leveldb::DB::Open(db_options, dbpath, &db));
|
||||||
|
|
||||||
|
// create first key range
|
||||||
|
leveldb::WriteBatch batch;
|
||||||
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
|
batch.Put(Key1(i), "value for range 1 key");
|
||||||
|
}
|
||||||
|
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
|
// create second key range
|
||||||
|
batch.Clear();
|
||||||
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
|
batch.Put(Key2(i), "value for range 2 key");
|
||||||
|
}
|
||||||
|
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
|
// delete second key range
|
||||||
|
batch.Clear();
|
||||||
|
for (size_t i = 0; i < kNumKeys; i++) {
|
||||||
|
batch.Delete(Key2(i));
|
||||||
|
}
|
||||||
|
ASSERT_OK(db->Write(leveldb::WriteOptions(), &batch));
|
||||||
|
|
||||||
|
// compact database
|
||||||
|
std::string start_key = Key1(0);
|
||||||
|
std::string end_key = Key1(kNumKeys - 1);
|
||||||
|
leveldb::Slice least(start_key.data(), start_key.size());
|
||||||
|
leveldb::Slice greatest(end_key.data(), end_key.size());
|
||||||
|
|
||||||
|
// commenting out the line below causes the example to work correctly
|
||||||
|
db->CompactRange(&least, &greatest);
|
||||||
|
|
||||||
|
// count the keys
|
||||||
|
leveldb::Iterator* iter = db->NewIterator(leveldb::ReadOptions());
|
||||||
|
size_t num_keys = 0;
|
||||||
|
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||||
|
num_keys++;
|
||||||
|
}
|
||||||
|
delete iter;
|
||||||
|
ASSERT_EQ(kNumKeys, num_keys) << "Bad number of keys";
|
||||||
|
|
||||||
|
// close database
|
||||||
|
delete db;
|
||||||
|
DestroyDB(dbpath, leveldb::Options());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
return leveldb::test::RunAllTests();
|
||||||
|
}
|
@ -109,7 +109,7 @@ TEST(Coding, Varint64) {
|
|||||||
values.push_back(power);
|
values.push_back(power);
|
||||||
values.push_back(power-1);
|
values.push_back(power-1);
|
||||||
values.push_back(power+1);
|
values.push_back(power+1);
|
||||||
};
|
}
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
for (int i = 0; i < values.size(); i++) {
|
for (int i = 0; i < values.size(); i++) {
|
||||||
|
@ -466,7 +466,7 @@ class PosixEnv : public Env {
|
|||||||
result = IOError(fname, errno);
|
result = IOError(fname, errno);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
virtual Status CreateDir(const std::string& name) {
|
virtual Status CreateDir(const std::string& name) {
|
||||||
Status result;
|
Status result;
|
||||||
@ -474,7 +474,7 @@ class PosixEnv : public Env {
|
|||||||
result = IOError(name, errno);
|
result = IOError(name, errno);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
virtual Status DeleteDir(const std::string& name) {
|
virtual Status DeleteDir(const std::string& name) {
|
||||||
Status result;
|
Status result;
|
||||||
@ -482,7 +482,7 @@ class PosixEnv : public Env {
|
|||||||
result = IOError(name, errno);
|
result = IOError(name, errno);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
|
||||||
virtual Status GetFileSize(const std::string& fname, uint64_t* size) {
|
virtual Status GetFileSize(const std::string& fname, uint64_t* size) {
|
||||||
Status s;
|
Status s;
|
||||||
|
Loading…
Reference in New Issue
Block a user