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

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 & lifetime fix 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 &leveldb_, kTestingMaxOpenCursors);
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 const std::string key1("key1");
pwnall 2017/03/24 09:16:03 You don't seem to reuse these strings (which is pe
dmurph 2017/03/24 23:33:39 Done.
225 const std::string key2("key2");
226 const std::string key3("key3");
227 const std::string value1("value1");
228 const std::string value2("value2");
229 const std::string value3("value3");
230
231 Put(key1, value1);
232 Put(key2, value2);
233 Put(key3, value3);
234
235 scoped_refptr<LevelDBTransaction> transaction = CreateTransaction();
236
237 std::unique_ptr<LevelDBIterator> evicted_normal_location =
238 transaction->CreateIterator();
239
240 std::unique_ptr<LevelDBIterator> evicted_before_start =
241 transaction->CreateIterator();
242
243 std::unique_ptr<LevelDBIterator> evicted_after_end =
244 transaction->CreateIterator();
245
246 std::unique_ptr<LevelDBIterator> it1 = transaction->CreateIterator();
247 std::unique_ptr<LevelDBIterator> it2 = transaction->CreateIterator();
248 std::unique_ptr<LevelDBIterator> it3 = transaction->CreateIterator();
249
250 evicted_normal_location->Seek("key1");
251 evicted_before_start->Seek("key1");
252 evicted_before_start->Prev();
253 evicted_after_end->SeekToLast();
254 evicted_after_end->Next();
255
256 // Nothing is purged, as we just have 3 iterators used.
257 EXPECT_FALSE(evicted_normal_location->IsEvicted());
258 EXPECT_FALSE(evicted_before_start->IsEvicted());
259 EXPECT_FALSE(evicted_after_end->IsEvicted());
260 EXPECT_FALSE(evicted_before_start->IsValid());
261 EXPECT_FALSE(evicted_after_end->IsValid());
262
263 // Should purge all of our earlier iterators.
264 it1->Seek("key1");
265 it2->Seek("key2");
266 it3->Seek("key3");
267
268 EXPECT_TRUE(evicted_normal_location->IsEvicted());
269 EXPECT_TRUE(evicted_before_start->IsEvicted());
270 EXPECT_TRUE(evicted_after_end->IsEvicted());
271
272 // Check we don't need to reload for just the key.
273 EXPECT_EQ(key1, evicted_normal_location->Key());
274 EXPECT_TRUE(evicted_normal_location->IsEvicted());
275
276 // Make sure iterators are reloaded correctly.
277 EXPECT_TRUE(evicted_normal_location->IsValid());
278 EXPECT_EQ(value1, evicted_normal_location->Value());
279 EXPECT_FALSE(evicted_normal_location->IsEvicted());
280 EXPECT_FALSE(evicted_before_start->IsValid());
281 EXPECT_FALSE(evicted_after_end->IsValid());
282
283 // And our |Value()| call purged the earlier iterator.
284 EXPECT_TRUE(it1->IsEvicted());
285 }
286
213 namespace { 287 namespace {
214 enum RangePrepareMode { 288 enum RangePrepareMode {
215 DataInMemory, 289 DataInMemory,
216 DataInDatabase, 290 DataInDatabase,
217 DataMixed, 291 DataMixed,
218 }; 292 };
219 } // namespace 293 } // namespace
220 294
221 class LevelDBTransactionRangeTest 295 class LevelDBTransactionRangeTest
222 : public LevelDBTransactionTest, 296 : public LevelDBTransactionTest,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 EXPECT_EQ(Compare(key_after_range_, it->Key()), 0); 428 EXPECT_EQ(Compare(key_after_range_, it->Key()), 0);
355 } 429 }
356 430
357 INSTANTIATE_TEST_CASE_P(LevelDBTransactionRangeTests, 431 INSTANTIATE_TEST_CASE_P(LevelDBTransactionRangeTests,
358 LevelDBTransactionRangeTest, 432 LevelDBTransactionRangeTest,
359 ::testing::Values(DataInMemory, 433 ::testing::Values(DataInMemory,
360 DataInDatabase, 434 DataInDatabase,
361 DataMixed)); 435 DataMixed));
362 436
363 } // namespace content 437 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698