1afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- C++ -*-===//
2afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
3afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//                     The LLVM Compiler Infrastructure
4afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
5afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// This file is distributed under the University of Illinois Open Source
6afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// License. See LICENSE.TXT for details.
7afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
8afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//===----------------------------------------------------------------------===//
9afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
10afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// This file defines the SparseMultiSet class, which adds multiset behavior to
11afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// the SparseSet.
12afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
13afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// A sparse multiset holds a small number of objects identified by integer keys
14afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// from a moderately sized universe. The sparse multiset uses more memory than
15afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// other containers in order to provide faster operations. Any key can map to
16afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// multiple values. A SparseMultiSetNode class is provided, which serves as a
17afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman// convenient base class for the contents of a SparseMultiSet.
18afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//
19afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman//===----------------------------------------------------------------------===//
20afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
21afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman#ifndef LLVM_ADT_SPARSEMULTISET_H
22afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman#define LLVM_ADT_SPARSEMULTISET_H
23afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
24afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman#include "llvm/ADT/SparseSet.h"
25afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
26afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilsemannamespace llvm {
27afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
28afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// Fast multiset implementation for objects that can be identified by small
29afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// unsigned keys.
30afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
31afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// SparseMultiSet allocates memory proportional to the size of the key
32afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// universe, so it is not recommended for building composite data structures.
33afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// It is useful for algorithms that require a single set with fast operations.
34afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
35afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// Compared to DenseSet and DenseMap, SparseMultiSet provides constant-time
36afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// fast clear() as fast as a vector.  The find(), insert(), and erase()
37afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// operations are all constant time, and typically faster than a hash table.
38afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// The iteration order doesn't depend on numerical key values, it only depends
39afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// on the order of insert() and erase() operations.  Iteration order is the
40afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// insertion order. Iteration is only provided over elements of equivalent
41afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// keys, but iterators are bidirectional.
42afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
43afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// Compared to BitVector, SparseMultiSet<unsigned> uses 8x-40x more memory, but
44afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// offers constant-time clear() and size() operations as well as fast iteration
45afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// independent on the size of the universe.
46afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
47afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// SparseMultiSet contains a dense vector holding all the objects and a sparse
48afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// array holding indexes into the dense vector.  Most of the memory is used by
49afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// the sparse array which is the size of the key universe. The SparseT template
50afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// parameter provides a space/speed tradeoff for sets holding many elements.
51afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
52afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// When SparseT is uint32_t, find() only touches up to 3 cache lines, but the
53afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// sparse array uses 4 x Universe bytes.
54afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
55afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// When SparseT is uint8_t (the default), find() touches up to 3+[N/256] cache
56afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// lines, but the sparse array is 4x smaller.  N is the number of elements in
57afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// the set.
58afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
59afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// For sets that may grow to thousands of elements, SparseT should be set to
60afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// uint16_t or uint32_t.
61afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
62afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// Multiset behavior is provided by providing doubly linked lists for values
63afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// that are inlined in the dense vector. SparseMultiSet is a good choice when
64afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// one desires a growable number of entries per key, as it will retain the
65afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// SparseSet algorithmic properties despite being growable. Thus, it is often a
66afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// better choice than a SparseSet of growable containers or a vector of
67afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// vectors. SparseMultiSet also keeps iterators valid after erasure (provided
68afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// the iterators don't point to the element erased), allowing for more
69afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// intuitive and fast removal.
70afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
71afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// @tparam ValueT      The type of objects in the set.
72afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
73afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman/// @tparam SparseT     An unsigned integer type. See above.
74afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman///
75afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilsemantemplate<typename ValueT,
76afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman         typename KeyFunctorT = llvm::identity<unsigned>,
77afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman         typename SparseT = uint8_t>
78afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilsemanclass SparseMultiSet {
79afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// The actual data that's stored, as a doubly-linked list implemented via
80afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// indices into the DenseVector.  The doubly linked list is implemented
81afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// circular in Prev indices, and INVALID-terminated in Next indices. This
82afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// provides efficient access to list tails. These nodes can also be
83afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// tombstones, in which case they are actually nodes in a single-linked
84afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// freelist of recyclable slots.
85afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  struct SMSNode {
86afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    static const unsigned INVALID = ~0U;
87afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
88afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    ValueT Data;
89afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Prev;
90afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Next;
91afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
92afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { }
93afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
94afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// List tails have invalid Nexts.
95afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool isTail() const {
96afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return Next == INVALID;
97afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
98afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
99afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Whether this node is a tombstone node, and thus is in our freelist.
100afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool isTombstone() const {
101afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return Prev == INVALID;
102afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
103afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
104afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Since the list is circular in Prev, all non-tombstone nodes have a valid
105afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Prev.
106afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool isValid() const { return Prev != INVALID; }
107afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  };
108afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
109afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef typename KeyFunctorT::argument_type KeyT;
110afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef SmallVector<SMSNode, 8> DenseT;
111afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  DenseT Dense;
112afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  SparseT *Sparse;
113afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned Universe;
114afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  KeyFunctorT KeyIndexOf;
115afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
116afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
117afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// We have a built-in recycler for reusing tombstone slots. This recycler
118afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// puts a singly-linked free list into tombstone slots, allowing us quick
119afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// erasure, iterator preservation, and dense size.
120afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned FreelistIdx;
121afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned NumFree;
122afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
123afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned sparseIndex(const ValueT &Val) const {
124afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(ValIndexOf(Val) < Universe &&
125afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman           "Invalid key in set. Did object mutate?");
126afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return ValIndexOf(Val);
127afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
128afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned sparseIndex(const SMSNode &N) const { return sparseIndex(N.Data); }
129afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
130afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  // Disable copy construction and assignment.
131afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  // This data structure is not meant to be used that way.
132afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  SparseMultiSet(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
133afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  SparseMultiSet &operator=(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
134afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
135afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Whether the given entry is the head of the list. List heads's previous
136afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// pointers are to the tail of the list, allowing for efficient access to the
137afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// list tail. D must be a valid entry node.
138afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  bool isHead(const SMSNode &D) const {
139afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(D.isValid() && "Invalid node for head");
140afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return Dense[D.Prev].isTail();
141afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
142afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
143afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Whether the given entry is a singleton entry, i.e. the only entry with
144afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// that key.
145afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  bool isSingleton(const SMSNode &N) const {
146afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(N.isValid() && "Invalid node for singleton");
147afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Is N its own predecessor?
148afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return &Dense[N.Prev] == &N;
149afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
150afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
151afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Add in the given SMSNode. Uses a free entry in our freelist if
152afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// available. Returns the index of the added node.
153afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned addValue(const ValueT& V, unsigned Prev, unsigned Next) {
154afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (NumFree == 0) {
155afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Dense.push_back(SMSNode(V, Prev, Next));
156afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return Dense.size() - 1;
157afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
158afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
159afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Peel off a free slot
160afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Idx = FreelistIdx;
161afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned NextFree = Dense[Idx].Next;
162afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(Dense[Idx].isTombstone() && "Non-tombstone free?");
163afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
164afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[Idx] = SMSNode(V, Prev, Next);
165afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    FreelistIdx = NextFree;
166afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    --NumFree;
167afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return Idx;
168afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
169afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
170afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Make the current index a new tombstone. Pushes it onto the freelist.
171afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  void makeTombstone(unsigned Idx) {
172afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[Idx].Prev = SMSNode::INVALID;
173afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[Idx].Next = FreelistIdx;
174afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    FreelistIdx = Idx;
175afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    ++NumFree;
176afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
177afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
178afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilsemanpublic:
179afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef ValueT value_type;
180afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef ValueT &reference;
181afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef const ValueT &const_reference;
182afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef ValueT *pointer;
183afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef const ValueT *const_pointer;
184afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
185afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  SparseMultiSet()
186afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    : Sparse(0), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) { }
187afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
188afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ~SparseMultiSet() { free(Sparse); }
189afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
190afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Set the universe size which determines the largest key the set can hold.
191afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// The universe must be sized before any elements can be added.
192afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
193afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// @param U Universe size. All object keys must be less than U.
194afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
195afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  void setUniverse(unsigned U) {
196afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // It's not hard to resize the universe on a non-empty set, but it doesn't
197afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // seem like a likely use case, so we can add that code when we need it.
198afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(empty() && "Can only resize universe on an empty map");
199afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Hysteresis prevents needless reallocations.
200afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (U >= Universe/4 && U <= Universe)
201afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return;
202afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    free(Sparse);
203afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // The Sparse array doesn't actually need to be initialized, so malloc
204afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // would be enough here, but that will cause tools like valgrind to
205afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // complain about branching on uninitialized data.
206afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
207afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Universe = U;
208afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
209afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
210afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Our iterators are iterators over the collection of objects that share a
211afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// key.
212afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  template<typename SMSPtrTy>
213afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  class iterator_base : public std::iterator<std::bidirectional_iterator_tag,
214afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman                                             ValueT> {
215afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    friend class SparseMultiSet;
216afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    SMSPtrTy SMS;
217afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Idx;
218afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned SparseIdx;
219afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
220afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base(SMSPtrTy P, unsigned I, unsigned SI)
221afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      : SMS(P), Idx(I), SparseIdx(SI) { }
222afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
223afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Whether our iterator has fallen outside our dense vector.
224afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool isEnd() const {
225afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      if (Idx == SMSNode::INVALID)
226afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        return true;
227afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
228afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      assert(Idx < SMS->Dense.size() && "Out of range, non-INVALID Idx?");
229afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return false;
230afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
231afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
232afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Whether our iterator is properly keyed, i.e. the SparseIdx is valid
233afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool isKeyed() const { return SparseIdx < SMS->Universe; }
234afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
235afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Prev() const { return SMS->Dense[Idx].Prev; }
236afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Next() const { return SMS->Dense[Idx].Next; }
237afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
238afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    void setPrev(unsigned P) { SMS->Dense[Idx].Prev = P; }
239afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
240afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
241afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  public:
242afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super;
243afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    typedef typename super::value_type value_type;
244afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    typedef typename super::difference_type difference_type;
245afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    typedef typename super::pointer pointer;
246afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    typedef typename super::reference reference;
247afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
248afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base(const iterator_base &RHS)
249afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { }
250afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
251afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    const iterator_base &operator=(const iterator_base &RHS) {
252afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      SMS = RHS.SMS;
253afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Idx = RHS.Idx;
254afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      SparseIdx = RHS.SparseIdx;
255afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return *this;
256afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
257afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
258afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    reference operator*() const {
259afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
260afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman             "Dereferencing iterator of invalid key or index");
261afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
262afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return SMS->Dense[Idx].Data;
263afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
264afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    pointer operator->() const { return &operator*(); }
265afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
266afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Comparison operators
267afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool operator==(const iterator_base &RHS) const {
268afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // end compares equal
269afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      if (SMS == RHS.SMS && Idx == RHS.Idx) {
270dc89ed7da30e882cfdb74968b2a7613e37570409NAKAMURA Takumi        assert((isEnd() || SparseIdx == RHS.SparseIdx) &&
271afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman               "Same dense entry, but different keys?");
272afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        return true;
273afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      }
274afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
275afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return false;
276afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
277afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
278afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    bool operator!=(const iterator_base &RHS) const {
279afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return !operator==(RHS);
280afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
281afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
282afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    /// Increment and decrement operators
283afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base &operator--() { // predecrement - Back up
284afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      assert(isKeyed() && "Decrementing an invalid iterator");
285dc89ed7da30e882cfdb74968b2a7613e37570409NAKAMURA Takumi      assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) &&
286afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman             "Decrementing head of list");
287afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
288afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // If we're at the end, then issue a new find()
289afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      if (isEnd())
290afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        Idx = SMS->findIndex(SparseIdx).Prev();
291afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      else
292afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        Idx = Prev();
293afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
294afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return *this;
295afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
296afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base &operator++() { // preincrement - Advance
297afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      assert(!isEnd() && isKeyed() && "Incrementing an invalid/end iterator");
298afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Idx = Next();
299afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return *this;
300afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
301afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base operator--(int) { // postdecrement
302afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      iterator_base I(*this);
303afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      --*this;
304afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return I;
305afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
306afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator_base operator++(int) { // postincrement
307afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      iterator_base I(*this);
308afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      ++*this;
309afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return I;
310afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
311afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  };
312afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef iterator_base<SparseMultiSet *> iterator;
313afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef iterator_base<const SparseMultiSet *> const_iterator;
314afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
315afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  // Convenience types
316afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  typedef std::pair<iterator, iterator> RangePair;
317afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
318afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Returns an iterator past this container. Note that such an iterator cannot
319afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// be decremented, but will compare equal to other end iterators.
320afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator end() { return iterator(this, SMSNode::INVALID, SMSNode::INVALID); }
321afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  const_iterator end() const {
322afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return const_iterator(this, SMSNode::INVALID, SMSNode::INVALID);
323afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
324afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
325afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Returns true if the set is empty.
326afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
327afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// This is not the same as BitVector::empty().
328afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
329afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  bool empty() const { return size() == 0; }
330afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
331afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Returns the number of elements in the set.
332afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
333afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// This is not the same as BitVector::size() which returns the size of the
334afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// universe.
335afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
336afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned size() const {
337afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
338afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return Dense.size() - NumFree;
339afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
340afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
341afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Clears the set.  This is a very fast constant time operation.
342afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
343afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  void clear() {
344afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Sparse does not need to be cleared, see find().
345afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense.clear();
346afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    NumFree = 0;
347afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    FreelistIdx = SMSNode::INVALID;
348afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
349afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
350afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Find an element by its index.
351afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
352afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// @param   Idx A valid index to find.
353afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// @returns An iterator to the element identified by key, or end().
354afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
355afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator findIndex(unsigned Idx) {
356afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(Idx < Universe && "Key out of range");
357afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(std::numeric_limits<SparseT>::is_integer &&
358afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman           !std::numeric_limits<SparseT>::is_signed &&
359afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman           "SparseT must be an unsigned integer type");
360afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
361afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
362afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      const unsigned FoundIdx = sparseIndex(Dense[i]);
363afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // Check that we're pointing at the correct entry and that it is the head
364afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // of a valid list.
365afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      if (Idx == FoundIdx && Dense[i].isValid() && isHead(Dense[i]))
366afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        return iterator(this, i, Idx);
367afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // Stride is 0 when SparseT >= unsigned.  We don't need to loop.
368afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      if (!Stride)
369afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman        break;
370afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
371afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return end();
372afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
373afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
374afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Find an element by its key.
375afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
376afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// @param   Key A valid key to find.
377afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// @returns An iterator to the element identified by key, or end().
378afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
379afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator find(const KeyT &Key) {
380afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return findIndex(KeyIndexOf(Key));
381afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
382afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
383afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  const_iterator find(const KeyT &Key) const {
384afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator I = const_cast<SparseMultiSet*>(this)->findIndex(KeyIndexOf(Key));
385afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return const_iterator(I.SMS, I.Idx, KeyIndexOf(Key));
386afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
387afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
388afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Returns the number of elements identified by Key. This will be linear in
389afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// the number of elements of that key.
390afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  unsigned count(const KeyT &Key) const {
391afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Ret = 0;
392afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    for (const_iterator It = find(Key); It != end(); ++It)
393afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      ++Ret;
394afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
395afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return Ret;
396afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
397afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
398afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Returns true if this set contains an element identified by Key.
399afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  bool contains(const KeyT &Key) const {
400afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return find(Key) != end();
401afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
402afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
403afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Return the head and tail of the subset's list, otherwise returns end().
404afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator getHead(const KeyT &Key) { return find(Key); }
405afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator getTail(const KeyT &Key) {
406afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator I = find(Key);
407afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (I != end())
408afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      I = iterator(this, I.Prev(), KeyIndexOf(Key));
409afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return I;
410afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
411afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
412afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// The bounds of the range of items sharing Key K. First member is the head
413afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// of the list, and the second member is a decrementable end iterator for
414afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// that key.
415afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  RangePair equal_range(const KeyT &K) {
416afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator B = find(K);
417afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
418afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return make_pair(B, E);
419afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
420afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
421afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Insert a new element at the tail of the subset list. Returns an iterator
422afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// to the newly added entry.
423afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator insert(const ValueT &Val) {
424afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned Idx = sparseIndex(Val);
425afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator I = findIndex(Idx);
426afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
427afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID);
428afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
429afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (I == end()) {
430afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // Make a singleton list
431afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Sparse[Idx] = NodeIdx;
432afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Dense[NodeIdx].Prev = NodeIdx;
433afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return iterator(this, NodeIdx, Idx);
434afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
435afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
436afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Stick it at the end.
437afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned HeadIdx = I.Idx;
438afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    unsigned TailIdx = I.Prev();
439afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[TailIdx].Next = NodeIdx;
440afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[HeadIdx].Prev = NodeIdx;
441afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[NodeIdx].Prev = TailIdx;
442afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
443afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return iterator(this, NodeIdx, Idx);
444afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
445afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
446afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Erases an existing element identified by a valid iterator.
447afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
448afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// This invalidates iterators pointing at the same entry, but erase() returns
449afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// an iterator pointing to the next element in the subset's list. This makes
450afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// it possible to erase selected elements while iterating over the subset:
451afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
452afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///   tie(I, E) = Set.equal_range(Key);
453afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///   while (I != E)
454afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///     if (test(*I))
455afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///       I = Set.erase(I);
456afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///     else
457afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///       ++I;
458afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
459afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Note that if the last element in the subset list is erased, this will
460afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// return an end iterator which can be decremented to get the new tail (if it
461afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// exists):
462afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///
463afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///  tie(B, I) = Set.equal_range(Key);
464afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///  for (bool isBegin = B == I; !isBegin; /* empty */) {
465afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///    isBegin = (--I) == B;
466afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///    if (test(I))
467afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///      break;
468afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///    I = erase(I);
469afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  ///  }
470afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator erase(iterator I) {
471afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    assert(I.isKeyed() && !I.isEnd() && !Dense[I.Idx].isTombstone() &&
472afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman           "erasing invalid/end/tombstone iterator");
473afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
474afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // First, unlink the node from its list. Then swap the node out with the
475afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // dense vector's last entry
476afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    iterator NextI = unlink(Dense[I.Idx]);
477afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
478afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Put in a tombstone.
479afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    makeTombstone(I.Idx);
480afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
481afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return NextI;
482afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
483afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
484afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Erase all elements with the given key. This invalidates all
485afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// iterators of that key.
486afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  void eraseAll(const KeyT &K) {
487afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    for (iterator I = find(K); I != end(); /* empty */)
488afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      I = erase(I);
489afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
490afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
491afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilsemanprivate:
492afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  /// Unlink the node from its list. Returns the next node in the list.
493afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  iterator unlink(const SMSNode &N) {
494afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (isSingleton(N)) {
495afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // Singleton is already unlinked
496afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      assert(N.Next == SMSNode::INVALID && "Singleton has next?");
497afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return iterator(this, SMSNode::INVALID, ValIndexOf(N.Data));
498afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
499afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
500afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (isHead(N)) {
501afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // If we're the head, then update the sparse array and our next.
502afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Sparse[sparseIndex(N)] = N.Next;
503afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Dense[N.Next].Prev = N.Prev;
504afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return iterator(this, N.Next, ValIndexOf(N.Data));
505afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
506afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
507afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    if (N.isTail()) {
508afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // If we're the tail, then update our head and our previous.
509afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      findIndex(sparseIndex(N)).setPrev(N.Prev);
510afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      Dense[N.Prev].Next = N.Next;
511afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
512afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      // Give back an end iterator that can be decremented
513afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      iterator I(this, N.Prev, ValIndexOf(N.Data));
514afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman      return ++I;
515afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    }
516afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
517afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    // Otherwise, just drop us
518afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[N.Next].Prev = N.Prev;
519afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    Dense[N.Prev].Next = N.Next;
520afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman    return iterator(this, N.Next, ValIndexOf(N.Data));
521afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman  }
522afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman};
523afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
524afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman} // end namespace llvm
525afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman
526afe77f33b2a361ed0d001596dcdde0e16d57abeeMichael Ilseman#endif
527