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" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 | 123 |
124 scoped_ptr<LevelDBTransaction::DataIterator> | 124 scoped_ptr<LevelDBTransaction::DataIterator> |
125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { | 125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { |
126 return make_scoped_ptr(new DataIterator(transaction)); | 126 return make_scoped_ptr(new DataIterator(transaction)); |
127 } | 127 } |
128 | 128 |
129 bool LevelDBTransaction::DataIterator::IsValid() const { | 129 bool LevelDBTransaction::DataIterator::IsValid() const { |
130 return iterator_ != data_->end(); | 130 return iterator_ != data_->end(); |
131 } | 131 } |
132 | 132 |
133 void LevelDBTransaction::DataIterator::SeekToLast() { | 133 leveldb::Status LevelDBTransaction::DataIterator::SeekToLast() { |
134 iterator_ = data_->end(); | 134 iterator_ = data_->end(); |
135 if (iterator_ != data_->begin()) | 135 if (iterator_ != data_->begin()) |
136 --iterator_; | 136 --iterator_; |
137 return leveldb::Status::OK(); | |
137 } | 138 } |
138 | 139 |
139 void LevelDBTransaction::DataIterator::Seek(const StringPiece& target) { | 140 leveldb::Status LevelDBTransaction::DataIterator::Seek( |
141 const StringPiece& target) { | |
140 iterator_ = data_->lower_bound(target); | 142 iterator_ = data_->lower_bound(target); |
143 return leveldb::Status::OK(); | |
141 } | 144 } |
142 | 145 |
143 void LevelDBTransaction::DataIterator::Next() { | 146 leveldb::Status LevelDBTransaction::DataIterator::Next() { |
144 DCHECK(IsValid()); | 147 DCHECK(IsValid()); |
145 ++iterator_; | 148 ++iterator_; |
149 return leveldb::Status::OK(); | |
146 } | 150 } |
147 | 151 |
148 void LevelDBTransaction::DataIterator::Prev() { | 152 leveldb::Status LevelDBTransaction::DataIterator::Prev() { |
149 DCHECK(IsValid()); | 153 DCHECK(IsValid()); |
150 if (iterator_ != data_->begin()) | 154 if (iterator_ != data_->begin()) |
151 --iterator_; | 155 --iterator_; |
152 else | 156 else |
153 iterator_ = data_->end(); | 157 iterator_ = data_->end(); |
158 return leveldb::Status::OK(); | |
154 } | 159 } |
155 | 160 |
156 StringPiece LevelDBTransaction::DataIterator::Key() const { | 161 StringPiece LevelDBTransaction::DataIterator::Key() const { |
157 DCHECK(IsValid()); | 162 DCHECK(IsValid()); |
158 return iterator_->first; | 163 return iterator_->first; |
159 } | 164 } |
160 | 165 |
161 StringPiece LevelDBTransaction::DataIterator::Value() const { | 166 StringPiece LevelDBTransaction::DataIterator::Value() const { |
162 DCHECK(IsValid()); | 167 DCHECK(IsValid()); |
163 DCHECK(!IsDeleted()); | 168 DCHECK(!IsDeleted()); |
(...skipping 30 matching lines...) Expand all Loading... | |
194 } | 199 } |
195 | 200 |
196 LevelDBTransaction::TransactionIterator::~TransactionIterator() { | 201 LevelDBTransaction::TransactionIterator::~TransactionIterator() { |
197 transaction_->UnregisterIterator(this); | 202 transaction_->UnregisterIterator(this); |
198 } | 203 } |
199 | 204 |
200 bool LevelDBTransaction::TransactionIterator::IsValid() const { | 205 bool LevelDBTransaction::TransactionIterator::IsValid() const { |
201 return !!current_; | 206 return !!current_; |
202 } | 207 } |
203 | 208 |
204 void LevelDBTransaction::TransactionIterator::SeekToLast() { | 209 leveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() { |
205 data_iterator_->SeekToLast(); | 210 leveldb::Status s = data_iterator_->SeekToLast(); |
jsbell
2014/04/14 20:44:20
DCHECK(s.ok()) since data_iterator_ should never f
cmumford
2014/04/14 23:39:23
Yes, DataIterator::SeekToLast() always returns OK(
| |
206 db_iterator_->SeekToLast(); | 211 if (!s.ok()) |
212 return s; | |
213 s = db_iterator_->SeekToLast(); | |
214 if (!s.ok()) | |
215 return s; | |
207 direction_ = REVERSE; | 216 direction_ = REVERSE; |
208 | 217 |
209 HandleConflictsAndDeletes(); | 218 HandleConflictsAndDeletes(); |
210 SetCurrentIteratorToLargestKey(); | 219 SetCurrentIteratorToLargestKey(); |
220 return s; | |
211 } | 221 } |
212 | 222 |
213 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { | 223 leveldb::Status LevelDBTransaction::TransactionIterator::Seek( |
214 data_iterator_->Seek(target); | 224 const StringPiece& target) { |
215 db_iterator_->Seek(target); | 225 leveldb::Status s = data_iterator_->Seek(target); |
226 if (!s.ok()) | |
227 return s; | |
228 s = db_iterator_->Seek(target); | |
229 if (!s.ok()) | |
230 return s; | |
216 direction_ = FORWARD; | 231 direction_ = FORWARD; |
217 | 232 |
218 HandleConflictsAndDeletes(); | 233 HandleConflictsAndDeletes(); |
219 SetCurrentIteratorToSmallestKey(); | 234 SetCurrentIteratorToSmallestKey(); |
235 return s; | |
220 } | 236 } |
221 | 237 |
222 void LevelDBTransaction::TransactionIterator::Next() { | 238 leveldb::Status LevelDBTransaction::TransactionIterator::Next() { |
223 DCHECK(IsValid()); | 239 DCHECK(IsValid()); |
224 if (data_changed_) | 240 if (data_changed_) |
225 RefreshDataIterator(); | 241 RefreshDataIterator(); |
226 | 242 |
243 leveldb::Status s; | |
227 if (direction_ != FORWARD) { | 244 if (direction_ != FORWARD) { |
228 // Ensure the non-current iterator is positioned after Key(). | 245 // Ensure the non-current iterator is positioned after Key(). |
229 | 246 |
230 LevelDBIterator* non_current = (current_ == db_iterator_.get()) | 247 LevelDBIterator* non_current = (current_ == db_iterator_.get()) |
231 ? data_iterator_.get() | 248 ? data_iterator_.get() |
232 : db_iterator_.get(); | 249 : db_iterator_.get(); |
233 | 250 |
234 non_current->Seek(Key()); | 251 non_current->Seek(Key()); |
235 if (non_current->IsValid() && | 252 if (non_current->IsValid() && |
236 !comparator_->Compare(non_current->Key(), Key())) { | 253 !comparator_->Compare(non_current->Key(), Key())) { |
237 // Take an extra step so the non-current key is | 254 // Take an extra step so the non-current key is |
238 // strictly greater than Key(). | 255 // strictly greater than Key(). |
239 non_current->Next(); | 256 s = non_current->Next(); |
240 } | 257 } |
241 DCHECK(!non_current->IsValid() || | 258 DCHECK(!non_current->IsValid() || |
242 comparator_->Compare(non_current->Key(), Key()) > 0); | 259 comparator_->Compare(non_current->Key(), Key()) > 0); |
243 | 260 |
244 direction_ = FORWARD; | 261 direction_ = FORWARD; |
245 } | 262 } |
246 | 263 |
247 current_->Next(); | 264 if (s.ok()) |
248 HandleConflictsAndDeletes(); | 265 s = current_->Next(); |
249 SetCurrentIteratorToSmallestKey(); | 266 if (s.ok()) { |
267 HandleConflictsAndDeletes(); | |
268 SetCurrentIteratorToSmallestKey(); | |
269 } | |
270 return s; | |
250 } | 271 } |
251 | 272 |
252 void LevelDBTransaction::TransactionIterator::Prev() { | 273 leveldb::Status LevelDBTransaction::TransactionIterator::Prev() { |
253 DCHECK(IsValid()); | 274 DCHECK(IsValid()); |
275 leveldb::Status s; | |
254 if (data_changed_) | 276 if (data_changed_) |
255 RefreshDataIterator(); | 277 RefreshDataIterator(); |
256 | 278 |
257 if (direction_ != REVERSE) { | 279 if (direction_ != REVERSE) { |
258 // Ensure the non-current iterator is positioned before Key(). | 280 // Ensure the non-current iterator is positioned before Key(). |
259 | 281 |
260 LevelDBIterator* non_current = (current_ == db_iterator_.get()) | 282 LevelDBIterator* non_current = (current_ == db_iterator_.get()) |
261 ? data_iterator_.get() | 283 ? data_iterator_.get() |
262 : db_iterator_.get(); | 284 : db_iterator_.get(); |
263 | 285 |
264 non_current->Seek(Key()); | 286 s = non_current->Seek(Key()); |
jsbell
2014/04/14 20:44:20
Does s need to be tested here?
cmumford
2014/04/14 23:39:23
Done.
| |
265 if (non_current->IsValid()) { | 287 if (non_current->IsValid()) { |
266 // Iterator is at first entry >= Key(). | 288 // Iterator is at first entry >= Key(). |
267 // Step back once to entry < key. | 289 // Step back once to entry < key. |
268 // This is why we don't check for the keys being the same before | 290 // This is why we don't check for the keys being the same before |
269 // stepping, like we do in Next() above. | 291 // stepping, like we do in Next() above. |
270 non_current->Prev(); | 292 non_current->Prev(); |
271 } else { | 293 } else { |
272 // Iterator has no entries >= Key(). Position at last entry. | 294 // Iterator has no entries >= Key(). Position at last entry. |
273 non_current->SeekToLast(); | 295 non_current->SeekToLast(); |
274 } | 296 } |
275 DCHECK(!non_current->IsValid() || | 297 DCHECK(!non_current->IsValid() || |
276 comparator_->Compare(non_current->Key(), Key()) < 0); | 298 comparator_->Compare(non_current->Key(), Key()) < 0); |
277 | 299 |
278 direction_ = REVERSE; | 300 direction_ = REVERSE; |
279 } | 301 } |
280 | 302 |
281 current_->Prev(); | 303 if (s.ok()) |
jsbell
2014/04/14 20:44:20
This repeated testing of s.ok() is weird. Can we j
cmumford
2014/04/14 23:39:23
Done.
| |
282 HandleConflictsAndDeletes(); | 304 s = current_->Prev(); |
283 SetCurrentIteratorToLargestKey(); | 305 if (s.ok()) { |
306 HandleConflictsAndDeletes(); | |
307 SetCurrentIteratorToLargestKey(); | |
308 } | |
309 return s; | |
284 } | 310 } |
285 | 311 |
286 StringPiece LevelDBTransaction::TransactionIterator::Key() const { | 312 StringPiece LevelDBTransaction::TransactionIterator::Key() const { |
287 DCHECK(IsValid()); | 313 DCHECK(IsValid()); |
288 if (data_changed_) | 314 if (data_changed_) |
289 RefreshDataIterator(); | 315 RefreshDataIterator(); |
290 return current_->Key(); | 316 return current_->Key(); |
291 } | 317 } |
292 | 318 |
293 StringPiece LevelDBTransaction::TransactionIterator::Value() const { | 319 StringPiece LevelDBTransaction::TransactionIterator::Value() const { |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 | 486 |
461 leveldb::Status s = db_->Write(*write_batch_); | 487 leveldb::Status s = db_->Write(*write_batch_); |
462 if (s.ok()) { | 488 if (s.ok()) { |
463 finished_ = true; | 489 finished_ = true; |
464 write_batch_->Clear(); | 490 write_batch_->Clear(); |
465 } | 491 } |
466 return s; | 492 return s; |
467 } | 493 } |
468 | 494 |
469 } // namespace content | 495 } // namespace content |
OLD | NEW |