|
1 | 1 | #include <Rcpp/Lightest> |
| 2 | +#include <Rcpp/Interrupt.h> /* for Rcpp::checkUserInterrupt() */ |
2 | 3 | using namespace Rcpp; |
3 | 4 |
|
4 | 5 | #include "../inst/include/TreeTools/assert.h" /* for ASSERT */ |
5 | 6 | #include "../inst/include/TreeTools/ClusterTable.h" /* for ClusterTable */ |
6 | 7 |
|
7 | 8 | #include <algorithm> /* for fill */ |
8 | 9 | #include <array> /* for array */ |
| 10 | +#include <chrono> /* for steady_clock (interrupt timing) */ |
9 | 11 | #include <string> /* for string (hash key) */ |
10 | 12 | #include <unordered_map> /* for unordered_map */ |
11 | 13 |
|
@@ -57,8 +59,18 @@ RawMatrix calc_consensus_tree( |
57 | 59 |
|
58 | 60 | int32 i = 0; |
59 | 61 | int32 splits_found = 0; |
| 62 | + auto lastInterrupt = std::chrono::steady_clock::now(); |
60 | 63 |
|
61 | 64 | do { |
| 65 | + // ~1 s user-interrupt check |
| 66 | + { |
| 67 | + const auto now = std::chrono::steady_clock::now(); |
| 68 | + if (std::chrono::duration_cast<std::chrono::seconds>( |
| 69 | + now - lastInterrupt).count() >= 1) { |
| 70 | + lastInterrupt = now; |
| 71 | + Rcpp::checkUserInterrupt(); |
| 72 | + } |
| 73 | + } |
62 | 74 | if (tables[i].NOSWX(ntip_3)) { |
63 | 75 | continue; |
64 | 76 | } |
@@ -187,8 +199,18 @@ List calc_split_frequencies( |
187 | 199 |
|
188 | 200 | // Reusable key buffer — avoids per-split heap allocation |
189 | 201 | std::string key(nbin, '\0'); |
| 202 | + auto lastInterrupt = std::chrono::steady_clock::now(); |
190 | 203 |
|
191 | 204 | for (int32 i = 0; i < n_trees; ++i) { |
| 205 | + // ~1 s user-interrupt check |
| 206 | + { |
| 207 | + const auto now = std::chrono::steady_clock::now(); |
| 208 | + if (std::chrono::duration_cast<std::chrono::seconds>( |
| 209 | + now - lastInterrupt).count() >= 1) { |
| 210 | + lastInterrupt = now; |
| 211 | + Rcpp::checkUserInterrupt(); |
| 212 | + } |
| 213 | + } |
192 | 214 | if (tables[i].NOSWX(ntip_3)) { |
193 | 215 | continue; |
194 | 216 | } |
|
0 commit comments