// collection.h

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Class to store a collection of sets with elements of type T.

#ifndef FST_EXTENSIONS_PDT_COLLECTION_H__
#define FST_EXTENSIONS_PDT_COLLECTION_H__

#include <algorithm>
#include <vector>
using std::vector;

#include <fst/bi-table.h>

namespace fst {

// Stores a collection of non-empty sets with elements of type T. A
// default constructor, equality ==, a total order <, and an STL-style
// hash class must be defined on the elements. Provides signed
// integer ID (of type I) of each unique set. The IDs are allocated
// starting from 0 in order.
template <class I, class T>
class Collection {
 public:
  struct Node {  // Trie node
    I node_id;   // Root is kNoNodeId;
    T element;

    Node() : node_id(kNoNodeId), element(T()) {}
    Node(I i, const T &t) : node_id(i), element(t) {}

    bool operator==(const Node& n) const {
      return n.node_id == node_id && n.element == element;
    }
  };

  struct NodeHash {
    size_t operator()(const Node &n) const {
      return n.node_id + hash_(n.element) * kPrime;
    }
  };

  typedef CompactHashBiTable<I, Node, NodeHash> NodeTable;

  class SetIterator {
   public:
    SetIterator(I id, Node node, NodeTable *node_table)
        :id_(id), node_(node), node_table_(node_table) {}

    bool Done() const { return id_ == kNoNodeId; }

    const T &Element() const { return node_.element; }

    void Next() {
      id_ = node_.node_id;
      if (id_ != kNoNodeId)
        node_ = node_table_->FindEntry(id_);
    }

   private:
    I id_;                     // Iterator set node id
    Node node_;                // Iterator set node
    NodeTable *node_table_;
  };

  Collection() {}

  // Lookups integer ID from set. If it doesn't exist, then adds it.
  // Set elements should be in strict order (and therefore unique).
  I FindId(const vector<T> &set) {
    I node_id = kNoNodeId;
    for (ssize_t i = set.size() - 1; i >= 0; --i) {
      Node node(node_id, set[i]);
      node_id = node_table_.FindId(node);
    }
    return node_id;
  }

  // Finds set given integer ID. Returns true if ID corresponds
  // to set. Use iterators below to traverse result.
  SetIterator FindSet(I id) {
    if (id < 0 && id >= node_table_.Size()) {
      return SetIterator(kNoNodeId, Node(kNoNodeId, T()), &node_table_);
    } else {
      return SetIterator(id, node_table_.FindEntry(id), &node_table_);
    }
  }

 private:
  static const I kNoNodeId;
  static const size_t kPrime;
  static std::tr1::hash<T> hash_;

  NodeTable node_table_;

  DISALLOW_COPY_AND_ASSIGN(Collection);
};

template<class I, class T> const I Collection<I, T>::kNoNodeId = -1;

template <class I, class T> const size_t Collection<I, T>::kPrime = 7853;

template <class I, class T> std::tr1::hash<T> Collection<I, T>::hash_;

}  // namespace fst

#endif  // FST_EXTENSIONS_PDT_COLLECTION_H__
