LCOV - code coverage report
Current view: top level - oks/src - index.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 124 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 8 0

            Line data    Source code
       1              : #define _OksBuildDll_
       2              : 
       3              : #include "oks/index.hpp"
       4              : #include "oks/attribute.hpp"
       5              : #include "oks/class.hpp"
       6              : 
       7              : namespace dunedaq {
       8              : namespace oks {
       9              : 
      10              : size_t
      11            0 : OksIndex::get_offset(OksClass *cl, OksAttribute *a)
      12              : {
      13            0 :   OksDataInfo::Map::const_iterator x = cl->p_data_info->find(a->p_name);
      14            0 :   return (x == cl->p_data_info->end()) ? 0 : x->second->offset;
      15              : }
      16              : 
      17              : 
      18            0 : OksIndex::OksIndex(OksClass *cl, OksAttribute *attr) :
      19              :   std::multiset<OksObject *, OksObjectSortBy> (get_offset(cl, attr)),
      20            0 :   c (cl),
      21            0 :   a (attr)
      22              : {
      23            0 :   const char * fname = "OksIndex::OksIndex(OksClass *, OksAttribute *";
      24              : 
      25            0 :   if(!c) {
      26            0 :     Oks::error_msg(fname) << "Can't build index for NIL class\n";
      27              :     return;
      28              :   }
      29              :   
      30            0 :   if(c->get_is_abstract()) {
      31            0 :     Oks::error_msg(fname)
      32            0 :       << "Can't build index for ABSTRACT class \"" << c->get_name() << "\"\n";
      33              :     return;
      34              :   }
      35              : 
      36            0 :   if(!a) {
      37            0 :     Oks::error_msg(fname) << "Can't build index for NIL attribute\n";
      38              :     return;
      39              :   }
      40              : 
      41            0 :   if(c->find_attribute(a->get_name()) == 0) {
      42            0 :     Oks::error_msg(fname)
      43            0 :       << "Can't find attribute \"" << a->p_name << "\" in class \""
      44            0 :       << c->get_name() << "\" to build index.\n";
      45              :     return;
      46              :   }
      47              : 
      48            0 :   if(c->p_indices && c->p_indices->find(a) != c->p_indices->end()) {
      49            0 :     Oks::error_msg(fname)
      50            0 :       << "Class \"" << c->get_name() << "\" already has index for attribute \""
      51            0 :       << a->p_name << "\".\n";
      52              :     return;
      53              :   }
      54              : 
      55            0 :   offset = ((*c->p_data_info)[a->p_name])->offset;
      56              : 
      57            0 :   if(!c->p_indices)
      58            0 :     c->p_indices = new OksIndex::Map();
      59              : 
      60            0 :   (*c->p_indices)[a] = this;
      61              : 
      62            0 :   if(c->p_objects && !c->p_objects->empty()) {
      63            0 :     for(OksObject::Map::iterator i = c->p_objects->begin(); i != c->p_objects->end(); ++i)
      64            0 :       insert((*i).second);
      65              :   }
      66              :   
      67            0 :   std::cout << "Build index for attribute \'" << a->p_name << "\' in class \'" << c->get_name()
      68            0 :             << "\' for " << size() << " instances\n";
      69              : 
      70              : #ifdef DEBUG_INDICES
      71              :   for(int j=0; j<entries(); j++) {
      72              :         OksObject *obj = at(j);
      73              : 
      74              :         std::cout << j << ".\tobject id \'" << obj->GetId() << "\'   "
      75              :                   << "\tvalue: \'" << obj->data[offset] << "\'\n";
      76              :   }
      77              : #endif
      78            0 : }
      79              : 
      80            0 : OksIndex::~OksIndex()
      81              : {
      82            0 :   if(c && a) {
      83            0 :     c->p_indices->erase(a);
      84              : 
      85            0 :     if(c->p_indices->empty()) {
      86            0 :       delete c->p_indices;
      87            0 :       c->p_indices = 0;
      88              :     }
      89              :   }
      90            0 : }
      91              : 
      92              : 
      93              : OksObject*
      94            0 : OksIndex::remove_obj(OksObject *o)
      95              : {
      96            0 :   std::pair<Position, Position> positions = equal_range(o);
      97            0 :   Position i = positions.first;
      98            0 :   Position i2 = positions.second;
      99              : 
     100            0 :   for(; i != i2; ++i) {
     101            0 :     if(o == *i) {
     102            0 :       erase(i);
     103            0 :       return o;
     104              :     }
     105              :   }
     106              : 
     107              :   return 0;
     108              : }
     109              : 
     110              : 
     111              : OksObject *
     112            0 : OksIndex::FindFirst(OksData *d) const
     113              : {
     114            0 :   OksObject test_o(offset, d);
     115              : 
     116            0 :   ConstPosition pos = lower_bound(&test_o);
     117              : 
     118            0 :   if(pos != end()) return *pos;
     119              : 
     120              :   return 0;
     121            0 : }
     122              : 
     123              : 
     124              : void
     125            0 : OksIndex::find_interval(OksData *d, OksQuery::Comparator f, ConstPosition& i1, ConstPosition& i2) const
     126              : {
     127            0 :   i1 = i2 = end();
     128              : 
     129            0 :   if(empty()) return;
     130              : 
     131            0 :   OksObject test_o(offset, d);
     132              : 
     133            0 :   if(f == OksQuery::equal_cmp) {
     134            0 :     i1 = lower_bound(&test_o);
     135              : 
     136            0 :     if(i1 != end()) {
     137            0 :       if((*i1)->data[offset] == *d) {
     138            0 :         i2 = upper_bound(&test_o);
     139              :       }
     140              :       else {
     141            0 :         i2 = i1;
     142              :       }
     143              :     }
     144              :   }
     145            0 :   else if(f == OksQuery::less_or_equal_cmp || f == OksQuery::less_cmp) {
     146            0 :     i1 = begin();
     147              : 
     148            0 :     if(f == OksQuery::less_cmp) {
     149            0 :       i2 = lower_bound(&test_o);
     150              :     }
     151              :     else {
     152            0 :       i2 = upper_bound(&test_o);
     153              :     }
     154              :   }
     155            0 :   else if(f == OksQuery::greater_or_equal_cmp || f == OksQuery::greater_cmp) {
     156            0 :     i2 = end();
     157              :     
     158            0 :     if(f == OksQuery::greater_cmp) {
     159            0 :       i1 = upper_bound(&test_o);
     160              :     }
     161              :     else {
     162            0 :       i1 = lower_bound(&test_o);
     163              :     }
     164              :   }
     165            0 : }
     166              : 
     167              : 
     168              : OksObject::List *
     169            0 : OksIndex::find_all(OksData *d, OksQuery::Comparator f) const
     170              : {
     171            0 :   OksObject::List * olist = 0;
     172              : 
     173            0 :   ConstPosition pos1, pos2;
     174              : 
     175            0 :   find_interval(d, f, pos1, pos2);
     176              : 
     177            0 :   if(pos1 != pos2) {
     178            0 :     olist = new OksObject::List();
     179            0 :     for(;pos1 != pos2; ++pos1) olist->push_back(*pos1);
     180              :   }
     181              : 
     182            0 :   return olist;
     183              : }
     184              : 
     185              : 
     186              : OksObject::List *
     187            0 : OksIndex::find_all(bool andOperation, OksData *d1, OksQuery::Comparator f1, OksData *d2, OksQuery::Comparator f2) const
     188              : {
     189            0 :   OksObject::List * olist = 0;
     190              :   
     191            0 :   ConstPosition a1, b1;
     192              :   
     193            0 :   find_interval(d1, f1, a1, b1);
     194              :   
     195            0 :   if((andOperation == true) && (a1 == b1)) return 0;
     196              :   
     197            0 :   ConstPosition a2, b2;
     198              : 
     199            0 :   find_interval(d2, f2, a2, b2);
     200              : 
     201            0 :   if(andOperation == true) { 
     202            0 :     if(a2 == b2) return 0;
     203              : 
     204              : 
     205              :       //
     206              :       // find intersection ([pos1,pos2] or NIL) of [a1,b1] and [a2,b2]
     207              :       // where begin() <= {a1,b1,a2,b2} <= end())
     208              :       //
     209              :       // (note that a1 and a2 are not equal to end() but b1 nad b2 have to be tested)
     210              :       //
     211              : 
     212            0 :     ConstPosition pos1, pos2;
     213              : 
     214            0 :     if((*a2)->data[offset] <= (*a1)->data[offset]) {
     215            0 :       if((b2 != end()) && ((*b2)->data[offset] < (*a1)->data[offset])) return 0;
     216            0 :       pos1 = a1;
     217              :     }
     218              :     else {
     219            0 :       if((b1 != end()) && (*a2)->data[offset] > (*b1)->data[offset]) return 0;
     220            0 :       pos1 = a2;
     221              :     }
     222              :     
     223            0 :     if(b2 == end() || b1 == end()) {
     224            0 :       pos2 = (b2 != end()) ? b2 : b1;
     225              :     }
     226              :     else
     227            0 :       pos2 = ((*b2)->data[offset] <= (*b1)->data[offset]) ? b2 : b1;
     228              : 
     229            0 :     olist = new OksObject::List();
     230            0 :     for(;pos1 != pos2; ++pos1) olist->push_back(*pos1);
     231              :   }
     232              :   else {
     233            0 :     if(a1 != b1 && a2 == b2) {
     234            0 :       olist = new OksObject::List();
     235            0 :       for(;a1 != b1; ++a1) olist->push_back(*a1);
     236              :     }
     237            0 :     else if(a2 != b2 && a1 == b1) {
     238            0 :       olist = new OksObject::List();
     239            0 :       for(;a2 != b2; ++a2) olist->push_back(*a2);
     240              :     }
     241            0 :     else if(a1 != b1 && a2 != b2) {
     242            0 :       olist = new OksObject::List();
     243              : 
     244              : 
     245              :         //
     246              :         // find union of [a1,b1] and [a2,b2] (i.e. [pos1,pos2] or [a1,b1],[a2,b2])
     247              :         // where begin() <= {a1,b1,a2,b2} <= end())
     248              :         //
     249              :         // (note that a1 and a2 are not equal to end() but b1 nad b2 have to be tested)
     250              :         //
     251              : 
     252            0 :       ConstPosition pos1, pos2;
     253              : 
     254            0 :       if((*a2)->data[offset] <= (*a1)->data[offset]) {
     255            0 :         if(b2 != end() && (*b2)->data[offset] < (*a1)->data[offset]) {
     256            0 :           for(;a2 != b2; ++a2) olist->push_back(*a2);
     257            0 :           for(;a1 != b1; ++a1) olist->push_back(*a1);
     258              : 
     259            0 :           return olist;
     260              :         }
     261              : 
     262            0 :         pos1 = a2;
     263              :       }
     264              :       else {
     265            0 :         if(b1 != end() && (*a2)->data[offset] > (*b1)->data[offset]) {
     266            0 :           for(;a1 != b1; ++a1) olist->push_back(*a1);
     267            0 :           for(;a2 != b2; ++a2) olist->push_back(*a2);
     268              : 
     269              :           return olist;
     270              :         }
     271              :                 
     272            0 :         pos1 = a1;
     273              :       }
     274              : 
     275            0 :       if(b2 == end() || b1 == end()) {
     276            0 :         pos2 = (b2 == end()) ? b2 : b1;
     277              :       }
     278              :       else
     279            0 :         pos2 = ((*b2)->data[offset] >= (*b1)->data[offset]) ? b2 : b1;
     280              : 
     281            0 :       for(;pos1 != pos2; ++pos1) olist->push_back(*pos1);
     282              :     }
     283              :   }
     284              : 
     285              :   return olist;
     286              : }
     287              : 
     288              : } // namespace oks
     289              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1