summaryrefslogtreecommitdiff
path: root/issues
diff options
context:
space:
mode:
authorChris Mumford <cmumford@google.com>2019-04-12 00:16:52 -0700
committerChris Mumford <cmumford@google.com>2019-04-12 00:16:52 -0700
commit7711e76766231bf93e0487c4530b2655e8c4c0b1 (patch)
tree68f12abbbc46ba8c4a17f43208874b7c19a6c8f2 /issues
parent71ed7c401ec1b1e38d6f7cb9eb2fcff93c24d1f1 (diff)
parent20fb601aa9f68ff0aa147df22524b7d01758552b (diff)
downloadleveldb-7711e76766231bf93e0487c4530b2655e8c4c0b1.tar.gz
Merge pull request #339 from richcole-at-amazon:master
PiperOrigin-RevId: 243156105
Diffstat (limited to 'issues')
-rw-r--r--issues/issue320_test.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/issues/issue320_test.cc b/issues/issue320_test.cc
new file mode 100644
index 0000000..a7c37b1
--- /dev/null
+++ b/issues/issue320_test.cc
@@ -0,0 +1,139 @@
+// Copyright (c) 2019 The LevelDB Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file. See the AUTHORS file for names of contributors.
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <math.h>
+
+#include "leveldb/db.h"
+#include "leveldb/write_batch.h"
+#include "util/testharness.h"
+
+using namespace std;
+
+namespace leveldb {
+
+namespace {
+
+unsigned int random(unsigned int max) {
+ return std::rand() % max;
+}
+
+string newString(int32_t index) {
+ const unsigned int len = 1024;
+ char bytes[len];
+ unsigned int i = 0;
+ while (i < 8) {
+ bytes[i] = 'a' + ((index >> (4 * i)) & 0xf);
+ ++i;
+ }
+ while (i < sizeof(bytes)) {
+ bytes[i] = 'a' + random(26);
+ ++i;
+ }
+ return string(bytes, sizeof(bytes));
+}
+
+} // namespace
+
+class Issue320 { };
+
+TEST(Issue320, Test) {
+ std::srand(0);
+
+ bool delete_before_put = false;
+ bool keep_snapshots = true;
+
+ vector<pair<string, string>*> test_map(10000, nullptr);
+ vector<Snapshot const*> snapshots(100, nullptr);
+
+ DB* db;
+ Options options;
+ options.create_if_missing = true;
+
+ std::string dbpath = test::TmpDir() + "/leveldb_issue320_test";
+ ASSERT_OK(DB::Open(options, dbpath, &db));
+
+ unsigned int target_size = 10000;
+ unsigned int num_items = 0;
+ unsigned long count = 0;
+ string key;
+ string value, old_value;
+
+ WriteOptions writeOptions;
+ ReadOptions readOptions;
+ while (count < 200000) {
+ if ((++count % 1000) == 0) {
+ cout << "count: " << count << endl;
+ }
+
+ unsigned int index = random(test_map.size());
+ WriteBatch batch;
+
+ if (test_map[index] == nullptr) {
+ num_items++;
+ test_map[index] =
+ new pair<string, string>(newString(index), newString(index));
+ batch.Put(test_map[index]->first, test_map[index]->second);
+ } else {
+ ASSERT_OK(db->Get(readOptions, test_map[index]->first, &old_value));
+ if (old_value != test_map[index]->second) {
+ cout << "ERROR incorrect value returned by Get" << endl;
+ cout << " count=" << count << endl;
+ cout << " old value=" << old_value << endl;
+ cout << " test_map[index]->second=" << test_map[index]->second << endl;
+ cout << " test_map[index]->first=" << test_map[index]->first << endl;
+ cout << " index=" << index << endl;
+ ASSERT_EQ(old_value, test_map[index]->second);
+ }
+
+ if (num_items >= target_size && random(100) > 30) {
+ batch.Delete(test_map[index]->first);
+ delete test_map[index];
+ test_map[index] = nullptr;
+ --num_items;
+ } else {
+ test_map[index]->second = newString(index);
+ if (delete_before_put) batch.Delete(test_map[index]->first);
+ batch.Put(test_map[index]->first, test_map[index]->second);
+ }
+ }
+
+ ASSERT_OK(db->Write(writeOptions, &batch));
+
+ if (keep_snapshots && random(10) == 0) {
+ unsigned int i = random(snapshots.size());
+ if (snapshots[i] != nullptr) {
+ db->ReleaseSnapshot(snapshots[i]);
+ }
+ snapshots[i] = db->GetSnapshot();
+ }
+ }
+
+ for (Snapshot const* snapshot : snapshots) {
+ if (snapshot) {
+ db->ReleaseSnapshot(snapshot);
+ }
+ }
+
+ for (size_t i = 0; i < test_map.size(); ++i) {
+ if (test_map[i] != nullptr) {
+ delete test_map[i];
+ test_map[i] = nullptr;
+ }
+ }
+
+ delete db;
+ DestroyDB(dbpath, options);
+}
+
+} // namespace leveldb
+
+int main(int argc, char** argv) {
+ return leveldb::test::RunAllTests();
+}