// EdoIdContext.cxx #include "EdoIdContext.h" #include #include #include #include "Index.h" #include "FileId.h" #include "EventId.h" #include "EdoType.h" #include "EdoKey.h" #include "EdoId.h" using std::ostream; using std::setw; using hes::Index; using hes::IndexVector; using hes::EventId; using hes::FileId; using hes::EdoKey; using hes::EdoType; using hes::EdoId; using hes::EdoIdContext; //********************************************************************** // Static member functions. //********************************************************************** // Version. Index EdoIdContext::version() { return 1; } //********************************************************************** // Member functions. //********************************************************************** // Default constructor. EdoIdContext::EdoIdContext() : m_max_allowed_index(511), m_size(0), m_ids(1) { assert( size() == 0 ); assert( max_index() == 0 ); } //********************************************************************** // Constructor from an index vector. EdoIdContext::EdoIdContext(IndexVector::const_iterator& iidv) : m_max_allowed_index(0), m_size(0), m_ids(1) { IndexVector::const_iterator iidv0 = iidv; Index ctxt_version = *iidv++; Index id_version = *iidv++; Index max_allowed_index = *iidv++; Index insize = *iidv++; if ( ctxt_version != version() ) { iidv = iidv0; return; } if ( id_version != EdoId::version() ) { iidv = iidv0; return; } if ( insize > max_allowed_index ) { iidv = iidv0; return; } if ( insize > max_allowed_index ) { iidv = iidv0; return; } m_max_allowed_index = max_allowed_index; for ( Index count=0; count 0 && midx >= max_index() ) { m_max_allowed_index = midx; } return m_max_allowed_index; } //********************************************************************** // Return the largest assigned index. Index EdoIdContext::max_index() const { return m_ids.size()-1; } //********************************************************************** // Return the number of assigned indices. Index EdoIdContext::size() const { return m_size; } //********************************************************************** // Insert an ID with a specified index. Index EdoIdContext::insert(EdoId id, Index idx) { // Exit if the ID is invalid. if ( ! id.is_valid() ) { return 0; } // Exit if the index is out of range. if ( idx <= 0 || idx > m_max_allowed_index ) { return 0; } // If the table is too small, increase it. if ( m_ids.size() <= idx ) { m_ids.insert(m_ids.end(), idx-m_ids.size()+1, EdoId()); assert( m_ids.size() == idx+1 ); } // Exit if the the index is already assigned to an ID. // There is an error if the assigned value differs from the // requested one. if ( m_ids[idx].is_valid() ) { if ( m_ids[idx] == id ) { return idx; } else { return 0; } } // Exit if the ID is already assigned to a different index. if ( index(id) != 0 ) { return 0; } // Make the new assignment. m_ids[idx] = id; ++m_size; return idx; } //********************************************************************** // Insert an EDO ID if unassigned. // Assign if unassigned. Index EdoIdContext::insert(EdoId id) { // Exit if the ID is invalid. if ( ! id.is_valid() ) { return 0; } // If the ID is already assigned to index, return it. { Index idx = index(id); if ( idx != 0 ) { return idx; } } // If the table is fully packed, add the new entry to the end. // We handle this first because it is the normal condition. if ( max_index() == size() ) { // There is an error if the table is at maximum size. if ( max_index() == max_allowed_index() ) { return 0; } m_ids.push_back(id); ++m_size; Index idx = size(); return idx; } // Otherwise put the entry in the first open position in the table. for ( Index idx=1; idx max_index() ) { return EdoId(); } assert( size() < m_ids.size() ); return m_ids[idx]; } //********************************************************************** // Write context to an index vector. IndexVector& EdoIdContext::write(IndexVector& idv) const { idv.push_back( version() ); idv.push_back( EdoId::version() ); idv.push_back( m_max_allowed_index ); idv.push_back( m_size ); Index count = 0; for ( Index idx=1; idx<=max_allowed_index(); ++idx ) { EdoId id = edo_id(idx); if ( id.is_valid() ) { ++count; idv.push_back(idx); idv.push_back( id.file_id().type_hi_index() ); idv.push_back( id.file_id().lo_index() ); idv.push_back( id.event_id().hi_index() ); idv.push_back( id.event_id().lo_index() ); idv.push_back( id.type().index() ); EdoKey key = id.key(); idv.insert(idv.end(), key.indices().begin(), key.indices().end() ); } } assert( count == size() ); return idv; } //********************************************************************** // Free functions. //********************************************************************** // Ouput stream. ostream& operator<<(ostream& lhs, const EdoIdContext& rhs) { lhs << "Context has " << rhs.size() << " entr"; if ( rhs.size() == 0 ) { lhs << "ies."; } else if ( rhs.size() == 1 ) { lhs << "y:"; } else { lhs << "ies:"; } Index count = 0; for ( Index idx=1; idx<=rhs.max_allowed_index(); ++idx ) { EdoId id = rhs.edo_id(idx); if ( id.is_valid() ) { ++count; lhs << '\n' << setw(8) << idx << " " << id; } } if ( count != rhs.size() ) { cout << endl; cout << "Error: size = " << rhs.size() << " but count = " << count << "!"; assert(false); } return lhs; } //**********************************************************************