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