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