Skip to content

Commit 02ac9f1

Browse files
committed
Merge upstream LevelDB 1.14.
2 parents 936b461 + 0b9a89f commit 02ac9f1

File tree

13 files changed

+137
-13
lines changed

13 files changed

+137
-13
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ Sanjay Ghemawat <[email protected]>
99

1010
# Partial list of contributors:
1111
Kevin Regan <[email protected]>
12+
Johan Bilien <[email protected]>

Makefile

+7-3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ TESTS = \
4444
filename_test \
4545
filter_block_test \
4646
issue178_test \
47+
issue200_test \
4748
log_test \
4849
memenv_test \
4950
skiplist_test \
@@ -71,7 +72,7 @@ SHARED = $(SHARED1)
7172
else
7273
# Update db.h if you change these.
7374
SHARED_MAJOR = 1
74-
SHARED_MINOR = 13
75+
SHARED_MINOR = 14
7576
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
7677
SHARED2 = $(SHARED1).$(SHARED_MAJOR)
7778
SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
@@ -154,6 +155,9 @@ filter_block_test: table/filter_block_test.o $(LIBOBJECTS) $(TESTHARNESS)
154155
issue178_test: issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS)
155156
$(CXX) $(LDFLAGS) issues/issue178_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
156157

158+
issue200_test: issues/issue200_test.o $(LIBOBJECTS) $(TESTHARNESS)
159+
$(CXX) $(LDFLAGS) issues/issue200_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
160+
157161
log_test: db/log_test.o $(LIBOBJECTS) $(TESTHARNESS)
158162
$(CXX) $(LDFLAGS) db/log_test.o $(LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS)
159163

@@ -191,14 +195,14 @@ IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBu
191195
mkdir -p ios-x86/$(dir $@)
192196
$(CXX) $(CXXFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@
193197
mkdir -p ios-arm/$(dir $@)
194-
$(DEVICEROOT)/usr/bin/$(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
198+
xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
195199
lipo ios-x86/$@ ios-arm/$@ -create -output $@
196200

197201
.c.o:
198202
mkdir -p ios-x86/$(dir $@)
199203
$(CC) $(CFLAGS) -isysroot $(SIMULATORROOT)/SDKs/iPhoneSimulator$(IOSVERSION).sdk -arch i686 -c $< -o ios-x86/$@
200204
mkdir -p ios-arm/$(dir $@)
201-
$(DEVICEROOT)/usr/bin/$(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
205+
xcrun -sdk iphoneos $(CC) $(CFLAGS) -isysroot $(DEVICEROOT)/SDKs/iPhoneOS$(IOSVERSION).sdk -arch armv6 -arch armv7 -c $< -o ios-arm/$@
202206
lipo ios-x86/$@ ios-arm/$@ -create -output $@
203207

204208
else

db/db_iter.cc

+5-4
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,13 @@ void DBIter::Next() {
161161
saved_key_.clear();
162162
return;
163163
}
164+
// saved_key_ already contains the key to skip past.
165+
} else {
166+
// Store in saved_key_ the current key so we skip it below.
167+
SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
164168
}
165169

166-
// Temporarily use saved_key_ as storage for key to skip.
167-
std::string* skip = &saved_key_;
168-
SaveKey(ExtractUserKey(iter_->key()), skip);
169-
FindNextUserEntry(true, skip);
170+
FindNextUserEntry(true, &saved_key_);
170171
}
171172

172173
void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {

db/db_test.cc

+35-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ class SpecialEnv : public EnvWrapper {
147147

148148
Status s = target()->NewWritableFile(f, r);
149149
if (s.ok()) {
150-
if (strstr(f.c_str(), ".sst") != NULL) {
150+
if (strstr(f.c_str(), ".ldb") != NULL) {
151151
*r = new SSTableFile(this, *r);
152152
} else if (strstr(f.c_str(), "MANIFEST") != NULL) {
153153
*r = new ManifestFile(this, *r);
@@ -484,6 +484,24 @@ class DBTest {
484484
}
485485
return false;
486486
}
487+
488+
// Returns number of files renamed.
489+
int RenameLDBToSST() {
490+
std::vector<std::string> filenames;
491+
ASSERT_OK(env_->GetChildren(dbname_, &filenames));
492+
uint64_t number;
493+
FileType type;
494+
int files_renamed = 0;
495+
for (size_t i = 0; i < filenames.size(); i++) {
496+
if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {
497+
const std::string from = TableFileName(dbname_, number);
498+
const std::string to = SSTTableFileName(dbname_, number);
499+
ASSERT_OK(env_->RenameFile(from, to));
500+
files_renamed++;
501+
}
502+
}
503+
return files_renamed;
504+
}
487505
};
488506

489507
TEST(DBTest, Empty) {
@@ -1632,6 +1650,22 @@ TEST(DBTest, MissingSSTFile) {
16321650
<< s.ToString();
16331651
}
16341652

1653+
TEST(DBTest, StillReadSST) {
1654+
ASSERT_OK(Put("foo", "bar"));
1655+
ASSERT_EQ("bar", Get("foo"));
1656+
1657+
// Dump the memtable to disk.
1658+
dbfull()->TEST_CompactMemTable();
1659+
ASSERT_EQ("bar", Get("foo"));
1660+
Close();
1661+
ASSERT_GT(RenameLDBToSST(), 0);
1662+
Options options = CurrentOptions();
1663+
options.paranoid_checks = true;
1664+
Status s = TryReopen(&options);
1665+
ASSERT_TRUE(s.ok());
1666+
ASSERT_EQ("bar", Get("foo"));
1667+
}
1668+
16351669
TEST(DBTest, FilesDeletedAfterCompaction) {
16361670
ASSERT_OK(Put("foo", "v2"));
16371671
Compact("a", "z");

db/filename.cc

+7-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ std::string LogFileName(const std::string& name, uint64_t number) {
3030
}
3131

3232
std::string TableFileName(const std::string& name, uint64_t number) {
33+
assert(number > 0);
34+
return MakeFileName(name, number, "ldb");
35+
}
36+
37+
std::string SSTTableFileName(const std::string& name, uint64_t number) {
3338
assert(number > 0);
3439
return MakeFileName(name, number, "sst");
3540
}
@@ -71,7 +76,7 @@ std::string OldInfoLogFileName(const std::string& dbname) {
7176
// dbname/LOG
7277
// dbname/LOG.old
7378
// dbname/MANIFEST-[0-9]+
74-
// dbname/[0-9]+.(log|sst)
79+
// dbname/[0-9]+.(log|sst|ldb)
7580
bool ParseFileName(const std::string& fname,
7681
uint64_t* number,
7782
FileType* type) {
@@ -106,7 +111,7 @@ bool ParseFileName(const std::string& fname,
106111
Slice suffix = rest;
107112
if (suffix == Slice(".log")) {
108113
*type = kLogFile;
109-
} else if (suffix == Slice(".sst")) {
114+
} else if (suffix == Slice(".sst") || suffix == Slice(".ldb")) {
110115
*type = kTableFile;
111116
} else if (suffix == Slice(".dbtmp")) {
112117
*type = kTempFile;

db/filename.h

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ extern std::string LogFileName(const std::string& dbname, uint64_t number);
3737
// "dbname".
3838
extern std::string TableFileName(const std::string& dbname, uint64_t number);
3939

40+
// Return the legacy file name for an sstable with the specified number
41+
// in the db named by "dbname". The result will be prefixed with
42+
// "dbname".
43+
extern std::string SSTTableFileName(const std::string& dbname, uint64_t number);
44+
4045
// Return the name of the descriptor file for the db named by
4146
// "dbname" and the specified incarnation number. The result will be
4247
// prefixed with "dbname".

db/filename_test.cc

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ TEST(FileNameTest, Parse) {
2727
{ "100.log", 100, kLogFile },
2828
{ "0.log", 0, kLogFile },
2929
{ "0.sst", 0, kTableFile },
30+
{ "0.ldb", 0, kTableFile },
3031
{ "CURRENT", 0, kCurrentFile },
3132
{ "LOCK", 0, kDBLockFile },
3233
{ "MANIFEST-2", 2, kDescriptorFile },

db/repair.cc

+8
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ class Repairer {
263263
std::string fname = TableFileName(dbname_, t->meta.number);
264264
int counter = 0;
265265
Status status = env_->GetFileSize(fname, &t->meta.file_size);
266+
if (!status.ok()) {
267+
fname = SSTTableFileName(dbname_, t->meta.number);
268+
Status s2 = env_->GetFileSize(fname, &t->meta.file_size);
269+
if (s2.ok())
270+
status = Status::OK();
271+
}
266272
if (status.ok()) {
267273
Iterator* iter = table_cache_->NewIterator(
268274
ReadOptions(), t->meta.number, t->meta.file_size);
@@ -293,6 +299,8 @@ class Repairer {
293299
}
294300
delete iter;
295301
}
302+
// If there was trouble opening an .sst file this will report that the .ldb
303+
// file was not found, which is kind of lame but shouldn't happen often.
296304
Log(options_.info_log, "Table #%llu: %d entries %s",
297305
(unsigned long long) t->meta.number,
298306
counter,

db/table_cache.cc

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
5454
RandomAccessFile* file = NULL;
5555
Table* table = NULL;
5656
s = env_->NewRandomAccessFile(fname, &file);
57+
if (!s.ok()) {
58+
std::string old_fname = SSTTableFileName(dbname_, file_number);
59+
if (env_->NewRandomAccessFile(old_fname, &file).ok()) {
60+
s = Status::OK();
61+
}
62+
}
5763
if (s.ok()) {
5864
s = Table::Open(*options_, file, file_size, &table);
5965
}

doc/impl.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ <h1>Files</h1>
1111

1212
The implementation of leveldb is similar in spirit to the
1313
representation of a single
14-
<a href="http://labs.google.com/papers/bigtable.html">
14+
<a href="http://research.google.com/archive/bigtable.html">
1515
Bigtable tablet (section 5.3)</a>.
1616
However the organization of the files that make up the representation
1717
is somewhat different and is explained below.

include/leveldb/db.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace leveldb {
1414

1515
// Update Makefile if you change these
1616
static const int kMajorVersion = 1;
17-
static const int kMinorVersion = 13;
17+
static const int kMinorVersion = 14;
1818

1919
struct Options;
2020
struct ReadOptions;

issues/issue200_test.cc

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2013 The LevelDB Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4+
5+
// Test for issue 200: when iterator switches direction from backward
6+
// to forward, the current key can be yielded unexpectedly if a new
7+
// mutation has been added just before the current key.
8+
9+
#include "leveldb/db.h"
10+
#include "util/testharness.h"
11+
12+
namespace leveldb {
13+
14+
class Issue200 { };
15+
16+
TEST(Issue200, Test) {
17+
// Get rid of any state from an old run.
18+
std::string dbpath = test::TmpDir() + "/leveldb_issue200_test";
19+
DestroyDB(dbpath, Options());
20+
21+
DB *db;
22+
Options options;
23+
options.create_if_missing = true;
24+
ASSERT_OK(DB::Open(options, dbpath, &db));
25+
26+
WriteOptions write_options;
27+
ASSERT_OK(db->Put(write_options, "1", "b"));
28+
ASSERT_OK(db->Put(write_options, "2", "c"));
29+
ASSERT_OK(db->Put(write_options, "3", "d"));
30+
ASSERT_OK(db->Put(write_options, "4", "e"));
31+
ASSERT_OK(db->Put(write_options, "5", "f"));
32+
33+
ReadOptions read_options;
34+
Iterator *iter = db->NewIterator(read_options);
35+
36+
// Add an element that should not be reflected in the iterator.
37+
ASSERT_OK(db->Put(write_options, "25", "cd"));
38+
39+
iter->Seek("5");
40+
ASSERT_EQ(iter->key().ToString(), "5");
41+
iter->Prev();
42+
ASSERT_EQ(iter->key().ToString(), "4");
43+
iter->Prev();
44+
ASSERT_EQ(iter->key().ToString(), "3");
45+
iter->Next();
46+
ASSERT_EQ(iter->key().ToString(), "4");
47+
iter->Next();
48+
ASSERT_EQ(iter->key().ToString(), "5");
49+
50+
delete iter;
51+
delete db;
52+
DestroyDB(dbpath, options);
53+
}
54+
55+
} // namespace leveldb
56+
57+
int main(int argc, char** argv) {
58+
return leveldb::test::RunAllTests();
59+
}

util/arena.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ char* Arena::AllocateFallback(size_t bytes) {
4040
}
4141

4242
char* Arena::AllocateAligned(size_t bytes) {
43-
const int align = sizeof(void*); // We'll align to pointer size
43+
const int align = (sizeof(void*) > 8) ? sizeof(void*) : 8;
4444
assert((align & (align-1)) == 0); // Pointer size should be a power of 2
4545
size_t current_mod = reinterpret_cast<uintptr_t>(alloc_ptr_) & (align-1);
4646
size_t slop = (current_mod == 0 ? 0 : align - current_mod);

0 commit comments

Comments
 (0)