// 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<uint32>(i) >= static_cast<uint32>(max_size_)) {
      return false;
    }
    // Unsigned comparison avoids checking sparse_to_dense_[i] < 0.
    return (uint32)sparse_to_dense_[i] < (uint32)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<uint32>(i) >= static_cast<uint32>(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_
