Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Side by Side Diff: content/browser/indexed_db/leveldb/leveldb_transaction_unittest.cc

Issue 2760163002: [IndexedDB] Pool and evict leveldb iterators, to save memory (Closed)
Patch Set: comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cstring> 8 #include <cstring>
9 #include <string> 9 #include <string>
10 10
11 #include "base/files/file.h" 11 #include "base/files/file.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h" 13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
16 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 16 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 17 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
18 #include "content/browser/indexed_db/leveldb/leveldb_env.h" 18 #include "content/browser/indexed_db/leveldb/leveldb_env.h"
19 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 19 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
20 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 20 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
21 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/leveldatabase/env_chromium.h" 22 #include "third_party/leveldatabase/env_chromium.h"
23 23
24 namespace content { 24 namespace content {
25 25
26 namespace { 26 namespace {
27 static const size_t kTestingMaxOpenCursors = 3;
27 28
28 class SimpleComparator : public LevelDBComparator { 29 class SimpleComparator : public LevelDBComparator {
29 public: 30 public:
30 int Compare(const base::StringPiece& a, 31 int Compare(const base::StringPiece& a,
31 const base::StringPiece& b) const override { 32 const base::StringPiece& b) const override {
32 size_t len = std::min(a.size(), b.size()); 33 size_t len = std::min(a.size(), b.size());
33 return memcmp(a.begin(), b.begin(), len); 34 return memcmp(a.begin(), b.begin(), len);
34 } 35 }
35 const char* Name() const override { return "temp_comparator"; } 36 const char* Name() const override { return "temp_comparator"; }
36 }; 37 };
37 38
39 } // namespace
40
38 class LevelDBTransactionTest : public testing::Test { 41 class LevelDBTransactionTest : public testing::Test {
39 public: 42 public:
40 LevelDBTransactionTest() {} 43 LevelDBTransactionTest() {}
41 void SetUp() override { 44 void SetUp() override {
42 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir()); 45 ASSERT_TRUE(temp_directory_.CreateUniqueTempDir());
43 LevelDBDatabase::Open(temp_directory_.GetPath(), &comparator_, &leveldb_); 46 leveldb::Status s =
47 LevelDBDatabase::Open(temp_directory_.GetPath(), &comparator_,
48 kTestingMaxOpenCursors, &leveldb_);
49 ASSERT_TRUE(s.ok());
44 ASSERT_TRUE(leveldb_); 50 ASSERT_TRUE(leveldb_);
45 } 51 }
46 void TearDown() override {} 52 void TearDown() override {}
47 53
48 protected: 54 protected:
49 // Convenience methods to access the database outside any 55 // Convenience methods to access the database outside any
50 // transaction to cut down on boilerplate around calls. 56 // transaction to cut down on boilerplate around calls.
51 void Put(const base::StringPiece& key, const std::string& value) { 57 void Put(const base::StringPiece& key, const std::string& value) {
52 std::string put_value = value; 58 std::string put_value = value;
53 leveldb::Status s = leveldb_->Put(key, &put_value); 59 leveldb::Status s = leveldb_->Put(key, &put_value);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 std::string put_value = value; 95 std::string put_value = value;
90 transaction->Put(key, &put_value); 96 transaction->Put(key, &put_value);
91 } 97 }
92 98
93 int Compare(const base::StringPiece& a, const base::StringPiece& b) const { 99 int Compare(const base::StringPiece& a, const base::StringPiece& b) const {
94 return comparator_.Compare(a, b); 100 return comparator_.Compare(a, b);
95 } 101 }
96 102
97 LevelDBDatabase* db() { return leveldb_.get(); } 103 LevelDBDatabase* db() { return leveldb_.get(); }
98 104
105 scoped_refptr<LevelDBTransaction> CreateTransaction() {
106 return new LevelDBTransaction(db());
107 }
108
99 private: 109 private:
100 base::ScopedTempDir temp_directory_; 110 base::ScopedTempDir temp_directory_;
101 SimpleComparator comparator_; 111 SimpleComparator comparator_;
102 std::unique_ptr<LevelDBDatabase> leveldb_; 112 std::unique_ptr<LevelDBDatabase> leveldb_;
103 113
104 DISALLOW_COPY_AND_ASSIGN(LevelDBTransactionTest); 114 DISALLOW_COPY_AND_ASSIGN(LevelDBTransactionTest);
105 }; 115 };
106 116
107 } // namespace
108
109 TEST_F(LevelDBTransactionTest, GetAndPut) { 117 TEST_F(LevelDBTransactionTest, GetAndPut) {
110 leveldb::Status status; 118 leveldb::Status status;
111 119
112 const std::string key("key"); 120 const std::string key("key");
113 std::string got_value; 121 std::string got_value;
114 122
115 const std::string old_value("value"); 123 const std::string old_value("value");
116 Put(key, old_value); 124 Put(key, old_value);
117 125
118 scoped_refptr<LevelDBTransaction> transaction = new LevelDBTransaction(db()); 126 scoped_refptr<LevelDBTransaction> transaction = new LevelDBTransaction(db());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 211
204 Get(key1, &got_value, &found); 212 Get(key1, &got_value, &found);
205 EXPECT_TRUE(found); 213 EXPECT_TRUE(found);
206 EXPECT_EQ(value1, got_value); 214 EXPECT_EQ(value1, got_value);
207 215
208 Get(key2, &got_value, &found); 216 Get(key2, &got_value, &found);
209 EXPECT_TRUE(found); 217 EXPECT_TRUE(found);
210 EXPECT_EQ(value3, got_value); 218 EXPECT_EQ(value3, got_value);
211 } 219 }
212 220
221 TEST_F(LevelDBTransactionTest, IterationWithEvictedCursors) {
222 leveldb::Status status;
223
224 Put("key1", "value1");
225 Put("key2", "value2");
226 Put("key3", "value3");
227
228 scoped_refptr<LevelDBTransaction> transaction = CreateTransaction();
229
230 std::unique_ptr<LevelDBIterator> evicted_normal_location =
231 transaction->CreateIterator();
232
233 std::unique_ptr<LevelDBIterator> evicted_before_start =
234 transaction->CreateIterator();
235
236 std::unique_ptr<LevelDBIterator> evicted_after_end =
237 transaction->CreateIterator();
238
239 std::unique_ptr<LevelDBIterator> it1 = transaction->CreateIterator();
240 std::unique_ptr<LevelDBIterator> it2 = transaction->CreateIterator();
241 std::unique_ptr<LevelDBIterator> it3 = transaction->CreateIterator();
242
243 evicted_normal_location->Seek("key1");
244 evicted_before_start->Seek("key1");
245 evicted_before_start->Prev();
246 evicted_after_end->SeekToLast();
247 evicted_after_end->Next();
248
249 // Nothing is purged, as we just have 3 iterators used.
250 EXPECT_FALSE(evicted_normal_location->IsDetached());
251 EXPECT_FALSE(evicted_before_start->IsDetached());
252 EXPECT_FALSE(evicted_after_end->IsDetached());
253 EXPECT_FALSE(evicted_before_start->IsValid());
254 EXPECT_FALSE(evicted_after_end->IsValid());
255
256 // Should purge all of our earlier iterators.
257 it1->Seek("key1");
258 it2->Seek("key2");
259 it3->Seek("key3");
260
261 EXPECT_TRUE(evicted_normal_location->IsDetached());
262 EXPECT_TRUE(evicted_before_start->IsDetached());
263 EXPECT_TRUE(evicted_after_end->IsDetached());
264
265 // Check we don't need to reload for just the key.
266 EXPECT_EQ("key1", evicted_normal_location->Key());
267 EXPECT_TRUE(evicted_normal_location->IsDetached());
268
269 // Make sure iterators are reloaded correctly.
270 EXPECT_TRUE(evicted_normal_location->IsValid());
271 EXPECT_EQ("value1", evicted_normal_location->Value());
272 EXPECT_FALSE(evicted_normal_location->IsDetached());
273 EXPECT_FALSE(evicted_before_start->IsValid());
274 EXPECT_FALSE(evicted_after_end->IsValid());
275
276 // And our |Value()| call purged the earlier iterator.
277 EXPECT_TRUE(it1->IsDetached());
278 }
279
213 namespace { 280 namespace {
214 enum RangePrepareMode { 281 enum RangePrepareMode {
215 DataInMemory, 282 DataInMemory,
216 DataInDatabase, 283 DataInDatabase,
217 DataMixed, 284 DataMixed,
218 }; 285 };
219 } // namespace 286 } // namespace
220 287
221 class LevelDBTransactionRangeTest 288 class LevelDBTransactionRangeTest
222 : public LevelDBTransactionTest, 289 : public LevelDBTransactionTest,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 EXPECT_EQ(Compare(key_after_range_, it->Key()), 0); 421 EXPECT_EQ(Compare(key_after_range_, it->Key()), 0);
355 } 422 }
356 423
357 INSTANTIATE_TEST_CASE_P(LevelDBTransactionRangeTests, 424 INSTANTIATE_TEST_CASE_P(LevelDBTransactionRangeTests,
358 LevelDBTransactionRangeTest, 425 LevelDBTransactionRangeTest,
359 ::testing::Values(DataInMemory, 426 ::testing::Values(DataInMemory,
360 DataInDatabase, 427 DataInDatabase,
361 DataMixed)); 428 DataMixed));
362 429
363 } // namespace content 430 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_transaction.cc ('k') | content/browser/indexed_db/leveldb/leveldb_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698