-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSPA.h
125 lines (113 loc) · 2.57 KB
/
SPA.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#ifndef SPA_H_
#define SPA_H_
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <algorithm>
#include "utility.h"
// SPA that is thread-safe but not multithreaded
template <class IT, class NT>
class SPA
{
public:
SPA(IT range)
{
values.resize(range);
flags.resize(range, 0);
}
template<typename KeyIterator>
void Initialize(KeyIterator first, KeyIterator last)
{
while(first != last)
{
flags[*first] = 1;
possible.push_back(*first);
++first;
}
}
template <typename AddOperation>
void Insert(IT tkey, NT tval, AddOperation addop)
{
if(flags[tkey] == 1)
{
values[tkey] = tval;
flags[tkey] = 2;
present.push_back(tkey);
}
else if(flags[tkey] == 2) // previously set
{
values[tkey] = addop(tval, values[tkey]);
}
}
size_t Size()
{
return present.size();
}
template<typename KeyIterator, typename ValueIterator>
void OutputReset(KeyIterator firstkey, ValueIterator firstvalue)
{
// the range starting from first is large enough to hold all output elements
for(auto index:present)
{
(*firstkey) = index;
(*firstvalue) = values[index];
++firstkey;
++firstvalue;
}
present.clear();
for(auto index:possible)
{
flags[index] = 0;
}
possible.clear();
}
vector<NT> values;
vector<short> flags; // 0: not-allowed (masked out), 1: allowed, 2: set
vector<IT> present;
vector<IT> possible;
};
// SPA that is thread-safe but not multithreaded
template <class IT>
class SPAStructure
{
public:
SPAStructure(IT range): committed(0)
{
flags.resize(range, 0);
}
template<typename KeyIterator>
void Initialize(KeyIterator first, KeyIterator last)
{
while(first != last)
{
flags[*first] = 1;
possible.push_back(*first);
++first;
}
}
void Insert(IT tkey)
{
if(flags[tkey] == 1)
{
flags[tkey] = 2;
++committed;
}
}
size_t Size()
{
return committed;
}
void Reset()
{
for(auto index:possible)
{
flags[index] = 0;
}
possible.clear();
committed = 0;
}
IT committed;
vector<short> flags; // 0: not-allowed (masked out), 1: allowed, 2: set
vector<IT> possible;
};
#endif