From 14a7ab1ce7ae4b05b4f56e7596bd289591d6e679 Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Tue, 2 Jul 2013 12:47:01 +0100 Subject: [PATCH] Flip path/type map in HDFDescriptor. Refs #7263 Looking up paths is far more common so make that faster. --- .../DataHandling/src/LoadMuonNexus2.cpp | 5 +- .../Kernel/inc/MantidKernel/HDFDescriptor.h | 12 ++- .../Framework/Kernel/src/HDFDescriptor.cpp | 91 ++++++++++++++----- 3 files changed, 79 insertions(+), 29 deletions(-) diff --git a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp index 0f477784753..fe2549066f2 100644 --- a/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp +++ b/Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp @@ -505,11 +505,12 @@ namespace Mantid { NXRoot root(descriptor.filename()); NXEntry entry = root.openFirstEntry(); + std::string versionField = "idf_version"; if(upperIDF) versionField = "IDF_version"; - if ( entry.getInt( versionField ) != 2 ) return 0; - std::string definition = entry.getString( "definition" ); + if ( entry.getInt(versionField) != 2 ) return 0; + std::string definition = entry.getString("definition"); if ( definition == "muonTD" || definition == "pulsedTD" ) { // If all this succeeded then we'll assume this is an ISIS Muon NeXus file version 2 diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/HDFDescriptor.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/HDFDescriptor.h index 13b2511e643..26f31b0a497 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/HDFDescriptor.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/HDFDescriptor.h @@ -9,6 +9,11 @@ #include <string> #include <utility> +namespace NeXus +{ + class File; +} + namespace Mantid { namespace Kernel @@ -90,6 +95,9 @@ namespace Mantid /// Initialize object with filename void initialize(const std::string& filename); + /// Walk the tree and cache the structure + void walkFile(::NeXus::File & file, const std::string & rootPath, const std::string & className, + std::map<std::string, std::string> & pmap, int level); /// Full filename std::string m_filename; @@ -99,8 +107,8 @@ namespace Mantid std::pair<std::string, std::string> m_firstEntryNameType; /// Root attributes std::set<std::string> m_rootAttrs; - /// Map of types to full path strings. - std::multimap<std::string, std::string> *m_typesToPaths; + /// Map of full path strings to types. Can check if path exists quickly + std::map<std::string, std::string> m_pathsToTypes; }; diff --git a/Code/Mantid/Framework/Kernel/src/HDFDescriptor.cpp b/Code/Mantid/Framework/Kernel/src/HDFDescriptor.cpp index fb1d3dac585..70fd3d55160 100644 --- a/Code/Mantid/Framework/Kernel/src/HDFDescriptor.cpp +++ b/Code/Mantid/Framework/Kernel/src/HDFDescriptor.cpp @@ -8,7 +8,6 @@ #include <Poco/Path.h> #include <cstring> -#include <iostream> namespace Mantid { @@ -100,7 +99,7 @@ namespace Mantid */ HDFDescriptor::HDFDescriptor(const std::string & filename) : m_filename(), m_extension(), m_firstEntryNameType(), - m_rootAttrs(), m_typesToPaths(NULL) + m_rootAttrs(), m_pathsToTypes() { if(filename.empty()) { @@ -124,7 +123,6 @@ namespace Mantid */ HDFDescriptor::~HDFDescriptor() { - delete m_typesToPaths; } /// Returns the name & type of the first entry in the file @@ -148,12 +146,7 @@ namespace Mantid */ bool HDFDescriptor::pathExists(const std::string& path) const { - auto iend = m_typesToPaths->end(); - for(auto it = m_typesToPaths->begin(); it != iend; ++it) - { - if(path == it->second) return true; - } - return false; + return (m_pathsToTypes.find(path) != m_pathsToTypes.end()); } /** @@ -163,13 +156,12 @@ namespace Mantid */ bool HDFDescriptor::pathOfTypeExists(const std::string& path, const std::string & type) const { - auto it = m_typesToPaths->lower_bound(type); - auto itend = m_typesToPaths->upper_bound(type); - for(; it != itend; ++it) + auto it = m_pathsToTypes.find(path); + if(it != m_pathsToTypes.end()) { - if(it->second == path) return true; + return (it->second == type); } - return false; + else return false; } /** @@ -178,10 +170,14 @@ namespace Mantid */ bool HDFDescriptor::classTypeExists(const std::string & classType) const { - return (m_typesToPaths->find(classType) != m_typesToPaths->end()); + auto iend = m_pathsToTypes.end(); + for(auto it = m_pathsToTypes.begin(); it != iend; ++it) + { + if(classType == it->second) return true; + } + return false; } - //--------------------------------------------------------------------------------------------------------------------------- // HDFDescriptor private methods //--------------------------------------------------------------------------------------------------------------------------- @@ -195,20 +191,65 @@ namespace Mantid m_extension = "." + Poco::Path(filename).getExtension(); ::NeXus::File file(this->filename()); - auto attrInfos = file.getAttrInfos(); - for(size_t i = 0; i < attrInfos.size(); ++i) + + file.openPath("/"); + m_rootAttrs.clear(); + m_pathsToTypes.clear(); + walkFile(file, "", "", m_pathsToTypes,0); + } + + /** + * Cache the structure in the given maps + * @param file An open NeXus File object + * @param rootPath The current path that is open in the file + * @param className The class of the current open path + * @param tmap [Out] An output map filled with mappings of type->path + * @param pmap [Out] An output map filled with mappings of path->type + * @param level An integer defining the current level in the file + */ + void HDFDescriptor::walkFile(::NeXus::File & file,const std::string & rootPath, const std::string & className, + std::map<std::string, std::string> & pmap, int level) + { + if (!rootPath.empty()) { - m_rootAttrs.insert(attrInfos[i].name); + pmap.insert(std::make_pair(rootPath, className)); } - auto entries = file.getEntries(); - for(auto it = entries.begin(); it != entries.end(); ++it) + if(level == 0) { - if(it->second == "CDF0.0") continue; - m_firstEntryNameType = std::make_pair(it->first, it->second); - break; + auto attrInfos = file.getAttrInfos(); + for(size_t i = 0; i < attrInfos.size(); ++i) + { + m_rootAttrs.insert(attrInfos[i].name); + } } - m_typesToPaths = file.getTypeMap(); + + auto dirents = file.getEntries(); + auto itend = dirents.end(); + for (auto it = dirents.begin(); it != itend; ++it) + { + const std::string & entryName = it->first; + const std::string & entryClass = it->second; + const std::string entryPath = rootPath + "/" + entryName; + if(entryClass == "SDS") + { + //tmap.insert(std::make_pair(entryClass, entryPath)); + pmap.insert(std::make_pair(entryPath, entryClass)); + } + else if(entryClass == "CDF0.0") + { + // Do nothing with this + } + else + { + if(level == 0) m_firstEntryNameType = (*it); //copy first entry name & type + file.openGroup(entryName, entryClass); + walkFile(file, entryPath, entryClass, pmap,level+1); + } + } + file.closeGroup(); } + + } // namespace Kernel } // namespace Mantid -- GitLab