LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-analytics/contrail-query-engine - db_query.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 248 275 90.2 %
Date: 2026-11-09 02:10:49 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include <boost/tuple/tuple.hpp>
       7             : #include <boost/foreach.hpp>
       8             : #include "query.h"
       9             : #include "stats_query.h"
      10             : #include "base/work_pipeline.h"
      11             : 
      12             : /*
      13             :  * This function performs GetRowAsync for each row key
      14             :  * Input: It takes rowkeys for which we have to get col
      15             :           values.Multiple instances execute this call
      16             :           simultaneously and possibly multiple times(steps)
      17             :           The instances store intermediate result in exts
      18             :           res stores consolidated result/instance
      19             :  * Ouput: Keeps calling itself for as many rowkeys involved
      20             :           Returns NULL if no more row key to be queried
      21             : */
      22      216135 : ExternalBase::Efn DbQueryUnit::QueryExec(uint32_t inst,
      23             :     const vector<q_result *> & exts,
      24             :     const Input & inp, Stage0Out & res) {
      25             : 
      26      216135 :     uint32_t step = exts.size();
      27      216238 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
      28      216238 :     Input & cinp = const_cast<Input &> (inp);
      29             :     // Previous row fetch resulted in error, dont issue any more requests
      30      216238 :     if (query_fetch_error) {
      31         360 :         return NULL;
      32             :     }
      33      217021 :     if (step) {
      34      215200 :         res.query_result.insert(res.query_result.end(),
      35      107610 :                                 exts[step-1]->begin(),
      36      107661 :                                 exts[step-1]->end());
      37             :     }
      38      216763 :     res.current_row = cinp.row_count.fetch_add(1);
      39      216763 :     const uint32_t current_row = res.current_row;
      40             :     // continue as long as we have not reached end of rows
      41      216763 :     if (current_row < inp.total_rows) {
      42             :         // Frame the getrow context
      43      108358 :         GetRowInput *ip_ctx = new GetRowInput();
      44      108257 :         ip_ctx->rowkey = cinp.keys[current_row];
      45      108036 :         ip_ctx->cfname = cinp.cf_name;
      46      108078 :         ip_ctx->crange = cinp.cr;
      47      108062 :         ip_ctx->where_vec = cinp.where_vec;
      48      108102 :         ip_ctx->chunk_no = m_query->parallel_batch_num;
      49      108102 :         ip_ctx->qid = m_query->query_id;
      50      108228 :         ip_ctx->sub_qid = sub_query_id;
      51      108228 :         ip_ctx->row_no = current_row;
      52      108228 :         ip_ctx->inst = inst;
      53      215849 :         return boost::bind(&DbQueryUnit::PipelineCb, this, cinp.cf_name,
      54      216386 :             cinp.keys[current_row], cinp.cr, cinp.where_vec, ip_ctx, _1);
      55             :     } else {
      56             :         // done processing fetching all rows
      57      108273 :         return NULL;
      58             :     }
      59             : }
      60             : 
      61      108088 : bool DbQueryUnit::PipelineCb(std::string &cfname, GenDb::DbDataValueVec &rowkey,
      62             :                            const GenDb::ColumnNameRange &cr,
      63             :                            GenDb::WhereIndexInfoVec &where_vec,
      64             :                            GetRowInput * ip_ctx, void *privdata) {
      65             : 
      66             :     // prepend T2: to value in each tuple in where_vec
      67      108088 :     std::string T2_string = GenDb::DbDataValueToString(rowkey.at(0));
      68      321462 :     BOOST_FOREACH(GenDb::WhereIndexInfo &where_info, where_vec) {
      69      106695 :         std::string value = GenDb::DbDataValueToString(where_info.get<2>());
      70      106648 :         if (boost::starts_with(value, "%")) {
      71        1583 :             continue;
      72             :         }
      73      105031 :         std::ostringstream where_oss;
      74      104809 :         where_oss << T2_string << ":" << value;
      75      105217 :         where_info.get<2>() = where_oss.str();
      76      106707 :     }
      77             :     /*
      78             :      *  Call GetRowAsync, with args prepopulated
      79             :      */
      80      108344 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
      81      216280 :     return m_query->dbif_->Db_GetRowAsync(cfname, rowkey, cr, where_vec,
      82             :         GenDb::DbConsistency::LOCAL_ONE,
      83      216015 :         boost::bind(&DbQueryUnit::cb, this, _1, _2, ip_ctx, privdata));
      84      108052 : }
      85             : 
      86             : /*
      87             :  * This function merges all the instance's results into the res
      88             :  */
      89        1802 : bool DbQueryUnit::QueryMerge(const std::vector<boost::shared_ptr<Stage0Out> >
      90             :                                   & subs,
      91             :                              const boost::shared_ptr<Input> & inp,
      92             :                              Output & res) {
      93             :     // Merge all the instances result. Each instance is a vector of
      94             :     // query_results from steps
      95        3603 :     res.query_result = boost::shared_ptr<std::vector<query_result_unit_t> >
      96        3603 :                                (new std::vector<query_result_unit_t>());
      97        1801 :     for (vector<boost::shared_ptr<Stage0Out> >::const_iterator it =
      98      111595 :              subs.begin(); it!=subs.end(); it++) {
      99      323959 :         res.query_result->insert(res.query_result->end(),
     100      107986 :                                 (*it)->query_result.begin(),
     101      107998 :                                 (*it)->query_result.end());
     102             :     }
     103        1801 :     return true;
     104             : }
     105             : 
     106             : /*
     107             :  * This function populates the rowkeys that have to be used
     108             :  * in querying.It populates it based on the cftype and the t2
     109             :  * and t1 values
     110             :  */
     111        1802 : std::vector<GenDb::DbDataValueVec> DbQueryUnit::populate_row_keys() {
     112        1802 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
     113        1802 :     uint32_t t2_start = m_query->from_time() >> g_viz_constants.RowTimeInBits;
     114        1802 :     uint32_t t2_end = m_query->end_time() >> g_viz_constants.RowTimeInBits;
     115             : 
     116        1802 :     if (m_query->is_object_table_query(m_query->table()))
     117             :     {
     118             :         GenDb::DbDataValue timestamp_start =
     119        1056 :             (uint32_t)std::numeric_limits<int32_t>::min();
     120        1056 :         cr.start_.push_back(timestamp_start);
     121        1055 :     }
     122             :     GenDb::DbDataValue timestamp_end =
     123        1801 :         (uint32_t)std::numeric_limits<int32_t>::max();
     124        1801 :     cr.finish_.push_back(timestamp_end);
     125             : 
     126        1801 :     std::vector<GenDb::DbDataValueVec> keys;    // vector of keys for multi-row get
     127        1801 :     GenDb::ColListVec mget_res;   // vector of result for each row
     128       15608 :     for (uint32_t t2 = t2_start; t2 <= t2_end; t2++)
     129             :     {
     130       13806 :         GenDb::ColList result;
     131       13806 :         GenDb::DbDataValueVec rowkey;
     132             : 
     133       13807 :         rowkey.push_back(t2);
     134       13786 :         if (m_query->is_stat_table_query(m_query->table())) {
     135        1716 :             uint8_t partition_no = 0;
     136        1716 :             rowkey.push_back(partition_no);
     137             :         }
     138       41422 :         if (m_query->is_flow_query(m_query->table()) ||
     139       27588 :                 m_query->is_session_query(m_query->table())) {
     140        3139 :             for (uint8_t part_no = (uint8_t)g_viz_constants.PARTITION_MIN;
     141        3139 :                      part_no < (uint8_t)g_viz_constants.PARTITION_MAX + 1;
     142             :                      part_no++) {
     143        2825 :                 GenDb::DbDataValueVec tmp_rowkey(rowkey);
     144        2810 :                 tmp_rowkey.push_back(part_no);
     145        2803 :                 if (m_query->is_flow_query(m_query->table())) {
     146        1604 :                     for (uint8_t is_si = 0; is_si < 2; is_si++) {
     147        1072 :                         GenDb::DbDataValueVec tmp_rowkey2(tmp_rowkey);
     148        1062 :                         tmp_rowkey2.push_back(is_si);
     149        1062 :                         for (GenDb::DbDataValueVec::iterator it =
     150        3189 :                                 row_key_suffix.begin(); it!=row_key_suffix.end();
     151        1066 :                                 it++) {
     152        1062 :                             GenDb::DbDataValueVec tmp_rowkey3(tmp_rowkey2);
     153        1064 :                             tmp_rowkey3.push_back(*it);
     154        1072 :                             keys.push_back(tmp_rowkey3);
     155        1072 :                         }
     156        1065 :                     }
     157             :                 } else {
     158        2279 :                     for (GenDb::DbDataValueVec::iterator it =
     159        9095 :                             row_key_suffix.begin(); it!=row_key_suffix.end();
     160        4541 :                             it++) {
     161        4540 :                         tmp_rowkey.push_back(*it);
     162             :                     }
     163        2272 :                     keys.push_back(tmp_rowkey);
     164             :                 }
     165        2817 :             }
     166             :         } else {
     167       13514 :             if (!t_only_row)
     168             :             {
     169        2046 :                 for (GenDb::DbDataValueVec::iterator it =
     170        6964 :                         row_key_suffix.begin(); it!=row_key_suffix.end();
     171        2871 :                         it++) {
     172        2878 :                     rowkey.push_back(*it);
     173             :                 }
     174             :             }
     175             : 
     176             :             // If querying message_index_tables, partition_no is an
     177             :             // additional row_key
     178             :             // It spans values 0..15
     179       13491 :             if (t_only_col) {
     180      112616 :                 for (uint8_t part_no = (uint8_t)g_viz_constants.PARTITION_MIN;
     181      112616 :                          part_no < (uint8_t)g_viz_constants.PARTITION_MAX + 1;
     182             :                          part_no++) {
     183      101472 :                     GenDb::DbDataValueVec tmp_rowkey(rowkey);
     184      100482 :                     tmp_rowkey.push_back(part_no);
     185      100681 :                     keys.push_back(tmp_rowkey);
     186      100739 :                 }
     187             :             } else {
     188        2030 :                 keys.push_back(rowkey);
     189             :             }
     190             :         }
     191       13499 :     }
     192        3604 :     return keys;
     193        1802 : }
     194             : 
     195             : /*
     196             :  * This function calls the GetRowAsync based on the input
     197             :  * passed to it. It creates a pipeline which executes
     198             :  * the multiple GetRow calls asynchronously. It also
     199             :  * provides a callback which is used to collect the
     200             :  * results from the GetRow operation
     201             :  */
     202        1802 : query_status_t DbQueryUnit::process_query()
     203             : {
     204        1802 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
     205        1802 :     uint32_t t2_start = m_query->from_time() >> g_viz_constants.RowTimeInBits;
     206        1802 :     uint32_t t2_end = m_query->end_time() >> g_viz_constants.RowTimeInBits;
     207             : 
     208        1802 :     QE_TRACE(DEBUG,  " Async Database query for " <<
     209             :             (t2_end - t2_start + 1) << " rows");
     210        1802 :     QE_TRACE(DEBUG,  " Async Database query for T2_start:"
     211             :             << t2_start
     212             :             << " T2_end:" << t2_end
     213             :             << " cf:" << cfname
     214             :             << " where_vec size:" << where_vec.size()
     215             :             << " column_start size:" << cr.start_.size()
     216             :             << " column_end size:" << cr.finish_.size()
     217             :             << " where_vec size:" << where_vec.size());
     218        1802 :     std::vector<GenDb::DbDataValueVec> keys = populate_row_keys();
     219             : 
     220             :     /* Create a pipeline to fetch all rows corresponding to keys */
     221        1802 :     int max_tasks = keys.size();
     222        1802 :     std::vector<std::pair<int,int> > tinfo;
     223      110566 :     for (uint idx=0; idx<(uint)max_tasks; idx++) {
     224      108764 :         tinfo.push_back(make_pair(0, -1));
     225             :     }
     226             : 
     227             :     QEPipeT * wp = new QEPipeT(
     228        3604 :         new WorkStage<Input, Output, q_result, Stage0Out>(
     229             :             tinfo,
     230             :             boost::bind(&DbQueryUnit::QueryExec, this, _1, _2, _3, _4),
     231        1802 :             boost::bind(&DbQueryUnit::QueryMerge, this, _1, _2, _3)));
     232             : 
     233             :     // Populate the input to the pipeline
     234        1802 :     boost::shared_ptr<Input> inp(new Input());
     235        1802 :     inp.get()->row_count = 0;
     236        1802 :     inp.get()->total_rows = keys.size();
     237        1802 :     inp.get()->cf_name = cfname;
     238        1802 :     inp.get()->cr = cr;
     239        1802 :     inp.get()->where_vec = where_vec;
     240        1802 :     inp.get()->keys = keys;
     241             :     // Start the pipeline with callback and input
     242        1802 :     wp->Start(boost::bind(&DbQueryUnit::WPCompleteCb, this, wp, _1), inp);
     243        1802 :     return QUERY_IN_PROGRESS;
     244        1802 : }
     245             : 
     246             : /*
     247             :  * This is called after getting all the results from
     248             :  * all the row keys. It copies result to the query_result
     249             :  * and deletes the pipeline
     250             :  */
     251        1802 : void DbQueryUnit::WPCompleteCb(QEPipeT *wp, bool ret_code) {
     252        1802 :     boost::shared_ptr<Output> res = wp->Result();
     253             :     //copy pipeline output to DbQueryUnit query_output
     254        1802 :     query_result = (res->query_result);
     255        1802 :     int size = res->query_result->size();
     256        1802 :     QE_TRACE(DEBUG,  " Database query completed with Async "
     257             :             << size << " rows");
     258             :     // Have the result ready and processing is done
     259             :     // sort the result before returning
     260        1802 :     std::sort(query_result->begin(), query_result->end());
     261        1802 :     if (IS_TRACE_ENABLED(WHERE_RESULT_TRACE)) {
     262           0 :         std::stringstream ss;
     263           0 :         for (std::vector<query_result_unit_t>::const_iterator it =
     264           0 :              query_result->begin(); it != query_result->end(); it++) {
     265           0 :             const query_result_unit_t &result_unit(*it);
     266           0 :             ss << "T: " << result_unit.timestamp << ": ";
     267           0 :             for (GenDb::DbDataValueVec::const_iterator rt =
     268           0 :                  result_unit.info.begin(); rt != result_unit.info.end();
     269           0 :                  rt++) {
     270           0 :                 ss << " " << *rt;
     271             :             }
     272           0 :             ss << std::endl;
     273             :         }
     274           0 :         QE_TRACE(DEBUG, "Result: " << cfname << ": " << ss.str());
     275           0 :     }
     276        1802 :     delete wp;
     277        1802 :     if (ret_code && !query_fetch_error) {
     278        1799 :         status_details = 0;
     279        1799 :         query_status = QUERY_SUCCESS;
     280             :     } else {
     281           3 :         query_status = QUERY_FAILURE;
     282             :     }
     283        1802 :     parent_query->subquery_processed(this);
     284        1802 : }
     285             : 
     286      108443 : void DbQueryUnit::cb(GenDb::DbOpResult::type dresult,
     287             :                      std::auto_ptr<GenDb::ColList> column_list,
     288             :                      GetRowInput * get_row_ctx, void * privdata) {
     289      108443 :     std::unique_ptr<q_result> q_result_ptr(new q_result);
     290      108442 :     std::unique_ptr<GetRowInput>  gri(get_row_ctx);
     291             :     uint32_t t2;
     292      108441 :     uint8_t session_type = 0;
     293      108441 :     uint8_t is_si = 0;
     294      108441 :     AnalyticsQuery *m_query = (AnalyticsQuery *)main_query;
     295      108441 :     QueryEngine *qe = m_query->qe_;
     296             :     try {
     297      108441 :         GenDb::DbDataValueVec val = gri.get()->rowkey;
     298      108424 :         t2 = boost::get<uint32_t>(val.at(0));
     299      108421 :         if (m_query->is_session_query(m_query->table())
     300      108425 :             || m_query->is_flow_query(m_query->table())) {
     301        3383 :             session_type = boost::get<uint8_t>(val.at(3));
     302        3384 :             is_si = boost::get<uint8_t>(val.at(2));
     303             :         }
     304      108424 :     } catch (boost::bad_get& ex) {
     305           0 :         assert(0);
     306             :     }
     307      108414 :     if (dresult != GenDb::DbOpResult::OK) {
     308             :        // Dont issue any more requests
     309          12 :        query_fetch_error = true;
     310          12 :        ExternalProcIf<q_result> * rpi(
     311             :            reinterpret_cast<ExternalProcIf<q_result> *>(privdata));
     312          12 :        if (m_query->is_stat_table_query(m_query->table())) {
     313           4 :             std::scoped_lock lock(qe->smutex_);
     314           4 :             qe->stable_stats_.Update(m_query->stat_name_attr, false, true,
     315             :                 false, 1);
     316           4 :        }
     317          12 :        rpi->Response(std::move(q_result_ptr));
     318          12 :        return;
     319             :     }
     320             :     // Update the reads against the stat
     321      108402 :     if (m_query->is_stat_table_query(m_query->table())) {
     322        1599 :         std::scoped_lock lock(qe->smutex_);
     323        1599 :         qe->stable_stats_.Update(m_query->stat_name_attr, false, false,
     324             :             false, 1);
     325        1599 :     }
     326      108395 :     GenDb::NewColVec::iterator i;
     327             : 
     328      113236 :     for (i = column_list->columns_.begin(); i != column_list->columns_.end();
     329        4811 :          i++) {
     330             :         {
     331        4811 :             query_result_unit_t result_unit;
     332             :             uint32_t t1;
     333        4811 :             if (m_query->is_stat_table_query(m_query->table())) {
     334             :                 try {
     335         221 :                     t1 = boost::get<uint32_t>(i->name->at(i->name->size()-2));
     336           0 :                 } catch (boost::bad_get& ex) {
     337           0 :                     assert(0);
     338             :                 }
     339        4590 :             } else if (m_query->is_session_query(m_query->table())
     340        4590 :                       || m_query->is_flow_query(m_query->table())) {
     341         408 :                 int ts_at = 2;
     342             :                 try {
     343         408 :                     t1 = boost::get<uint32_t>(i->name->at(ts_at));
     344           0 :                 } catch (boost::bad_get& ex) {
     345           0 :                     assert(0);
     346             :                 }
     347             :             } else {
     348             :                 // For MessageIndex tables t1 is stored in the first column
     349             :                 // except for timestamp table
     350        4182 :                 int ts_at = 0;
     351        4182 :                 if (t_only_col) {
     352        4062 :                     ts_at = i->name->size() - 2;
     353             :                 } else {
     354         120 :                     ts_at = i->name->size() - 1;
     355             :                 }
     356        4182 :                 assert(ts_at >= 0);
     357             :                 try {
     358        4182 :                     t1 = boost::get<uint32_t>(i->name->at(ts_at));
     359           0 :                 } catch (boost::bad_get& ex) {
     360           0 :                     assert(0);
     361             :                 }
     362             :             }
     363        4811 :             result_unit.timestamp = TIMESTAMP_FROM_T2T1(t2, t1);
     364             : 
     365        5376 :             if
     366        9383 :             ((result_unit.timestamp < m_query->from_time()) ||
     367        4572 :              (result_unit.timestamp > m_query->end_time()))
     368             :             {
     369             :                 //QE_TRACE(DEBUG, "Discarding timestamp "
     370             :                 //        << result_unit.timestamp);
     371             :                 // got a result outside of the time range
     372         565 :                 continue;
     373             :             }
     374             : 
     375             :            // Add to result vector
     376        4246 :             if (m_query->is_stat_table_query(m_query->table())) {
     377         220 :                 std::string attribstr;
     378             :                 boost::uuids::uuid uuid;
     379             : 
     380             :                 try {
     381         220 :                     uuid = boost::get<boost::uuids::uuid>(i->name->at(i->name->size()-1));
     382           0 :                 } catch (boost::bad_get& ex) {
     383           0 :                     QE_ASSERT(0);
     384           0 :                 } catch (const std::out_of_range& oor) {
     385           0 :                     QE_ASSERT(0);
     386             :                 }
     387             : 
     388             :                 try {
     389         220 :                     attribstr = boost::get<std::string>(i->value->at(i->value->size()-1));
     390           0 :                 } catch (boost::bad_get& ex) {
     391           0 :                     QE_ASSERT(0);
     392           0 :                 } catch (const std::out_of_range& oor) {
     393           0 :                     QE_ASSERT(0);
     394             :                 }
     395             : 
     396         220 :                 result_unit.set_stattable_info(
     397             :                     attribstr,
     398             :                     uuid);
     399        4246 :             } else if (m_query->is_session_query(m_query->table())
     400        4026 :                       || m_query->is_flow_query(m_query->table())) {
     401         243 :                 result_unit.info.clear();
     402         243 :                 result_unit.info.push_back(is_si);
     403         243 :                 result_unit.info.push_back(session_type);
     404         243 :                 result_unit.info.push_back(i->name->at(0));
     405         243 :                 result_unit.info.push_back(i->name->at(1));
     406         243 :                 result_unit.info.push_back(i->name->at(2));
     407         243 :                 result_unit.info.push_back(i->name->at(3));
     408         243 :                 GenDb::DbDataValueVec::const_iterator itr;
     409             :                 GenDb::DbDataValueVec::const_iterator end =
     410         243 :                     (m_query->selectquery_->unroll_needed?
     411         243 :                         (i->value->end()):(i->value->end() - 1));
     412        7155 :                 for (itr = i->value->begin(); itr != end;
     413        6912 :                     itr++) {
     414        6912 :                     result_unit.info.push_back(*itr);
     415             :                 }
     416             :             } else {
     417             :                 // If message index table uuid is not the value, but
     418             :                 // column name
     419        3783 :                 if (t_only_col) {
     420        3664 :                     GenDb::DbDataValueVec val = gri.get()->rowkey;
     421        3664 :                     message_table_query_get_row(val, i, result_unit);
     422        3664 :                 } else {
     423         119 :                     result_unit.info = *i->value;
     424             :                 }
     425             :             }
     426        4245 :             q_result_ptr->push_back(result_unit);
     427        4811 :         }
     428             : 
     429             :     }
     430      108410 :     if (privdata) {
     431      108412 :         ExternalProcIf<q_result> * rpi(
     432             :             reinterpret_cast<ExternalProcIf<q_result> *>(privdata));
     433      108412 :         rpi->Response(std::move(q_result_ptr));
     434             :     }
     435             : 
     436      108455 : }
     437             : 
     438        3664 : void DbQueryUnit::message_table_query_get_row(
     439             :                                 GenDb::DbDataValueVec const &val,
     440             :                                 GenDb::NewColVec::iterator const &res_it,
     441             :                                 query_result_unit_t &result_unit) {
     442             :     // cassandra returns fields in the ascending order by column-name.
     443             :     // pushing fields in order as per schema.
     444             :     // key      = rowkey[0]     T2
     445             :     // key2     = rowkey[1]     partition
     446             :     // column1  = name[0]       T1
     447             :     // column2  = name[1]       UUID
     448             :     // column3  = value[10]     T2:Source
     449             :     // column4  = value[11]     T2:Messagetype
     450             :     // column5  = value[12]     T2:ModuleId
     451             :     // column6  = value[13]     T2:<object-type1>:<object-value1>)
     452             :     // column7  = value[14]
     453             :     // column8  = value[15]
     454             :     // column9  = value[16]
     455             :     // column10 = value[0]
     456             :     // column11 = value[1]
     457             :     // column12 = value[2]
     458             :     // column13 = value[3]
     459             :     // column14 = value[4]
     460             :     // column15 = value[5]
     461             :     // column16 = value[6]
     462             :     // column17 = value[7]
     463             :     // column18 = value[8]
     464             :     // column19 = value[9]
     465             :     // DATA     = value[17]
     466        3664 :     result_unit.info.push_back(val.at(0));
     467        3664 :     result_unit.info.push_back(val.at(1));
     468        3664 :     result_unit.info.push_back(res_it->name->at(0));
     469        3664 :     result_unit.info.push_back(res_it->name->at(1));
     470        3664 :     result_unit.info.push_back(res_it->value->at(10));
     471        3664 :     result_unit.info.push_back(res_it->value->at(11));
     472        3664 :     result_unit.info.push_back(res_it->value->at(12));
     473        3664 :     result_unit.info.push_back(res_it->value->at(13));
     474        3664 :     result_unit.info.push_back(res_it->value->at(14));
     475        3664 :     result_unit.info.push_back(res_it->value->at(15));
     476        3664 :     result_unit.info.push_back(res_it->value->at(16));
     477        3664 :     result_unit.info.push_back(res_it->value->at(0));
     478        3664 :     result_unit.info.push_back(res_it->value->at(1));
     479        3664 :     result_unit.info.push_back(res_it->value->at(2));
     480        3664 :     result_unit.info.push_back(res_it->value->at(3));
     481        3664 :     result_unit.info.push_back(res_it->value->at(4));
     482        3664 :     result_unit.info.push_back(res_it->value->at(5));
     483        3664 :     result_unit.info.push_back(res_it->value->at(6));
     484        3664 :     result_unit.info.push_back(res_it->value->at(7));
     485        3663 :     result_unit.info.push_back(res_it->value->at(8));
     486        3664 :     result_unit.info.push_back(res_it->value->at(9));
     487        3664 :     result_unit.info.push_back(res_it->value->at(17));
     488        3664 : }

Generated by: LCOV version 1.14