// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ #define CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_ #include #include #include #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" #include "content/browser/indexed_db/leveldb/leveldb_database.h" #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" namespace content { class LevelDBWriteBatch; class CONTENT_EXPORT LevelDBTransaction : public base::RefCounted { public: explicit LevelDBTransaction(LevelDBDatabase* db); void Put(const base::StringPiece& key, std::string* value); void Remove(const base::StringPiece& key); bool Get(const base::StringPiece& key, std::string* value, bool* found); bool Commit(); void Rollback(); scoped_ptr CreateIterator(); private: virtual ~LevelDBTransaction(); friend class base::RefCounted; struct Record { Record(); ~Record(); std::string key; std::string value; bool deleted; }; class Comparator { public: explicit Comparator(const LevelDBComparator* comparator) : comparator_(comparator) {} bool operator()(const base::StringPiece& a, const base::StringPiece& b) const { return comparator_->Compare(a, b) < 0; } private: const LevelDBComparator* comparator_; }; typedef std::map DataType; class DataIterator : public LevelDBIterator { public: static scoped_ptr Create(LevelDBTransaction* transaction); virtual ~DataIterator(); virtual bool IsValid() const OVERRIDE; virtual void SeekToLast() OVERRIDE; virtual void Seek(const base::StringPiece& slice) OVERRIDE; virtual void Next() OVERRIDE; virtual void Prev() OVERRIDE; virtual base::StringPiece Key() const OVERRIDE; virtual base::StringPiece Value() const OVERRIDE; bool IsDeleted() const; private: explicit DataIterator(LevelDBTransaction* transaction); DataType* data_; DataType::iterator iterator_; }; class TransactionIterator : public LevelDBIterator { public: virtual ~TransactionIterator(); static scoped_ptr Create( scoped_refptr transaction); virtual bool IsValid() const OVERRIDE; virtual void SeekToLast() OVERRIDE; virtual void Seek(const base::StringPiece& target) OVERRIDE; virtual void Next() OVERRIDE; virtual void Prev() OVERRIDE; virtual base::StringPiece Key() const OVERRIDE; virtual base::StringPiece Value() const OVERRIDE; void DataChanged(); private: explicit TransactionIterator(scoped_refptr transaction); void HandleConflictsAndDeletes(); void SetCurrentIteratorToSmallestKey(); void SetCurrentIteratorToLargestKey(); void RefreshDataIterator() const; bool DataIteratorIsLower() const; bool DataIteratorIsHigher() const; scoped_refptr transaction_; const LevelDBComparator* comparator_; mutable scoped_ptr data_iterator_; scoped_ptr db_iterator_; LevelDBIterator* current_; enum Direction { FORWARD, REVERSE }; Direction direction_; mutable bool data_changed_; }; void Set(const base::StringPiece& key, std::string* value, bool deleted); void Clear(); void RegisterIterator(TransactionIterator* iterator); void UnregisterIterator(TransactionIterator* iterator); void NotifyIterators(); LevelDBDatabase* db_; const LevelDBSnapshot snapshot_; const LevelDBComparator* comparator_; Comparator data_comparator_; DataType data_; bool finished_; std::set iterators_; }; class LevelDBWriteOnlyTransaction { public: static scoped_ptr Create(LevelDBDatabase* db); ~LevelDBWriteOnlyTransaction(); void Remove(const base::StringPiece& key); bool Commit(); private: explicit LevelDBWriteOnlyTransaction(LevelDBDatabase* db); LevelDBDatabase* db_; scoped_ptr write_batch_; bool finished_; }; } // namespace content #endif // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_