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