Introduce tgba::release_iter().
Instead of "delete iter;" we now do "aut->release_iter(iter);" to give the iterator back to the automaton. The TGBA classes now reuse a previously returned tgba_succ_iterator to answer a succ_iter() call, therefore avoiding (1) memory allocation, as well as (2) vtable and other constant member initialization. * src/tgba/tgba.hh, src/tgba/tgba.cc (release_iter, iter_cache_): Implement a release_iter() that stores the released iterator in iter_cache_. * src/tgba/succiter.hh (internal::succ_iterable): Move... * src/tgba/tgba.hh (tgba::succ_iterable): ... here. And use release_iter(). * iface/dve2/dve2.cc, src/kripke/kripke.cc, src/kripke/kripke.hh, src/tgba/succiterconcrete.cc, src/tgba/succiterconcrete.hh, src/tgba/taatgba.hh, src/tgba/tgbabddconcrete.cc, src/tgba/tgbaexplicit.hh, src/tgba/tgbamask.cc, src/tgba/tgbaproduct.cc, src/tgba/tgbaproxy.cc, src/tgba/tgbascc.cc, src/tgba/tgbatba.cc, src/tgba/tgbaunion.cc, src/tgba/tgbaunion.hh, src/tgba/wdbacomp.cc, src/tgbaalgos/bfssteps.cc, src/tgbaalgos/compsusp.cc, src/tgbaalgos/cycles.cc, src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtgbasat.cc, src/tgbaalgos/gtec/gtec.cc, src/tgbaalgos/gv04.cc, src/tgbaalgos/isweakscc.cc, src/tgbaalgos/lbtt.cc, src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/magic.cc, src/tgbaalgos/ndfs_result.hxx, src/tgbaalgos/neverclaim.cc, src/tgbaalgos/reachiter.cc, src/tgbaalgos/replayrun.cc, src/tgbaalgos/safety.cc, src/tgbaalgos/scc.cc, src/tgbaalgos/se05.cc, src/tgbaalgos/simulation.cc, src/tgbaalgos/tau03.cc, src/tgbaalgos/tau03opt.cc: Use release_iter() instead of deleting iterators, and used recycle iter_cache_ in implementations of tgba::succ_iter().
This commit is contained in:
parent
487cd01d9f
commit
06c69f88ff
40 changed files with 386 additions and 248 deletions
|
|
@ -71,8 +71,48 @@ namespace spot
|
|||
{
|
||||
protected:
|
||||
tgba();
|
||||
// Any iterator returned via release_iter.
|
||||
mutable tgba_succ_iterator* iter_cache_;
|
||||
|
||||
public:
|
||||
|
||||
#ifndef SWIG
|
||||
class succ_iterable
|
||||
{
|
||||
protected:
|
||||
const tgba* aut_;
|
||||
tgba_succ_iterator* it_;
|
||||
public:
|
||||
succ_iterable(const tgba* aut, tgba_succ_iterator* it)
|
||||
: aut_(aut), it_(it)
|
||||
{
|
||||
}
|
||||
|
||||
succ_iterable(succ_iterable&& other)
|
||||
: aut_(other.aut_), it_(other.it_)
|
||||
{
|
||||
other.it_ = nullptr;
|
||||
}
|
||||
|
||||
~succ_iterable()
|
||||
{
|
||||
if (it_)
|
||||
aut_->release_iter(it_);
|
||||
}
|
||||
|
||||
internal::succ_iterator begin()
|
||||
{
|
||||
it_->first();
|
||||
return it_->done() ? nullptr : it_;
|
||||
}
|
||||
|
||||
internal::succ_iterator end()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
virtual ~tgba();
|
||||
|
||||
/// \brief Get the initial state of the automaton.
|
||||
|
|
@ -111,15 +151,29 @@ namespace spot
|
|||
const state* global_state = nullptr,
|
||||
const tgba* global_automaton = nullptr) const = 0;
|
||||
|
||||
#ifndef SWIG
|
||||
/// \brief Build an iterable over the successors of \a s.
|
||||
///
|
||||
/// This is meant to be used as
|
||||
/// <code>for (auto i: aut->out(s)) { /* i->current_state() */ }</code>.
|
||||
internal::succ_iterable
|
||||
succ_iterable
|
||||
succ(const state* s) const
|
||||
{
|
||||
return {this, succ_iter(s)};
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Release an iterator after usage.
|
||||
///
|
||||
/// This iterator can then be reused by succ_iter() to avoid
|
||||
/// memory allocation.
|
||||
void release_iter(tgba_succ_iterator* i) const
|
||||
{
|
||||
if (iter_cache_)
|
||||
delete i;
|
||||
else
|
||||
iter_cache_ = i;
|
||||
}
|
||||
|
||||
/// \brief Get a formula that must hold whatever successor is taken.
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue