@@ -211,7 +211,6 @@ id_t GBWTGraph::max_node_id() const {
211
211
return next_id - 1 ;
212
212
}
213
213
214
- // Using undocumented parts of the GBWT interface. --Jouni
215
214
bool GBWTGraph::follow_edges_impl (const handle_t & handle, bool go_left, const std::function<bool (const handle_t &)>& iteratee) const {
216
215
217
216
// Incoming edges correspond to the outgoing edges of the reverse node.
@@ -220,9 +219,12 @@ bool GBWTGraph::follow_edges_impl(const handle_t& handle, bool go_left, const st
220
219
curr = gbwt::Node::reverse (curr);
221
220
}
222
221
223
- gbwt::CompressedRecord record = this ->index ->record (curr);
224
- for (gbwt::rank_type outrank = 0 ; outrank < record.outdegree (); outrank++) {
225
- gbwt::node_type next = record.successor (outrank);
222
+ // Cache the node.
223
+ gbwt::CachedGBWT cache (*(this ->index ), true );
224
+ gbwt::size_type cache_index = cache.findRecord (curr);
225
+
226
+ for (gbwt::rank_type outrank = 0 ; outrank < cache.outdegree (cache_index); outrank++) {
227
+ gbwt::node_type next = cache.successor (cache_index, outrank);
226
228
if (next == gbwt::ENDMARKER) {
227
229
continue ;
228
230
}
@@ -361,15 +363,47 @@ gbwt::BidirectionalState GBWTGraph::bd_find(const std::vector<handle_t>& path) c
361
363
return result;
362
364
}
363
365
364
- // Using undocumented parts of the GBWT interface. --Jouni
365
366
bool GBWTGraph::follow_paths (gbwt::SearchState state, const std::function<bool (const gbwt::SearchState&)>& iteratee) const {
366
- gbwt::CompressedRecord record = this ->index ->record (state.node );
367
- for (gbwt::rank_type outrank = 0 ; outrank < record.outdegree (); outrank++) {
368
- gbwt::node_type next_node = record.successor (outrank);
369
- if (next_node == gbwt::ENDMARKER) {
367
+ gbwt::CachedGBWT cache (*(this ->index ), true );
368
+ return this ->follow_paths (cache, state, iteratee);
369
+ }
370
+
371
+ bool GBWTGraph::follow_paths (gbwt::BidirectionalState state, bool backward, const std::function<bool (const gbwt::BidirectionalState&)>& iteratee) const {
372
+ gbwt::CachedGBWT cache (*(this ->index ), true );
373
+ return this ->follow_paths (cache, state, backward, iteratee);
374
+ }
375
+
376
+ // ------------------------------------------------------------------------------
377
+
378
+ gbwt::SearchState GBWTGraph::find (const gbwt::CachedGBWT& cache, const std::vector<handle_t >& path) const {
379
+ if (path.empty ()) {
380
+ return gbwt::SearchState ();
381
+ }
382
+ gbwt::SearchState result = this ->get_state (cache, path[0 ]);
383
+ for (size_t i = 1 ; i < path.size () && !result.empty (); i++) {
384
+ result = cache.extend (result, handle_to_node (path[i]));
385
+ }
386
+ return result;
387
+ }
388
+
389
+ gbwt::BidirectionalState GBWTGraph::bd_find (const gbwt::CachedGBWT& cache, const std::vector<handle_t >& path) const {
390
+ if (path.empty ()) {
391
+ return gbwt::BidirectionalState ();
392
+ }
393
+ gbwt::BidirectionalState result = this ->get_bd_state (cache, path[0 ]);
394
+ for (size_t i = 1 ; i < path.size () && !result.empty (); i++) {
395
+ result = cache.bdExtendForward (result, handle_to_node (path[i]));
396
+ }
397
+ return result;
398
+ }
399
+
400
+ bool GBWTGraph::follow_paths (const gbwt::CachedGBWT& cache, gbwt::SearchState state, const std::function<bool (const gbwt::SearchState&)>& iteratee) const {
401
+ gbwt::size_type cache_index = cache.findRecord (state.node );
402
+ for (gbwt::rank_type outrank = 0 ; outrank < cache.outdegree (cache_index); outrank++) {
403
+ if (cache.successor (cache_index, outrank) == gbwt::ENDMARKER) {
370
404
continue ;
371
405
}
372
- gbwt::SearchState next_state (next_node, record. LF (state. range , next_node) );
406
+ gbwt::SearchState next_state = cache. cachedExtend (state, cache_index, outrank );
373
407
if (!iteratee (next_state)) {
374
408
return false ;
375
409
}
@@ -378,27 +412,13 @@ bool GBWTGraph::follow_paths(gbwt::SearchState state, const std::function<bool(c
378
412
return true ;
379
413
}
380
414
381
- // Using undocumented parts of the GBWT interface. --Jouni
382
- bool GBWTGraph::follow_paths (gbwt::BidirectionalState state, bool backward, const std::function<bool (const gbwt::BidirectionalState&)>& iteratee) const {
383
- if (backward) {
384
- state.flip ();
385
- }
386
-
387
- gbwt::CompressedRecord record = this ->index ->record (state.forward .node );
388
- for (gbwt::rank_type outrank = 0 ; outrank < record.outdegree (); outrank++) {
389
- gbwt::node_type next_node = record.successor (outrank);
390
- if (next_node == gbwt::ENDMARKER) {
415
+ bool GBWTGraph::follow_paths (const gbwt::CachedGBWT& cache, gbwt::BidirectionalState state, bool backward, const std::function<bool (const gbwt::BidirectionalState&)>& iteratee) const {
416
+ gbwt::size_type cache_index = cache.findRecord (backward ? state.backward .node : state.forward .node );
417
+ for (gbwt::rank_type outrank = 0 ; outrank < cache.outdegree (cache_index); outrank++) {
418
+ if (cache.successor (cache_index, outrank) == gbwt::ENDMARKER) {
391
419
continue ;
392
420
}
393
- gbwt::size_type reverse_offset = 0 ;
394
- gbwt::BidirectionalState next_state = state;
395
- next_state.forward .node = next_node;
396
- next_state.forward .range = record.bdLF (state.forward .range , next_node, reverse_offset);
397
- next_state.backward .range .first += reverse_offset;
398
- next_state.backward .range .second = next_state.backward .range .first + next_state.forward .size () - 1 ;
399
- if (backward) {
400
- next_state.flip ();
401
- }
421
+ gbwt::BidirectionalState next_state = (backward ? cache.cachedExtendBackward (state, cache_index, outrank) : cache.cachedExtendForward (state, cache_index, outrank));
402
422
if (!iteratee (next_state)) {
403
423
return false ;
404
424
}
@@ -443,12 +463,16 @@ void for_each_haplotype_window(const GBWTGraph& graph, size_t window_size,
443
463
444
464
// Traverse all starting nodes in parallel.
445
465
graph.for_each_handle ([&](const handle_t & h) -> bool {
466
+
467
+ // Get a GBWT cache.
468
+ gbwt::CachedGBWT cache = graph.get_cache ();
469
+
446
470
// Initialize the stack with both orientations.
447
471
std::stack<GBWTTraversal> windows;
448
472
size_t node_length = graph.get_length (h);
449
473
for (bool is_reverse : { false , true }) {
450
474
handle_t handle = (is_reverse ? graph.flip (h) : h);
451
- gbwt::SearchState state = graph.get_state (handle);
475
+ gbwt::SearchState state = graph.get_state (cache, handle);
452
476
if (state.empty ()) {
453
477
continue ;
454
478
}
@@ -467,24 +491,21 @@ void for_each_haplotype_window(const GBWTGraph& graph, size_t window_size,
467
491
}
468
492
469
493
// Try to extend the window to all successor nodes.
470
- // We are using undocumented parts of the GBWT interface. --Jouni
471
494
bool extend_success = false ;
472
- gbwt::CompressedRecord record = graph.index ->record (window.state .node );
473
- for (gbwt::rank_type outrank = 0 ; outrank < record.outdegree (); outrank++) {
474
- gbwt::node_type next_node = record.successor (outrank);
475
- if (next_node == gbwt::ENDMARKER) {
495
+ gbwt::size_type cache_index = cache.findRecord (window.state .node );
496
+ for (gbwt::rank_type outrank = 0 ; outrank < cache.outdegree (cache_index); outrank++) {
497
+ if (cache.successor (cache_index, outrank) == gbwt::ENDMARKER) {
476
498
continue ;
477
499
}
478
- gbwt::range_type next_range = record. LF (window.state . range , next_node );
479
- if (gbwt::Range:: empty (next_range )) {
500
+ gbwt::SearchState next_state = cache. cachedExtend (window.state , cache_index, outrank );
501
+ if (next_state. empty ()) {
480
502
continue ;
481
503
}
482
- handle_t next_handle = GBWTGraph::node_to_handle (next_node );
504
+ handle_t next_handle = GBWTGraph::node_to_handle (next_state. node );
483
505
GBWTTraversal next_window = window;
484
506
next_window.traversal .push_back (next_handle);
485
507
next_window.length += std::min (graph.get_length (next_handle), target_length - window.length );
486
- next_window.state .node = next_node;
487
- next_window.state .range = next_range;
508
+ next_window.state = next_state;
488
509
windows.push (next_window);
489
510
extend_success = true ;
490
511
}
0 commit comments