Deterministic destruction of Components.
* Change: In Hurrican::Component::_preDestroy(), the cascaded destruction of slaves Components and subsequent ring merge and Rubber creation was using set<> sorted on pointer values. This was making the order of destruction of the slaves components non-deterministic. Now the sets are sorted according to their id (see Entity). * Change: In Hurricane::SharedProperty, the _ownerSet is now a vector<> instead of a set<>. This will slow the search process, but hopefully this is needed only during construction/destruction of a Property so the slow down shouldn't be too much. This has also an impact on Hurricane::Relation.
This commit is contained in:
parent
73a085308c
commit
db8e51524f
|
@ -88,9 +88,9 @@ namespace Anabatic {
|
|||
Edge* edge = new Edge ( source, target, flags );
|
||||
edge->_postCreate();
|
||||
|
||||
cdebug_log(110,1) << "Edge::create(): " << (void*)edge << ":" << edge << endl;
|
||||
cdebug_log(110,0) << "source:" << (void*)source << ":" << edge->getSource() << endl;
|
||||
cdebug_log(110,0) << "target:" << (void*)target << ":" << edge->getTarget() << endl;
|
||||
cdebug_log(110,1) << "Edge::create(): " << /*(void*)edge << ":" <<*/ edge << endl;
|
||||
cdebug_log(110,0) << "source:" << /*(void*)source << ":" <<*/ edge->getSource() << endl;
|
||||
cdebug_log(110,0) << "target:" << /*(void*)target << ":" <<*/ edge->getTarget() << endl;
|
||||
cdebug_tabw(110,-1);
|
||||
return edge;
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ stylesTable = \
|
|||
, (Drawing, 'gmetalv' , { 'color':'200,200,255', 'pattern':'light_antihash1.8', 'border':1 })
|
||||
, (Drawing, 'gcut' , { 'color':'255,255,190', 'border':1 })
|
||||
, (Drawing, 'Anabatic::Edge' , { 'color':'255,255,190', 'pattern':'0000000000000000', 'border':4, 'threshold':0.02*scale })
|
||||
, (Drawing, 'Anabatic::GCell', { 'color':'128,128,128', 'pattern':'0000000000000000', 'border':4, 'threshold':0.10*scale })
|
||||
, (Drawing, 'Anabatic::GCell', { 'color':'255,255,190', 'pattern':'0000000000000000', 'border':4, 'threshold':0.10*scale })
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace CRL {
|
|||
_stressDisplayAction->setStatusTip ( tr("Intensive use of display redrawing") );
|
||||
connect ( _stressDisplayAction, SIGNAL(triggered()), this, SLOT(stressDisplay()) );
|
||||
|
||||
debugMenu->addAction ( _stressDisplayAction );
|
||||
//debugMenu->addAction ( _stressDisplayAction );
|
||||
|
||||
getCellWidget()->addDrawExtensionGo ( DemoGo::staticGetName()
|
||||
, DemoGo::initDrawDemoGo
|
||||
|
|
|
@ -408,58 +408,50 @@ void Component::_postCreate()
|
|||
void Component::_preDestroy()
|
||||
// *************************
|
||||
{
|
||||
cdebug_log(18,1) << "entering Component::_Predestroy: " << this << endl;
|
||||
cdebug_log(18,1) << "entering Component::_preDestroy: " << this << endl;
|
||||
|
||||
clearProperties();
|
||||
|
||||
set<Component*> componentSet;
|
||||
getSlaveComponents().fill(componentSet);
|
||||
set<Component*,Entity::CompareById> components;
|
||||
getSlaveComponents().fill( components );
|
||||
components.insert( this );
|
||||
|
||||
set<Hook*> masterHookSet;
|
||||
componentSet.insert(this);
|
||||
for_each_component(component, getCollection(componentSet)) {
|
||||
component->unmaterialize();
|
||||
for_each_hook(hook, component->getHooks()) {
|
||||
for_each_hook(hook, hook->getHooks()) {
|
||||
if (hook->isMaster() && (componentSet.find(hook->getComponent()) == componentSet.end()))
|
||||
masterHookSet.insert(hook);
|
||||
end_for;
|
||||
}
|
||||
if (!hook->isMaster()) hook->detach();
|
||||
end_for;
|
||||
vector<Hook*> masterHooks;
|
||||
|
||||
for ( Component* component : components ) {
|
||||
component->unmaterialize();
|
||||
for ( Hook* chook : component->getHooks() ) {
|
||||
for ( Hook* shook : chook->getHooks() ) {
|
||||
if (shook->isMaster() and (components.find(shook->getComponent()) == components.end()) )
|
||||
masterHooks.push_back( shook );
|
||||
}
|
||||
end_for;
|
||||
if (not chook->isMaster()) chook->detach();
|
||||
}
|
||||
}
|
||||
|
||||
componentSet.erase(this);
|
||||
for_each_component(component, getCollection(componentSet)) {
|
||||
component->destroy();
|
||||
end_for;
|
||||
}
|
||||
components.erase( this );
|
||||
for ( Component* component : components ) component->destroy();
|
||||
|
||||
set<Rubber*> rubberSet;
|
||||
set<Hook*> mainMasterHookSet;
|
||||
for_each_hook(hook, getCollection(masterHookSet)) {
|
||||
Rubber* rubber = hook->getComponent()->getRubber();
|
||||
if (!rubber)
|
||||
mainMasterHookSet.insert(hook);
|
||||
else {
|
||||
if (rubberSet.find(rubber) == rubberSet.end()) {
|
||||
rubberSet.insert(rubber);
|
||||
mainMasterHookSet.insert(hook);
|
||||
}
|
||||
set<Rubber*,Entity::CompareById> rubbers;
|
||||
vector<Hook*> mainMasterHooks;
|
||||
|
||||
for ( Hook* mhook : masterHooks ) {
|
||||
Rubber* rubber = mhook->getComponent()->getRubber();
|
||||
if (not rubber)
|
||||
mainMasterHooks.push_back( mhook );
|
||||
else {
|
||||
if (rubbers.find(rubber) == rubbers.end()) {
|
||||
rubbers.insert( rubber );
|
||||
mainMasterHooks.push_back( mhook );
|
||||
}
|
||||
end_for;
|
||||
}
|
||||
}
|
||||
|
||||
Hook* masterHook = NULL;
|
||||
for_each_hook(hook, getCollection(mainMasterHookSet)) {
|
||||
if (!masterHook)
|
||||
masterHook = hook;
|
||||
else
|
||||
hook->merge(masterHook);
|
||||
end_for;
|
||||
for ( Hook* hook : mainMasterHooks ) {
|
||||
if (not masterHook) masterHook = hook;
|
||||
else hook->merge( masterHook );
|
||||
}
|
||||
/**/
|
||||
|
||||
_bodyHook.detach();
|
||||
|
||||
|
@ -467,7 +459,6 @@ void Component::_preDestroy()
|
|||
|
||||
if (_net) _net->_getComponentSet()._remove(this);
|
||||
|
||||
|
||||
cdebug_log(18,0) << "exiting Component::_Predestroy:" << endl;
|
||||
cdebug_tabw(18,-1);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,9 @@ namespace Hurricane {
|
|||
|
||||
|
||||
void DBo::_postCreate ()
|
||||
{ }
|
||||
{
|
||||
cdebug_log(0,0) << "DBo::_postCreate() " << this << endl;
|
||||
}
|
||||
|
||||
|
||||
void DBo::_preDestroy ()
|
||||
|
@ -64,7 +66,9 @@ namespace Hurricane {
|
|||
|
||||
void DBo::destroy ()
|
||||
{
|
||||
cdebug_log(0,1) << "DBo::destroy() " << this << endl;
|
||||
_preDestroy();
|
||||
cdebug_tabw(0,-1);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,8 @@ Hook* Hook::merge(Hook* hook)
|
|||
if (hook == this)
|
||||
throw Error("Can't merge : itself");
|
||||
|
||||
cdebug_log(0,0) << "Hook::merge() hook:" << hook->getComponent() << endl;
|
||||
|
||||
Hook* masterHook = hook->getPreviousMasterHook();
|
||||
Hook* nextHook = masterHook->_nextHook;
|
||||
masterHook->_nextHook = _nextHook;
|
||||
|
|
|
@ -226,25 +226,53 @@ namespace Hurricane {
|
|||
|
||||
void SharedProperty::_preDestroy ()
|
||||
{
|
||||
Property::_preDestroy();
|
||||
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) {
|
||||
_ownerSet[i]->_onDestroyed(this);
|
||||
_ownerSet[i] = NULL;
|
||||
}
|
||||
_ownerSet.clear();
|
||||
|
||||
while (!_ownerSet.empty()) {
|
||||
DBo* owner = *_ownerSet.begin();
|
||||
_ownerSet.erase(owner);
|
||||
owner->_onDestroyed(this);
|
||||
// while (!_ownerSet.empty()) {
|
||||
// DBo* owner = *_ownerSet.begin();
|
||||
// _ownerSet.erase(owner);
|
||||
// owner->_onDestroyed(this);
|
||||
// }
|
||||
|
||||
Property::_preDestroy();
|
||||
}
|
||||
|
||||
|
||||
void SharedProperty::_erase ( DBo* owner )
|
||||
{
|
||||
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) {
|
||||
if (_ownerSet[i] == owner) {
|
||||
std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] );
|
||||
_ownerSet.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SharedProperty::onCapturedBy ( DBo* owner )
|
||||
{
|
||||
_ownerSet.insert(owner);
|
||||
for ( DBo* dbo : _ownerSet ) {
|
||||
if (dbo == owner) return;
|
||||
}
|
||||
_ownerSet.push_back( owner );
|
||||
|
||||
//_ownerSet.insert(owner);
|
||||
}
|
||||
|
||||
|
||||
void SharedProperty::onReleasedBy ( DBo* owner )
|
||||
{
|
||||
_ownerSet.erase(owner);
|
||||
for ( size_t i=0 ; i<_ownerSet.size() ; ++i ) {
|
||||
if (_ownerSet[i] == owner) {
|
||||
std::swap( _ownerSet[i], _ownerSet[_ownerSet.size()-1] );
|
||||
_ownerSet.pop_back();
|
||||
}
|
||||
}
|
||||
//_ownerSet.erase(owner);
|
||||
|
||||
if (_ownerSet.empty()) onNotOwned();
|
||||
}
|
||||
|
|
|
@ -99,7 +99,8 @@ DBos Relation::getSlaveOwners() const
|
|||
void Relation::onReleasedBy(DBo* owner)
|
||||
// ************************************
|
||||
{
|
||||
_getOwnerSet().erase(owner);
|
||||
_erase( owner );
|
||||
//_getOwnerSet().erase(owner);
|
||||
|
||||
if (owner == _masterOwner) destroy();
|
||||
}
|
||||
|
|
|
@ -433,14 +433,23 @@ template<class Element> class IntrusiveSet {
|
|||
_length = newLength;
|
||||
_array = new Element*[_length];
|
||||
memset(_array, 0, _length * sizeof(Element*));
|
||||
cdebug_log(0,0) << "IntrusiveSet::_resize() " << oldLength << " -> " << newLength << endl;
|
||||
|
||||
for (unsigned index = 0; index < oldLength; index++) {
|
||||
Element* element = oldArray[index];
|
||||
if (not element)
|
||||
cdebug_log(0,0) << "| bucket:" << setw(4) << index << " empty" << endl;
|
||||
|
||||
while (element) {
|
||||
Element* nextElement = _getNextElement(element);
|
||||
unsigned newIndex = (_getHashValue(element) / 8) % _length;
|
||||
_setNextElement(element, _array[newIndex]);
|
||||
_array[newIndex] = element;
|
||||
element = nextElement;
|
||||
|
||||
cdebug_log(0,0) << "| bucket:" << setw(4) << index
|
||||
<< " -> " << setw(4) << newIndex
|
||||
<< " + " << element << endl;
|
||||
}
|
||||
}
|
||||
delete[] oldArray;
|
||||
|
|
|
@ -396,7 +396,7 @@ namespace Hurricane {
|
|||
unsigned int _count;
|
||||
};
|
||||
public:
|
||||
typedef set<DBo*> DBoSet;
|
||||
typedef vector<DBo*> DBoSet;
|
||||
typedef map<string,Orphaned> OrphanedMap;
|
||||
public:
|
||||
static const OrphanedMap& getOrphaneds ();
|
||||
|
@ -411,6 +411,7 @@ namespace Hurricane {
|
|||
virtual void onCapturedBy ( DBo* owner );
|
||||
virtual void onReleasedBy ( DBo* owner );
|
||||
virtual void onNotOwned ();
|
||||
void _erase ( DBo* owner );
|
||||
inline DBoSet& _getOwnerSet ();
|
||||
virtual string _getString () const;
|
||||
virtual Record* _getRecord () const;
|
||||
|
|
Loading…
Reference in New Issue