llvm.org GIT mirror llvm / a5b4760
Give SmallSet a reasonable fallback if it gets large: use an std::set. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33582 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 13 years ago
1 changed file(s) with 51 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_ADT_SMALLSET_H
1515
1616 #include "llvm/ADT/SmallVector.h"
17 #include
1718
1819 namespace llvm {
1920
2021 /// SmallSet - This maintains a set of unique values, optimizing for the case
2122 /// when the set is small (less than N). In this case, the set can be
22 /// maintained with no mallocs.
23 /// maintained with no mallocs. If the set gets large, we expand to using an
24 /// std::set to maintain reasonable lookup times.
2325 ///
24 /// Note that this set does not guarantee that the elements in the set will be
25 /// ordered.
26 /// Note that this set does not provide a way to iterate over members in the
27 /// set.
2628 template
2729 class SmallSet {
30 /// Use a SmallVector to hold the elements here (even though it will never
31 /// reach it's 'large' stage) to avoid calling the default ctors of elements
32 /// we will never use.
2833 SmallVector Vector;
34 std::set Set;
35 typedef typename SmallVector::const_iterator VIterator;
2936 typedef typename SmallVector::iterator mutable_iterator;
3037 public:
3138 SmallSet() {}
3239
33 // Support iteration.
34 typedef typename SmallVector::const_iterator iterator;
35 typedef typename SmallVector::const_iterator const_iterator;
36
37 iterator begin() const { return Vector.begin(); }
38 iterator end() const { return Vector.end(); }
39
40 bool empty() const { return Vector.empty(); }
41 unsigned size() const { return Vector.size(); }
42
43 iterator find(const T &V) const {
44 for (iterator I = begin(), E = end(); I != E; ++I)
45 if (*I == V)
46 return I;
47 return end();
40 bool empty() const { return Vector.empty() && Set.empty(); }
41 unsigned size() const {
42 return isSmall() ? Vector.size() : Set.size();
4843 }
4944
5045 /// count - Return true if the element is in the set.
51 unsigned count(const T &V) const {
52 // Since the collection is small, just do a linear search.
53 return find(V) != end();
46 bool count(const T &V) const {
47 if (isSmall()) {
48 // Since the collection is small, just do a linear search.
49 return vfind(V) != Vector.end();
50 } else {
51 return Set.count(V);
52 }
5453 }
5554
5655 /// insert - Insert an element into the set if it isn't already there.
5756 bool insert(const T &V) {
58 iterator I = find(V);
59 if (I != end()) // Don't reinsert if it already exists.
57 if (!isSmall())
58 return Set.insert(V).second;
59
60 VIterator I = vfind(V);
61 if (I != Vector.end()) // Don't reinsert if it already exists.
6062 return false;
61 Vector.push_back(V);
63 if (Vector.size() < N) {
64 Vector.push_back(V);
65 return true;
66 }
67
68 // Otherwise, grow from vector to set.
69 while (!Vector.empty()) {
70 Set.insert(Vector.back());
71 Vector.pop_back();
72 }
73 Set.insert(V);
6274 return true;
6375 }
6476
65 void erase(const T &V) {
77 bool erase(const T &V) {
78 if (!isSmall())
79 return Set.erase(V).second;
6680 for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
6781 if (*I == V) {
6882 Vector.erase(I);
69 return;
83 return true;
7084 }
85 return false;
7186 }
7287
7388 void clear() {
7489 Vector.clear();
90 Set.clear();
7591 }
76
92 private:
93 bool isSmall() const { return Set.empty(); }
94
95 VIterator vfind(const T &V) const {
96 for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
97 if (*I == V)
98 return I;
99 return Vector.end();
100 }
77101 };
78102
79103