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