/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef _DAI_PERF_SCENARIO_H_ #define _DAI_PERF_SCENARIO_H_ #include "TestUtilityAsserts.h" #include "OdPerfTimer.h" #include "daiModel.h" #include "daiEntity.h" #include "daiAggr/daiAggr.h" #include "daiRepository.h" #include "MemoryStream.h" #include "daiValidation/daiValidator.h" #include "daiObjectSDAI.h" #include "OdDbStub.h" #define SCHEMA_ENTITIES_MULTIPLIER 500 namespace PerfScenarios { namespace { void putAttr(OdDAI::ApplicationInstance* pAppInstance, OdDAI::Entity* pEntity, OdRxValue attrValue) { OdArray attrsArray = pEntity->attributes().getArray(); for (auto attr : attrsArray) { if (OdDAI::ExplicitAttribute::cast(attr).isNull()) continue; pAppInstance->putAttr(attr->name(), attrValue); } OdArray superTypesArray = pEntity->supertypes().getArray(); for (auto st : superTypesArray) { putAttr(pAppInstance, st, attrValue); } } void getAttr(OdDAI::ApplicationInstance* pAppInstance, OdDAI::Entity* pEntity, OdRxValue attrValue) { OdArray attrsArray = pEntity->attributes().getArray(); for (auto attr : attrsArray) { if (OdDAI::ExplicitAttribute::cast(attr).isNull()) continue; attrValue = pAppInstance->getAttr(attr->name()); } OdArray superTypesArray = pEntity->supertypes().getArray(); for (auto st : superTypesArray) { getAttr(pAppInstance, st, attrValue); } } } /** \details The base class for performance unit tests. */ class PerfScenarioBase { public: PerfScenarioBase() { } virtual ~PerfScenarioBase() { } virtual bool run() = 0; }; /** \details A performance test for checking the creation of explicit atrtibutes for all schema entities. */ class PerfInstancesCreation : public PerfScenarioBase { public: PerfInstancesCreation(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { auto entities = m_pModel->underlyingSchema()->entities(); m_pPerfTimer->start(); for (auto it = entities->newIterator(); it->next();) { for (int i = 0; i < SCHEMA_ENTITIES_MULTIPLIER * 10; ++i) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) break; m_pModel->appendEntityInstance(m_pModel->createEntityInstance(pEntity->name())); } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the creation and filling of explicit atrtibutes for all schema entities. */ class PerfInstancesCreationAndFilling : public PerfScenarioBase { public: PerfInstancesCreationAndFilling(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdRxValue attrValue; auto entities = m_pModel->underlyingSchema()->entities(); m_pPerfTimer->start(); for (auto it = entities->newIterator(); it->next();) { for (int i = 0; i < SCHEMA_ENTITIES_MULTIPLIER; ++i) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) break; OdDAI::ApplicationInstancePtr pAppInstance = m_pModel->createEntityInstance(pEntity->name()); if (pAppInstance.isNull()) break; putAttr(pAppInstance, pEntity, attrValue); m_pModel->appendEntityInstance(pAppInstance); } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the getting data from explicit attributes for all schema entities. */ class PerfInstanceAttributesGetting : public PerfScenarioBase { public: PerfInstanceAttributesGetting(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdRxValue attrValue; auto entities = m_pModel->underlyingSchema()->entities(); for (auto it = entities->newIterator(); it->next();) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) continue; OdDAI::ApplicationInstancePtr pAppInstance = m_pModel->createEntityInstance(pEntity->name()); if (pAppInstance.isNull()) continue; putAttr(pAppInstance, pEntity, attrValue); m_pModel->appendEntityInstance(pAppInstance); } m_pPerfTimer->start(); for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { for (int i = 0; i < SCHEMA_ENTITIES_MULTIPLIER * 30; ++i) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); OdDAI::EntityPtr pEntity = m_pModel->getEntityDefinition(pAppInstance->typeName()); getAttr(pAppInstance, pEntity, attrValue); } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the reading repository from the buffer. */ class PerfModelReading : public PerfScenarioBase { public: PerfModelReading(OdDAI::Repository* pRepository, OdStreamBuf* pStream, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pRepository(pRepository) , m_pStream(pStream) , m_pPerfTimer(pPerfTimer) { } bool run() override { m_pPerfTimer->start(); TEST_ASSERT(m_pRepository->readStream(m_pStream) == eOk); m_pPerfTimer->stop(); return true; } private: OdDAI::RepositoryPtr m_pRepository; OdStreamBufPtr m_pStream; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the writing repository to the buffer. */ class PerfModelWriting : public PerfScenarioBase { public: PerfModelWriting(OdDAI::Repository* pRepository, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pRepository(pRepository) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdStreamBufPtr pStream = OdMemoryStream::createNew(); m_pPerfTimer->start(); TEST_ASSERT(m_pRepository->writeStream(pStream) == eOk); m_pPerfTimer->stop(); return true; } private: OdDAI::RepositoryPtr m_pRepository; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking validation. */ class PerfValidation: public PerfScenarioBase { public: PerfValidation(OdDAI::Validator* pValidator, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pValidator(pValidator) , m_pPerfTimer(pPerfTimer) { } bool run() override { m_pPerfTimer->start(); try { m_pValidator->run(); } catch (...) { oddaiPrintConsoleString(L"Validation process thrown exception."); } m_pPerfTimer->stop(); return true; } private: OdDAI::ValidatorPtr m_pValidator; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the findusers method calls for all schema entities. */ class PerfInstanceFind : public PerfScenarioBase { public: PerfInstanceFind(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdRxValue attrValue; auto entities = m_pModel->underlyingSchema()->entities(); for (auto it = entities->newIterator(); it->next();) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) continue; OdDAI::ApplicationInstancePtr pAppInstance = m_pModel->createEntityInstance(pEntity->name()); if (pAppInstance.isNull()) continue; putAttr(pAppInstance, pEntity, attrValue); m_pModel->appendEntityInstance(pAppInstance); } m_pPerfTimer->start(); int totalusers = 0; for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); { OdDAI::NonPersistentList instanceReferences; instanceReferences.createEmpty(); auto resultList = pAppInstance->findUsers(&instanceReferences); int nUsers = resultList->getMemberCount(); if (nUsers > 0) { totalusers += nUsers; } } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the findusedin method calls for all schema entities within created file content. */ class PerfInstanceFindUsedInRW : public PerfScenarioBase { public: PerfInstanceFindUsedInRW(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdRxValue attrValue; OdArray fullAttrsArray; auto entities = m_pModel->underlyingSchema()->entities(); auto entIdx = 0; for (auto it = entities->newIterator(); it->next();) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) continue; OdDAI::ApplicationInstancePtr pAppInstance = m_pModel->createEntityInstance(pEntity->name()); if (pAppInstance.isNull()) continue; putAttr(pAppInstance, pEntity, attrValue); OdArray attrsArray = pEntity->attributes().getArray(); for (auto attr : attrsArray) { if (OdDAI::ExplicitAttribute::cast(attr).isNull()) continue; fullAttrsArray.append(attr); } m_pModel->appendEntityInstance(pAppInstance); entIdx++; } m_pPerfTimer->start(); int totalusers = 0; for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); { for (auto attr : fullAttrsArray) { OdDAI::NonPersistentList instanceReferences; instanceReferences.createEmpty(); auto resultList = pAppInstance->findUsedIn(*attr, &instanceReferences); int nUsers = resultList->getMemberCount(); if (nUsers > 0) { totalusers += nUsers; } } } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the findusedin method calls for all schema entities in existed file. */ class PerfInstanceFindUsedInRO : public PerfScenarioBase { public: PerfInstanceFindUsedInRO(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { OdRxValue attrValue; OdArray fullAttrsArray; auto entities = m_pModel->underlyingSchema()->entities(); auto entIdx = 0; for (auto it = entities->newIterator(); it->next();) { OdDAI::EntityPtr pEntity = it->object(); if (!pEntity->instantiable()) continue; OdArray attrsArray = pEntity->attributes().getArray(); for (auto attr : attrsArray) { if (OdDAI::ExplicitAttribute::cast(attr).isNull()) continue; fullAttrsArray.append(attr); } entIdx++; } m_pPerfTimer->start(); int totalusers = 0; for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); { for (auto attr : fullAttrsArray) { OdDAI::NonPersistentList instanceReferences; instanceReferences.createEmpty(); auto resultList = pAppInstance->findUsedIn(*attr, &instanceReferences); int nUsers = resultList->getMemberCount(); if (nUsers > 0) { totalusers += nUsers; } } } } m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the findusedin method calls for real ifc data in existed file. */ class PerfInstanceFindUsedInRealData : public PerfScenarioBase { public: PerfInstanceFindUsedInRealData(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { m_pPerfTimer->start(); int totalusers = 0; for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); { OdDAI::NonPersistentList instanceReferences; instanceReferences.createEmpty(); OdDAI::NonPersistentList domain; domain.createEmpty(); auto resultAttrsList = pAppInstance->findRolesOf(&instanceReferences); std::set entityAttrs; OdInt nUsers = resultAttrsList->getMemberCount(); auto itAttrs = resultAttrsList->createConstIterator(); OdInt ind = 0; //Check users attributes for (itAttrs->beginning(); itAttrs->next();) { OdDAI::OdDAIObjectSDAI* instAttribute; itAttrs->getCurrentMember() >> instAttribute; OdDAI::AttributePtr explAttr = OdDAI::Attribute::cast(instAttribute); if (explAttr) { auto attrType = explAttr->entityDef(); auto resultList = pAppInstance->findUsedIn(*explAttr, &instanceReferences); int nUsers = resultList->getMemberCount(); if (nUsers > 0) { totalusers += nUsers; } ++ind; } } } } oddaiPrintConsoleString(OD_T("Usedin total -> %d\n"), totalusers); m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; /** \details A performance test for checking the findusedin method calls for real ifc data in existed file. */ class PerfInstanceFindUsersRealData : public PerfScenarioBase { public: PerfInstanceFindUsersRealData(OdDAI::Model* pModel, OdPerfTimerBase* pPerfTimer) : PerfScenarioBase() , m_pModel(pModel) , m_pPerfTimer(pPerfTimer) { } bool run() override { m_pPerfTimer->start(); int totalusers = 0; for (auto it = m_pModel->newIterator(); !it->done(); it->step()) { OdDAI::ApplicationInstancePtr pAppInstance = it->id().openObject(); { OdDAI::NonPersistentList instanceReferences; instanceReferences.createEmpty(); OdDAI::NonPersistentList domain; domain.createEmpty(); auto resultList = pAppInstance->findUsers(&instanceReferences); int nUsers = resultList->getMemberCount(); //oddaiPrintConsoleString(OD_T("ID = #%hd -> %d\n"), pAppInstance->id()->getHandle(), nUsers); if (nUsers > 0) { totalusers += nUsers; } } } oddaiPrintConsoleString(OD_T("Users total -> %d\n"), totalusers); m_pPerfTimer->stop(); return true; } private: OdDAI::ModelPtr m_pModel; OdPerfTimerBase* m_pPerfTimer; }; } #endif //_DAI_PERF_SCENARIO_H_