3
3
4
4
#include < cassert>
5
5
#include < cstddef>
6
+ #include < functional>
6
7
#include < iterator>
7
8
#include < map>
9
+ #include < unordered_map>
8
10
#include < vector>
9
11
12
+ namespace llvm {
13
+ class raw_ostream ;
14
+ };
15
+
10
16
namespace klee {
11
17
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 {
13
25
private:
14
- size_t capacity;
15
- std::map<size_t , ValueType> internalStorage;
26
+ std::unordered_map<size_t , ValueType> internalStorage;
16
27
ValueType defaultValue;
28
+ Eq eq;
17
29
18
30
bool contains (size_t key) const { return internalStorage.count (key) != 0 ; }
19
31
20
32
public:
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);
46
41
}
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
+ }
56
43
57
44
SparseStorage (const std::vector<ValueType> &values,
58
45
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]) ;
62
49
}
63
50
}
64
51
65
52
void store (size_t idx, const ValueType &value) {
66
- if (idx < capacity) {
53
+ if (eq (value, defaultValue)) {
54
+ internalStorage.erase (idx);
55
+ } else {
67
56
internalStorage[idx] = value;
68
57
}
69
58
}
@@ -77,55 +66,81 @@ template <typename ValueType> class SparseStorage {
77
66
}
78
67
79
68
ValueType load (size_t idx) const {
80
- assert (idx < capacity && idx >= 0 );
81
69
return contains (idx) ? internalStorage.at (idx) : defaultValue;
82
70
}
83
71
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);
98
76
}
99
-
100
- capacity = newCapacity;
77
+ return sizeOfRange;
101
78
}
102
79
103
80
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 ;
106
82
}
107
83
108
84
bool operator !=(const SparseStorage<ValueType> &another) const {
109
85
return !(*this == another);
110
86
}
111
87
112
88
bool operator <(const SparseStorage &another) const {
113
- return internalStorage < another. internalStorage ;
89
+ return compare (another) == - 1 ;
114
90
}
115
91
116
92
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 ();
118
134
}
119
135
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 ;
122
137
};
123
138
124
139
template <typename U>
125
140
SparseStorage<unsigned char > sparseBytesFromValue (const U &value) {
126
141
const unsigned char *valueUnsignedCharIterator =
127
142
reinterpret_cast <const unsigned char *>(&value);
128
- SparseStorage<unsigned char > result ( sizeof (value)) ;
143
+ SparseStorage<unsigned char > result;
129
144
result.store (0 , valueUnsignedCharIterator,
130
145
valueUnsignedCharIterator + sizeof (value));
131
146
return result;
0 commit comments