33
44#define SPLITCODE_VERSION " 0.31.5"
55
6+ #include < atomic>
67#include < string>
78#include < iostream>
89#include < vector>
@@ -84,6 +85,7 @@ struct SplitCode {
8485 thisIsParent = true ;
8586 isNested = false ;
8687 opt_show_not_found = false ;
88+ qc_rows = 0 ;
8789 }
8890
8991 SplitCode (int nFiles, SplitCode* sc) { // nesting
@@ -143,6 +145,7 @@ struct SplitCode {
143145 num_reads_assigned = 0 ;
144146 summary_n_reads_filtered = 0 ;
145147 summary_n_reads_filtered_assigned = 0 ;
148+ qc_rows = 0 ;
146149 this ->summary_file = sc->summary_file ;
147150
148151 this ->trim_5_str = " " ; // Only applies to parent
@@ -216,6 +219,7 @@ struct SplitCode {
216219 no_tags = false ;
217220 thisIsParent = true ;
218221 isNested = false ;
222+ qc_rows = 0 ;
219223 this ->summary_file = summary_file;
220224 this ->trim_5_str = trim_5_str;
221225 this ->trim_3_str = trim_3_str;
@@ -458,13 +462,23 @@ struct SplitCode {
458462 if (do_qc) {
459463 of << " \t " << " \" tag_qc\" : " << " [" << " \n " ;
460464 bool first = true ;
461- for (int i = 0 ; i < qc.size (); i++) {
465+ /* for (int i = 0; i < qc.size(); i++) {
462466 if (qc[i].size() == 0) continue;
463467 for (int j = 0; j < qc[i].size(); j++) {
464468 if (!first) of << ",";
465469 if (!first) of << "\n";
466470 first = false;
467- of << " \t\t {\" tag\" : \" " << names[i] << " \" , \" distance\" : " << j << " , \" count\" : " << qc[i][j] << " }" ;
471+ of << "\t\t{\"tag\": \"" << names[i] << "\", \"distance\": " << j << ", \"count\": " << *(qc[i][j]) << "}";
472+ }
473+ }*/
474+ for (std::size_t i = 0 ; i < qc_rows; ++i) {
475+ for (std::size_t j = 0 ; j < QC_COLS; ++j) {
476+ auto count = qc_at (i, j).load (std::memory_order_relaxed);
477+ if (!first) of << " ,\n " ;
478+ first = false ;
479+ of << " \t\t {\" tag\" : \" " << names[i]
480+ << " \" , \" distance\" : " << j
481+ << " , \" count\" : " << count << " }" ;
468482 }
469483 }
470484 if (!first) of << " \n " ;
@@ -1055,9 +1069,18 @@ struct SplitCode {
10551069 }
10561070 }*/
10571071 if (do_qc) {
1058- qc.resize (names.size ());
1059- for (size_t i = 0 ; i < qc.size (); i++) {
1060- qc[i].resize (4 ,0 );
1072+ /* qc.resize(names.size());
1073+ for (auto &row : qc) {
1074+ row.clear();
1075+ row.reserve(4);
1076+ for (int j = 0; j < 4; ++j) {
1077+ row.emplace_back(std::make_unique<std::atomic<unsigned long long>>(0ULL));
1078+ }
1079+ }*/
1080+ qc_rows = names.size ();
1081+ qc = std::make_unique<std::atomic<unsigned long long >[]>(qc_rows * QC_COLS);
1082+ for (std::size_t i = 0 ; i < qc_rows * QC_COLS; ++i) {
1083+ qc[i].store (0 , std::memory_order_relaxed);
10611084 }
10621085 }
10631086
@@ -1076,6 +1099,10 @@ struct SplitCode {
10761099 init = true ;
10771100 }
10781101
1102+ inline std::atomic<unsigned long long > &qc_at (std::size_t row, std::size_t col) {
1103+ return qc[row * QC_COLS + col];
1104+ }
1105+
10791106 struct VectorHasher {
10801107 size_t operator ()(const std::vector<uint32_t >& v) const {
10811108 uint64_t r = v.size ()-1 ;
@@ -4214,8 +4241,11 @@ struct SplitCode {
42144241 }
42154242 if (do_qc && !u.empty ()) { // Now, store the QC
42164243 for (auto &q : qc_vec) {
4217- auto & qc_ = qc[q.first ];
4218- qc_[q.second > 3 ? 3 : q.second ]++;
4244+ // auto& qc_ = qc[q.first];
4245+ // (*(qc_[q.second > 3 ? 3 : q.second]))++;
4246+ std::size_t row = q.first ;
4247+ std::size_t col = q.second > 3 ? 3 : q.second ;
4248+ qc_at (row, col).fetch_add (1 , std::memory_order_relaxed);
42194249 }
42204250 }
42214251 }
@@ -4945,7 +4975,10 @@ struct SplitCode {
49454975 std::unordered_map<std::vector<uint32_t >, std::string, VectorHasher> groupmapinv_keep;
49464976 std::unordered_map<std::vector<uint32_t >, int , VectorHasher> groupmapinv_discard;
49474977
4948- std::vector<std::vector<uint64_t >> qc; // outer vector index = tag name id; vector indices = tag edit distance; value = count
4978+ // std::vector<std::vector<std::unique_ptr<std::atomic<unsigned long long>>>> qc; // outer vector index = tag name id; vector indices = tag edit distance; value = count
4979+ std::unique_ptr<std::atomic<unsigned long long >[]> qc;
4980+ std::size_t qc_rows;
4981+ static constexpr std::size_t QC_COLS = 4 ;
49494982 bool do_qc; // Should we do QC (i.e. do tag-level statistics?)
49504983
49514984 std::unordered_map<uint32_t ,int > min_finds_map;
0 commit comments