leveldb_transaction.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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)
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/strings/string_piece.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_database.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace content {
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LevelDBWriteBatch;
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CONTENT_EXPORT LevelDBTransaction
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : public base::RefCounted<LevelDBTransaction> {
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  explicit LevelDBTransaction(LevelDBDatabase* db);
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();
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  friend class base::RefCounted<LevelDBTransaction>;
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  struct Record {
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    Record();
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ~Record();
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    std::string key;
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    std::string value;
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool deleted;
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  class Comparator {
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   public:
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    explicit Comparator(const LevelDBComparator* comparator)
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        : comparator_(comparator) {}
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool operator()(const base::StringPiece& a,
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    const base::StringPiece& b) const {
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return comparator_->Compare(a, b) < 0;
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)   private:
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const LevelDBComparator* comparator_;
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef std::map<base::StringPiece, Record*, Comparator> DataType;
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  class DataIterator : public LevelDBIterator {
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   public:
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    static scoped_ptr<DataIterator> Create(LevelDBTransaction* transaction);
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    virtual ~DataIterator();
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual bool IsValid() const OVERRIDE;
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status SeekToLast() OVERRIDE;
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Seek(const base::StringPiece& slice) OVERRIDE;
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Next() OVERRIDE;
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Prev() OVERRIDE;
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Key() const OVERRIDE;
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Value() const OVERRIDE;
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    bool IsDeleted() const;
78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   private:
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    explicit DataIterator(LevelDBTransaction* transaction);
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DataType* data_;
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DataType::iterator iterator_;
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  class TransactionIterator : public LevelDBIterator {
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   public:
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual ~TransactionIterator();
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    static scoped_ptr<TransactionIterator> Create(
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        scoped_refptr<LevelDBTransaction> transaction);
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    virtual bool IsValid() const OVERRIDE;
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status SeekToLast() OVERRIDE;
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Seek(const base::StringPiece& target) OVERRIDE;
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Next() OVERRIDE;
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    virtual leveldb::Status Prev() OVERRIDE;
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Key() const OVERRIDE;
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    virtual base::StringPiece Value() const OVERRIDE;
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void DataChanged();
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)   private:
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    explicit TransactionIterator(scoped_refptr<LevelDBTransaction> transaction);
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void HandleConflictsAndDeletes();
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void SetCurrentIteratorToSmallestKey();
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    void SetCurrentIteratorToLargestKey();
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    void RefreshDataIterator() const;
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool DataIteratorIsLower() const;
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool DataIteratorIsHigher() const;
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<LevelDBTransaction> transaction_;
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const LevelDBComparator* comparator_;
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    mutable scoped_ptr<DataIterator> data_iterator_;
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_ptr<LevelDBIterator> db_iterator_;
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LevelDBIterator* current_;
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    enum Direction {
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      FORWARD,
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      REVERSE
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    };
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Direction direction_;
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    mutable bool data_changed_;
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  };
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Set(const base::StringPiece& key, std::string* value, bool deleted);
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void Clear();
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void RegisterIterator(TransactionIterator* iterator);
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void UnregisterIterator(TransactionIterator* iterator);
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void NotifyIterators();
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LevelDBDatabase* db_;
130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const LevelDBSnapshot snapshot_;
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  const LevelDBComparator* comparator_;
132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  Comparator data_comparator_;
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DataType data_;
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool finished_;
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::set<TransactionIterator*> iterators_;
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Reads go straight to the database, ignoring any writes cached in
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// write_batch_, and writes are write-through, without consolidation.
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class LevelDBDirectTransaction {
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static scoped_ptr<LevelDBDirectTransaction> Create(LevelDBDatabase* db);
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~LevelDBDirectTransaction();
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Put(const base::StringPiece& key, const std::string* value);
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  leveldb::Status Get(const base::StringPiece& key,
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      std::string* value,
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      bool* found);
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Remove(const base::StringPiece& key);
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  leveldb::Status Commit();
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private:
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit LevelDBDirectTransaction(LevelDBDatabase* db);
154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LevelDBDatabase* db_;
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<LevelDBWriteBatch> write_batch_;
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool finished_;
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace content
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_
163