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

Generated by: LCOV version 1.14