leveldb_transaction.h revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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
20namespace content {
21
22class LevelDBWriteBatch;
23
24class 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:
59    explicit Comparator(const LevelDBComparator* comparator)
60        : comparator_(comparator) {}
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.
153class 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