text: // 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 <map>
  #include <set>
  #include <string>
  
  #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<LevelDBTransaction> {
   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<LevelDBIterator> CreateIterator();
  
   private:
    virtual ~LevelDBTransaction();
    friend class base::RefCounted<LevelDBTransaction>;
  
    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<base::StringPiece, Record*, Comparator> DataType;
  
    class DataIterator : public LevelDBIterator {
     public:
      static scoped_ptr<DataIterator> 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<TransactionIterator> Create(
          scoped_refptr<LevelDBTransaction> 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<LevelDBTransaction> transaction);
      void HandleConflictsAndDeletes();
      void SetCurrentIteratorToSmallestKey();
      void SetCurrentIteratorToLargestKey();
      void RefreshDataIterator() const;
      bool DataIteratorIsLower() const;
      bool DataIteratorIsHigher() const;
  
      scoped_refptr<LevelDBTransaction> transaction_;
      const LevelDBComparator* comparator_;
      mutable scoped_ptr<DataIterator> data_iterator_;
      scoped_ptr<LevelDBIterator> 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<TransactionIterator*> iterators_;
  };
  
  class LevelDBWriteOnlyTransaction {
   public:
    static scoped_ptr<LevelDBWriteOnlyTransaction> Create(LevelDBDatabase* db);
  
    ~LevelDBWriteOnlyTransaction();
    void Remove(const base::StringPiece& key);
    bool Commit();
  
   private:
    explicit LevelDBWriteOnlyTransaction(LevelDBDatabase* db);
  
    LevelDBDatabase* db_;
    scoped_ptr<LevelDBWriteBatch> write_batch_;
    bool finished_;
  };
  
  }  // namespace content
  
  #endif  // CONTENT_BROWSER_INDEXED_DB_LEVELDB_LEVELDB_TRANSACTION_H_
  