5
5
#include < cstddef>
6
6
#include < iterator>
7
7
#include < map>
8
+ #include < unordered_map>
8
9
#include < vector>
9
10
11
+ namespace llvm {
12
+ class raw_ostream ;
13
+ };
14
+
10
15
namespace klee {
11
16
17
+ enum class Density {
18
+ Sparse,
19
+ Dense,
20
+ };
21
+
12
22
template <typename ValueType> class SparseStorage {
13
23
private:
14
- size_t capacity;
15
- std::map<size_t , ValueType> internalStorage;
24
+ std::unordered_map<size_t , ValueType> internalStorage;
16
25
ValueType defaultValue;
17
26
18
27
bool contains (size_t key) const { return internalStorage.count (key) != 0 ; }
19
28
20
29
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;
30
+ SparseStorage (const ValueType &defaultValue = ValueType())
31
+ : defaultValue(defaultValue) {}
32
+
33
+ SparseStorage (const std::unordered_map<size_t , ValueType> &internalStorage,
34
+ const ValueType &defaultValue)
35
+ : defaultValue(defaultValue) {
36
+ for (auto &[index, value] : internalStorage) {
37
+ store (index, value);
46
38
}
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) {}
39
+ }
56
40
57
41
SparseStorage (const std::vector<ValueType> &values,
58
42
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];
43
+ : defaultValue(defaultValue) {
44
+ for (size_t idx = 0 ; idx < values.size (); ++idx) {
45
+ store ( idx, values[idx]) ;
62
46
}
63
47
}
64
48
65
49
void store (size_t idx, const ValueType &value) {
66
- if (idx < capacity) {
50
+ if (value == defaultValue) {
51
+ internalStorage.erase (idx);
52
+ } else {
67
53
internalStorage[idx] = value;
68
54
}
69
55
}
@@ -77,55 +63,82 @@ template <typename ValueType> class SparseStorage {
77
63
}
78
64
79
65
ValueType load (size_t idx) const {
80
- assert (idx < capacity && idx >= 0 );
81
66
return contains (idx) ? internalStorage.at (idx) : defaultValue;
82
67
}
83
68
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);
69
+ size_t sizeOfSetRange () const {
70
+ size_t sizeOfRange = 0 ;
71
+ for (auto i : internalStorage) {
72
+ sizeOfRange = std::max (i.first , sizeOfRange);
98
73
}
99
-
100
- capacity = newCapacity;
74
+ return sizeOfRange;
101
75
}
102
76
103
77
bool operator ==(const SparseStorage<ValueType> &another) const {
104
- return size () == another.size () && defaultValue == another.defaultValue &&
105
- internalStorage == another.internalStorage ;
78
+ return defaultValue == another.defaultValue && compare (another) == 0 ;
106
79
}
107
80
108
81
bool operator !=(const SparseStorage<ValueType> &another) const {
109
82
return !(*this == another);
110
83
}
111
84
112
85
bool operator <(const SparseStorage &another) const {
113
- return internalStorage < another. internalStorage ;
86
+ return compare (another) == - 1 ;
114
87
}
115
88
116
89
bool operator >(const SparseStorage &another) const {
117
- return internalStorage > another.internalStorage ;
90
+ return compare (another) == 1 ;
91
+ }
92
+
93
+ int compare (const SparseStorage<ValueType> &other) const {
94
+ auto ordered = calculateOrderedStorage ();
95
+ auto otherOrdered = other.calculateOrderedStorage ();
96
+
97
+ if (ordered == otherOrdered) {
98
+ return 0 ;
99
+ } else {
100
+ return ordered < otherOrdered ? -1 : 1 ;
101
+ }
102
+ }
103
+
104
+ std::map<size_t , ValueType> calculateOrderedStorage () const {
105
+ std::map<size_t , ValueType> ordered;
106
+ for (const auto &i : internalStorage) {
107
+ ordered.insert (i);
108
+ }
109
+ return ordered;
110
+ }
111
+
112
+ std::vector<ValueType> getFirstNIndexes (size_t n) const {
113
+ std::vector<ValueType> vectorized (n);
114
+ for (size_t i = 0 ; i < n; i++) {
115
+ vectorized[i] = load (i);
116
+ }
117
+ return vectorized;
118
+ }
119
+
120
+ const std::unordered_map<size_t , ValueType> &storage () const {
121
+ return internalStorage;
122
+ };
123
+
124
+ const ValueType &defaultV () const { return defaultValue; };
125
+
126
+ void reset () { internalStorage.clear (); }
127
+
128
+ void reset (ValueType newDefault) {
129
+ defaultValue = newDefault;
130
+ internalStorage.clear ();
118
131
}
119
132
120
- Iterator begin () const { return Iterator ( 0 , this ); }
121
- Iterator end () const { return Iterator ( size (), this ); }
133
+ // Specialized for unsigned char in .cpp
134
+ void print (llvm::raw_ostream &os, Density) const ;
122
135
};
123
136
124
137
template <typename U>
125
138
SparseStorage<unsigned char > sparseBytesFromValue (const U &value) {
126
139
const unsigned char *valueUnsignedCharIterator =
127
140
reinterpret_cast <const unsigned char *>(&value);
128
- SparseStorage<unsigned char > result ( sizeof (value)) ;
141
+ SparseStorage<unsigned char > result;
129
142
result.store (0 , valueUnsignedCharIterator,
130
143
valueUnsignedCharIterator + sizeof (value));
131
144
return result;
0 commit comments