diff --git a/bdsg/include/bdsg/overlays/packed_reference_path_overlay.hpp b/bdsg/include/bdsg/overlays/packed_reference_path_overlay.hpp index 8bbba7ce..80e9d306 100644 --- a/bdsg/include/bdsg/overlays/packed_reference_path_overlay.hpp +++ b/bdsg/include/bdsg/overlays/packed_reference_path_overlay.hpp @@ -40,6 +40,11 @@ class PackedReferencePathOverlay : public PackedPositionOverlay { /// Make a PackedReferencePathOverlay. Do the indexing and compute the /// additional indexes that the base class doesn't have. PackedReferencePathOverlay(const PathHandleGraph* graph, const std::unordered_set& extra_path_names = {}, size_t steps_per_index = 20000000); + + /// Make a PackedReferencePathOverlay with path filtering. + /// If all_paths is true, indexes all paths visible via for_each_path_handle(). + /// If false, indexes only REFERENCE and GENERIC sense paths. + PackedReferencePathOverlay(const PathHandleGraph* graph, bool all_paths); // We assume that tracing out a path is fast in the backing graph, but // finding visits on nodes is slow. We override the reverse lookups to go @@ -49,11 +54,17 @@ class PackedReferencePathOverlay : public PackedPositionOverlay { virtual path_handle_t get_path_handle_of_step(const step_handle_t& step_handle) const; protected: - + + /// Whether to index all paths (true) or only REFERENCE and GENERIC paths (false). + bool all_paths = true; + // PathHandleGraph interface - + + /// Override to filter paths based on all_paths flag. + bool for_each_path_handle_impl(const std::function& iteratee) const; + /// Calls the given function for each step of the given handle on a path. - /// We treat steps as "on" handles in either orientation. + /// We treat steps as "on" handles in either orientation. virtual bool for_each_step_on_handle_impl(const handle_t& handle, const function& iteratee) const; diff --git a/bdsg/src/packed_reference_path_overlay.cpp b/bdsg/src/packed_reference_path_overlay.cpp index 9a0d6daf..f0948c3f 100644 --- a/bdsg/src/packed_reference_path_overlay.cpp +++ b/bdsg/src/packed_reference_path_overlay.cpp @@ -23,6 +23,25 @@ PackedReferencePathOverlay::PackedReferencePathOverlay(const PathHandleGraph* gr this->last_step_to_path_idx.resize(get_thread_count(), 0); } +PackedReferencePathOverlay::PackedReferencePathOverlay(const PathHandleGraph* graph, bool all_paths) + : PackedPositionOverlay(), all_paths(all_paths) { + // Can't use delegating constructor because we need all_paths set before + // index_path_positions runs (it calls for_each_path_handle which uses our override). + this->graph = graph; + this->steps_per_index = 20000000; + index_path_positions(); + this->last_step_to_path_idx.resize(get_thread_count(), 0); +} + +bool PackedReferencePathOverlay::for_each_path_handle_impl(const std::function& iteratee) const { + if (all_paths) { + return graph->for_each_path_handle(iteratee); + } else { + std::unordered_set senses = {PathSense::REFERENCE, PathSense::GENERIC}; + return graph->for_each_path_matching(&senses, nullptr, nullptr, iteratee); + } +} + path_handle_t PackedReferencePathOverlay::get_path_handle_of_step(const step_handle_t& step_handle) const { // this index-scanning logic mimics that in for_each_step_on_handle_impl below // (tradeoff of parallel construction vs faster lookup)