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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 6 #define CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/strings/string_piece.h" 16 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 17 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 18 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 19 20 namespace content { 21 22 class LevelDBWriteBatch; 23 24 class CONTENT_EXPORT LevelDBTransaction 25 : public base::RefCounted<LevelDBTransaction> { 26 public: 27 void Put(const base::StringPiece& key, std::string* value); 28 void Remove(const base::StringPiece& key); 29 virtual leveldb::Status Get(const base::StringPiece& key, 30 std::string* value, 31 bool* found); 32 virtual leveldb::Status Commit(); 33 void Rollback(); 34 35 scoped_ptr<LevelDBIterator> CreateIterator(); 36 37 protected: 38 virtual ~LevelDBTransaction(); 39 explicit LevelDBTransaction(LevelDBDatabase* db); 40 friend class IndexedDBClassFactory; 41 42 private: 43 friend class base::RefCounted<LevelDBTransaction>; 44 FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, Transaction); 45 FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionCommitTest); 46 FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionIterator); 47 48 struct Record { 49 Record(); 50 ~Record(); 51 std::string key; 52 std::string value; 53 bool deleted; 54 }; 55 56 class Comparator { 57 public: 58 explicit Comparator(const LevelDBComparator* comparator) 59 : comparator_(comparator) {} 60 bool operator()(const base::StringPiece& a, 61 const base::StringPiece& b) const { 62 return comparator_->Compare(a, b) < 0; 63 } 64 65 private: 66 const LevelDBComparator* comparator_; 67 }; 68 69 typedef std::map<base::StringPiece, Record*, Comparator> DataType; 70 71 class DataIterator : public LevelDBIterator { 72 public: 73 static scoped_ptr<DataIterator> Create(LevelDBTransaction* transaction); 74 virtual ~DataIterator(); 75 76 virtual bool IsValid() const OVERRIDE; 77 virtual leveldb::Status SeekToLast() OVERRIDE; 78 virtual leveldb::Status Seek(const base::StringPiece& slice) OVERRIDE; 79 virtual leveldb::Status Next() OVERRIDE; 80 virtual leveldb::Status Prev() OVERRIDE; 81 virtual base::StringPiece Key() const OVERRIDE; 82 virtual base::StringPiece Value() const OVERRIDE; 83 bool IsDeleted() const; 84 85 private: 86 explicit DataIterator(LevelDBTransaction* transaction); 87 DataType* data_; 88 DataType::iterator iterator_; 89 90 DISALLOW_COPY_AND_ASSIGN(DataIterator); 91 }; 92 93 class TransactionIterator : public LevelDBIterator { 94 public: 95 virtual ~TransactionIterator(); 96 static scoped_ptr<TransactionIterator> Create( 97 scoped_refptr<LevelDBTransaction> transaction); 98 99 virtual bool IsValid() const OVERRIDE; 100 virtual leveldb::Status SeekToLast() OVERRIDE; 101 virtual leveldb::Status Seek(const base::StringPiece& target) OVERRIDE; 102 virtual leveldb::Status Next() OVERRIDE; 103 virtual leveldb::Status Prev() OVERRIDE; 104 virtual base::StringPiece Key() const OVERRIDE; 105 virtual base::StringPiece Value() const OVERRIDE; 106 void DataChanged(); 107 108 private: 109 enum Direction { FORWARD, REVERSE }; 110 111 explicit TransactionIterator(scoped_refptr<LevelDBTransaction> transaction); 112 void HandleConflictsAndDeletes(); 113 void SetCurrentIteratorToSmallestKey(); 114 void SetCurrentIteratorToLargestKey(); 115 void RefreshDataIterator() const; 116 bool DataIteratorIsLower() const; 117 bool DataIteratorIsHigher() const; 118 119 scoped_refptr<LevelDBTransaction> transaction_; 120 const LevelDBComparator* comparator_; 121 mutable scoped_ptr<DataIterator> data_iterator_; 122 scoped_ptr<LevelDBIterator> db_iterator_; 123 LevelDBIterator* current_; 124 125 Direction direction_; 126 mutable bool data_changed_; 127 128 DISALLOW_COPY_AND_ASSIGN(TransactionIterator); 129 }; 130 131 void Set(const base::StringPiece& key, std::string* value, bool deleted); 132 void Clear(); 133 void RegisterIterator(TransactionIterator* iterator); 134 void UnregisterIterator(TransactionIterator* iterator); 135 void NotifyIterators(); 136 137 LevelDBDatabase* db_; 138 const LevelDBSnapshot snapshot_; 139 const LevelDBComparator* comparator_; 140 Comparator data_comparator_; 141 DataType data_; 142 bool finished_; 143 std::set<TransactionIterator*> iterators_; 144 145 DISALLOW_COPY_AND_ASSIGN(LevelDBTransaction); 146 }; 147 148 // Reads go straight to the database, ignoring any writes cached in 149 // write_batch_, and writes are write-through, without consolidation. 150 class LevelDBDirectTransaction { 151 public: 152 static scoped_ptr<LevelDBDirectTransaction> Create(LevelDBDatabase* db); 153 154 ~LevelDBDirectTransaction(); 155 void Put(const base::StringPiece& key, const std::string* value); 156 leveldb::Status Get(const base::StringPiece& key, 157 std::string* value, 158 bool* found); 159 void Remove(const base::StringPiece& key); 160 leveldb::Status Commit(); 161 162 private: 163 explicit LevelDBDirectTransaction(LevelDBDatabase* db); 164 165 LevelDBDatabase* db_; 166 scoped_ptr<LevelDBWriteBatch> write_batch_; 167 bool finished_; 168 169 DISALLOW_COPY_AND_ASSIGN(LevelDBDirectTransaction); 170 }; 171 172 } // namespace content 173 174 #endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 175