Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Read variable-length data from 1-D array dataset. More...
#include <ReadHDF5VarLen.hpp>
Public Member Functions | |
ReadHDF5VarLen (DebugOutput &debug_output, void *buffer, size_t buffer_size) | |
Constructor. | |
virtual | ~ReadHDF5VarLen () |
ErrorCode | read_data (ReadHDF5Dataset &data_set, const Range &offsets, EntityHandle start_offset, hid_t data_type, const Range &file_ids, const std::vector< unsigned > &vals_per_ent, const Range &ranged_file_ids) |
Do actual read of data set. | |
ErrorCode | read_offsets (ReadHDF5Dataset &data_set, const Range &file_ids, EntityHandle start_file_id, EntityHandle nudge, Range &offsets_out, std::vector< unsigned > &counts_out) |
Read set description table or offset vector for var-len tags or old-format poly(gon|hedra) connectivity. | |
ErrorCode | read (ReadHDF5Dataset &offset_data, ReadHDF5Dataset &value_data, const Range &file_ids, EntityHandle start_file_id, hid_t data_type, const Range *ranged=0) |
Protected Member Functions | |
virtual ErrorCode | store_data (EntityHandle file_id, void *data, long num_data, bool ranged)=0 |
Store data list for a single entity. | |
Protected Attributes | |
DebugOutput & | dbgOut |
Static Private Member Functions | |
static bool | is_ranged (EntityHandle file_id, Range::const_iterator &ranged_iter, Range::const_iterator ranged_end) |
Test if passed file_id is value pointed to by ranged_iter, and if so, incremenet ranged_iter. | |
Private Attributes | |
void *const | dataBuffer |
const size_t | bufferSize |
Read variable-length data from 1-D array dataset.
Utility class for reading variable-length data from an HDF5 dataset. Used for reading set contents, set parents, set children, polygon and polyhedron connectivity, and variable-length tag data.
This is an abstract class. The pure virtual store_data
method must be implemented to create a concrete instance.
Definition at line 32 of file ReadHDF5VarLen.hpp.
moab::ReadHDF5VarLen::ReadHDF5VarLen | ( | DebugOutput & | debug_output, |
void * | buffer, | ||
size_t | buffer_size | ||
) | [inline] |
Constructor.
buffer | A temporary buffer to use during read |
buffer_size | Size of buffer , in bytes. |
Definition at line 68 of file ReadHDF5VarLen.hpp.
: dbgOut( debug_output ), dataBuffer( buffer ), bufferSize( buffer_size ) { }
virtual moab::ReadHDF5VarLen::~ReadHDF5VarLen | ( | ) | [inline, virtual] |
Definition at line 73 of file ReadHDF5VarLen.hpp.
{}
bool moab::ReadHDF5VarLen::is_ranged | ( | EntityHandle | file_id, |
Range::const_iterator & | ranged_iter, | ||
Range::const_iterator | ranged_end | ||
) | [static, private] |
Test if passed file_id is value pointed to by ranged_iter, and if so, incremenet ranged_iter.
Definition at line 14 of file ReadHDF5VarLen.cpp.
Referenced by read_data().
{ if( ranged_iter == range_end ) return false; assert( file_id <= *ranged_iter ); if( *ranged_iter != file_id ) return false; ++ranged_iter; return true; }
ErrorCode moab::ReadHDF5VarLen::read | ( | ReadHDF5Dataset & | offset_data, |
ReadHDF5Dataset & | value_data, | ||
const Range & | file_ids, | ||
EntityHandle | start_file_id, | ||
hid_t | data_type, | ||
const Range * | ranged = 0 |
||
) | [inline] |
Definition at line 135 of file ReadHDF5VarLen.hpp.
References ErrorCode, MB_SUCCESS, read_data(), and read_offsets().
{ ErrorCode rval; const EntityHandle nudge = 1; Range offsets; std::vector< unsigned > counts; rval = read_offsets( offset_data, file_ids, start_file_id, nudge, offsets, counts ); if( MB_SUCCESS != rval ) return rval; Range empty; rval = read_data( value_data, offsets, nudge, data_type, file_ids, counts, ranged ? *ranged : empty ); return rval; }
ErrorCode moab::ReadHDF5VarLen::read_data | ( | ReadHDF5Dataset & | data_set, |
const Range & | offsets, | ||
EntityHandle | start_offset, | ||
hid_t | data_type, | ||
const Range & | file_ids, | ||
const std::vector< unsigned > & | vals_per_ent, | ||
const Range & | ranged_file_ids | ||
) |
Do actual read of data set.
data_set | The data set to read. |
file_ids | The file ids of the entities to read. |
start_file_id | The file id corresponding to the first row of the dataset |
data_type | The desired, in-memory data type for values |
vals_per_ent | The number of values for each entity |
ranged_file_ids | Those file ids for which the 'ranged' argument to storedata should be passed as true . |
Definition at line 27 of file ReadHDF5VarLen.cpp.
References moab::Range::begin(), bufferSize, dataBuffer, dbgOut, moab::ReadHDF5Dataset::done(), moab::Range::end(), ErrorCode, moab::ReadHDF5Dataset::get_debug_desc(), moab::ReadHDF5Dataset::get_read_count(), is_ranged(), MB_SUCCESS, moab::DebugOutput::printf(), moab::ReadHDF5Dataset::read(), moab::ReadHDF5Dataset::set_file_ids(), moab::Range::size(), and store_data().
Referenced by read().
{ ErrorCode rval; const size_t value_size = H5Tget_size( data_type ); const size_t buffer_size = bufferSize / value_size; unsigned char* const data_buffer = reinterpret_cast< unsigned char* >( dataBuffer ); std::vector< unsigned char > partial; // for when we read only part of the contents of a set/entity Range::const_iterator fileid_iter = file_ids.begin(); Range::const_iterator ranged_iter = ranged_file_ids.begin(); std::vector< unsigned >::const_iterator count_iter = vals_per_ent.begin(); size_t count, offset; bool ranged; int nn = 0; assert( file_ids.size() == vals_per_ent.size() ); try { data_set.set_file_ids( offsets, start_offset, buffer_size, data_type ); } catch( ReadHDF5Dataset::Exception& ) { return MB_FAILURE; } dbgOut.printf( 3, "Reading %s in %lu chunks\n", data_set.get_debug_desc(), data_set.get_read_count() ); while( !data_set.done() ) { dbgOut.printf( 3, "Reading chunk %d of %s\n", ++nn, data_set.get_debug_desc() ); try { data_set.read( data_buffer, count ); } catch( ReadHDF5Dataset::Exception& ) { return MB_FAILURE; } assert( 0 == count || fileid_iter != file_ids.end() ); // Handle 'special' case where we read some, but not all // of the data for an entity during the last iteration. offset = 0; if( !partial.empty() ) { // didn't read all of previous entity assert( fileid_iter != file_ids.end() ); assert( 0 == ( partial.size() % value_size ) ); size_t num_prev = partial.size() / value_size; offset = *count_iter - num_prev; if( offset > count ) { // still don't have all partial.insert( partial.end(), data_buffer, data_buffer + count * value_size ); continue; } partial.insert( partial.end(), data_buffer, data_buffer + offset * value_size ); ranged = is_ranged( *fileid_iter, ranged_iter, ranged_file_ids.end() ); assert( partial.size() == *count_iter * value_size ); rval = store_data( *fileid_iter, &partial[0], *count_iter, ranged ); if( MB_SUCCESS != rval ) return rval; ++count_iter; ++fileid_iter; partial.clear(); } // Process contents for all entities for which we // have read the complete list while( count_iter != vals_per_ent.end() && offset + *count_iter <= count ) { assert( fileid_iter != file_ids.end() ); ranged = is_ranged( *fileid_iter, ranged_iter, ranged_file_ids.end() ); rval = store_data( *fileid_iter, data_buffer + offset * value_size, *count_iter, ranged ); if( MB_SUCCESS != rval ) return rval; offset += *count_iter; ++count_iter; ++fileid_iter; } // If we did not read all of the final entity, // store what we did read to be processed in the // next iteration if( offset < count ) { assert( partial.empty() ); partial.insert( partial.end(), data_buffer + offset * value_size, data_buffer + count * value_size ); } } // NOTE: If the last set is empty, we will not process it here // assert(fileid_iter == file_ids.end()); #ifndef NDEBUG for( ; fileid_iter != file_ids.end(); ++fileid_iter ) { assert( 0 == *count_iter ); ++count_iter; } #endif return MB_SUCCESS; }
ErrorCode moab::ReadHDF5VarLen::read_offsets | ( | ReadHDF5Dataset & | data_set, |
const Range & | file_ids, | ||
EntityHandle | start_file_id, | ||
EntityHandle | nudge, | ||
Range & | offsets_out, | ||
std::vector< unsigned > & | counts_out | ||
) |
Read set description table or offset vector for var-len tags or old-format poly(gon|hedra) connectivity.
data_set | The data set to read. |
file_ids | The file ids of the entities to read. |
start_file_id | The file id corresponding to the first row of the dataset |
num_columns | The number of columns of offsets in the dataset |
indices | Array of length num_columns contaning the indices of the columns to read. |
nudge | Amount by which to offset values in offset_out to avoid putting zeros in Range. Must be greater than 0. Probably 1. |
offsets_out | An array of length num_columns which will be populated with the resulting list of offsets into the contents list calculated from reading the offsets from the passed data set. |
counts_out | An array of length num_columns of std::vectors, where each vector will be filled with one value per file ID indicating the length of the data for the corresponding file ID. |
ranged_file_ids | If non-null, the last column of the table will be read and tested for the ranged bit. For all file_ids for which the range bit is set, the file ID will be added to this list. |
Definition at line 291 of file ReadHDF5VarLen.cpp.
References moab::Range::begin(), buffer, bufferSize, moab::Range::clear(), moab::Range::const_pair_begin(), moab::Range::const_pair_end(), dataBuffer, dbgOut, moab::ReadHDF5Dataset::done(), moab::Range::empty(), moab::Range::end(), moab::Range::front(), moab::ReadHDF5Dataset::get_debug_desc(), moab::ReadHDF5Dataset::get_read_count(), moab::Range::insert(), MB_SUCCESS, moab::DebugOutput::printf(), moab::ReadHDF5Dataset::read(), moab::ReadHDF5Dataset::set_file_ids(), moab::Range::size(), and moab::Range::const_iterator::start_of_block().
Referenced by read().
{ // Use hints to make sure insertion into ranges is O(1) offsets_out.clear(); counts_out.clear(); counts_out.reserve( file_ids.size() ); Range::iterator hint; // Calculate which rows we need to read from the offsets table Range rows; hint = rows.begin(); Range::const_pair_iterator pair = file_ids.const_pair_begin(); // special case if reading first entity in dataset, because // there is no previous end value. if( pair != file_ids.const_pair_end() && pair->first == start_file_id ) { hint = rows.insert( nudge, pair->second - start_file_id + nudge ); ++pair; } while( pair != file_ids.const_pair_end() ) { hint = rows.insert( hint, pair->first - start_file_id + nudge - 1, pair->second - start_file_id + nudge ); ++pair; } // set up read of offsets dataset hsize_t buffer_size = bufferSize / sizeof( hssize_t ); hssize_t* buffer = reinterpret_cast< hssize_t* >( dataBuffer ); data_set.set_file_ids( rows, nudge, buffer_size, H5T_NATIVE_HSSIZE ); hssize_t prev_end; bool have_prev_end = false; // If we're reading the first row of the table, then the // previous end is implicitly -1. if( !file_ids.empty() && file_ids.front() == start_file_id ) { prev_end = -1; have_prev_end = true; } dbgOut.printf( 3, "Reading %s in %lu chunks\n", data_set.get_debug_desc(), data_set.get_read_count() ); // read offset table size_t count, offset; Range::const_iterator fiter = file_ids.begin(); hint = offsets_out.begin(); int nn = 0; while( !data_set.done() ) { dbgOut.printf( 3, "Reading chunk %d of %s\n", ++nn, data_set.get_debug_desc() ); try { data_set.read( buffer, count ); } catch( ReadHDF5Dataset::Exception& ) { return MB_FAILURE; } if( !count ) // might have been NULL read for collective IO continue; // If the previous end values were read in the previous iteration, // then they're stored in prev_end. offset = 0; if( have_prev_end ) { counts_out.push_back( buffer[0] - prev_end ); hint = offsets_out.insert( hint, prev_end + 1 + nudge, buffer[0] + nudge ); ++fiter; offset = 1; have_prev_end = false; } while( offset < count ) { assert( fiter != file_ids.end() ); // whenever we get to a gap between blocks we need to // advance one step because we read an extra end id // preceding teah block if( fiter == fiter.start_of_block() ) { if( offset == count - 1 ) break; ++offset; } size_t s = buffer[offset - 1] + 1; size_t e = buffer[offset]; counts_out.push_back( e - s + 1 ); hint = offsets_out.insert( hint, s + nudge, e + nudge ); ++fiter; ++offset; } // If we did not end on the boundary between two blocks, // then we need to save the end indices for the final entry // for use in the next iteration. Similarly, if we ended // with extra values that were read with the express intention // of getting the previous end values for a block, we need to // save them. This case only arises if we hit the break in // the above loop. if( fiter != fiter.start_of_block() || offset < count ) { assert( !have_prev_end ); if( offset == count ) { --offset; assert( fiter != fiter.start_of_block() ); } else { assert( offset + 1 == count ); assert( fiter == fiter.start_of_block() ); } have_prev_end = true; prev_end = buffer[offset]; } } assert( !have_prev_end ); assert( fiter == file_ids.end() ); return MB_SUCCESS; }
virtual ErrorCode moab::ReadHDF5VarLen::store_data | ( | EntityHandle | file_id, |
void * | data, | ||
long | num_data, | ||
bool | ranged | ||
) | [protected, pure virtual] |
Store data list for a single entity.
The is the pure virtual method that must be provided. It is responsible for storing the data read for a single entity.
This function will always be called in the order of the file_ids in the range passed to the read
method.
file_id | The file ID for the entity |
data | A pointer to the data for the entity |
num_data | Number of values for the entity |
ranged | For set contents, true if in ranged format. |
Referenced by read_data().
const size_t moab::ReadHDF5VarLen::bufferSize [private] |
Definition at line 39 of file ReadHDF5VarLen.hpp.
Referenced by read_data(), and read_offsets().
void* const moab::ReadHDF5VarLen::dataBuffer [private] |
Definition at line 38 of file ReadHDF5VarLen.hpp.
Referenced by read_data(), and read_offsets().
DebugOutput& moab::ReadHDF5VarLen::dbgOut [protected] |
Definition at line 35 of file ReadHDF5VarLen.hpp.
Referenced by read_data(), and read_offsets().