mirror of https://github.com/KLayout/klayout.git
WIP: more preparations
This commit is contained in:
parent
1bdf18a51b
commit
5aa301bcc6
|
|
@ -1698,21 +1698,83 @@ private:
|
||||||
int m_pn, m_ps;
|
int m_pn, m_ps;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t skip_info_storage_threshold = 1;
|
||||||
|
|
||||||
class EdgeProcessorStates
|
class EdgeProcessorStates
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct SkipInfo
|
struct SkipInfo
|
||||||
{
|
{
|
||||||
SkipInfo (size_t _skip, size_t _skip_res)
|
SkipInfo (size_t _skip, const std::vector<size_t> &_skip_res)
|
||||||
: skip (_skip), skip_res (_skip_res)
|
: skip (_skip), m_skip_res_n (0), m_skip_res (0)
|
||||||
{ }
|
{
|
||||||
|
set_skip_res (_skip_res.begin (), _skip_res.end ());
|
||||||
|
}
|
||||||
|
|
||||||
SkipInfo ()
|
SkipInfo ()
|
||||||
: skip (0), skip_res (0)
|
: skip (0), m_skip_res_n (0), m_skip_res (0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
SkipInfo (const SkipInfo &si)
|
||||||
|
: skip (0), m_skip_res_n (0), m_skip_res (0)
|
||||||
|
{
|
||||||
|
operator= (si);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SkipInfo ()
|
||||||
|
{
|
||||||
|
if (m_skip_res_n > skip_info_storage_threshold) {
|
||||||
|
delete[] skip_res ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipInfo &operator= (const SkipInfo &si)
|
||||||
|
{
|
||||||
|
if (&si != this) {
|
||||||
|
skip = si.skip;
|
||||||
|
const size_t *n = si.skip_res ();
|
||||||
|
set_skip_res (n, n + si.m_skip_res_n);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iter>
|
||||||
|
void set_skip_res (Iter b, Iter e)
|
||||||
|
{
|
||||||
|
if (m_skip_res_n > skip_info_storage_threshold) {
|
||||||
|
delete[] (reinterpret_cast<size_t *> (m_skip_res));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_skip_res_n = e - b;
|
||||||
|
if (m_skip_res_n <= skip_info_storage_threshold) {
|
||||||
|
if (b == e) {
|
||||||
|
m_skip_res = 0;
|
||||||
|
} else {
|
||||||
|
m_skip_res = *b;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size_t *t = new size_t[m_skip_res_n];
|
||||||
|
m_skip_res = reinterpret_cast<size_t> (t);
|
||||||
|
for (Iter i = b; i != e; ++i) {
|
||||||
|
*t++ = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t *skip_res () const
|
||||||
|
{
|
||||||
|
if (m_skip_res_n <= skip_info_storage_threshold) {
|
||||||
|
return &m_skip_res;
|
||||||
|
} else {
|
||||||
|
return reinterpret_cast<const size_t *> (m_skip_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t skip;
|
size_t skip;
|
||||||
size_t skip_res;
|
|
||||||
|
private:
|
||||||
|
size_t m_skip_res_n;
|
||||||
|
size_t m_skip_res;
|
||||||
};
|
};
|
||||||
|
|
||||||
EdgeProcessorStates (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &procs)
|
EdgeProcessorStates (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &procs)
|
||||||
|
|
@ -1905,15 +1967,14 @@ public:
|
||||||
*
|
*
|
||||||
* This method will return true if at least one of the edge sinks received the edge
|
* This method will return true if at least one of the edge sinks received the edge
|
||||||
*/
|
*/
|
||||||
bool push_edge (const db::Edge &e)
|
void push_edge (const db::Edge &e)
|
||||||
{
|
{
|
||||||
bool any = false;
|
size_t i = 0;
|
||||||
for (std::vector<EdgeProcessorState>::iterator s = m_states.begin (); s != m_states.end (); ++s) {
|
for (std::vector<EdgeProcessorState>::iterator s = m_states.begin (); s != m_states.end (); ++s, ++i) {
|
||||||
if (s->push_edge (e)) {
|
if (s->push_edge (e)) {
|
||||||
any = true;
|
++m_nres [i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1922,26 +1983,33 @@ public:
|
||||||
* This is for optimization of the polygon generation. Stitching of edges does not happen if
|
* This is for optimization of the polygon generation. Stitching of edges does not happen if
|
||||||
* there are no news.
|
* there are no news.
|
||||||
*/
|
*/
|
||||||
void skip_n (size_t n)
|
void skip_n (const SkipInfo &si)
|
||||||
{
|
{
|
||||||
|
const size_t *n = si.skip_res ();
|
||||||
for (std::vector<EdgeProcessorState>::iterator s = m_states.begin (); s != m_states.end (); ++s) {
|
for (std::vector<EdgeProcessorState>::iterator s = m_states.begin (); s != m_states.end (); ++s) {
|
||||||
s->skip_n (n);
|
s->skip_n (*n++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a new SkipInfo entry
|
* @brief Gets a new SkipInfo entry
|
||||||
*/
|
*/
|
||||||
size_t skip_entry (size_t skip, size_t skip_res)
|
size_t skip_entry (size_t skip, const std::vector<size_t> &skip_res)
|
||||||
{
|
{
|
||||||
if (! m_skip_queue.empty ()) {
|
if (! m_skip_queue.empty ()) {
|
||||||
|
|
||||||
size_t n = m_skip_queue.front ();
|
size_t n = m_skip_queue.front ();
|
||||||
m_skip_queue.pop_front ();
|
m_skip_queue.pop_front ();
|
||||||
m_skip_info[n] = SkipInfo (skip, skip_res);
|
m_skip_info[n].skip = skip;
|
||||||
|
m_skip_info[n].set_skip_res (skip_res.begin (), skip_res.end ());
|
||||||
|
|
||||||
return n + 1;
|
return n + 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
m_skip_info.push_back (SkipInfo (skip, skip_res));
|
m_skip_info.push_back (SkipInfo (skip, skip_res));
|
||||||
return m_skip_info.size ();
|
return m_skip_info.size ();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1979,11 +2047,31 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Begins an interval that can potentially be skipped
|
||||||
|
*/
|
||||||
|
void begin_skip_interval ()
|
||||||
|
{
|
||||||
|
m_nres.clear ();
|
||||||
|
m_nres.resize (m_states.size (), size_t (0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finishes an interval that can potentially be skipped
|
||||||
|
*
|
||||||
|
* Returns the index of a new skip interval entry containing the skip information.
|
||||||
|
*/
|
||||||
|
size_t end_skip_interval (size_t skip)
|
||||||
|
{
|
||||||
|
return skip_entry (skip, m_nres);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<EdgeProcessorState> m_states;
|
std::vector<EdgeProcessorState> m_states;
|
||||||
bool m_selects_edges, m_prefer_touch;
|
bool m_selects_edges, m_prefer_touch;
|
||||||
std::vector<SkipInfo> m_skip_info;
|
std::vector<SkipInfo> m_skip_info;
|
||||||
std::list<size_t> m_skip_queue;
|
std::list<size_t> m_skip_queue;
|
||||||
|
std::vector<size_t> m_nres;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2266,14 +2354,14 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
|
||||||
|
|
||||||
const EdgeProcessorStates::SkipInfo &skip_info = gs.skip_info (c->data);
|
const EdgeProcessorStates::SkipInfo &skip_info = gs.skip_info (c->data);
|
||||||
#ifdef DEBUG_EDGE_PROCESSOR
|
#ifdef DEBUG_EDGE_PROCESSOR
|
||||||
printf ("X %ld->%d,%d\n", long (c->data), int (skip_info.skip), int (skip_info.skip_res));
|
printf ("X %ld->%d\n", long (c->data), int (skip_info.skip));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (skip_info.skip != 0 && (c + skip_info.skip >= future || (c + skip_info.skip)->data != 0)) {
|
if (skip_info.skip != 0 && (c + skip_info.skip >= future || (c + skip_info.skip)->data != 0)) {
|
||||||
|
|
||||||
tl_assert (c + skip_info.skip <= future);
|
tl_assert (c + skip_info.skip <= future);
|
||||||
|
|
||||||
gs.skip_n (skip_info.skip_res);
|
gs.skip_n (skip_info);
|
||||||
|
|
||||||
// skip this interval - has not changed
|
// skip this interval - has not changed
|
||||||
c += skip_info.skip;
|
c += skip_info.skip;
|
||||||
|
|
@ -2281,7 +2369,7 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
std::vector <WorkEdge>::iterator c0 = c;
|
std::vector <WorkEdge>::iterator c0 = c;
|
||||||
size_t n_res = 0;
|
gs.begin_skip_interval ();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
|
@ -2388,9 +2476,7 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
|
||||||
gs.end_coincident ();
|
gs.end_coincident ();
|
||||||
|
|
||||||
if (e != mp_work_edges->end ()) {
|
if (e != mp_work_edges->end ()) {
|
||||||
if (gs.push_edge (*e)) {
|
gs.push_edge (*e);
|
||||||
++n_res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -2402,7 +2488,7 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
|
||||||
} while (c != future && ! gs.is_reset ());
|
} while (c != future && ! gs.is_reset ());
|
||||||
|
|
||||||
// TODO: assert that there is no overflow here:
|
// TODO: assert that there is no overflow here:
|
||||||
c0->data = gs.skip_entry (std::distance (c0, c), n_res);
|
c0->data = gs.end_skip_interval (std::distance (c0, c));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue