OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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_transaction.h" | 5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" | 8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" |
9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" | 9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" |
10 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 10 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
11 | 11 |
12 using base::StringPiece; | 12 using base::StringPiece; |
13 | 13 |
14 namespace content { | 14 namespace content { |
15 | 15 |
16 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) | 16 LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db) |
17 : db_(db), snapshot_(db), comparator_(db->Comparator()), finished_(false) { | 17 : db_(db), |
18 tree_.abstractor().comparator_ = comparator_; | 18 snapshot_(db), |
| 19 comparator_(db->Comparator()), |
| 20 data_comparator_(comparator_), |
| 21 data_(data_comparator_), |
| 22 finished_(false) {} |
| 23 |
| 24 LevelDBTransaction::Record::Record() : deleted(false) {} |
| 25 LevelDBTransaction::Record::~Record() {} |
| 26 |
| 27 void LevelDBTransaction::Clear() { |
| 28 for (DataType::iterator it = data_.begin(); it != data_.end(); ++it) { |
| 29 delete it->second; |
| 30 } |
| 31 data_.clear(); |
19 } | 32 } |
20 | 33 |
21 LevelDBTransaction::AVLTreeNode::AVLTreeNode() {} | 34 LevelDBTransaction::~LevelDBTransaction() { Clear(); } |
22 LevelDBTransaction::AVLTreeNode::~AVLTreeNode() {} | |
23 | |
24 void LevelDBTransaction::ClearTree() { | |
25 TreeType::Iterator iterator; | |
26 iterator.StartIterLeast(&tree_); | |
27 | |
28 std::vector<AVLTreeNode*> nodes; | |
29 | |
30 while (*iterator) { | |
31 nodes.push_back(*iterator); | |
32 ++iterator; | |
33 } | |
34 tree_.Purge(); | |
35 | |
36 for (size_t i = 0; i < nodes.size(); ++i) | |
37 delete nodes[i]; | |
38 } | |
39 | |
40 LevelDBTransaction::~LevelDBTransaction() { ClearTree(); } | |
41 | 35 |
42 void LevelDBTransaction::Set(const StringPiece& key, | 36 void LevelDBTransaction::Set(const StringPiece& key, |
43 std::string* value, | 37 std::string* value, |
44 bool deleted) { | 38 bool deleted) { |
45 DCHECK(!finished_); | 39 DCHECK(!finished_); |
46 bool new_node = false; | 40 DataType::iterator it = data_.find(key); |
47 AVLTreeNode* node = tree_.Search(key); | |
48 | 41 |
49 if (!node) { | 42 if (it == data_.end()) { |
50 node = new AVLTreeNode; | 43 Record* record = new Record(); |
51 node->key = key.as_string(); | 44 record->key.assign(key.begin(), key.end() - key.begin()); |
52 tree_.Insert(node); | 45 record->value.swap(*value); |
53 new_node = true; | 46 record->deleted = deleted; |
| 47 data_[record->key] = record; |
| 48 NotifyIterators(); |
| 49 return; |
54 } | 50 } |
55 node->value.swap(*value); | |
56 node->deleted = deleted; | |
57 | 51 |
58 if (new_node) | 52 it->second->value.swap(*value); |
59 NotifyIteratorsOfTreeChange(); | 53 it->second->deleted = deleted; |
60 } | 54 } |
61 | 55 |
62 void LevelDBTransaction::Put(const StringPiece& key, std::string* value) { | 56 void LevelDBTransaction::Put(const StringPiece& key, std::string* value) { |
63 Set(key, value, false); | 57 Set(key, value, false); |
64 } | 58 } |
65 | 59 |
66 void LevelDBTransaction::Remove(const StringPiece& key) { | 60 void LevelDBTransaction::Remove(const StringPiece& key) { |
67 std::string empty; | 61 std::string empty; |
68 Set(key, &empty, true); | 62 Set(key, &empty, true); |
69 } | 63 } |
70 | 64 |
71 bool LevelDBTransaction::Get(const StringPiece& key, | 65 bool LevelDBTransaction::Get(const StringPiece& key, |
72 std::string* value, | 66 std::string* value, |
73 bool* found) { | 67 bool* found) { |
74 *found = false; | 68 *found = false; |
75 DCHECK(!finished_); | 69 DCHECK(!finished_); |
76 AVLTreeNode* node = tree_.Search(key); | 70 std::string string_key(key.begin(), key.end() - key.begin()); |
| 71 DataType::const_iterator it = data_.find(string_key); |
77 | 72 |
78 if (node) { | 73 if (it != data_.end()) { |
79 if (node->deleted) | 74 if (it->second->deleted) |
80 return true; | 75 return true; |
81 | 76 |
82 *value = node->value; | 77 *value = it->second->value; |
83 *found = true; | 78 *found = true; |
84 return true; | 79 return true; |
85 } | 80 } |
86 | 81 |
87 bool ok = db_->Get(key, value, found, &snapshot_); | 82 bool ok = db_->Get(key, value, found, &snapshot_); |
88 if (!ok) { | 83 if (!ok) { |
89 DCHECK(!*found); | 84 DCHECK(!*found); |
90 return false; | 85 return false; |
91 } | 86 } |
92 return true; | 87 return true; |
93 } | 88 } |
94 | 89 |
95 bool LevelDBTransaction::Commit() { | 90 bool LevelDBTransaction::Commit() { |
96 DCHECK(!finished_); | 91 DCHECK(!finished_); |
97 | 92 |
98 if (tree_.IsEmpty()) { | 93 if (data_.empty()) { |
99 finished_ = true; | 94 finished_ = true; |
100 return true; | 95 return true; |
101 } | 96 } |
102 | 97 |
103 scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); | 98 scoped_ptr<LevelDBWriteBatch> write_batch = LevelDBWriteBatch::Create(); |
104 | 99 |
105 TreeType::Iterator iterator; | 100 for (DataType::iterator iterator = data_.begin(); iterator != data_.end(); |
106 iterator.StartIterLeast(&tree_); | 101 ++iterator) { |
107 | 102 if (!iterator->second->deleted) |
108 while (*iterator) { | 103 write_batch->Put(iterator->first, iterator->second->value); |
109 AVLTreeNode* node = *iterator; | |
110 if (!node->deleted) | |
111 write_batch->Put(node->key, node->value); | |
112 else | 104 else |
113 write_batch->Remove(node->key); | 105 write_batch->Remove(iterator->first); |
114 ++iterator; | |
115 } | 106 } |
116 | 107 |
117 if (!db_->Write(*write_batch)) | 108 if (!db_->Write(*write_batch)) |
118 return false; | 109 return false; |
119 | 110 |
120 ClearTree(); | 111 Clear(); |
121 finished_ = true; | 112 finished_ = true; |
122 return true; | 113 return true; |
123 } | 114 } |
124 | 115 |
125 void LevelDBTransaction::Rollback() { | 116 void LevelDBTransaction::Rollback() { |
126 DCHECK(!finished_); | 117 DCHECK(!finished_); |
127 finished_ = true; | 118 finished_ = true; |
128 ClearTree(); | 119 Clear(); |
129 } | 120 } |
130 | 121 |
131 scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() { | 122 scoped_ptr<LevelDBIterator> LevelDBTransaction::CreateIterator() { |
132 return TransactionIterator::Create(this).PassAs<LevelDBIterator>(); | 123 return TransactionIterator::Create(this).PassAs<LevelDBIterator>(); |
133 } | 124 } |
134 | 125 |
135 scoped_ptr<LevelDBTransaction::TreeIterator> | 126 scoped_ptr<LevelDBTransaction::DataIterator> |
136 LevelDBTransaction::TreeIterator::Create(LevelDBTransaction* transaction) { | 127 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { |
137 return make_scoped_ptr(new TreeIterator(transaction)); | 128 return make_scoped_ptr(new DataIterator(transaction)); |
138 } | 129 } |
139 | 130 |
140 bool LevelDBTransaction::TreeIterator::IsValid() const { return !!*iterator_; } | 131 bool LevelDBTransaction::DataIterator::IsValid() const { |
141 | 132 return iterator_ != data_->end(); |
142 void LevelDBTransaction::TreeIterator::SeekToLast() { | |
143 iterator_.StartIterGreatest(tree_); | |
144 if (IsValid()) | |
145 key_ = (*iterator_)->key; | |
146 } | 133 } |
147 | 134 |
148 void LevelDBTransaction::TreeIterator::Seek(const StringPiece& target) { | 135 void LevelDBTransaction::DataIterator::SeekToLast() { |
149 iterator_.StartIter(tree_, target, TreeType::EQUAL); | 136 iterator_ = data_->end(); |
150 if (!IsValid()) | 137 if (iterator_ != data_->begin()) |
151 iterator_.StartIter(tree_, target, TreeType::GREATER); | 138 --iterator_; |
152 | |
153 if (IsValid()) | |
154 key_ = (*iterator_)->key; | |
155 } | 139 } |
156 | 140 |
157 void LevelDBTransaction::TreeIterator::Next() { | 141 void LevelDBTransaction::DataIterator::Seek(const StringPiece& target) { |
| 142 iterator_ = data_->lower_bound(target); |
| 143 } |
| 144 |
| 145 void LevelDBTransaction::DataIterator::Next() { |
158 DCHECK(IsValid()); | 146 DCHECK(IsValid()); |
159 ++iterator_; | 147 ++iterator_; |
160 if (IsValid()) { | |
161 DCHECK_GE(transaction_->comparator_->Compare((*iterator_)->key, key_), 0); | |
162 key_ = (*iterator_)->key; | |
163 } | |
164 } | 148 } |
165 | 149 |
166 void LevelDBTransaction::TreeIterator::Prev() { | 150 void LevelDBTransaction::DataIterator::Prev() { |
167 DCHECK(IsValid()); | 151 DCHECK(IsValid()); |
168 --iterator_; | 152 if (iterator_ != data_->begin()) |
169 if (IsValid()) { | 153 --iterator_; |
170 DCHECK_LT(tree_->abstractor().comparator_->Compare((*iterator_)->key, key_), | 154 else |
171 0); | 155 iterator_ = data_->end(); |
172 key_ = (*iterator_)->key; | |
173 } | |
174 } | 156 } |
175 | 157 |
176 StringPiece LevelDBTransaction::TreeIterator::Key() const { | 158 StringPiece LevelDBTransaction::DataIterator::Key() const { |
177 DCHECK(IsValid()); | 159 DCHECK(IsValid()); |
178 return key_; | 160 return iterator_->first; |
179 } | 161 } |
180 | 162 |
181 StringPiece LevelDBTransaction::TreeIterator::Value() const { | 163 StringPiece LevelDBTransaction::DataIterator::Value() const { |
182 DCHECK(IsValid()); | 164 DCHECK(IsValid()); |
183 DCHECK(!IsDeleted()); | 165 DCHECK(!IsDeleted()); |
184 return (*iterator_)->value; | 166 return iterator_->second->value; |
185 } | 167 } |
186 | 168 |
187 bool LevelDBTransaction::TreeIterator::IsDeleted() const { | 169 bool LevelDBTransaction::DataIterator::IsDeleted() const { |
188 DCHECK(IsValid()); | 170 DCHECK(IsValid()); |
189 return (*iterator_)->deleted; | 171 return iterator_->second->deleted; |
190 } | 172 } |
191 | 173 |
192 void LevelDBTransaction::TreeIterator::Reset() { | 174 LevelDBTransaction::DataIterator::~DataIterator() {} |
193 DCHECK(IsValid()); | |
194 iterator_.StartIter(tree_, key_, TreeType::EQUAL); | |
195 DCHECK(IsValid()); | |
196 } | |
197 | 175 |
198 LevelDBTransaction::TreeIterator::~TreeIterator() {} | 176 LevelDBTransaction::DataIterator::DataIterator(LevelDBTransaction* transaction) |
199 | 177 : data_(&transaction->data_), |
200 LevelDBTransaction::TreeIterator::TreeIterator(LevelDBTransaction* transaction) | 178 iterator_(data_->end()) {} |
201 : tree_(&transaction->tree_), transaction_(transaction) {} | |
202 | 179 |
203 scoped_ptr<LevelDBTransaction::TransactionIterator> | 180 scoped_ptr<LevelDBTransaction::TransactionIterator> |
204 LevelDBTransaction::TransactionIterator::Create( | 181 LevelDBTransaction::TransactionIterator::Create( |
205 scoped_refptr<LevelDBTransaction> transaction) { | 182 scoped_refptr<LevelDBTransaction> transaction) { |
206 return make_scoped_ptr(new TransactionIterator(transaction)); | 183 return make_scoped_ptr(new TransactionIterator(transaction)); |
207 } | 184 } |
208 | 185 |
209 LevelDBTransaction::TransactionIterator::TransactionIterator( | 186 LevelDBTransaction::TransactionIterator::TransactionIterator( |
210 scoped_refptr<LevelDBTransaction> transaction) | 187 scoped_refptr<LevelDBTransaction> transaction) |
211 : transaction_(transaction), | 188 : transaction_(transaction), |
212 comparator_(transaction_->comparator_), | 189 comparator_(transaction_->comparator_), |
213 tree_iterator_(TreeIterator::Create(transaction_.get())), | 190 data_iterator_(DataIterator::Create(transaction_.get())), |
214 db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)), | 191 db_iterator_(transaction_->db_->CreateIterator(&transaction_->snapshot_)), |
215 current_(0), | 192 current_(0), |
216 direction_(FORWARD), | 193 direction_(FORWARD), |
217 tree_changed_(false) { | 194 data_changed_(false) { |
218 transaction_->RegisterIterator(this); | 195 transaction_->RegisterIterator(this); |
219 } | 196 } |
220 | 197 |
221 LevelDBTransaction::TransactionIterator::~TransactionIterator() { | 198 LevelDBTransaction::TransactionIterator::~TransactionIterator() { |
222 transaction_->UnregisterIterator(this); | 199 transaction_->UnregisterIterator(this); |
223 } | 200 } |
224 | 201 |
225 bool LevelDBTransaction::TransactionIterator::IsValid() const { | 202 bool LevelDBTransaction::TransactionIterator::IsValid() const { |
226 return !!current_; | 203 return !!current_; |
227 } | 204 } |
228 | 205 |
229 void LevelDBTransaction::TransactionIterator::SeekToLast() { | 206 void LevelDBTransaction::TransactionIterator::SeekToLast() { |
230 tree_iterator_->SeekToLast(); | 207 data_iterator_->SeekToLast(); |
231 db_iterator_->SeekToLast(); | 208 db_iterator_->SeekToLast(); |
232 direction_ = REVERSE; | 209 direction_ = REVERSE; |
233 | 210 |
234 HandleConflictsAndDeletes(); | 211 HandleConflictsAndDeletes(); |
235 SetCurrentIteratorToLargestKey(); | 212 SetCurrentIteratorToLargestKey(); |
236 } | 213 } |
237 | 214 |
238 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { | 215 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { |
239 tree_iterator_->Seek(target); | 216 data_iterator_->Seek(target); |
240 db_iterator_->Seek(target); | 217 db_iterator_->Seek(target); |
241 direction_ = FORWARD; | 218 direction_ = FORWARD; |
242 | 219 |
243 HandleConflictsAndDeletes(); | 220 HandleConflictsAndDeletes(); |
244 SetCurrentIteratorToSmallestKey(); | 221 SetCurrentIteratorToSmallestKey(); |
245 } | 222 } |
246 | 223 |
247 void LevelDBTransaction::TransactionIterator::Next() { | 224 void LevelDBTransaction::TransactionIterator::Next() { |
248 DCHECK(IsValid()); | 225 DCHECK(IsValid()); |
249 if (tree_changed_) | 226 if (data_changed_) |
250 RefreshTreeIterator(); | 227 RefreshDataIterator(); |
251 | 228 |
252 if (direction_ != FORWARD) { | 229 if (direction_ != FORWARD) { |
253 // Ensure the non-current iterator is positioned after Key(). | 230 // Ensure the non-current iterator is positioned after Key(). |
254 | 231 |
255 LevelDBIterator* non_current = (current_ == db_iterator_.get()) | 232 LevelDBIterator* non_current = (current_ == db_iterator_.get()) |
256 ? tree_iterator_.get() | 233 ? data_iterator_.get() |
257 : db_iterator_.get(); | 234 : db_iterator_.get(); |
258 | 235 |
259 non_current->Seek(Key()); | 236 non_current->Seek(Key()); |
260 if (non_current->IsValid() && | 237 if (non_current->IsValid() && |
261 !comparator_->Compare(non_current->Key(), Key())) | 238 !comparator_->Compare(non_current->Key(), Key())) { |
262 non_current->Next(); // Take an extra step so the non-current key is | 239 // Take an extra step so the non-current key is |
263 // strictly greater than Key(). | 240 // strictly greater than Key(). |
264 | 241 non_current->Next(); |
| 242 } |
265 DCHECK(!non_current->IsValid() || | 243 DCHECK(!non_current->IsValid() || |
266 comparator_->Compare(non_current->Key(), Key()) > 0); | 244 comparator_->Compare(non_current->Key(), Key()) > 0); |
267 | 245 |
268 direction_ = FORWARD; | 246 direction_ = FORWARD; |
269 } | 247 } |
270 | 248 |
271 current_->Next(); | 249 current_->Next(); |
272 HandleConflictsAndDeletes(); | 250 HandleConflictsAndDeletes(); |
273 SetCurrentIteratorToSmallestKey(); | 251 SetCurrentIteratorToSmallestKey(); |
274 } | 252 } |
275 | 253 |
276 void LevelDBTransaction::TransactionIterator::Prev() { | 254 void LevelDBTransaction::TransactionIterator::Prev() { |
277 DCHECK(IsValid()); | 255 DCHECK(IsValid()); |
278 if (tree_changed_) | 256 if (data_changed_) |
279 RefreshTreeIterator(); | 257 RefreshDataIterator(); |
280 | 258 |
281 if (direction_ != REVERSE) { | 259 if (direction_ != REVERSE) { |
282 // Ensure the non-current iterator is positioned before Key(). | 260 // Ensure the non-current iterator is positioned before Key(). |
283 | 261 |
284 LevelDBIterator* non_current = (current_ == db_iterator_.get()) | 262 LevelDBIterator* non_current = (current_ == db_iterator_.get()) |
285 ? tree_iterator_.get() | 263 ? data_iterator_.get() |
286 : db_iterator_.get(); | 264 : db_iterator_.get(); |
287 | 265 |
288 non_current->Seek(Key()); | 266 non_current->Seek(Key()); |
289 if (non_current->IsValid()) { | 267 if (non_current->IsValid()) { |
290 // Iterator is at first entry >= Key(). | 268 // Iterator is at first entry >= Key(). |
291 // Step back once to entry < key. | 269 // Step back once to entry < key. |
292 // This is why we don't check for the keys being the same before | 270 // This is why we don't check for the keys being the same before |
293 // stepping, like we do in Next() above. | 271 // stepping, like we do in Next() above. |
294 non_current->Prev(); | 272 non_current->Prev(); |
295 } else { | 273 } else { |
296 non_current->SeekToLast(); // Iterator has no entries >= Key(). Position | 274 // Iterator has no entries >= Key(). Position at last entry. |
297 // at last entry. | 275 non_current->SeekToLast(); |
298 } | 276 } |
299 DCHECK(!non_current->IsValid() || | 277 DCHECK(!non_current->IsValid() || |
300 comparator_->Compare(non_current->Key(), Key()) < 0); | 278 comparator_->Compare(non_current->Key(), Key()) < 0); |
301 | 279 |
302 direction_ = REVERSE; | 280 direction_ = REVERSE; |
303 } | 281 } |
304 | 282 |
305 current_->Prev(); | 283 current_->Prev(); |
306 HandleConflictsAndDeletes(); | 284 HandleConflictsAndDeletes(); |
307 SetCurrentIteratorToLargestKey(); | 285 SetCurrentIteratorToLargestKey(); |
308 } | 286 } |
309 | 287 |
310 StringPiece LevelDBTransaction::TransactionIterator::Key() const { | 288 StringPiece LevelDBTransaction::TransactionIterator::Key() const { |
311 DCHECK(IsValid()); | 289 DCHECK(IsValid()); |
312 if (tree_changed_) | 290 if (data_changed_) |
313 RefreshTreeIterator(); | 291 RefreshDataIterator(); |
314 return current_->Key(); | 292 return current_->Key(); |
315 } | 293 } |
316 | 294 |
317 StringPiece LevelDBTransaction::TransactionIterator::Value() const { | 295 StringPiece LevelDBTransaction::TransactionIterator::Value() const { |
318 DCHECK(IsValid()); | 296 DCHECK(IsValid()); |
319 if (tree_changed_) | 297 if (data_changed_) |
320 RefreshTreeIterator(); | 298 RefreshDataIterator(); |
321 return current_->Value(); | 299 return current_->Value(); |
322 } | 300 } |
323 | 301 |
324 void LevelDBTransaction::TransactionIterator::TreeChanged() { | 302 void LevelDBTransaction::TransactionIterator::DataChanged() { |
325 tree_changed_ = true; | 303 data_changed_ = true; |
326 } | 304 } |
327 | 305 |
328 void LevelDBTransaction::TransactionIterator::RefreshTreeIterator() const { | 306 void LevelDBTransaction::TransactionIterator::RefreshDataIterator() const { |
329 DCHECK(tree_changed_); | 307 DCHECK(data_changed_); |
330 | 308 |
331 tree_changed_ = false; | 309 data_changed_ = false; |
332 | 310 |
333 if (tree_iterator_->IsValid() && tree_iterator_.get() == current_) { | 311 if (data_iterator_->IsValid() && data_iterator_.get() == current_) { |
334 tree_iterator_->Reset(); | |
335 return; | 312 return; |
336 } | 313 } |
337 | 314 |
338 if (db_iterator_->IsValid()) { | 315 if (db_iterator_->IsValid()) { |
339 // There could be new nodes in the tree that we should iterate over. | 316 // There could be new records in data that we should iterate over. |
340 | 317 |
341 if (direction_ == FORWARD) { | 318 if (direction_ == FORWARD) { |
342 // Try to seek tree iterator to something greater than the db iterator. | 319 // Try to seek data iterator to something greater than the db iterator. |
343 tree_iterator_->Seek(db_iterator_->Key()); | 320 data_iterator_->Seek(db_iterator_->Key()); |
344 if (tree_iterator_->IsValid() && | 321 if (data_iterator_->IsValid() && |
345 !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key())) | 322 !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) { |
346 tree_iterator_->Next(); // If equal, take another step so the tree | 323 // If equal, take another step so the data iterator is strictly greater. |
347 // iterator is strictly greater. | 324 data_iterator_->Next(); |
| 325 } |
348 } else { | 326 } else { |
349 // If going backward, seek to a key less than the db iterator. | 327 // If going backward, seek to a key less than the db iterator. |
350 DCHECK_EQ(REVERSE, direction_); | 328 DCHECK_EQ(REVERSE, direction_); |
351 tree_iterator_->Seek(db_iterator_->Key()); | 329 data_iterator_->Seek(db_iterator_->Key()); |
352 if (tree_iterator_->IsValid()) | 330 if (data_iterator_->IsValid()) |
353 tree_iterator_->Prev(); | 331 data_iterator_->Prev(); |
354 } | 332 } |
355 } | 333 } |
356 } | 334 } |
357 | 335 |
358 bool LevelDBTransaction::TransactionIterator::TreeIteratorIsLower() const { | 336 bool LevelDBTransaction::TransactionIterator::DataIteratorIsLower() const { |
359 return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) < 0; | 337 return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) < 0; |
360 } | 338 } |
361 | 339 |
362 bool LevelDBTransaction::TransactionIterator::TreeIteratorIsHigher() const { | 340 bool LevelDBTransaction::TransactionIterator::DataIteratorIsHigher() const { |
363 return comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key()) > 0; | 341 return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) > 0; |
364 } | 342 } |
365 | 343 |
366 void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() { | 344 void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() { |
367 bool loop = true; | 345 bool loop = true; |
368 | 346 |
369 while (loop) { | 347 while (loop) { |
370 loop = false; | 348 loop = false; |
371 | 349 |
372 if (tree_iterator_->IsValid() && db_iterator_->IsValid() && | 350 if (data_iterator_->IsValid() && db_iterator_->IsValid() && |
373 !comparator_->Compare(tree_iterator_->Key(), db_iterator_->Key())) { | 351 !comparator_->Compare(data_iterator_->Key(), db_iterator_->Key())) { |
374 // For equal keys, the tree iterator takes precedence, so move the | 352 // For equal keys, the data iterator takes precedence, so move the |
375 // database iterator another step. | 353 // database iterator another step. |
376 if (direction_ == FORWARD) | 354 if (direction_ == FORWARD) |
377 db_iterator_->Next(); | 355 db_iterator_->Next(); |
378 else | 356 else |
379 db_iterator_->Prev(); | 357 db_iterator_->Prev(); |
380 } | 358 } |
381 | 359 |
382 // Skip over delete markers in the tree iterator until it catches up with | 360 // Skip over delete markers in the data iterator until it catches up with |
383 // the db iterator. | 361 // the db iterator. |
384 if (tree_iterator_->IsValid() && tree_iterator_->IsDeleted()) { | 362 if (data_iterator_->IsValid() && data_iterator_->IsDeleted()) { |
385 if (direction_ == FORWARD && | 363 if (direction_ == FORWARD && |
386 (!db_iterator_->IsValid() || TreeIteratorIsLower())) { | 364 (!db_iterator_->IsValid() || DataIteratorIsLower())) { |
387 tree_iterator_->Next(); | 365 data_iterator_->Next(); |
388 loop = true; | 366 loop = true; |
389 } else if (direction_ == REVERSE && | 367 } else if (direction_ == REVERSE && |
390 (!db_iterator_->IsValid() || TreeIteratorIsHigher())) { | 368 (!db_iterator_->IsValid() || DataIteratorIsHigher())) { |
391 tree_iterator_->Prev(); | 369 data_iterator_->Prev(); |
392 loop = true; | 370 loop = true; |
393 } | 371 } |
394 } | 372 } |
395 } | 373 } |
396 } | 374 } |
397 | 375 |
398 void | 376 void |
399 LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() { | 377 LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() { |
400 LevelDBIterator* smallest = 0; | 378 LevelDBIterator* smallest = 0; |
401 | 379 |
402 if (tree_iterator_->IsValid()) | 380 if (data_iterator_->IsValid()) |
403 smallest = tree_iterator_.get(); | 381 smallest = data_iterator_.get(); |
404 | 382 |
405 if (db_iterator_->IsValid()) { | 383 if (db_iterator_->IsValid()) { |
406 if (!smallest || | 384 if (!smallest || |
407 comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0) | 385 comparator_->Compare(db_iterator_->Key(), smallest->Key()) < 0) |
408 smallest = db_iterator_.get(); | 386 smallest = db_iterator_.get(); |
409 } | 387 } |
410 | 388 |
411 current_ = smallest; | 389 current_ = smallest; |
412 } | 390 } |
413 | 391 |
414 void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() { | 392 void LevelDBTransaction::TransactionIterator::SetCurrentIteratorToLargestKey() { |
415 LevelDBIterator* largest = 0; | 393 LevelDBIterator* largest = 0; |
416 | 394 |
417 if (tree_iterator_->IsValid()) | 395 if (data_iterator_->IsValid()) |
418 largest = tree_iterator_.get(); | 396 largest = data_iterator_.get(); |
419 | 397 |
420 if (db_iterator_->IsValid()) { | 398 if (db_iterator_->IsValid()) { |
421 if (!largest || | 399 if (!largest || |
422 comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0) | 400 comparator_->Compare(db_iterator_->Key(), largest->Key()) > 0) |
423 largest = db_iterator_.get(); | 401 largest = db_iterator_.get(); |
424 } | 402 } |
425 | 403 |
426 current_ = largest; | 404 current_ = largest; |
427 } | 405 } |
428 | 406 |
429 void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) { | 407 void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) { |
430 DCHECK(iterators_.find(iterator) == iterators_.end()); | 408 DCHECK(iterators_.find(iterator) == iterators_.end()); |
431 iterators_.insert(iterator); | 409 iterators_.insert(iterator); |
432 } | 410 } |
433 | 411 |
434 void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) { | 412 void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) { |
435 DCHECK(iterators_.find(iterator) != iterators_.end()); | 413 DCHECK(iterators_.find(iterator) != iterators_.end()); |
436 iterators_.erase(iterator); | 414 iterators_.erase(iterator); |
437 } | 415 } |
438 | 416 |
439 void LevelDBTransaction::NotifyIteratorsOfTreeChange() { | 417 void LevelDBTransaction::NotifyIterators() { |
440 for (std::set<TransactionIterator*>::iterator i = iterators_.begin(); | 418 for (std::set<TransactionIterator*>::iterator i = iterators_.begin(); |
441 i != iterators_.end(); | 419 i != iterators_.end(); |
442 ++i) { | 420 ++i) { |
443 TransactionIterator* transaction_iterator = *i; | 421 TransactionIterator* transaction_iterator = *i; |
444 transaction_iterator->TreeChanged(); | 422 transaction_iterator->DataChanged(); |
445 } | 423 } |
446 } | 424 } |
447 | 425 |
448 scoped_ptr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::Create( | 426 scoped_ptr<LevelDBWriteOnlyTransaction> LevelDBWriteOnlyTransaction::Create( |
449 LevelDBDatabase* db) { | 427 LevelDBDatabase* db) { |
450 return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db)); | 428 return make_scoped_ptr(new LevelDBWriteOnlyTransaction(db)); |
451 } | 429 } |
452 | 430 |
453 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db) | 431 LevelDBWriteOnlyTransaction::LevelDBWriteOnlyTransaction(LevelDBDatabase* db) |
454 : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} | 432 : db_(db), write_batch_(LevelDBWriteBatch::Create()), finished_(false) {} |
(...skipping 12 matching lines...) Expand all Loading... |
467 | 445 |
468 if (!db_->Write(*write_batch_)) | 446 if (!db_->Write(*write_batch_)) |
469 return false; | 447 return false; |
470 | 448 |
471 finished_ = true; | 449 finished_ = true; |
472 write_batch_->Clear(); | 450 write_batch_->Clear(); |
473 return true; | 451 return true; |
474 } | 452 } |
475 | 453 |
476 } // namespace content | 454 } // namespace content |
OLD | NEW |