33
44#include < cassert>
55#include < cstddef>
6+ #include < functional>
67#include < iterator>
78#include < map>
9+ #include < unordered_map>
810#include < vector>
911
12+ namespace llvm {
13+ class raw_ostream ;
14+ };
15+
1016namespace klee {
1117
12- template <typename ValueType> class SparseStorage {
18+ enum class Density {
19+ Sparse,
20+ Dense,
21+ };
22+
23+ template <typename ValueType, typename Eq = std::equal_to<ValueType>>
24+ class SparseStorage {
1325private:
14- size_t capacity;
15- std::map<size_t , ValueType> internalStorage;
26+ std::unordered_map<size_t , ValueType> internalStorage;
1627 ValueType defaultValue;
28+ Eq eq;
1729
1830 bool contains (size_t key) const { return internalStorage.count (key) != 0 ; }
1931
2032public:
21- struct Iterator {
22- using iterator_category = std::input_iterator_tag;
23- using difference_type = std::ptrdiff_t ;
24- using value_type = ValueType;
25- using pointer = ValueType *;
26- using reference = ValueType &;
27-
28- private:
29- size_t idx;
30- const SparseStorage *owner;
31-
32- public:
33- Iterator (size_t idx, const SparseStorage *owner) : idx(idx), owner(owner) {}
34-
35- value_type operator *() const { return owner->load (idx); }
36-
37- Iterator &operator ++() {
38- ++idx;
39- return *this ;
40- }
41-
42- Iterator operator ++(int ) {
43- Iterator snap = *this ;
44- ++(*this );
45- return snap;
33+ SparseStorage (const ValueType &defaultValue = ValueType())
34+ : defaultValue(defaultValue) {}
35+
36+ SparseStorage (const std::unordered_map<size_t , ValueType> &internalStorage,
37+ const ValueType &defaultValue)
38+ : defaultValue(defaultValue) {
39+ for (auto &[index, value] : internalStorage) {
40+ store (index, value);
4641 }
47-
48- bool operator ==(const Iterator &other) const { return idx == other.idx ; }
49-
50- bool operator !=(const Iterator &other) const { return !(*this == other); }
51- };
52-
53- SparseStorage (size_t capacity = 0 ,
54- const ValueType &defaultValue = ValueType())
55- : capacity(capacity), defaultValue(defaultValue) {}
42+ }
5643
5744 SparseStorage (const std::vector<ValueType> &values,
5845 const ValueType &defaultValue = ValueType())
59- : capacity(values.capacity()), defaultValue(defaultValue) {
60- for (size_t idx = 0 ; idx < values.capacity (); ++idx) {
61- internalStorage[ idx] = values[idx];
46+ : defaultValue(defaultValue) {
47+ for (size_t idx = 0 ; idx < values.size (); ++idx) {
48+ store ( idx, values[idx]) ;
6249 }
6350 }
6451
6552 void store (size_t idx, const ValueType &value) {
66- if (idx < capacity) {
53+ if (eq (value, defaultValue)) {
54+ internalStorage.erase (idx);
55+ } else {
6756 internalStorage[idx] = value;
6857 }
6958 }
@@ -77,55 +66,81 @@ template <typename ValueType> class SparseStorage {
7766 }
7867
7968 ValueType load (size_t idx) const {
80- assert (idx < capacity && idx >= 0 );
8169 return contains (idx) ? internalStorage.at (idx) : defaultValue;
8270 }
8371
84- size_t size () const { return capacity; }
85-
86- void resize (size_t newCapacity) {
87- assert (newCapacity >= 0 );
88- // Free to extend
89- if (newCapacity >= capacity) {
90- capacity = newCapacity;
91- return ;
92- }
93-
94- // Truncate unnessecary elements
95- auto iterOnNewSize = internalStorage.lower_bound (newCapacity);
96- while (iterOnNewSize != internalStorage.end ()) {
97- iterOnNewSize = internalStorage.erase (iterOnNewSize);
72+ size_t sizeOfSetRange () const {
73+ size_t sizeOfRange = 0 ;
74+ for (auto i : internalStorage) {
75+ sizeOfRange = std::max (i.first , sizeOfRange);
9876 }
99-
100- capacity = newCapacity;
77+ return sizeOfRange;
10178 }
10279
10380 bool operator ==(const SparseStorage<ValueType> &another) const {
104- return size () == another.size () && defaultValue == another.defaultValue &&
105- internalStorage == another.internalStorage ;
81+ return defaultValue == another.defaultValue && compare (another) == 0 ;
10682 }
10783
10884 bool operator !=(const SparseStorage<ValueType> &another) const {
10985 return !(*this == another);
11086 }
11187
11288 bool operator <(const SparseStorage &another) const {
113- return internalStorage < another. internalStorage ;
89+ return compare (another) == - 1 ;
11490 }
11591
11692 bool operator >(const SparseStorage &another) const {
117- return internalStorage > another.internalStorage ;
93+ return compare (another) == 1 ;
94+ }
95+
96+ int compare (const SparseStorage<ValueType> &other) const {
97+ auto ordered = calculateOrderedStorage ();
98+ auto otherOrdered = other.calculateOrderedStorage ();
99+
100+ if (ordered == otherOrdered) {
101+ return 0 ;
102+ } else {
103+ return ordered < otherOrdered ? -1 : 1 ;
104+ }
105+ }
106+
107+ std::map<size_t , ValueType> calculateOrderedStorage () const {
108+ std::map<size_t , ValueType> ordered;
109+ for (const auto &i : internalStorage) {
110+ ordered.insert (i);
111+ }
112+ return ordered;
113+ }
114+
115+ std::vector<ValueType> getFirstNIndexes (size_t n) const {
116+ std::vector<ValueType> vectorized (n);
117+ for (size_t i = 0 ; i < n; i++) {
118+ vectorized[i] = load (i);
119+ }
120+ return vectorized;
121+ }
122+
123+ const std::unordered_map<size_t , ValueType> &storage () const {
124+ return internalStorage;
125+ };
126+
127+ const ValueType &defaultV () const { return defaultValue; };
128+
129+ void reset () { internalStorage.clear (); }
130+
131+ void reset (ValueType newDefault) {
132+ defaultValue = newDefault;
133+ internalStorage.clear ();
118134 }
119135
120- Iterator begin () const { return Iterator (0 , this ); }
121- Iterator end () const { return Iterator (size (), this ); }
136+ void print (llvm::raw_ostream &os, Density) const ;
122137};
123138
124139template <typename U>
125140SparseStorage<unsigned char > sparseBytesFromValue (const U &value) {
126141 const unsigned char *valueUnsignedCharIterator =
127142 reinterpret_cast <const unsigned char *>(&value);
128- SparseStorage<unsigned char > result ( sizeof (value)) ;
143+ SparseStorage<unsigned char > result;
129144 result.store (0 , valueUnsignedCharIterator,
130145 valueUnsignedCharIterator + sizeof (value));
131146 return result;
0 commit comments