text: /*
   * Copyright 2017-2020
   *   Andreia Correia <andreia.veiga@unine.ch>
   *   Pedro Ramalhete <pramalhe@gmail.com>
   *   Pascal Felber <pascal.felber@unine.ch>
   *
   * This work is published under the MIT license. See LICENSE.txt
   */
  #ifndef _PTMDB_INCLUDE_DB_H_
  #define _PTMDB_INCLUDE_DB_H_
  
  #include "iterator.h"
  #include "options.h"
  #include "ptmdb.h"
  #include "status.h"
  #include "write_batch.h"
  
  namespace ptmdb {
  
  static const int kMajorVersion = 0;
  static const int kMinorVersion = 6;
  
  struct Options;
  struct ReadOptions;
  struct WriteOptions;
  class WriteBatch;
  
  // Abstract handle to particular state of a DB.
  // A Snapshot is an immutable object and can therefore be safely
  // accessed from multiple threads without any external synchronization.
  class Snapshot {
  protected:
      virtual ~Snapshot();
  };
  
  // A range of keys
  struct Range {
      Slice start;          // Included in the range
      Slice limit;          // Not included in the range
  
      Range() { }
      Range(const Slice& s, const Slice& l) : start(s), limit(l) { }
  };
  
  // A DB is a persistent ordered map from keys to values.
  // A DB is safe for concurrent access from multiple threads without
  // any external synchronization.
  class DB {
  public:
      // Open the database with the specified "name".
      // Stores a pointer to a heap-allocated database in *dbptr and returns
      // OK on success.
      // Stores NULL in *dbptr and returns a non-OK status on error.
      // Caller should delete *dbptr when it is no longer needed.
      static Status Open(const Options& options,
              const std::string& name,
              DB** dbptr);
  
      DB() { }
      ~DB() { }
  
      // Set the database entry for "key" to "value".  Returns OK on success,
      // and a non-OK status on error.
      // Note: consider setting options.sync = true.
      virtual Status Put(const WriteOptions& options,
              const Slice& key,
              const Slice& value) = 0;
  
      // Remove the database entry (if any) for "key".  Returns OK on
      // success, and a non-OK status on error.  It is not an error if "key"
      // did not exist in the database.
      // Note: consider setting options.sync = true.
      virtual Status Delete(const WriteOptions& options, const Slice& key) = 0;
  
      // Apply the specified updates to the database.
      // Returns OK on success, non-OK on failure.
      // Note: consider setting options.sync = true.
      virtual Status Write(const WriteOptions& options, WriteBatch* updates) = 0;
  
      virtual long size() = 0;
      // If the database contains an entry for "key" store the
      // corresponding value in *value and return OK.
      //
      // If there is no entry for "key" leave *value unchanged and return
      // a status for which Status::IsNotFound() returns true.
      //
      // May return some other Status on an error.
      virtual Status Get(const ReadOptions& options,
              const Slice& key, std::string* value) = 0;
  
      // Return a heap-allocated iterator over the contents of the database.
      // The result of NewIterator() is initially invalid (caller must
      // call one of the Seek methods on the iterator before using it).
      //
      // Caller should delete the iterator when it is no longer needed.
      // The returned iterator should be deleted before this db is deleted.
      virtual Iterator* NewIterator(const ReadOptions& options) = 0;
  
  
  private:
      // No copying allowed
      DB(const DB&);
      void operator=(const DB&);
  };
  
  // Destroy the contents of the specified database.
  // Be very careful using this method.
  //
  // Note: For backwards compatibility, if DestroyDB is unable to list the
  // database files, Status::OK() will still be returned masking this failure.
  Status DestroyDB(const std::string& name, const Options& options);
  
  // If a DB cannot be opened, you may attempt to call this method to
  // resurrect as much of the contents of the database as possible.
  // Some data may be lost, so be careful when calling this function
  // on a database that contains important information.
  Status RepairDB(const std::string& dbname, const Options& options);
  
  // A read-only transaction can be executed by passing a lambda, function pointer or std::function
  #ifdef PTMDB_CAPTURE_BY_COPY
  // Used by CX-Redo (capture by value and uint64_t return value)
  template<typename R, typename F> R readTx(F&& func) { return PTM_READ_TX<R>(func); }
  #else
  // Used by Romulus and all the other durabletx PTMs (capture by ref and no return value needed)
  template<typename F> void readTx(F&& func) { PTM_READ_TX(func); }
  #endif
  
  }  // namespace ptmdb
  
  
  #endif
  