forked from DataBeaver/trimps-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spirepool.cpp
108 lines (90 loc) · 1.95 KB
/
spirepool.cpp
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
#include "spirepool.h"
#include "spirelayout.h"
using namespace std;
Pool::Pool(unsigned s, ScoreFunc *f):
max_size(s),
score_func(f),
isolated_until(0)
{ }
void Pool::reset(ScoreFunc *f)
{
lock_guard<mutex> lock(layouts_mutex);
layouts.clear();
if(f)
score_func = f;
}
void Pool::add_layout(const Layout &layout)
{
lock_guard<mutex> lock(layouts_mutex);
if(layouts.size()>=max_size && score_func(layout)<score_func(layouts.back()))
return;
Number score = score_func(layout);
auto i = layouts.begin();
for(; (i!=layouts.end() && score_func(*i)>score); ++i)
if(i->get_cost()<=layout.get_cost())
return;
if(i!=layouts.end() && score_func(*i)==score)
{
*i = layout;
++i;
}
else
layouts.insert(i, layout);
while(i!=layouts.end())
{
if(i->get_cost()>=layout.get_cost())
i = layouts.erase(i);
else
++i;
}
if(layouts.size()>max_size)
layouts.pop_back();
}
Layout Pool::get_best_layout() const
{
lock_guard<mutex> lock(layouts_mutex);
return layouts.front();
}
bool Pool::get_best_layout(Layout &layout) const
{
lock_guard<mutex> lock(layouts_mutex);
if(score_func(layout)>=score_func(layouts.front()))
return false;
layout = layouts.front();
return true;
}
Layout Pool::get_random_layout(Random &random) const
{
lock_guard<mutex> lock(layouts_mutex);
Number total = 0;
for(const auto &l: layouts)
total += score_func(l);
if(!total)
{
auto i = layouts.begin();
advance(i, random()%layouts.size());
return *i;
}
Number p = ((static_cast<Number>(random())<<32)+random())%total;
for(const auto &l: layouts)
{
Number score = score_func(l);
if(p<score)
return l;
p -= score;
}
throw logic_error("Spire::get_random_layout");
}
Number Pool::get_best_score() const
{
lock_guard<mutex> lock(layouts_mutex);
return score_func(layouts.front());
}
void Pool::set_isolated_until(unsigned cycle)
{
isolated_until.store(cycle);
}
bool Pool::check_isolation(unsigned cycle) const
{
return isolated_until.load()>cycle;
}