#include "mindb.h" #include namespace geoworld { void MineralsDB::resolveReferences() { // Resolving all mineral references to classes for (MineralMap::iterator iMin = _minerals.begin(); iMin != _minerals.end(); ++iMin) { resolve(iMin->second->clazz); } // Determining all class groupings of minerals for (ClassesMap::const_iterator iClass = _classes.all.begin(); iClass != _classes.all.end(); ++iClass) { DirectMineralList & grouping = _groups.classes[iClass->first] = DirectMineralList(); for (MineralMap::iterator iMin = _minerals.begin(); iMin != _minerals.end(); ++iMin) { if (!iMin->second->clazz.isNull()) { const std::string & name = iMin->second->clazz->name; if (name == iClass->first) grouping.push_back(iMin->second); } } if (grouping.empty()) _groups.classes.erase(iClass->first); } // Resolving all group definition minerals for (MineralGroups::iterator iGrp = _groups.all.begin(); iGrp != _groups.all.end(); ++iGrp) { for (MineralGroupDef::MineralList::iterator iGrpMin = iGrp->second->members.begin(); iGrpMin != iGrp->second->members.end(); ++iGrpMin) resolve(*iGrpMin); } for (MineralMap::iterator i = _minerals.begin(); i != _minerals.end(); ++i) { for (MineralDef::GenesisList::iterator ig = i->second->genesis.begin(); ig != i->second->genesis.end(); ++ig) { resolve(ig->associations); resolve(ig->protolith); resolve(ig->host.mineral); resolve(ig->environments); } } } void MineralsDB::createIndexes() { // Create class-by-silica index for (ClassesMap::const_iterator j = _classes.all.begin(); j != _classes.all.end(); ++j) for (MineralClass::DispositionList::const_iterator i = j->second->dispositions.begin(); i != j->second->dispositions.end(); ++i) _classes.silica[i->silica.base].insert(j->second); // Create mineral-by-associated index for (MineralMap::const_iterator i = _minerals.begin(); i != _minerals.end(); ++i) { for (MineralDef::GenesisList::const_iterator j = i->second->genesis.begin(); j != i->second->genesis.end(); ++j) { for (MineralReferenceList::const_iterator k = j->associations.begin(); k != j->associations.end(); ++k) { if (!k->mineral.isNull()) { PetrogenyMineralMultiMap::iterator u = _associations.find(k->mineral); if (u == _associations.end()) u = _associations.insert(_associations.begin(), std::pair< MineralPtr, PetrogenyMineralSet > (k->mineral, PetrogenyMineralSet())); u->second.insert(GenesisMineralMapping(*k, i->second, j)); } } } } // Create mineral-by-protolith index for (MineralMap::const_iterator i = _minerals.begin(); i != _minerals.end(); ++i) { for (MineralDef::GenesisList::const_iterator j = i->second->genesis.begin(); j != i->second->genesis.end(); ++j) { for (MineralReferenceList::const_iterator k = j->protolith.begin(); k != j->protolith.end(); ++k) { if (!k->mineral.isNull()) { PetrogenyMineralMultiMap::iterator u = _protoliths.find(k->mineral); if (u == _protoliths.end()) u = _protoliths.insert(_protoliths.begin(), std::pair< MineralPtr, PetrogenyMineralSet > (k->mineral, PetrogenyMineralSet())); u->second.insert(GenesisMineralMapping(*k, i->second, j)); } } } } // Create mineral-by-host index for (MineralMap::const_iterator i = _minerals.begin(); i != _minerals.end(); ++i) { for (MineralDef::GenesisList::const_iterator j = i->second->genesis.begin(); j != i->second->genesis.end(); ++j) { if (j->host) { PetrogenyMineralMultiMap::iterator u = _hosts.find(j->host.mineral); if (u == _hosts.end()) u = _hosts.insert(_hosts.begin(), std::pair< MineralPtr, PetrogenyMineralSet > (j->host.mineral, PetrogenyMineralSet())); u->second.insert(GenesisMineralMapping(j->host, i->second, j)); } } } // Create mineral-by-environment index for (MineralMap::const_iterator i = _minerals.begin(); i != _minerals.end(); ++i) { for (MineralDef::GenesisList::const_iterator j = i->second->genesis.begin(); j != i->second->genesis.end(); ++j) { for (MinClassReferenceList::const_iterator k = j->environments.begin(); k != j->environments.end(); ++k) { if (!k->isNull()) { PetrogenyClassMultiMap::iterator u = _environments.find(*k); if (u == _environments.end()) u = _environments.insert(_environments.begin(), std::pair< MinClassPtr, PetrogenyClassSet > (*k, PetrogenyClassSet())); u->second.insert(GenesisClassMapping(i->second, j)); } } } } } void MineralsDB::resolve( MineralPtr & rWRef ) { if (!rWRef.isNull() && rWRef.getState() == MineralPtr::Weak) { MineralMap::const_iterator iMineral = _minerals.find(rWRef.getName()); if (iMineral != _minerals.end()) rWRef.resolve(iMineral->second); else rWRef.makeNull(); } } void MineralsDB::resolve( mars::WeakReference< MineralClass > & rWRef ) { if (!rWRef.isNull() && rWRef.getState() == mars::WeakReference< MineralClass >::Weak) { ClassesMap::const_iterator iClass = _classes.all.find(rWRef.getName()); if (iClass != _classes.all.end()) rWRef.resolve(iClass->second); else rWRef.makeNull(); } } void MineralsDB::resolve( MinClassReferenceList & list ) { for (MinClassReferenceList::iterator i = list.begin(); i != list.end(); ++i) { resolve (*i); } } void MineralsDB::resolve( MineralReferenceList & list ) { class MineralReferenceCompare { public: inline bool operator() (const MineralReference & a, const MineralReference & b) const { if (a.mineral.isNull()) return !b.mineral.isNull(); else if (b.mineral.isNull()) return false; else { const std::string & aName = getName(a.mineral), bName = getName(b.mineral); if (aName == bName) return a.distributions.to_ulong() < b.distributions.to_ulong(); else return aName < bName; } } }; std::set tracker; for (MineralReferenceList::iterator i = list.begin(); i != list.end(); ++i) { MineralMap::const_iterator iMin = _minerals.find(getName(i->mineral)); if (iMin != _minerals.end()) { tracker.insert(*i); i->mineral.resolve(iMin->second); } } MineralReferenceList::iterator i = list.begin(); if (i != list.end()) do { MineralGroupMap::const_iterator iClass = _groups.classes.find(getName(i->mineral)); if (iClass != _groups.classes.end()) { MineralReference oMineralDefault = *i; i = list.erase(i); for (DirectMineralList::const_iterator iClassMin = iClass->second.begin(); iClassMin != iClass->second.end(); ++iClassMin) { oMineralDefault.mineral = MineralPtr (*iClassMin); if (tracker.end() == tracker.find(oMineralDefault)) { list.insert(i, oMineralDefault); tracker.insert(oMineralDefault); } } } else { MineralGroups::const_iterator iGrp = _groups.all.find(getName(i->mineral)); if (iGrp != _groups.all.end()) { MineralReference oMineralDefault = *i; i = list.erase(i); for (MineralGroupDef::MineralList::const_iterator iGrpMin = iGrp->second->members.begin(); iGrpMin != iGrp->second->members.end(); ++iGrpMin) { oMineralDefault.mineral = *iGrpMin; if (tracker.end() == tracker.find(oMineralDefault)) { list.insert(i, oMineralDefault); tracker.insert(oMineralDefault); } } } else i++; } } while (i != list.end()); } const mars::ptr< MineralDef > MineralsDB::getMinByName( const std::string & sName ) const { MineralMap::const_iterator i = _minerals.find(sName); if (i == _minerals.end()) throw Ex("No such mineral"); else return i->second; } const mars::ptr< MineralClass > MineralsDB::getClassByName( const std::string & sName ) const { ClassesMap::const_iterator i = _classes.all.find(sName); if (i == _classes.all.end()) throw Ex("No such mineral class"); else return i->second; } mars::ptr< MineralClass > MineralsDB::addClass( const mars::ptr< MineralClass > & ptr ) { switch (ptr->type) { case MineralClass::Type_Igneous: _classes.igneous[ptr->name] = ptr; break; case MineralClass::Type_Sedimentary: _classes.sedimentary[ptr->name] = ptr; break; } _classes.all[ptr->name] = ptr; return ptr; } mars::ptr< MineralGroupDef > MineralsDB::addGroup( const mars::ptr< MineralGroupDef > & ptr ) { return _groups.all[ptr->name] = ptr; } mars::ptr< MineralDef > MineralsDB::addMineral( const mars::ptr< MineralDef > & ptr ) { return _minerals[ptr->name] = ptr; } geoworld::MineralsDB::classes_const_iterator MineralsDB::beginClasses( const MineralClass::Type enmcType ) const { const ClassesMap * pMap = NULL; switch (enmcType) { case MineralClass::Type_Igneous: pMap = &_classes.igneous; break; case MineralClass::Type_Sedimentary: pMap = &_classes.sedimentary; break; default: pMap = &_classes.all; break; } return classes_const_iterator(pMap->begin()); } geoworld::MineralsDB::classes_const_iterator MineralsDB::endClasses( const MineralClass::Type enmcType ) const { const ClassesMap * pMap = NULL; switch (enmcType) { case MineralClass::Type_Igneous: pMap = &_classes.igneous; break; case MineralClass::Type_Sedimentary: pMap = &_classes.sedimentary; break; default: pMap = &_classes.all; break; } return classes_const_iterator(pMap->end()); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getAssociatedMinerals( const std::string & sName ) const { MineralMap::const_iterator i = _minerals.find(sName); if (i != _minerals.end()) return getAssociatedMinerals(MineralPtr(i->second)); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getAssociatedMinerals( const MineralPtr & pMin ) const { PetrogenyMineralMultiMap::const_iterator i = _associations.find(pMin); if (i != _associations.end()) return PetrogenyMineralSetFacade(i->second); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getIncubatedMinerals( const std::string & sName ) const { MineralMap::const_iterator i = _minerals.find(sName); if (i != _minerals.end()) return getIncubatedMinerals(MineralPtr(i->second)); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getIncubatedMinerals( const MineralPtr & pMin ) const { PetrogenyMineralMultiMap::const_iterator i = _protoliths.find(pMin); if (i != _protoliths.end()) return PetrogenyMineralSetFacade(i->second); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getHostedMinerals( const std::string & sName ) const { MineralMap::const_iterator i = _minerals.find(sName); if (i != _minerals.end()) return getHostedMinerals(MineralPtr(i->second)); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyMineralSetFacade MineralsDB::getHostedMinerals( const MineralPtr & pMin ) const { PetrogenyMineralMultiMap::const_iterator i = _hosts.find(pMin); if (i != _hosts.end()) return PetrogenyMineralSetFacade(i->second); else return PetrogenyMineralSetFacade(_endMineralPetrogeny); } MineralsDB::PetrogenyClassSetFacade MineralsDB::getMineralsByEnvironment( const std::string & sName ) const { ClassesMap::const_iterator i = _classes.all.find(sName); if (i != _classes.all.end()) return getMineralsByEnvironment(MinClassPtr(i->second)); else return PetrogenyClassSetFacade(_endClassPetrogeny); } MineralsDB::PetrogenyClassSetFacade MineralsDB::getMineralsByEnvironment( const MinClassPtr & pClass ) const { PetrogenyClassMultiMap::const_iterator i = _environments.find(pClass); if (i != _environments.end()) return PetrogenyClassSetFacade(i->second); else return PetrogenyClassSetFacade(_endClassPetrogeny); } // TODO: Move? bool PetrogenyDef::intersection( const MineralReferenceList & lstSubject, const MineralDepositList & lstObject ) { for (MineralReferenceList::const_iterator i = lstSubject.begin(); i != lstSubject.end(); ++i) for (MineralDepositList::const_iterator j = lstObject.begin(); j != lstObject.end(); ++j) if (*i & *j) return true; return false; } // TODO: Move? bool PetrogenyDef::intersection( const MinClassReferenceList & lstSubject, const MinClassPtr & pMinClassObject ) { for (MinClassReferenceList::const_iterator i = lstSubject.begin(); i != lstSubject.end(); ++i) if (*i == pMinClassObject) return true; return false; } }