From 6716423a6895c2be539bc6e0f03d42a2740e19d9 Mon Sep 17 00:00:00 2001 From: aothms Date: Fri, 8 Jan 2016 06:35:53 +0100 Subject: [PATCH] Sort instances on name rather than on std::map occurrence. Add chunk-size command line argument. --- src/ifcconvert/IfcConvert.cpp | 5 +++ src/ifcparse/IfcHdf5File.cpp | 75 ++++++++++++++++++++++++++++++++--- src/ifcparse/IfcHdf5File.h | 6 +++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index e704006023..ec307f20f7 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -94,6 +94,7 @@ int main(int argc, char** argv) { ("output-file", boost::program_options::value(), "output geometry file"); std::string bounds; + uint32_t hdf5_chunk_size; std::vector entity_vector; boost::program_options::options_description geom_options; geom_options.add_options() @@ -139,6 +140,7 @@ int main(int argc, char** argv) { ("hdf5-fix-global-id", "") ("hdf5-instantiate-inverse", "") ("hdf5-instantiate-select", "") + ("hdf5-chunk-size", boost::program_options::value(&hdf5_chunk_size), "") ("include", "Specifies that the entities listed after --entities are to be included") ("exclude", @@ -271,6 +273,9 @@ int main(int argc, char** argv) { settings.fix_global_id() = vmap.count("hdf5-fix-global-id") != 0; settings.instantiate_inverse() = vmap.count("hdf5-instantiate-inverse") != 0; settings.instantiate_select() = vmap.count("hdf5-instantiate-select") != 0; + if (vmap.count("hdf5-chunk-size") == 1) { + settings.chunk_size() = hdf5_chunk_size; + } f.write_hdf5(output_filename, settings); exit_code = 0; } diff --git a/src/ifcparse/IfcHdf5File.cpp b/src/ifcparse/IfcHdf5File.cpp index a2f9316462..51a2de4043 100644 --- a/src/ifcparse/IfcHdf5File.cpp +++ b/src/ifcparse/IfcHdf5File.cpp @@ -459,13 +459,32 @@ void IfcParse::IfcHdf5File::write_schema(const IfcParse::schema_definition& sche for (auto it = schema.entities().begin(); it != schema.entities().end(); ++it) { declared_types[(*it)->type()] = commit(map_entity(*it), (*it)->name()); } + + H5::StrType schema_name_t; + schema_name_t.copy(H5::PredType::C_S1); + schema_name_t.setSize(schema.name().size()); + + hsize_t schema_name_length = 1; + H5::DataSpace schema_name_s(1, &schema_name_length); + + H5::Attribute attr = schema_group.createAttribute("iso_10303_26_data", schema_name_t, schema_name_s); + attr.write(schema_name_t, schema.name()); + attr.close(); }; std::pair IfcParse::IfcHdf5File::make_instance_reference(const IfcUtil::IfcBaseClass* instance) const { +#ifdef SORT_ON_NAME + const std::vector& es = sorted_entities.find(instance->declaration().type())->second; +#else const std::vector& es = sorted_entities.find(instance->declaration().type())->second; +#endif auto dataset_id = std::lower_bound(dataset_names.begin(), dataset_names.end(), instance->declaration().type()); - auto instance_id = std::lower_bound(es.begin(), es.end(), instance); // TODO: << make a vector of ids to make sure pointers are stable +#ifdef SORT_ON_NAME + auto instance_id = std::lower_bound(es.begin(), es.end(), instance->data().id()); +#else + auto instance_id = std::lower_bound(es.begin(), es.end(), instance); +#endif size_t dataset_offset = std::distance(dataset_names.begin(), dataset_id); size_t instance_offset = std::distance(es.begin(), instance_id); @@ -550,8 +569,13 @@ void IfcParse::IfcHdf5File::write_population(IfcFile& f) { IfcSchema::Type::Enum ty = it->second->declaration().type(); tys.insert(ty); // This already is sorted on entity instance name +#ifdef SORT_ON_NAME + sorted_entities[ty].push_back(static_cast(it->first)); +#else sorted_entities[ty].push_back(it->second); +#endif +#ifndef SORT_ON_NAME if (settings_.instantiate_select()) { bool has=false; for (unsigned i = 0; i < it->second->data().getArgumentCount(); ++i) { @@ -582,10 +606,33 @@ void IfcParse::IfcHdf5File::write_population(IfcFile& f) { static_cast(&it->second->data())->Unload(); } } +#endif } dataset_names.assign(tys.begin(), tys.end()); std::sort(dataset_names.begin(), dataset_names.end()); + + { + hsize_t dataset_names_length = dataset_names.size(); + H5::DataSpace dataset_names_s(1, &dataset_names_length); + + H5::Attribute attr = schema_group.createAttribute("iso_10303_26_data_set_names", *default_types[simple_type::string_type], dataset_names_s); + char** attr_data = (char**) allocator.allocate(sizeof(char*) * dataset_names_length); + size_t i = 0; + for (auto it = dataset_names.begin(); it != dataset_names.end(); ++it, ++i) { + std::string nm = IfcSchema::Type::ToString(*it); + attr_data[i] = (char*) allocator.allocate(nm.size() + 1); + strcpy(attr_data[i], nm.c_str()); + } + attr.write(*default_types[simple_type::string_type], attr_data); + attr.close(); + } + +#ifdef SORT_ON_NAME + for (auto it = sorted_entities.begin(); it != sorted_entities.end(); ++it) { + std::sort(it->second.begin(), it->second.end()); + } +#endif for (auto it = dataset_names.begin(); it != dataset_names.end(); ++it) { @@ -596,13 +643,24 @@ void IfcParse::IfcHdf5File::write_population(IfcFile& f) { std::cerr << IfcSchema::Type::ToString(*it) << std::endl; +#ifdef SORT_ON_NAME + std::vector es; + es.reserve(sorted_entities.find(*it)->second.size()); + for (auto jt = sorted_entities.find(*it)->second.begin(); jt != sorted_entities.find(*it)->second.end(); ++jt) { + es.push_back(f.entityById(*jt)); + } +#else const std::vector& es = sorted_entities.find(*it)->second; +#endif size_t datatype_size = declared_types[*it]->getSize(); hsize_t dims = es.size(); - // don't chunk too small - // hsize_t chunk = (std::min)(std::max(es.size() / 64, (size_t)8), es.size()); - // hsize_t chunk = (std::min)( (std::max)(es.size() / 8, (size_t) 128 ) , es.size()); - hsize_t chunk = dims; + + hsize_t chunk; + if (settings_.chunk_size() > 0 && settings_.chunk_size() < dims) { + chunk = static_cast(settings_.chunk_size()); + } else { + chunk = dims; + } const H5::DSetCreatPropList* plist; // H5O_MESG_MAX_SIZE = 65536 @@ -619,6 +677,10 @@ void IfcParse::IfcHdf5File::write_population(IfcFile& f) { // Set compact according to h5ex_d_compact.c plist_->setLayout(H5D_COMPACT); plist = plist_; + } else if (chunk != dims){ + H5::DSetCreatPropList* plist_ = new H5::DSetCreatPropList; + plist_->setChunk(1, &chunk); + plist = plist_; } else { plist = &H5::DSetCreatPropList::DEFAULT; } @@ -688,7 +750,8 @@ void IfcParse::IfcHdf5File::write_population(IfcFile& f) { member_type.close(); member_type = dt->getMemberDataType(member_idx++); - write_number_of_size(ptr, member_type.getSize(), static_cast(dat.id())); + const unsigned int inst_name = static_cast(dat.id()); + write_number_of_size(ptr, member_type.getSize(), inst_name); member_type.close(); // ----v----- In some IFC files there are extra superfluous attributes in the instantiation. For example FJK haus. diff --git a/src/ifcparse/IfcHdf5File.h b/src/ifcparse/IfcHdf5File.h index ede25fa299..30e11f2b47 100644 --- a/src/ifcparse/IfcHdf5File.h +++ b/src/ifcparse/IfcHdf5File.h @@ -20,6 +20,8 @@ #ifndef IFCHDF5FILE_H #define IFCHDF5FILE_H +#define SORT_ON_NAME + #include "H5Cpp.h" #include "../ifcparse/Hdf5Settings.h" @@ -71,7 +73,11 @@ namespace IfcParse { std::map default_type_names; std::map default_cpp_type_names; +#ifdef SORT_ON_NAME + std::map > sorted_entities; +#else std::map > sorted_entities; +#endif std::vector dataset_names; H5::DataType* map_type(const IfcParse::parameter_type* pt);