leveldb_transaction.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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: 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Put(const base::StringPiece& key, std::string* value); 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Remove(const base::StringPiece& key); 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Get(const base::StringPiece& key, 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* value, 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool* found); 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Commit(); 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Rollback(); 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBIterator> CreateIterator(); 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~LevelDBTransaction(); 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) explicit LevelDBTransaction(LevelDBDatabase* db); 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) friend class IndexedDBClassFactory; 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) friend class base::RefCounted<LevelDBTransaction>; 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, Transaction); 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionCommitTest); 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionIterator); 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) struct Record { 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Record(); 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ~Record(); 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string key; 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string value; 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool deleted; 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class Comparator { 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit Comparator(const LevelDBComparator* comparator) 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : comparator_(comparator) {} 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool operator()(const base::StringPiece& a, 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const base::StringPiece& b) const { 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return comparator_->Compare(a, b) < 0; 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) typedef std::map<base::StringPiece, Record*, Comparator> DataType; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class DataIterator : public LevelDBIterator { 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static scoped_ptr<DataIterator> Create(LevelDBTransaction* transaction); 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~DataIterator(); 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual bool IsValid() const OVERRIDE; 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status SeekToLast() OVERRIDE; 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Seek(const base::StringPiece& slice) OVERRIDE; 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Next() OVERRIDE; 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Prev() OVERRIDE; 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Key() const OVERRIDE; 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Value() const OVERRIDE; 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool IsDeleted() const; 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit DataIterator(LevelDBTransaction* transaction); 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType* data_; 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType::iterator iterator_; 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DataIterator); 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) class TransactionIterator : public LevelDBIterator { 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~TransactionIterator(); 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static scoped_ptr<TransactionIterator> Create( 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual bool IsValid() const OVERRIDE; 990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status SeekToLast() OVERRIDE; 1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Seek(const base::StringPiece& target) OVERRIDE; 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Next() OVERRIDE; 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual leveldb::Status Prev() OVERRIDE; 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Key() const OVERRIDE; 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual base::StringPiece Value() const OVERRIDE; 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void DataChanged(); 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit TransactionIterator(scoped_refptr<LevelDBTransaction> transaction); 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void HandleConflictsAndDeletes(); 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetCurrentIteratorToSmallestKey(); 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetCurrentIteratorToLargestKey(); 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RefreshDataIterator() const; 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool DataIteratorIsLower() const; 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool DataIteratorIsHigher() const; 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_refptr<LevelDBTransaction> transaction_; 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mutable scoped_ptr<DataIterator> data_iterator_; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBIterator> db_iterator_; 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBIterator* current_; 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) enum Direction { 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) FORWARD, 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) REVERSE 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Direction direction_; 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mutable bool data_changed_; 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TransactionIterator); 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) }; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Set(const base::StringPiece& key, std::string* value, bool deleted); 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Clear(); 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void RegisterIterator(TransactionIterator* iterator); 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void UnregisterIterator(TransactionIterator* iterator); 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void NotifyIterators(); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBDatabase* db_; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBSnapshot snapshot_; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const LevelDBComparator* comparator_; 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Comparator data_comparator_; 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DataType data_; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool finished_; 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::set<TransactionIterator*> iterators_; 145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LevelDBTransaction); 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Reads go straight to the database, ignoring any writes cached in 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// write_batch_, and writes are write-through, without consolidation. 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class LevelDBDirectTransaction { 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static scoped_ptr<LevelDBDirectTransaction> Create(LevelDBDatabase* db); 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ~LevelDBDirectTransaction(); 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Put(const base::StringPiece& key, const std::string* value); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Get(const base::StringPiece& key, 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string* value, 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool* found); 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Remove(const base::StringPiece& key); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leveldb::Status Commit(); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) explicit LevelDBDirectTransaction(LevelDBDatabase* db); 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LevelDBDatabase* db_; 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LevelDBWriteBatch> write_batch_; 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool finished_; 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LevelDBDirectTransaction); 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace content 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ 176