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

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

Issue 2760163002: [IndexedDB] Pool and evict leveldb iterators, to save memory (Closed)
Patch Set: comments Created 3 years, 8 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h" 5 #include "content/browser/indexed_db/leveldb/leveldb_iterator_impl.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
11 12
12 static leveldb::Slice MakeSlice(const base::StringPiece& s) { 13 static leveldb::Slice MakeSlice(const base::StringPiece& s) {
13 return leveldb::Slice(s.begin(), s.size()); 14 return leveldb::Slice(s.begin(), s.size());
14 } 15 }
15 16
16 static base::StringPiece MakeStringPiece(const leveldb::Slice& s) { 17 static base::StringPiece MakeStringPiece(const leveldb::Slice& s) {
17 return base::StringPiece(s.data(), s.size()); 18 return base::StringPiece(s.data(), s.size());
18 } 19 }
19 20
20 namespace content { 21 namespace content {
21 22
22 LevelDBIteratorImpl::~LevelDBIteratorImpl() { 23 LevelDBIteratorImpl::~LevelDBIteratorImpl() {
24 db_->OnIteratorDestroyed(this);
23 } 25 }
24 26
25 LevelDBIteratorImpl::LevelDBIteratorImpl(std::unique_ptr<leveldb::Iterator> it) 27 LevelDBIteratorImpl::LevelDBIteratorImpl(std::unique_ptr<leveldb::Iterator> it,
26 : iterator_(std::move(it)) {} 28 LevelDBDatabase* db,
29 const leveldb::Snapshot* snapshot)
30 : iterator_(std::move(it)), db_(db), snapshot_(snapshot) {}
27 31
28 void LevelDBIteratorImpl::CheckStatus() { 32 leveldb::Status LevelDBIteratorImpl::CheckStatus() {
33 DCHECK(!IsDetached());
29 const leveldb::Status& s = iterator_->status(); 34 const leveldb::Status& s = iterator_->status();
30 if (!s.ok()) 35 if (!s.ok())
31 LOG(ERROR) << "LevelDB iterator error: " << s.ToString(); 36 LOG(ERROR) << "LevelDB iterator error: " << s.ToString();
37 return s;
32 } 38 }
33 39
34 bool LevelDBIteratorImpl::IsValid() const { 40 bool LevelDBIteratorImpl::IsValid() const {
35 return iterator_->Valid(); 41 return iterator_state_ == IteratorState::EVICTED_AND_VALID ||
42 iterator_->Valid();
36 } 43 }
37 44
38 leveldb::Status LevelDBIteratorImpl::SeekToLast() { 45 leveldb::Status LevelDBIteratorImpl::SeekToLast() {
46 WillUseDBIterator();
47 DCHECK(iterator_);
39 iterator_->SeekToLast(); 48 iterator_->SeekToLast();
40 CheckStatus(); 49 return CheckStatus();
41 return iterator_->status();
42 } 50 }
43 51
44 leveldb::Status LevelDBIteratorImpl::Seek(const base::StringPiece& target) { 52 leveldb::Status LevelDBIteratorImpl::Seek(const base::StringPiece& target) {
53 WillUseDBIterator();
54 DCHECK(iterator_);
45 iterator_->Seek(MakeSlice(target)); 55 iterator_->Seek(MakeSlice(target));
46 CheckStatus(); 56 return CheckStatus();
47 return iterator_->status();
48 } 57 }
49 58
50 leveldb::Status LevelDBIteratorImpl::Next() { 59 leveldb::Status LevelDBIteratorImpl::Next() {
51 DCHECK(IsValid()); 60 DCHECK(IsValid());
61 WillUseDBIterator();
62 DCHECK(iterator_);
52 iterator_->Next(); 63 iterator_->Next();
53 CheckStatus(); 64 return CheckStatus();
54 return iterator_->status();
55 } 65 }
56 66
57 leveldb::Status LevelDBIteratorImpl::Prev() { 67 leveldb::Status LevelDBIteratorImpl::Prev() {
58 DCHECK(IsValid()); 68 DCHECK(IsValid());
69 WillUseDBIterator();
70 DCHECK(iterator_);
59 iterator_->Prev(); 71 iterator_->Prev();
60 CheckStatus(); 72 return CheckStatus();
61 return iterator_->status();
62 } 73 }
63 74
64 base::StringPiece LevelDBIteratorImpl::Key() const { 75 base::StringPiece LevelDBIteratorImpl::Key() const {
65 DCHECK(IsValid()); 76 DCHECK(IsValid());
77 if (IsDetached())
78 return key_before_eviction_;
66 return MakeStringPiece(iterator_->key()); 79 return MakeStringPiece(iterator_->key());
67 } 80 }
68 81
69 base::StringPiece LevelDBIteratorImpl::Value() const { 82 base::StringPiece LevelDBIteratorImpl::Value() const {
70 DCHECK(IsValid()); 83 DCHECK(IsValid());
84 // Always need to update the LRU, so we always call this. Const-cast needed,
85 // as we're implementing a caching layer.
86 LevelDBIteratorImpl* non_const = const_cast<LevelDBIteratorImpl*>(this);
87 non_const->WillUseDBIterator();
71 return MakeStringPiece(iterator_->value()); 88 return MakeStringPiece(iterator_->value());
72 } 89 }
73 90
91 void LevelDBIteratorImpl::Detach() {
92 DCHECK(!IsDetached());
93 if (iterator_->Valid()) {
94 iterator_state_ = IteratorState::EVICTED_AND_VALID;
95 key_before_eviction_ = iterator_->key().ToString();
96 } else {
97 iterator_state_ = IteratorState::EVICTED_AND_INVALID;
98 }
99 iterator_.reset();
100 }
101
102 bool LevelDBIteratorImpl::IsDetached() const {
103 return iterator_state_ != IteratorState::ACTIVE;
104 }
105
106 void LevelDBIteratorImpl::WillUseDBIterator() {
107 db_->OnIteratorUsed(this);
108 if (!IsDetached())
109 return;
110
111 iterator_ = db_->CreateLevelDBIterator(snapshot_);
112 if (iterator_state_ == IteratorState::EVICTED_AND_VALID) {
113 iterator_->Seek(key_before_eviction_);
114 key_before_eviction_.clear();
115 DCHECK(IsValid());
116 } else {
117 DCHECK(!iterator_->Valid());
118 }
119 iterator_state_ = IteratorState::ACTIVE;
120 }
121
74 } // namespace content 122 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_iterator_impl.h ('k') | content/browser/indexed_db/leveldb/leveldb_transaction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698