text: /**
   * (c) Camille Scott, 2019
   * File   : qfstorage.hh
   * License: MIT
   * Author : Camille Scott <camille.scott.w@gmail.com>
   * Date   : 30.08.2019
   */
  /* qfstorage.hh -- goetia-modified oxli storage
   *
   * Copyright (C) 2018 Camille Scott
   * All rights reserved.
   *
   * This software may be modified and distributed under the terms
   * of the MIT license.  See the LICENSE file for details.
   *
   *** END GOETIA LICENSE BLOCK
   *
   * This file is part of khmer, https://github.com/dib-lab/khmer/, and is
   * Copyright (C) 2016, The Regents of the University of California.
   * 
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met:
   * 
   *     * Redistributions of source code must retain the above copyright
   *       notice, this list of conditions and the following disclaimer.
   * 
   *     * Redistributions in binary form must reproduce the above
   *       copyright notice, this list of conditions and the following
   *       disclaimer in the documentation and/or other materials provided
   *       with the distribution.
   * 
   *     * Neither the name of the University of California nor the names
   *       of its contributors may be used to endorse or promote products
   *       derived from this software without specific prior written
   *       permission.
   * 
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   * LICENSE (END)
   * 
   * Contact: khmer-project@idyll.org
   */
  
  #ifndef GOETIA_QFSTORAGE_HH
  #define GOETIA_QFSTORAGE_HH
  
  #include <cassert>
  #include <array>
  #include <memory>
  #include <mutex>
  #include <unordered_map>
  #include <string>
  
  #include "goetia/meta.hh"
  #include "goetia/storage/storage.hh"
  
  struct quotient_filter;
  typedef quotient_filter QF;
  
  namespace goetia {
  
  
  class QFStorage;
  
  
  template<>
  struct StorageTraits<QFStorage> {
      static constexpr bool is_probabilistic = true;
      static constexpr bool is_counting      = true;
      
      typedef std::tuple<int> params_type;
      static constexpr params_type default_params = std::make_tuple(20);
  };
  
  
  
  /*
   * \class QFStorage
   *
   * \brief A Quotient Filter storage
   */
  class QFStorage : public Storage<uint64_t>,
                    public Tagged<QFStorage> {
  protected:
      std::shared_ptr<QF> cf;
      int _size;
  
  public:
  
    using Storage<uint64_t>::value_type;
    using Traits = StorageTraits<QFStorage>;
  
    QFStorage(int size);
  
    ~QFStorage();
  
    static std::shared_ptr<QFStorage> build(int size) {
        return std::make_shared<QFStorage>(size);
    }
  
    static std::shared_ptr<QFStorage> build(typename Traits::params_type params) {
        return make_shared_from_tuple<QFStorage>(std::move(params));
    }
  
    std::shared_ptr<QFStorage> clone() const;
  
    const bool insert(value_type khash);
    const count_t insert_and_query(value_type khash);
  
    // get the count for the given k-mer hash.
    const count_t query(value_type khash) const;
  
    // Accessors for protected/private table info members
    // xnslots is larger than nslots. It includes some extra slots to deal
    // with some details of how the counting is implemented
    std::vector<uint64_t> get_tablesizes() const;
    const size_t n_tables() const { return 1; }
    
    const uint64_t n_unique_kmers() const;
    const uint64_t n_occupied() const;
  
    void save(std::string outfilename, uint16_t ksize);
    void load(std::string infilename, uint16_t &ksize);
  
    byte_t **get_raw_tables() { return nullptr; }
    void reset() {}; //nop
  
    double estimated_fp() {
        double fp = n_occupied() / get_tablesizes()[0];
        fp = pow(fp, n_tables());
        return fp;
    }
  
    static std::shared_ptr<QFStorage> deserialize(std::ifstream& in) {
      return {};
    }
  
    void serialize(std::ofstream& out) {}
  
  
  };
  
  }
  
  #endif
  