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:
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Put(const base::StringPiece& key, std::string* value);
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Remove(const base::StringPiece& key);
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual leveldb::Status Get(const base::StringPiece& key,
306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              std::string* value,
316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              bool* found);
326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual leveldb::Status Commit();
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void Rollback();
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<LevelDBIterator> CreateIterator();
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) protected:
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~LevelDBTransaction();
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit LevelDBTransaction(LevelDBDatabase* db);
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  friend class IndexedDBClassFactory;
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private:
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  friend class base::RefCounted<LevelDBTransaction>;
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, Transaction);
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionCommitTest);
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(LevelDBDatabaseTest, TransactionIterator);
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  struct Record {
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Record();
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ~Record();
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    std::string key;
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    std::string value;
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool deleted;
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  class Comparator {
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   public:
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    explicit Comparator(const LevelDBComparator* comparator)
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        : comparator_(comparator) {}
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool operator()(const base::StringPiece& a,
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    const base::StringPiece& b) const {
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return comparator_->Compare(a, b) < 0;
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   private:
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const LevelDBComparator* comparator_;
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef std::map<base::StringPiece, Record*, Comparator> DataType;
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  class DataIterator : public LevelDBIterator {
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   public:
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    static scoped_ptr<DataIterator> Create(LevelDBTransaction* transaction);
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    virtual ~DataIterator();
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual bool IsValid() const OVERRIDE;
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status SeekToLast() OVERRIDE;
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Seek(const base::StringPiece& slice) OVERRIDE;
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Next() OVERRIDE;
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Prev() OVERRIDE;
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Key() const OVERRIDE;
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Value() const OVERRIDE;
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool IsDeleted() const;
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   private:
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    explicit DataIterator(LevelDBTransaction* transaction);
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DataType* data_;
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DataType::iterator iterator_;
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(DataIterator);
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  class TransactionIterator : public LevelDBIterator {
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   public:
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual ~TransactionIterator();
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    static scoped_ptr<TransactionIterator> Create(
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        scoped_refptr<LevelDBTransaction> transaction);
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual bool IsValid() const OVERRIDE;
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status SeekToLast() OVERRIDE;
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Seek(const base::StringPiece& target) OVERRIDE;
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Next() OVERRIDE;
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Prev() OVERRIDE;
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Key() const OVERRIDE;
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Value() const OVERRIDE;
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void DataChanged();
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   private:
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    enum Direction { FORWARD, REVERSE };
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    explicit TransactionIterator(scoped_refptr<LevelDBTransaction> transaction);
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void HandleConflictsAndDeletes();
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void SetCurrentIteratorToSmallestKey();
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void SetCurrentIteratorToLargestKey();
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void RefreshDataIterator() const;
116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool DataIteratorIsLower() const;
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool DataIteratorIsHigher() const;
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<LevelDBTransaction> transaction_;
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const LevelDBComparator* comparator_;
121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    mutable scoped_ptr<DataIterator> data_iterator_;
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_ptr<LevelDBIterator> db_iterator_;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LevelDBIterator* current_;
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Direction direction_;
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    mutable bool data_changed_;
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(TransactionIterator);
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Set(const base::StringPiece& key, std::string* value, bool deleted);
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void Clear();
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void RegisterIterator(TransactionIterator* iterator);
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void UnregisterIterator(TransactionIterator* iterator);
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void NotifyIterators();
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LevelDBDatabase* db_;
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const LevelDBSnapshot snapshot_;
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const LevelDBComparator* comparator_;
140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Comparator data_comparator_;
141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DataType data_;
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool finished_;
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::set<TransactionIterator*> iterators_;
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LevelDBTransaction);
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Reads go straight to the database, ignoring any writes cached in
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// write_batch_, and writes are write-through, without consolidation.
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class LevelDBDirectTransaction {
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static scoped_ptr<LevelDBDirectTransaction> Create(LevelDBDatabase* db);
153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~LevelDBDirectTransaction();
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Put(const base::StringPiece& key, const std::string* value);
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  leveldb::Status Get(const base::StringPiece& key,
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      std::string* value,
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      bool* found);
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Remove(const base::StringPiece& key);
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  leveldb::Status Commit();
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit LevelDBDirectTransaction(LevelDBDatabase* db);
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LevelDBDatabase* db_;
166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<LevelDBWriteBatch> write_batch_;
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool finished_;
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LevelDBDirectTransaction);
170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace content
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_
175