From d6fee8b4014bd0f4805a04d8a2d870901fdb7065 Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 20 Jul 2020 10:17:12 +0300 Subject: [PATCH] #19765 EDF 21730 - long time to load med file file with huge amount of groups --- idl/SALOMEDS.idl | 4 + src/SALOMEDS/SALOMEDS_UseCaseBuilder.cxx | 13 ++ src/SALOMEDS/SALOMEDS_UseCaseBuilder.hxx | 1 + src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.cxx | 15 ++ src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.hxx | 2 + .../SALOMEDSClient_UseCaseBuilder.hxx | 1 + .../SALOMEDSImpl_AttributeTreeNode.cxx | 11 +- .../SALOMEDSImpl_AttributeTreeNode.hxx | 2 +- .../SALOMEDSImpl_ChildNodeIterator.cxx | 8 +- src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx | 2 +- .../SALOMEDSImpl_UseCaseBuilder.cxx | 142 ++++++++++++++---- .../SALOMEDSImpl_UseCaseBuilder.hxx | 6 + 12 files changed, 171 insertions(+), 36 deletions(-) diff --git a/idl/SALOMEDS.idl b/idl/SALOMEDS.idl index db5cc8cd6..b6c4dcf2b 100644 --- a/idl/SALOMEDS.idl +++ b/idl/SALOMEDS.idl @@ -1166,6 +1166,10 @@ Activates the %UseCaseIterator. Adds a child object theObject to the given father theFather object in the use case. */ boolean AppendTo(in SObject theFather, in SObject theObject); +/*! + Return index of a child among father children +*/ + long GetIndexInFather(in SObject theFather, in SObject theObject); /*! Inserts in the use case the object theFirst before the object theNext. */ diff --git a/src/SALOMEDS/SALOMEDS_UseCaseBuilder.cxx b/src/SALOMEDS/SALOMEDS_UseCaseBuilder.cxx index 31e7f3c1f..12863e92a 100644 --- a/src/SALOMEDS/SALOMEDS_UseCaseBuilder.cxx +++ b/src/SALOMEDS/SALOMEDS_UseCaseBuilder.cxx @@ -104,6 +104,19 @@ bool SALOMEDS_UseCaseBuilder::InsertBefore(const _PTR(SObject)& theFirst, _PTR(S return ret; } +int SALOMEDS_UseCaseBuilder::GetIndexInFather(const _PTR(SObject)& theFather, const _PTR(SObject)& theChild) +{ + int ret; + SALOMEDS_SObject* father = dynamic_cast(theFather.get()); + SALOMEDS_SObject* child = dynamic_cast(theChild.get()); + if (_isLocal) { + SALOMEDS::Locker lock; + ret = _local_impl->GetIndexInFather(*(father->GetLocalImpl()), *(child->GetLocalImpl())); + } + else ret = _corba_impl->GetIndexInFather(father->GetCORBAImpl(), child->GetCORBAImpl()); + return ret; +} + bool SALOMEDS_UseCaseBuilder::SetCurrentObject(const _PTR(SObject)& theObject) { bool ret; diff --git a/src/SALOMEDS/SALOMEDS_UseCaseBuilder.hxx b/src/SALOMEDS/SALOMEDS_UseCaseBuilder.hxx index ebc49dd66..b75aca17e 100644 --- a/src/SALOMEDS/SALOMEDS_UseCaseBuilder.hxx +++ b/src/SALOMEDS/SALOMEDS_UseCaseBuilder.hxx @@ -52,6 +52,7 @@ public: virtual bool Remove(const _PTR(SObject)& theObject); virtual bool AppendTo(const _PTR(SObject)& theFather, _PTR(SObject) theObject); virtual bool InsertBefore(const _PTR(SObject)& theFirst, _PTR(SObject) theNext); + virtual int GetIndexInFather(const _PTR(SObject)& theFather, const _PTR(SObject)& theObject); virtual bool SetCurrentObject(const _PTR(SObject)& theObject); virtual bool SetRootCurrent(); virtual bool HasChildren(const _PTR(SObject)& theObject); diff --git a/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.cxx b/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.cxx index 81b15f494..f353fe9dd 100644 --- a/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.cxx +++ b/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.cxx @@ -114,6 +114,21 @@ CORBA::Boolean SALOMEDS_UseCaseBuilder_i::AppendTo(SALOMEDS::SObject_ptr theFath return _impl->AppendTo(_impl->GetSObject(idF.in()), _impl->GetSObject( idO.in())); } +//============================================================================ +/*! Function : GetIndexInFather + * Purpose : + */ +//============================================================================ +CORBA::Long SALOMEDS_UseCaseBuilder_i::GetIndexInFather(SALOMEDS::SObject_ptr theFather, + SALOMEDS::SObject_ptr theObject) +{ + SALOMEDS::Locker lock; + if(!_impl || theFather->_is_nil() || theObject->_is_nil()) return -1; + CORBA::String_var idF = theFather->GetID(); + CORBA::String_var idO = theObject->GetID(); + return _impl->GetIndexInFather(_impl->GetSObject(idF.in()), _impl->GetSObject( idO.in())); +} + //============================================================================ /*! Function : InsertBefore * Purpose : diff --git a/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.hxx b/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.hxx index 6412db059..901b7e2be 100644 --- a/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.hxx +++ b/src/SALOMEDS/SALOMEDS_UseCaseBuilder_i.hxx @@ -67,6 +67,8 @@ public: virtual CORBA::Boolean AppendTo(SALOMEDS::SObject_ptr theFather, SALOMEDS::SObject_ptr theObject); + virtual CORBA::Long GetIndexInFather(SALOMEDS::SObject_ptr theFather, SALOMEDS::SObject_ptr theObject); + virtual CORBA::Boolean InsertBefore(SALOMEDS::SObject_ptr theFirst, SALOMEDS::SObject_ptr theNext); virtual CORBA::Boolean SetCurrentObject(SALOMEDS::SObject_ptr theObject); diff --git a/src/SALOMEDSClient/SALOMEDSClient_UseCaseBuilder.hxx b/src/SALOMEDSClient/SALOMEDSClient_UseCaseBuilder.hxx index ac6b1f6df..dce9c7de3 100644 --- a/src/SALOMEDSClient/SALOMEDSClient_UseCaseBuilder.hxx +++ b/src/SALOMEDSClient/SALOMEDSClient_UseCaseBuilder.hxx @@ -41,6 +41,7 @@ public: virtual bool Remove(const _PTR(SObject)& theObject) = 0; virtual bool AppendTo(const _PTR(SObject)& theFather, _PTR(SObject) theObject) = 0; virtual bool InsertBefore(const _PTR(SObject)& theFirst, _PTR(SObject) theNext) = 0; + virtual int GetIndexInFather(const _PTR(SObject)& theFather, const _PTR(SObject)& theObject) = 0; virtual bool SetCurrentObject(const _PTR(SObject)& theObject) = 0; virtual bool SetRootCurrent() = 0; virtual bool HasChildren(const _PTR(SObject)& theObject) = 0; diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.cxx index 79f00488c..1c1120812 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.cxx @@ -64,8 +64,9 @@ const std::string& SALOMEDSImpl_AttributeTreeNode::ID() const //======================================================================= //function : Append //purpose : Add as last child of me +//return : index of TN under this, in C mode //======================================================================= -bool SALOMEDSImpl_AttributeTreeNode::Append (SALOMEDSImpl_AttributeTreeNode* TN) +bool SALOMEDSImpl_AttributeTreeNode::Append (SALOMEDSImpl_AttributeTreeNode* TN, int* childIndex) { CheckLocked(); @@ -76,6 +77,7 @@ bool SALOMEDSImpl_AttributeTreeNode::Append (SALOMEDSImpl_AttributeTreeNode* TN) TN->SetNext(NULL); // Deconnects from next. // Find the last + int index = 0; if (!HasFirst()) { SetFirst(TN); TN->SetPrevious(NULL); // Deconnects from previous. @@ -84,15 +86,20 @@ bool SALOMEDSImpl_AttributeTreeNode::Append (SALOMEDSImpl_AttributeTreeNode* TN) SALOMEDSImpl_AttributeTreeNode* Last = GetFirst(); while (Last && Last->HasNext()) { Last = Last->GetNext(); + ++index; } Last->SetNext(TN); TN->SetPrevious(Last); + ++index; } // Set Father TN->SetFather(this); SetModifyFlag(); //SRN: Mark the study as being modified, so it could be saved - + + if ( childIndex ) + *childIndex = index; + return (TN); } diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.hxx b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.hxx index 8d0bba2e0..1344f3ea4 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.hxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_AttributeTreeNode.hxx @@ -48,7 +48,7 @@ public: void SetFirst(const SALOMEDSImpl_AttributeTreeNode* value); void SetTreeID(const std::string& value); - bool Append(SALOMEDSImpl_AttributeTreeNode* value); + bool Append(SALOMEDSImpl_AttributeTreeNode* value, int* childIndex = 0 ); bool Prepend(SALOMEDSImpl_AttributeTreeNode* value); bool Remove(); bool InsertBefore(SALOMEDSImpl_AttributeTreeNode* value); diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_ChildNodeIterator.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_ChildNodeIterator.cxx index a6bf4dc7a..5f11d442f 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_ChildNodeIterator.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_ChildNodeIterator.cxx @@ -31,10 +31,10 @@ { \ while (myNode && (myNode->Depth() > myFirstLevel) && myNode->myNext == NULL) \ myNode = myNode->myFather; \ - if (myNode && (myNode->Depth() > myFirstLevel) && myNode->myFather != NULL) \ - myNode = myNode->myNext; \ - else \ - myNode = NULL; \ + if (myNode && (myNode->Depth() > myFirstLevel) && myNode->myFather != NULL) \ + myNode = myNode->myNext; \ + else \ + myNode = NULL; \ } //======================================================================= diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx index 9b0f1390d..7e2283971 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx @@ -803,7 +803,7 @@ bool SALOMEDSImpl_Study::Impl_SaveAs(const std::string& aStudyUrl, if (buffer[aLen-1] == '\n') buffer[aLen-1] = char(0); #ifdef WIN32 - // Force removing readonly attribute from a file under Windows, because of a but in the HDF + // Force removing readonly attribute from a file under Windows, because of a but in the HDF std::string aReadOlnyRmCmd = "attrib -r \"" + aStudyTmpDir + std::string(buffer)+ "\" > nul 2>&1"; #ifdef UNICODE std::wstring awReadOlnyRmCmd = Kernel_Utils::utf8_decode_s(aReadOlnyRmCmd); diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.cxx b/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.cxx index 69aefb501..2ae8c8c09 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.cxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.cxx @@ -43,12 +43,12 @@ namespace { bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const { std::string firstName, secondName; SALOMEDSImpl_SObject refSO; - firstSO.ReferencedObject(refSO) ? - firstName = refSO.GetName() : - firstName = firstSO.GetName(); - secondSO.ReferencedObject(refSO) ? - secondName = refSO.GetName() : - secondName = secondSO.GetName(); + firstSO.ReferencedObject(refSO) ? + firstName = refSO.GetName() : + firstName = firstSO.GetName(); + secondSO.ReferencedObject(refSO) ? + secondName = refSO.GetName() : + secondName = secondSO.GetName(); return firstName < secondName; } }; @@ -58,12 +58,12 @@ namespace { bool operator()( SALOMEDSImpl_SObject firstSO, SALOMEDSImpl_SObject secondSO ) const { std::string firstName, secondName; SALOMEDSImpl_SObject refSO; - firstSO.ReferencedObject(refSO) ? - firstName = refSO.GetName() : - firstName = firstSO.GetName(); - secondSO.ReferencedObject(refSO) ? - secondName = refSO.GetName() : - secondName = secondSO.GetName(); + firstSO.ReferencedObject(refSO) ? + firstName = refSO.GetName() : + firstName = firstSO.GetName(); + secondSO.ReferencedObject(refSO) ? + secondName = refSO.GetName() : + secondName = secondSO.GetName(); return firstName > secondName; } }; @@ -75,7 +75,7 @@ namespace { */ //============================================================================ SALOMEDSImpl_UseCaseBuilder::SALOMEDSImpl_UseCaseBuilder(DF_Document* theDocument) -:_doc(theDocument) + :_doc(theDocument), _lastChild(0), _childIndex(-1) { if(!_doc) return; @@ -127,10 +127,11 @@ bool SALOMEDSImpl_UseCaseBuilder::Append(const SALOMEDSImpl_SObject& theObject) } DF_Label aCurrent = aRef->Get(); - if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID()))) + if(aCurrent.IsNull() || !(aCurrentNode=(SALOMEDSImpl_AttributeTreeNode*)aCurrent.FindAttribute(_root->ID()))) aCurrentNode = _root; - aCurrentNode->Append(aNode); + aCurrentNode->Append(aNode, &_childIndex); + _lastChild = aNode; // Mantis issue 0020136: Drag&Drop in OB SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject); @@ -138,7 +139,7 @@ bool SALOMEDSImpl_UseCaseBuilder::Append(const SALOMEDSImpl_SObject& theObject) return true; } - //============================================================================ +//============================================================================ /*! Function : Remove * Purpose : */ @@ -147,12 +148,15 @@ bool SALOMEDSImpl_UseCaseBuilder::Remove(const SALOMEDSImpl_SObject& theObject) { if(!_root || !theObject) return false; - DF_Label aLabel = theObject.GetLabel(); + DF_Label aLabel = theObject.GetLabel(); if(aLabel.IsNull()) return false; SALOMEDSImpl_AttributeTreeNode* aNode = NULL; if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false; + if ( _lastChild && aNode->GetFather() == _lastChild->GetFather() ) + _lastChild = 0; + aNode->Remove(); std::vector aList; @@ -160,13 +164,13 @@ bool SALOMEDSImpl_UseCaseBuilder::Remove(const SALOMEDSImpl_SObject& theObject) SALOMEDSImpl_AttributeReference* aRef = NULL; if(!(aRef=(SALOMEDSImpl_AttributeReference*)_root->FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) { - aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label()); - } + aRef = SALOMEDSImpl_AttributeReference::Set(_root->Label(), _root->Label()); + } DF_Label aCurrent = aRef->Get(); SALOMEDSImpl_ChildNodeIterator aChildItr(aNode, true); - for(; aChildItr.More(); aChildItr.Next()) + for(; aChildItr.More(); aChildItr.Next()) aList.push_back(aChildItr.Value()); for(int i = 0, len = aList.size(); iID()); } + if ( aNode == _lastChild && !_lastChild->HasNext() && _lastChild->GetFather() == aFather ) + return true; // aNode is already the last child + aNode->Remove(); - bool ret = aFather->Append(aNode); + bool ret = true; + if ( _lastChild && _lastChild->GetFather() == aFather && + !_lastChild->HasNext() ) // _lastChild is the last under aFather + { + _lastChild->InsertAfter( aNode ); + _lastChild = aNode; + ++_childIndex; + } + else + { + ret = aFather->Append(aNode, &_childIndex); + _lastChild = aNode; + } // Mantis issue 0020136: Drag&Drop in OB SALOMEDSImpl_Study::GetStudyImpl(theObject.GetLabel())->addSO_Notification(theObject); @@ -213,12 +232,70 @@ bool SALOMEDSImpl_UseCaseBuilder::AppendTo(const SALOMEDSImpl_SObject& theFather return ret; } +//============================================================================ +/*! Function : GetIndexInFather + * Purpose : + */ +//============================================================================ +int SALOMEDSImpl_UseCaseBuilder::GetIndexInFather(const SALOMEDSImpl_SObject& theFather, + const SALOMEDSImpl_SObject& theObject) +{ + int index = -1; + if(!_root || !theFather || !theObject) return index; + + DF_Label aFatherLabel = theFather.GetLabel(), aLabel = theObject.GetLabel(); + if(aFatherLabel == aLabel) return index; + + SALOMEDSImpl_AttributeTreeNode *aFather = NULL, *aNode = NULL; + + if(aFatherLabel.IsNull()) return index; + if(!(aFather=(SALOMEDSImpl_AttributeTreeNode*)aFatherLabel.FindAttribute(_root->ID()))) return index; + + if(aLabel.IsNull()) return index; + if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) { + aNode = SALOMEDSImpl_AttributeTreeNode::Set(aLabel, _root->ID()); + } + + if ( _lastChild && _lastChild->GetFather() == aFather ) + { + if ( aNode == _lastChild ) + index = _childIndex; + else if ( aNode == _lastChild->GetPrevious()) + index = _childIndex - 1; + else if ( aNode == _lastChild->GetNext()) + { + index = ++_childIndex; + _lastChild = aNode; + } + } + + if ( index < 0 ) + { + SALOMEDSImpl_AttributeTreeNode* Last = aFather->GetFirst(); + for ( index = 0; Last && Last->HasNext(); ++index ) + { + Last = Last->GetNext(); + if ( aNode == Last ) + break; + } + if ( Last != aNode ) + index = -1; + else if ( !Last->HasNext() ) + { + _lastChild = Last; + _childIndex = index; + } + } + + return index; +} + //============================================================================ /*! Function : InsertBefore * Purpose : */ //============================================================================ -bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst, +bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFirst, const SALOMEDSImpl_SObject& theNext) { if(!_root || !theFirst || !theNext) return false; @@ -227,7 +304,7 @@ bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFi if(aFirstLabel == aLabel) return false; SALOMEDSImpl_AttributeTreeNode *aFirstNode = NULL, *aNode = NULL; - + if(aFirstLabel.IsNull()) return false; if((aFirstNode=(SALOMEDSImpl_AttributeTreeNode*)aFirstLabel.FindAttribute(_root->ID()))) { aFirstNode->Remove(); @@ -235,14 +312,22 @@ bool SALOMEDSImpl_UseCaseBuilder::InsertBefore(const SALOMEDSImpl_SObject& theFi } aFirstNode = SALOMEDSImpl_AttributeTreeNode::Set(aFirstLabel, _root->ID()); - + if(aLabel.IsNull()) return false; - if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false; + if(!(aNode=(SALOMEDSImpl_AttributeTreeNode*)aLabel.FindAttribute(_root->ID()))) return false; aFirstNode->Remove(); bool ret = aNode->InsertBefore(aFirstNode); + if ( _lastChild && _lastChild->GetFather() == aNode->GetFather() ) + { + if ( aNode == _lastChild ) + ++_childIndex; + else + _lastChild = 0; + } + // Mantis issue 0020136: Drag&Drop in OB SALOMEDSImpl_Study::GetStudyImpl(theFirst.GetLabel())->addSO_Notification(theFirst); @@ -335,14 +420,15 @@ bool SALOMEDSImpl_UseCaseBuilder::SortChildren(const SALOMEDSImpl_SObject& theOb for ( SALOMEDSImpl_AttributeTreeNode* aChildNode=aNode->GetFirst(); aChildNode; aChildNode=aChildNode->GetNext() ) { if ( SALOMEDSImpl_SObject aSO = SALOMEDSImpl_Study::SObject( aChildNode->Label() ) ) { if ( aChildNode->FindAttribute( SALOMEDSImpl_AttributeReference::GetID() ) ) - aRefSOs.push_back( aSO ); + aRefSOs.push_back( aSO ); else - aNodeSOs.push_back( aSO ); + aNodeSOs.push_back( aSO ); } } if ( aRefSOs.empty() && aNodeSOs.empty() ) return false; - //sort items by names in ascending/descending order + //sort items by names in ascending/descending order + _lastChild = 0; std::list::iterator it; if ( !aRefSOs.empty() ) { theAscendingOrder ? aRefSOs.sort( AscSortSOs() ) : aRefSOs.sort( DescSortSOs() ); diff --git a/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.hxx b/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.hxx index ffc201ee0..22b9b372a 100644 --- a/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.hxx +++ b/src/SALOMEDSImpl/SALOMEDSImpl_UseCaseBuilder.hxx @@ -43,6 +43,10 @@ private: SALOMEDSImpl_AttributeTreeNode* _root; DF_Document* _doc; + //[bos #19765] optimize inserting huge nb objects in the study + SALOMEDSImpl_AttributeTreeNode* _lastChild; + int _childIndex; // in C mode + public: //! standard constructor @@ -59,6 +63,8 @@ public: virtual bool InsertBefore(const SALOMEDSImpl_SObject& theFirst, const SALOMEDSImpl_SObject& theNext); + int GetIndexInFather(const SALOMEDSImpl_SObject& theFather, const SALOMEDSImpl_SObject& theObject); + virtual bool SetCurrentObject(const SALOMEDSImpl_SObject& theObject); virtual bool SetRootCurrent(); -- 2.39.2