1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <map> 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <set> 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string> 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/gtest_prod_util.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/string_piece.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_database.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content { 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LevelDBWriteBatch; 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CONTENT_EXPORT LevelDBTransaction 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : public base::RefCounted<LevelDBTransaction> { 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Put(const base::StringPiece& key, std::string* value); 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Remove(const base::StringPiece& key); 296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual leveldb::Status Get(const base::StringPiece& key, 306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) std::string* value, 316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool* found); 326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) virtual leveldb::Status Commit(); 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Rollback(); 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBIterator> CreateIterator(); 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) protected: 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~LevelDBTransaction(); 39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit LevelDBTransaction(LevelDBDatabase* db); 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) friend class IndexedDBClassFactory; 416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private: 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) friend class base::RefCounted<LevelDBTransaction>; 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, Transaction); 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionCommitTest); 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionIterator); 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) struct Record { 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Record(); 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ~Record(); 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string key; 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string value; 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool deleted; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class Comparator { 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit Comparator(const LevelDBComparator* comparator) 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : comparator_(comparator) {} 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool operator()(const base::StringPiece& a, 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const base::StringPiece& b) const { 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return comparator_->Compare(a, b) < 0; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) typedef std::map<base::StringPiece, Record*, Comparator> DataType; 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class DataIterator : public LevelDBIterator { 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static scoped_ptr<DataIterator> Create(LevelDBTransaction* transaction); 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~DataIterator(); 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual bool IsValid() const OVERRIDE; 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status SeekToLast() OVERRIDE; 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Seek(const base::StringPiece& slice) OVERRIDE; 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Next() OVERRIDE; 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Prev() OVERRIDE; 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Key() const OVERRIDE; 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Value() const OVERRIDE; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool IsDeleted() const; 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit DataIterator(LevelDBTransaction* transaction); 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType* data_; 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType::iterator iterator_; 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DataIterator); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class TransactionIterator : public LevelDBIterator { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~TransactionIterator(); 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static scoped_ptr<TransactionIterator> Create( 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual bool IsValid() const OVERRIDE; 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status SeekToLast() OVERRIDE; 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Seek(const base::StringPiece& target) OVERRIDE; 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Next() OVERRIDE; 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Prev() OVERRIDE; 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Key() const OVERRIDE; 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Value() const OVERRIDE; 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void DataChanged(); 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci enum Direction { FORWARD, REVERSE }; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit TransactionIterator(scoped_refptr<LevelDBTransaction> transaction); 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void HandleConflictsAndDeletes(); 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetCurrentIteratorToSmallestKey(); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetCurrentIteratorToLargestKey(); 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RefreshDataIterator() const; 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool DataIteratorIsLower() const; 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool DataIteratorIsHigher() const; 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction_; 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mutable scoped_ptr<DataIterator> data_iterator_; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBIterator> db_iterator_; 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBIterator* current_; 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Direction direction_; 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mutable bool data_changed_; 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TransactionIterator); 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Set(const base::StringPiece& key, std::string* value, bool deleted); 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Clear(); 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void RegisterIterator(TransactionIterator* iterator); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void UnregisterIterator(TransactionIterator* iterator); 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void NotifyIterators(); 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBDatabase* db_; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBSnapshot snapshot_; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Comparator data_comparator_; 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType data_; 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool finished_; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::set<TransactionIterator*> iterators_; 144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LevelDBTransaction); 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Reads go straight to the database, ignoring any writes cached in 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// write_batch_, and writes are write-through, without consolidation. 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class LevelDBDirectTransaction { 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static scoped_ptr<LevelDBDirectTransaction> Create(LevelDBDatabase* db); 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~LevelDBDirectTransaction(); 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Put(const base::StringPiece& key, const std::string* value); 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Get(const base::StringPiece& key, 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* value, 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool* found); 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Remove(const base::StringPiece& key); 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Commit(); 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit LevelDBDirectTransaction(LevelDBDatabase* db); 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBDatabase* db_; 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBWriteBatch> write_batch_; 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool finished_; 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LevelDBDirectTransaction); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 175