aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Chromium Automerger <chromium-automerger@android>2013-02-07 07:18:45 +0000
committerAndroid Chromium Automerger <chromium-automerger@android>2013-02-07 07:18:45 +0000
commitc2d7b4cdc20c2be7327e8e720edef2710fceb36c (patch)
tree97f0c58656c7885c4b1d8e25a6e43187f7c2e90f
parent4b2795fc373851344a0e226f1a6a8ff92d3c713a (diff)
parentbbb0263070defe02ffee97b35d0dc31d3f6297a3 (diff)
downloadsrc-c2d7b4cdc20c2be7327e8e720edef2710fceb36c.tar.gz
Merge third_party/leveldatabase/src from https://chromium.googlesource.com/external/leveldb.git at bbb0263070defe02ffee97b35d0dc31d3f6297a3
This commit was generated by merge_from_chromium.py. Change-Id: I190efa357792229ca14ea1419a069eafa4ae8a90
-rw-r--r--db/db_impl.cc16
-rw-r--r--db/db_test.cc31
-rw-r--r--util/hash.cc11
3 files changed, 52 insertions, 6 deletions
diff --git a/db/db_impl.cc b/db/db_impl.cc
index c9de169..058d56d 100644
--- a/db/db_impl.cc
+++ b/db/db_impl.cc
@@ -310,16 +310,24 @@ Status DBImpl::Recover(VersionEdit* edit) {
if (!s.ok()) {
return s;
}
+ std::set<uint64_t> expected;
+ versions_->AddLiveFiles(&expected);
uint64_t number;
FileType type;
std::vector<uint64_t> logs;
for (size_t i = 0; i < filenames.size(); i++) {
- if (ParseFileName(filenames[i], &number, &type)
- && type == kLogFile
- && ((number >= min_log) || (number == prev_log))) {
- logs.push_back(number);
+ if (ParseFileName(filenames[i], &number, &type)) {
+ expected.erase(number);
+ if (type == kLogFile && ((number >= min_log) || (number == prev_log)))
+ logs.push_back(number);
}
}
+ if (!expected.empty()) {
+ char buf[50];
+ snprintf(buf, sizeof(buf), "%d missing files; e.g.",
+ static_cast<int>(expected.size()));
+ return Status::Corruption(buf, TableFileName(dbname_, *(expected.begin())));
+ }
// Recover in the order in which the logs were generated
std::sort(logs.begin(), logs.end());
diff --git a/db/db_test.cc b/db/db_test.cc
index 684ea3b..2f51296 100644
--- a/db/db_test.cc
+++ b/db/db_test.cc
@@ -461,6 +461,20 @@ class DBTest {
}
return result;
}
+
+ bool DeleteAnSSTFile() {
+ std::vector<std::string> filenames;
+ ASSERT_OK(env_->GetChildren(dbname_, &filenames));
+ uint64_t number;
+ FileType type;
+ for (size_t i = 0; i < filenames.size(); i++) {
+ if (ParseFileName(filenames[i], &number, &type) && type == kTableFile) {
+ ASSERT_OK(env_->DeleteFile(TableFileName(dbname_, number)));
+ return true;
+ }
+ }
+ return false;
+ }
};
TEST(DBTest, Empty) {
@@ -1567,6 +1581,23 @@ TEST(DBTest, ManifestWriteError) {
}
}
+TEST(DBTest, MissingSSTFile) {
+ ASSERT_OK(Put("foo", "bar"));
+ ASSERT_EQ("bar", Get("foo"));
+
+ // Dump the memtable to disk.
+ dbfull()->TEST_CompactMemTable();
+ ASSERT_EQ("bar", Get("foo"));
+
+ ASSERT_TRUE(DeleteAnSSTFile());
+ Options options = CurrentOptions();
+ options.paranoid_checks = true;
+ Status s = TryReopen(&options);
+ ASSERT_TRUE(!s.ok());
+ ASSERT_TRUE(s.ToString().find("issing") != std::string::npos)
+ << s.ToString();
+}
+
TEST(DBTest, FilesDeletedAfterCompaction) {
ASSERT_OK(Put("foo", "v2"));
Compact("a", "z");
diff --git a/util/hash.cc b/util/hash.cc
index ba18180..07cf022 100644
--- a/util/hash.cc
+++ b/util/hash.cc
@@ -6,6 +6,13 @@
#include "util/coding.h"
#include "util/hash.h"
+// The FALLTHROUGH_INTENDED macro can be used to annotate implicit fall-through
+// between switch labels. The real definition should be provided externally.
+// This one is a fallback version for unsupported compilers.
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED do { } while (0)
+#endif
+
namespace leveldb {
uint32_t Hash(const char* data, size_t n, uint32_t seed) {
@@ -28,10 +35,10 @@ uint32_t Hash(const char* data, size_t n, uint32_t seed) {
switch (limit - data) {
case 3:
h += data[2] << 16;
- // fall through
+ FALLTHROUGH_INTENDED;
case 2:
h += data[1] << 8;
- // fall through
+ FALLTHROUGH_INTENDED;
case 1:
h += data[0];
h *= m;