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

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 & simplifying MRU interaction 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_->NotifyIteratorDestroyed(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 void 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();
32 } 37 }
33 38
34 bool LevelDBIteratorImpl::IsValid() const { 39 bool LevelDBIteratorImpl::IsValid() const {
35 return iterator_->Valid(); 40 return iterator_state_ == IteratorState::EVICTED_AND_VALID ||
41 iterator_->Valid();
36 } 42 }
37 43
38 leveldb::Status LevelDBIteratorImpl::SeekToLast() { 44 leveldb::Status LevelDBIteratorImpl::SeekToLast() {
45 WillUseDBIterator();
46 DCHECK(iterator_);
39 iterator_->SeekToLast(); 47 iterator_->SeekToLast();
40 CheckStatus(); 48 CheckStatus();
pwnall 2017/03/27 17:08:04 I don't know how accepted this is in Chromium / go
dmurph 2017/03/27 21:32:05 sure.
41 return iterator_->status(); 49 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 CheckStatus();
47 return iterator_->status(); 57 return iterator_->status();
48 } 58 }
49 59
50 leveldb::Status LevelDBIteratorImpl::Next() { 60 leveldb::Status LevelDBIteratorImpl::Next() {
51 DCHECK(IsValid()); 61 DCHECK(IsValid());
62 WillUseDBIterator();
63 DCHECK(iterator_);
52 iterator_->Next(); 64 iterator_->Next();
53 CheckStatus(); 65 CheckStatus();
54 return iterator_->status(); 66 return iterator_->status();
55 } 67 }
56 68
57 leveldb::Status LevelDBIteratorImpl::Prev() { 69 leveldb::Status LevelDBIteratorImpl::Prev() {
58 DCHECK(IsValid()); 70 DCHECK(IsValid());
71 WillUseDBIterator();
72 DCHECK(iterator_);
59 iterator_->Prev(); 73 iterator_->Prev();
60 CheckStatus(); 74 CheckStatus();
61 return iterator_->status(); 75 return iterator_->status();
62 } 76 }
63 77
64 base::StringPiece LevelDBIteratorImpl::Key() const { 78 base::StringPiece LevelDBIteratorImpl::Key() const {
65 DCHECK(IsValid()); 79 DCHECK(IsValid());
80 if (IsDetached())
81 return key_before_eviction_;
66 return MakeStringPiece(iterator_->key()); 82 return MakeStringPiece(iterator_->key());
67 } 83 }
68 84
69 base::StringPiece LevelDBIteratorImpl::Value() const { 85 base::StringPiece LevelDBIteratorImpl::Value() const {
70 DCHECK(IsValid()); 86 DCHECK(IsValid());
87 // Always need to update the LRU, so we always call this. Const-cast needed,
88 // as we're dealing with a caching layer.
jsbell 2017/03/27 15:35:34 nit: dealing with -> implementing ??
dmurph 2017/03/27 21:32:05 Done.
89 LevelDBIteratorImpl* non_const = const_cast<LevelDBIteratorImpl*>(this);
90 non_const->WillUseDBIterator();
71 return MakeStringPiece(iterator_->value()); 91 return MakeStringPiece(iterator_->value());
72 } 92 }
73 93
94 void LevelDBIteratorImpl::Detach() {
95 DCHECK(!IsDetached());
96 if (iterator_->Valid()) {
97 iterator_state_ = IteratorState::EVICTED_AND_VALID;
98 key_before_eviction_ = iterator_->key().ToString();
99 } else {
100 iterator_state_ = IteratorState::EVICTED_AND_INVALID;
101 }
102 iterator_.reset();
103 }
104
105 bool LevelDBIteratorImpl::IsDetached() const {
106 return iterator_state_ != IteratorState::ACTIVE;
107 }
108
109 void LevelDBIteratorImpl::WillUseDBIterator() {
110 db_->NotifyIteratorUsed(this);
111 if (!IsDetached())
112 return;
113
114 iterator_ = db_->CreateLevelDBIterator(snapshot_);
115 if (iterator_state_ == IteratorState::EVICTED_AND_VALID) {
116 iterator_->Seek(key_before_eviction_);
117 key_before_eviction_.clear();
118 DCHECK(IsValid());
119 } else {
120 DCHECK(!iterator_->Valid());
121 }
122 iterator_state_ = IteratorState::ACTIVE;
123 }
124
74 } // namespace content 125 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698