// Copyright 2006 The RE2 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 UTIL_SPARSE_SET_H_
#define UTIL_SPARSE_SET_H_

// DESCRIPTION
// 
// SparseSet<T>(m) is a set of integers in [0, m).
// It requires sizeof(int)*m memory, but it provides
// fast iteration through the elements in the set and fast clearing
// of the set.
// 
// Insertion and deletion are constant time operations.
// 
// Allocating the set is a constant time operation 
// when memory allocation is a constant time operation.
// 
// Clearing the set is a constant time operation (unusual!).
// 
// Iterating through the set is an O(n) operation, where n
// is the number of items in the set (not O(m)).
//
// The set iterator visits entries in the order they were first 
// inserted into the array.  It is safe to add items to the set while
// using an iterator: the iterator will visit indices added to the set
// during the iteration, but will not re-visit indices whose values
// change after visiting.  Thus SparseSet can be a convenient
// implementation of a work queue.
// 
// The SparseSet implementation is NOT thread-safe.  It is up to the
// caller to make sure only one thread is accessing the set.  (Typically
// these sets are temporary values and used in situations where speed is
// important.)
// 
// The SparseSet interface does not present all the usual STL bells and
// whistles.
// 
// Implemented with reference to Briggs & Torczon, An Efficient
// Representation for Sparse Sets, ACM Letters on Programming Languages
// and Systems, Volume 2, Issue 1-4 (March-Dec.  1993), pp.  59-69.
// 
// For a generalization to sparse array, see sparse_array.h.

// IMPLEMENTATION
//
// See sparse_array.h for implementation details

#include <string.h>

#include "util/util.h"

namespace re2 {

class SparseSet {
 public:
  SparseSet()
    : size_(0), max_size_(0), sparse_to_dense_(NULL), dense_(NULL) {}

  SparseSet(int max_size) {
    max_size_ = max_size;
    sparse_to_dense_ = new int[max_size];
    dense_ = new int[max_size];
    // Don't need to zero the memory, but do so anyway
    // to appease Valgrind.
    if (InitMemory()) {
      for (int i = 0; i < max_size; i++) {
        dense_[i] = 0xababababU;
        sparse_to_dense_[i] = 0xababababU;
      }
    }
    size_ = 0;
  }

  ~SparseSet() {
    delete[] sparse_to_dense_;
    delete[] dense_;
  }

  typedef int* iterator;
  typedef const int* const_iterator;

  int size() const { return size_; }
  iterator begin() { return dense_; }
  iterator end() { return dense_ + size_; }
  const_iterator begin() const { return dense_; }
  const_iterator end() const { return dense_ + size_; }

  // Change the maximum size of the array.
  // Invalidates all iterators.
  void resize(int new_max_size) {
    if (size_ > new_max_size)
      size_ = new_max_size;
    if (new_max_size > max_size_) {
      int* a = new int[new_max_size];
      if (sparse_to_dense_) {
        memmove(a, sparse_to_dense_, max_size_*sizeof a[0]);
        if (InitMemory()) {
          for (int i = max_size_; i < new_max_size; i++)
            a[i] = 0xababababU;
        }
        delete[] sparse_to_dense_;
      }
      sparse_to_dense_ = a;

      a = new int[new_max_size];
      if (dense_) {
        memmove(a, dense_, size_*sizeof a[0]);
        if (InitMemory()) {
          for (int i = size_; i < new_max_size; i++)
            a[i] = 0xababababU;
        }
        delete[] dense_;
      }
      dense_ = a;
    }
    max_size_ = new_max_size;
  }

  // Return the maximum size of the array.
  // Indices can be in the range [0, max_size).
  int max_size() const { return max_size_; }

  // Clear the array.
  void clear() { size_ = 0; }

  // Check whether i is in the array.
  bool contains(int i) const {
    DCHECK_GE(i, 0);
    DCHECK_LT(i, max_size_);
    if (static_cast<uint>(i) >= static_cast<uint>(max_size_)) {
      return false;
    }
    // Unsigned comparison avoids checking sparse_to_dense_[i] < 0.
    return (uint)sparse_to_dense_[i] < (uint)size_ && 
      dense_[sparse_to_dense_[i]] == i;
  }

  // Adds i to the set.
  void insert(int i) {
    if (!contains(i))
      insert_new(i);
  }

  // Set the value at the new index i to v.
  // Fast but unsafe: only use if contains(i) is false.
  void insert_new(int i) {
    if (static_cast<uint>(i) >= static_cast<uint>(max_size_)) {
      // Semantically, end() would be better here, but we already know
      // the user did something stupid, so begin() insulates them from
      // dereferencing an invalid pointer.
      return;
    }
    DCHECK(!contains(i));
    DCHECK_LT(size_, max_size_);
    sparse_to_dense_[i] = size_;
    dense_[size_] = i;
    size_++;
  }

  // Comparison function for sorting.
  // Can sort the sparse array so that future iterations
  // will visit indices in increasing order using
  // std::sort(arr.begin(), arr.end(), arr.less);
  static bool less(int a, int b) { return a < b; }

 private:
  static bool InitMemory() {
#ifdef MEMORY_SANITIZER
    return true;
#else
    return RunningOnValgrind();
#endif
  }

  int size_;
  int max_size_;
  int* sparse_to_dense_;
  int* dense_;

  DISALLOW_COPY_AND_ASSIGN(SparseSet);
};

}  // namespace re2

#endif  // UTIL_SPARSE_SET_H_
