Skip to content

Commit

Permalink
Flip path/type map in HDFDescriptor. Refs #7263
Browse files Browse the repository at this point in the history
Looking up paths is far more common so make that faster.
  • Loading branch information
martyngigg committed Jul 4, 2013
1 parent 5fd18f6 commit 14a7ab1
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 29 deletions.
5 changes: 3 additions & 2 deletions Code/Mantid/Framework/DataHandling/src/LoadMuonNexus2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 10 additions & 2 deletions Code/Mantid/Framework/Kernel/inc/MantidKernel/HDFDescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include <string>
#include <utility>

namespace NeXus
{
class File;
}

namespace Mantid
{
namespace Kernel
Expand Down Expand Up @@ -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;
Expand All @@ -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;
};


Expand Down
91 changes: 66 additions & 25 deletions Code/Mantid/Framework/Kernel/src/HDFDescriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <Poco/Path.h>

#include <cstring>
#include <iostream>

namespace Mantid
{
Expand Down Expand Up @@ -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())
{
Expand All @@ -124,7 +123,6 @@ namespace Mantid
*/
HDFDescriptor::~HDFDescriptor()
{
delete m_typesToPaths;
}

/// Returns the name & type of the first entry in the file
Expand All @@ -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());
}

/**
Expand All @@ -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;
}

/**
Expand All @@ -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
//---------------------------------------------------------------------------------------------------------------------------
Expand All @@ -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

0 comments on commit 14a7ab1

Please sign in to comment.