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