diff --git a/bdsg/include/bdsg/snarl_distance_index.hpp b/bdsg/include/bdsg/snarl_distance_index.hpp index 211d36bf..9cd60ff2 100644 --- a/bdsg/include/bdsg/snarl_distance_index.hpp +++ b/bdsg/include/bdsg/snarl_distance_index.hpp @@ -813,11 +813,19 @@ class SnarlDistanceIndex : public SnarlDecomposition, public TriviallySerializab * The root vector stores the root of every connected component, which can be a * node, snarl, or chain */ - const static size_t ROOT_RECORD_SIZE = 5; - const static size_t COMPONENT_COUNT_OFFSET = 1; - const static size_t NODE_COUNT_OFFSET = 2; - const static size_t MIN_NODE_ID_OFFSET = 3; - const static size_t MAX_TREE_DEPTH_OFFSET = 4; + const static size_t ROOT_RECORD_SIZE = 6; + const static size_t VERSION_NUMBER_OFFSET = 1; + const static size_t COMPONENT_COUNT_OFFSET = 2; + const static size_t NODE_COUNT_OFFSET = 3; + const static size_t MIN_NODE_ID_OFFSET = 4; + const static size_t MAX_TREE_DEPTH_OFFSET = 5; + + // While the version number is 3, store it in a bit masked way + // to avoid getting confused with old indexes without version numbers + // that start with component count + const static size_t CURRENT_VERSION_NUMBER = 3; + /// Arbitrary large number which doens't overflow the number of bits we give + const static size_t VERSION_NUMBER_SENTINEL = (1 << 10) - 1; /*Node record * - A node record for nodes in snarls/roots. These are interpreted as either trivial chains or nodes. @@ -1123,6 +1131,7 @@ class SnarlDistanceIndex : public SnarlDecomposition, public TriviallySerializab RootRecord (size_t pointer, const bdsg::yomo::UniqueMappedPointer* tree_records); RootRecord (net_handle_t net, const bdsg::yomo::UniqueMappedPointer* tree_records); + size_t get_version_number() const {return VERSION_NUMBER_SENTINEL ^ (*records)->at(record_offset+VERSION_NUMBER_OFFSET);} size_t get_connected_component_count() const {return (*records)->at(record_offset+COMPONENT_COUNT_OFFSET);} size_t get_node_count() const {return (*records)->at(record_offset+NODE_COUNT_OFFSET);} size_t get_max_tree_depth() const {return (*records)->at(record_offset+MAX_TREE_DEPTH_OFFSET);} @@ -1141,6 +1150,8 @@ class SnarlDistanceIndex : public SnarlDecomposition, public TriviallySerializab RootRecordWriter (size_t pointer, size_t connected_component_count, size_t node_count, size_t max_tree_depth, handlegraph::nid_t min_node_id, bdsg::yomo::UniqueMappedPointer* records); + // Doesn't accept a value because it uses CURRENT_VERSION_NUMBER + void set_version_number(); void set_connected_component_count(size_t connected_component_count); void set_node_count(size_t node_count); void set_max_tree_depth(size_t tree_depth); diff --git a/bdsg/src/snarl_distance_index.cpp b/bdsg/src/snarl_distance_index.cpp index 50d3c2b1..2f65b0a0 100644 --- a/bdsg/src/snarl_distance_index.cpp +++ b/bdsg/src/snarl_distance_index.cpp @@ -1064,6 +1064,11 @@ void SnarlDistanceIndex::deserialize(int fd) { //This gets called by TriviallySerializable::deserialize(filename), which //doesn't check for the prefix, so this should expect it snarl_tree_records.load(fd, get_prefix()); + RootRecord root_record (get_root(), &snarl_tree_records); + if (root_record.get_version_number() != CURRENT_VERSION_NUMBER) { + throw runtime_error("error: Trying to load a SnarlDistanceIndex which is not version " + + std::to_string(CURRENT_VERSION_NUMBER) + "; try regenerating the index"); + } } void SnarlDistanceIndex::serialize_members(std::ostream& out) const { @@ -1075,6 +1080,11 @@ void SnarlDistanceIndex::deserialize_members(std::istream& in){ //This gets called by Serializable::deserialize(istream), which has already //read the prefix, so don't expect the prefix snarl_tree_records.load_after_prefix(in, get_prefix()); + RootRecord root_record (get_root(), &snarl_tree_records); + if (root_record.get_version_number() != CURRENT_VERSION_NUMBER) { + throw runtime_error("error: Trying to load a SnarlDistanceIndex which is not version " + + std::to_string(CURRENT_VERSION_NUMBER) + "; try regenerating the index"); + } } uint32_t SnarlDistanceIndex::get_magic_number()const { @@ -4103,11 +4113,19 @@ SnarlDistanceIndex::RootRecordWriter::RootRecordWriter (size_t pointer, size_t c set_node_count(node_count); set_max_tree_depth(max_tree_depth); set_connected_component_count(connected_component_count); + set_version_number(); #ifdef count_allocations cerr << "new_root\t" << (ROOT_RECORD_SIZE + connected_component_count + (node_count*2)) << "\t" << (*records)->siz e() << endl; #endif } +void SnarlDistanceIndex::RootRecordWriter::set_version_number() { +#ifdef debug_distance_indexing + cerr << record_offset+VERSION_NUMBER_OFFSET << " set version number to be " << CURRENT_VERSION_NUMBER << endl; + assert((*records)->at(record_offset+VERSION_NUMBER_OFFSET) == 0); +#endif + (*records)->at(record_offset+VERSION_NUMBER_OFFSET) = VERSION_NUMBER_SENTINEL ^ CURRENT_VERSION_NUMBER; +} void SnarlDistanceIndex::RootRecordWriter::set_connected_component_count(size_t connected_component_count) { #ifdef debug_distance_indexing