Commit 06c69f88 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

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().
parent 487cd01d
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012 Laboratoire de Recherche et Développement // Copyright (C) 2011, 2012, 2014 Laboratoire de Recherche et Développement
// de l'Epita (LRDE) // de l'Epita (LRDE)
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -214,9 +214,8 @@ namespace spot ...@@ -214,9 +214,8 @@ namespace spot
~callback_context() ~callback_context()
{ {
callback_context::transitions_t::const_iterator it; for (auto t: transitions)
for (it = transitions.begin(); it != transitions.end(); ++it) t->destroy();
(*it)->destroy();
} }
}; };
...@@ -260,6 +259,13 @@ namespace spot ...@@ -260,6 +259,13 @@ namespace spot
{ {
} }
void recycle(const callback_context* cc, bdd cond)
{
delete cc_;
cc_ = cc;
kripke_succ_iterator::recycle(cond);
}
~dve2_succ_iterator() ~dve2_succ_iterator()
{ {
delete cc_; delete cc_;
...@@ -661,6 +667,11 @@ namespace spot ...@@ -661,6 +667,11 @@ namespace spot
~dve2_kripke() ~dve2_kripke()
{ {
if (iter_cache_)
{
delete iter_cache_;
iter_cache_ = nullptr;
}
delete[] format_filter_; delete[] format_filter_;
delete[] vname_; delete[] vname_;
if (compress_) if (compress_)
...@@ -857,6 +868,14 @@ namespace spot ...@@ -857,6 +868,14 @@ namespace spot
cc->transitions.push_back(local_state->clone()); cc->transitions.push_back(local_state->clone());
} }
if (iter_cache_)
{
dve2_succ_iterator* it =
down_cast<dve2_succ_iterator*>(iter_cache_);
it->recycle(cc, scond);
iter_cache_ = nullptr;
return it;
}
return new dve2_succ_iterator(cc, scond); return new dve2_succ_iterator(cc, scond);
} }
......
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Developpement de l'Epita // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2010, 2014 Laboratoire de Recherche et
// Developpement de l'Epita
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
...@@ -20,11 +22,6 @@ ...@@ -20,11 +22,6 @@
namespace spot namespace spot
{ {
kripke_succ_iterator::kripke_succ_iterator(const bdd& cond)
: cond_(cond)
{
}
kripke_succ_iterator::~kripke_succ_iterator() kripke_succ_iterator::~kripke_succ_iterator()
{ {
} }
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2010, 2013 Laboratoire de Recherche et // Copyright (C) 2009, 2010, 2013, 2014 Laboratoire de Recherche et
// Developpement de l'Epita // Developpement de l'Epita
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -48,7 +48,16 @@ namespace spot ...@@ -48,7 +48,16 @@ namespace spot
/// ///
/// The \a cond argument will be the one returned /// The \a cond argument will be the one returned
/// by kripke_succ_iterator::current_condition(). /// by kripke_succ_iterator::current_condition().
kripke_succ_iterator(const bdd& cond); kripke_succ_iterator(const bdd& cond)
: cond_(cond)
{
}
void recycle(const bdd& cond)
{
cond_ = cond;
}
virtual ~kripke_succ_iterator(); virtual ~kripke_succ_iterator();
virtual bdd current_condition() const; virtual bdd current_condition() const;
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
namespace spot namespace spot
{ {
class tgba;
/// \ingroup tgba_essentials /// \ingroup tgba_essentials
/// \brief Iterate over the successors of a state. /// \brief Iterate over the successors of a state.
/// ///
...@@ -100,8 +102,6 @@ namespace spot ...@@ -100,8 +102,6 @@ namespace spot
//@} //@}
}; };
class tgba;
namespace internal namespace internal
{ {
struct SPOT_API succ_iterator struct SPOT_API succ_iterator
...@@ -137,34 +137,6 @@ namespace spot ...@@ -137,34 +137,6 @@ namespace spot
it_ = nullptr; it_ = nullptr;
} }
}; };
class SPOT_API 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()
{
delete it_;
}
succ_iterator begin()
{
it_->first();
return it_->done() ? nullptr : it_;
}
succ_iterator end()
{
return nullptr;
}
};
} }
} }
......
// Copyright (C) 2009 Laboratoire de Recherche et Développement // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2014 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -24,15 +25,6 @@ ...@@ -24,15 +25,6 @@
namespace spot namespace spot
{ {
tgba_succ_iterator_concrete::tgba_succ_iterator_concrete
(const tgba_bdd_core_data& d, bdd successors)
: data_(d),
succ_set_(successors),
succ_set_left_(successors),
current_(bddfalse)
{
}
tgba_succ_iterator_concrete::~tgba_succ_iterator_concrete() tgba_succ_iterator_concrete::~tgba_succ_iterator_concrete()
{ {
} }
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013 Laboratoire de Recherche et Developpement de // Copyright (C) 2013, 2014 Laboratoire de Recherche et Developpement de
// l'Epita (LRDE). // l'Epita (LRDE).
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
...@@ -45,7 +45,19 @@ namespace spot ...@@ -45,7 +45,19 @@ namespace spot
/// \param d The core data of the automata. /// \param d The core data of the automata.
/// These contains sets of variables useful to split a BDD, and /// These contains sets of variables useful to split a BDD, and
/// compute acceptance conditions. /// compute acceptance conditions.
tgba_succ_iterator_concrete(const tgba_bdd_core_data& d, bdd successors); tgba_succ_iterator_concrete(const tgba_bdd_core_data& d, bdd successors)
: data_(d)
{
recycle(successors);
}
void recycle(bdd successors)
{
succ_set_ = successors;
succ_set_left_ = successors;
current_ = bddfalse;
}
virtual ~tgba_succ_iterator_concrete(); virtual ~tgba_succ_iterator_concrete();
// iteration // iteration
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2011, 2012, 2013 Laboratoire de Recherche et // Copyright (C) 2009, 2011, 2012, 2013, 2014 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
......
// Copyright (C) 2011 Laboratoire de Recherche et Developpement de // -*- coding: utf-8 -*-
// Copyright (C) 2011, 2014 Laboratoire de Recherche et Developpement de
// l'EPITA (LRDE). // l'EPITA (LRDE).
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -24,7 +25,8 @@ ...@@ -24,7 +25,8 @@
namespace spot namespace spot
{ {
tgba::tgba() tgba::tgba()
: last_support_conditions_input_(0), : iter_cache_(nullptr),
last_support_conditions_input_(0),
last_support_variables_input_(0), last_support_variables_input_(0),
num_acc_(-1) num_acc_(-1)
{ {
...@@ -36,6 +38,7 @@ namespace spot ...@@ -36,6 +38,7 @@ namespace spot
last_support_conditions_input_->destroy(); last_support_conditions_input_->destroy();
if (last_support_variables_input_) if (last_support_variables_input_)
last_support_variables_input_->destroy(); last_support_variables_input_->destroy();
delete iter_cache_;
} }
bdd bdd
......
...@@ -71,8 +71,48 @@ namespace spot ...@@ -71,8 +71,48 @@ namespace spot
{ {
protected: protected:
tgba(); tgba();
// Any iterator returned via release_iter.
mutable tgba_succ_iterator* iter_cache_;
public: 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(); virtual ~tgba();
/// \brief Get the initial state of the automaton. /// \brief Get the initial state of the automaton.
...@@ -111,15 +151,29 @@ namespace spot ...@@ -111,15 +151,29 @@ namespace spot
const state* global_state = nullptr, const state* global_state = nullptr,
const tgba* global_automaton = nullptr) const = 0; const tgba* global_automaton = nullptr) const = 0;
#ifndef SWIG
/// \brief Build an iterable over the successors of \a s. /// \brief Build an iterable over the successors of \a s.
/// ///
/// This is meant to be used as /// This is meant to be used as
/// <code>for (auto i: aut->out(s)) { /* i->current_state() */ }</code>. /// <code>for (auto i: aut->out(s)) { /* i->current_state() */ }</code>.
internal::succ_iterable succ_iterable
succ(const state* s) const succ(const state* s) const
{ {
return {this, succ_iter(s)}; 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. /// \brief Get a formula that must hold whatever successor is taken.
/// ///
......
// Copyright (C) 2011 Laboratoire de Recherche et Développement de // -*- coding: utf-8 -*-
// l'Epita (LRDE). // Copyright (C) 2011, 2014 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre // département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie. // et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -107,6 +108,15 @@ namespace spot ...@@ -107,6 +108,15 @@ namespace spot
bdd global_conds = global_automaton->support_conditions(global_state); bdd global_conds = global_automaton->support_conditions(global_state);
succ_set = bdd_appexcomp(succ_set, global_conds, bddop_and, varused); succ_set = bdd_appexcomp(succ_set, global_conds, bddop_and, varused);
} }
// Do not allocate an iterator if we can reuse one.
if (iter_cache_)
{
tgba_succ_iterator_concrete* res =
down_cast<tgba_succ_iterator_concrete*>(iter_cache_);
iter_cache_ = nullptr;
res->recycle(succ_set);
return res;
}
return new tgba_succ_iterator_concrete(data_, succ_set); return new tgba_succ_iterator_concrete(data_, succ_set);
} }
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2010, 2011, 2012, 2013 Laboratoire de Recherche // Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
// et Développement de l'Epita. // Recherche et Développement de l'Epita.
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie. // Université Pierre et Marie Curie.
...@@ -202,6 +202,12 @@ namespace spot ...@@ -202,6 +202,12 @@ namespace spot
{ {
} }
void recycle(const State* start, bdd all_acc)
{
start_ = start;
all_acceptance_conditions_ = all_acc;
}
virtual void first() virtual void first()
{ {
it_ = start_->successors.begin(); it_ = start_->successors.begin();
...@@ -508,6 +514,14 @@ namespace spot ...@@ -508,6 +514,14 @@ namespace spot
(void) global_state; (void) global_state;
(void) global_automaton; (void) global_automaton;
if (this->iter_cache_)
{
tgba_explicit_succ_iterator<State>* it =
down_cast<tgba_explicit_succ_iterator<State>*>(this->iter_cache_);
it->recycle(s, this->all_acceptance_conditions());
this->iter_cache_ = nullptr;
return it;
}
return return
new tgba_explicit_succ_iterator<State>(s, new tgba_explicit_succ_iterator<State>(s,
this this
......
...@@ -141,7 +141,16 @@ namespace spot ...@@ -141,7 +141,16 @@ namespace spot
const state*, const state*,
const tgba*) const const tgba*) const
{ {
succ_iter_filtered* res = new succ_iter_filtered; succ_iter_filtered* res;
if (iter_cache_)
{
res = down_cast<succ_iter_filtered*>(iter_cache_);
iter_cache_ = nullptr;
}
else
{
res = new succ_iter_filtered;
}
for (auto it: original_->succ(local_state)) for (auto it: original_->succ(local_state))
{ {
const state* s = it->current_state(); const state* s = it->current_state();
......
// Copyright (C) 2009, 2011, 2012 Laboratoire de Recherche et // -*- coding: utf-8 -*-
// Dveloppement de l'Epita (LRDE). // Copyright (C) 2009, 2011, 2012, 2014 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de
// Paris 6 (LIP6), dpartement Systmes Rpartis Coopratifs (SRC), // Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Universit Pierre et Marie Curie. // Université Pierre et Marie Curie.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
...@@ -88,6 +89,15 @@ namespace spot ...@@ -88,6 +89,15 @@ namespace spot
{ {
} }
void recycle(const tgba* l, tgba_succ_iterator* left,
const tgba* r, tgba_succ_iterator* right)
{
l->release_iter(left_);
left_ = left;
r->release_iter(right_);
right_ = right;
}
virtual ~tgba_succ_iterator_product_common() virtual ~tgba_succ_iterator_product_common()
{ {
delete left_; delete left_;
...@@ -390,6 +400,15 @@ namespace spot ...@@ -390,6 +400,15 @@ namespace spot
tgba_succ_iterator* ri = right_->succ_iter(s->right(), tgba_succ_iterator* ri = right_->succ_iter(s->right(),
global_state, global_automaton); global_state, global_automaton);
if (iter_cache_)
{
tgba_succ_iterator_product_common* it =
down_cast<tgba_succ_iterator_product_common*>(iter_cache_);
it->recycle(left_, li, right_, ri);
iter_cache_ = nullptr;
return it;
}
fixed_size_pool* p = const_cast<fixed_size_pool*>(&pool_); fixed_size_pool* p = const_cast<fixed_size_pool*>(&pool_);
if (left_kripke_) if (left_kripke_)
return new tgba_succ_iterator_product_kripke(li, ri, p); return new tgba_succ_iterator_product_kripke(li, ri, p);
......
// Copyright (C) 2013 Laboratoire de Recherche et // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -41,6 +42,11 @@ namespace spot ...@@ -41,6 +42,11 @@ namespace spot
const state* global_state, const state* global_state,
const tgba* global_automaton) const const tgba* global_automaton) const
{ {
if (iter_cache_)
{
original_->release_iter(iter_cache_);
iter_cache_ = nullptr;
}
return original_->succ_iter(local_state, global_state, global_automaton); return original_->succ_iter(local_state, global_state, global_automaton);
} }
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2009, 2012, 2013 Laboratoire de recherche et // Copyright (C) 2009, 2012, 2013, 2014 Laboratoire de recherche et
// développement de l'Epita. // développement de l'Epita.
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
...@@ -50,6 +50,11 @@ namespace spot ...@@ -50,6 +50,11 @@ namespace spot
const state* global_state, const state* global_state,
const tgba* global_automaton) const const tgba* global_automaton) const
{