(file) Return to CMPI_Wql2Dnf.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManager2 / CMPI

  1 schuur 1.1 //%2003////////////////////////////////////////////////////////////////////////
  2            //
  3            // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
  4            // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
  6            // IBM Corp.; EMC Corporation, The Open Group.
  7            //
  8            // Permission is hereby granted, free of charge, to any person obtaining a copy
  9            // of this software and associated documentation files (the "Software"), to
 10            // deal in the Software without restriction, including without limitation the
 11            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 12            // sell copies of the Software, and to permit persons to whom the Software is
 13            // furnished to do so, subject to the following conditions:
 14            //
 15            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 16            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 17            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 18            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 19            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 20            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 21            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 22 schuur 1.1 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 23            //
 24            //==============================================================================
 25            //
 26            // Author:      Markus Mueller (sedgewick_de@yahoo.de)
 27            //
 28            // Modified By: Adrian Schuur, schuur@de.ibm.com
 29            //
 30            //%/////////////////////////////////////////////////////////////////////////////
 31            
 32            
 33 schuur 1.2 #define CMPI_VER_86 1
 34 schuur 1.1 
 35            #include <Pegasus/Common/Array.h>
 36            #include <Pegasus/Common/Stack.h>
 37            #include <Pegasus/WQL/WQLOperation.h>
 38            #include <Pegasus/WQL/WQLOperand.h>
 39            #include <Pegasus/WQL/WQLParser.h>
 40            
 41            #include "CMPI_Wql2Dnf.h"
 42            
 43 schuur 1.4 PEGASUS_USING_STD;
 44 schuur 1.1 PEGASUS_NAMESPACE_BEGIN
 45            
 46            #define PEGASUS_ARRAY_T term_el
 47            # include <Pegasus/Common/ArrayImpl.h>
 48            #undef PEGASUS_ARRAY_T
 49            
 50            #define PEGASUS_ARRAY_T eval_el
 51            # include <Pegasus/Common/ArrayImpl.h>
 52            #undef PEGASUS_ARRAY_T
 53            
 54            #define PEGASUS_ARRAY_T stack_el
 55            # include <Pegasus/Common/ArrayImpl.h>
 56            #undef PEGASUS_ARRAY_T
 57            
 58            #define PEGASUS_ARRAY_T TableauRow
 59            # include <Pegasus/Common/ArrayImpl.h>
 60            #undef PEGASUS_ARRAY_T
 61            
 62            
 63            //
 64            // Terminal element methods 
 65 schuur 1.1 //
 66            void term_el::negate(void)
 67            {
 68                switch (op)
 69                {
 70                    case WQL_EQ: op = WQL_NE; break;
 71                    case WQL_NE: op = WQL_EQ; break;
 72                    case WQL_LT: op = WQL_GE; break;
 73                    case WQL_LE: op = WQL_GT; break;
 74                    case WQL_GT: op = WQL_LE; break;
 75                    case WQL_GE: op = WQL_LT; break;
 76                    default: break;
 77                }
 78            };
 79            
 80            String opnd2string(const WQLOperand &o) {
 81                switch (o.getType()) {
 82                case WQLOperand::PROPERTY_NAME:
 83                   return o.getPropertyName();
 84                case WQLOperand::STRING_VALUE:
 85                   return o.getStringValue();
 86 schuur 1.1     case WQLOperand::INTEGER_VALUE:
 87                   return Formatter::format("$0",o.getIntegerValue());
 88                case WQLOperand::DOUBLE_VALUE:
 89                   return Formatter::format("$0",o.getDoubleValue());
 90                case WQLOperand::BOOLEAN_VALUE:
 91                   return Formatter::format("$0",o.getBooleanValue());
 92                default: ;
 93               }
 94 schuur 1.3    return "NULL_VALUE";
 95 schuur 1.1 }
 96            
 97            
 98            CMPIPredOp mapOperation(WQLOperation op) {
 99               static CMPIPredOp ops[]={(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,
100                  CMPI_PredOp_Equals,
101                  CMPI_PredOp_NotEquals,
102                  CMPI_PredOp_LessThan,
103                  CMPI_PredOp_LessThanOrEquals,
104                  CMPI_PredOp_GreaterThan,
105                  CMPI_PredOp_GreaterThanOrEquals,
106                  (CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0,(CMPIPredOp)0};
107               return ops[(int)op];
108 schuur 1.3 }
109 schuur 1.1 
110            CMPIType mapType(WQLOperand::Type typ) {
111               switch (typ) {
112                case WQLOperand::PROPERTY_NAME:
113                   return CMPI_nameString;
114                case WQLOperand::STRING_VALUE:
115                   return CMPI_charString;
116                case WQLOperand::INTEGER_VALUE:
117                   return CMPI_integerString;
118                case WQLOperand::DOUBLE_VALUE:
119                   return CMPI_realString;
120                case WQLOperand::BOOLEAN_VALUE:
121                   return CMPI_booleanString;
122                case WQLOperand::NULL_VALUE:
123                   return CMPI_null;
124              }
125              return CMPI_null;
126            }
127            
128            int term_el::toStrings(CMPIType &typ, CMPIPredOp &opr, String &o1, String &o2) const {
129               opr=mapOperation(op);
130 schuur 1.1    o1=opnd2string(opn1);
131 schuur 1.3    o2=opnd2string(opn2);
132 schuur 1.1    if (opn1.getType()==WQLOperand::PROPERTY_NAME) typ=mapType(opn2.getType());
133               else typ=mapType(opn1.getType());
134               return 0;
135            }
136            
137            //
138 schuur 1.3 // Evaluation heap element methods
139 schuur 1.1 //
140 schuur 1.3 stack_el eval_el::getFirst() 
141            { 
142               return stack_el(opn1, is_terminal1);
143            }
144 schuur 1.1 
145 schuur 1.3 stack_el eval_el::getSecond()
146            {
147               return stack_el(opn2, is_terminal2);
148            }
149 schuur 1.1 
150            void eval_el::setFirst(const stack_el s)
151            {
152                 opn1 = s.opn;
153                 is_terminal1 = s.is_terminal;
154            }
155 schuur 1.3 
156 schuur 1.1 void eval_el::setSecond(const stack_el s)
157            {
158                opn2 = s.opn;
159                is_terminal2 = s.is_terminal;
160            }
161 schuur 1.3 
162 schuur 1.1 void eval_el::assign_unary_to_first(const eval_el & assignee)
163            {
164                opn1 = assignee.opn1;
165                is_terminal1 = assignee.is_terminal1;
166            }
167            
168            void eval_el::assign_unary_to_second(const eval_el & assignee)
169            {
170                opn2 = assignee.opn1;
171                is_terminal2 = assignee.is_terminal1;
172            }
173            
174            // Ordering operators, so that op1 > op2 for all non-terminals
175            // and terminals appear in the second operand first
176 schuur 1.3 void eval_el::order(void)
177 schuur 1.1 {
178                int k;
179                if ((!is_terminal1) && (!is_terminal2))
180                    if ((k = opn2) > opn1)
181                    {
182                        opn2 = opn1;
183                        opn1 =  k;
184                    }
185                else if ((is_terminal1) && (!is_terminal2))
186                    if ((k = opn2) > opn1)
187                    {
188                        opn2 = opn1;
189                        opn1 =  k;
190                        is_terminal1 = false;
191                        is_terminal2 = true;
192                    }
193            }
194            
195            //
196            // Helper function copied from WQLSelectStatement
197            // 
198 schuur 1.1 
199            template<class T>
200            inline static Boolean _Compare(const T& x, const T& y, WQLOperation op)
201            {
202                switch (op)
203                {
204                    case WQL_EQ: 
205                        return x == y;
206            
207                    case WQL_NE: 
208                        return x != y;
209            
210                    case WQL_LT: 
211                        return x < y;
212                    case WQL_LE: 
213                        return x <= y;
214            
215                    case WQL_GT: 
216                        return x > y;
217            
218                    case WQL_GE: 
219 schuur 1.1             return x >= y;
220            
221                    default:
222                        PEGASUS_ASSERT(0);
223                }
224            
225                return false;
226            }
227            
228            static bool operator==(const WQLOperand& x, const WQLOperand& y)
229            {
230               if (x.getType()==y.getType()) switch (x.getType()) {
231               case WQLOperand::PROPERTY_NAME:
232                  return x.getPropertyName()==y.getPropertyName();
233               case WQLOperand::INTEGER_VALUE:
234                  return x.getIntegerValue()==y.getIntegerValue();
235               case WQLOperand::DOUBLE_VALUE:
236                  return x.getDoubleValue()==y.getDoubleValue();
237               case WQLOperand::BOOLEAN_VALUE:
238                  return x.getBooleanValue()==y.getBooleanValue();
239               case WQLOperand::STRING_VALUE:
240 schuur 1.1       return x.getStringValue()==y.getStringValue();
241               case WQLOperand::NULL_VALUE: 
242                  return true;
243               }
244               return false;
245            }
246            
247            static bool operator==(const term_el& x, const term_el& y)
248            {
249            	return x.op == y.op && 
250            	   x.opn1 == y.opn1 && 
251            	   x.opn2 == y.opn2;
252            }
253            
254            static void addIfNotExists(TableauRow &tr, const term_el& el)
255            {
256               for (int i=0,m=tr.size(); i<m; i++) {
257                  if (tr[i]==el) return;
258               }
259               tr.append(el);
260            }
261 schuur 1.1 
262            
263            static Boolean _Evaluate(
264                const WQLOperand& lhs, 
265                const WQLOperand& rhs, 
266                WQLOperation op)
267            {
268                switch (lhs.getType())
269                {
270                    case WQLOperand::NULL_VALUE:
271                    {
272                        // This cannot happen since expressions of the form
273                        // OPERAND OPERATOR NULL are converted to unary form.
274                        // For example: "count IS NULL" is treated as a unary
275                        // operation in which IS_NULL is the unary operation
276                        // and count is the the unary operand.
277            
278                        PEGASUS_ASSERT(0);
279                        break;
280                    }
281            
282 schuur 1.1         case WQLOperand::INTEGER_VALUE:
283                    {
284                        return _Compare(
285                            lhs.getIntegerValue(),
286                            rhs.getIntegerValue(),
287                            op);
288                    }
289            
290                    case WQLOperand::DOUBLE_VALUE:
291                    {
292                        return _Compare(
293                            lhs.getDoubleValue(),
294                            rhs.getDoubleValue(),
295                            op);
296                    }
297            
298                    case WQLOperand::BOOLEAN_VALUE:
299                    {
300                        return _Compare(
301                            lhs.getBooleanValue(),
302                            rhs.getBooleanValue(),
303 schuur 1.1                 op);
304                    }
305            
306                    case WQLOperand::STRING_VALUE:
307                    {
308                        return _Compare(
309                            lhs.getStringValue(),
310                            rhs.getStringValue(),
311                            op);
312                    }
313            
314                    default:
315                        PEGASUS_ASSERT(0);
316                }
317            
318                return false;
319            }
320            
321            
322            //
323            // WQL Compiler methods
324 schuur 1.1 //
325                
326            CMPI_Wql2Dnf::CMPI_Wql2Dnf(const String condition, const String pref) 
327            {
328                WQLSelectStatement wqs;
329                WQLParser::parse(pref+condition,wqs);
330                eval_heap.reserveCapacity(16);
331                terminal_heap.reserveCapacity(16);
332                _tableau.clear();
333                compile(&wqs);
334            }
335            
336            CMPI_Wql2Dnf::CMPI_Wql2Dnf() 
337            {
338                eval_heap.reserveCapacity(16);
339                terminal_heap.reserveCapacity(16);
340                _tableau.clear();
341            }
342            
343            CMPI_Wql2Dnf::CMPI_Wql2Dnf(const WQLSelectStatement & wqs)
344            {
345 schuur 1.1     eval_heap.reserveCapacity(16);
346                terminal_heap.reserveCapacity(16);
347                _tableau.clear();
348                compile(&wqs);
349            }
350            
351            CMPI_Wql2Dnf::CMPI_Wql2Dnf(const WQLSelectStatement * wqs)
352            {
353                eval_heap.reserveCapacity(16);
354                terminal_heap.reserveCapacity(16);
355                _tableau.clear();
356                compile(wqs);
357            }
358            
359            CMPI_Wql2Dnf::~CMPI_Wql2Dnf() {}
360            
361            void CMPI_Wql2Dnf::compile(const WQLSelectStatement * wqs)
362            {
363                if (!wqs->hasWhereClause()) return;
364                _tableau.clear();
365            
366 schuur 1.1     _buildEvalHeap(wqs);
367                _pushNOTDown();
368                _factoring();
369                
370                Array<stack_el> disj;
371                _gatherDisj(disj);
372                if (disj.size() == 0)
373                    if (terminal_heap.size() > 0)
374                       // point to the remaining terminal element
375 schuur 1.3             disj.append(stack_el(0,true));
376 schuur 1.1 
377                for (Uint32 i=0, n =disj.size(); i< n; i++)
378                {
379                    TableauRow tr;
380                    Array<stack_el> conj;
381            
382                    if (!disj[i].is_terminal)
383                    {
384                       _gatherConj(conj, disj[i]);
385                        for( Uint32 j=0, m = conj.size(); j < m; j++)
386            	        addIfNotExists(tr,terminal_heap[conj[j].opn]);
387            //                tr.append(terminal_heap[conj[j].opn]);
388                    }
389                    else
390            	   addIfNotExists(tr,terminal_heap[disj[i].opn]);
391            //	   tr.append(terminal_heap[disj[i].opn]);
392                    _tableau.append(tr);
393                }
394            
395                eval_heap.clear();
396                   
397 schuur 1.1     //print();
398                printTableau();
399                //_sortTableau();
400            }
401            
402            Boolean CMPI_Wql2Dnf::evaluate(WQLPropertySource * source) const
403            {
404               Boolean b = false;
405               WQLOperand lhs, rhs;
406            
407               for(Uint32 i=0,n = _tableau.size(); i < n; i++)
408               {
409                   TableauRow tr = _tableau[i];
410                   for(Uint32 j=0,m = tr.size(); j < m; j++)
411                   {
412                       lhs = tr[j].opn1;
413                       CMPI_Wql2Dnf::_ResolveProperty(lhs,source);
414                       rhs = tr[j].opn2;
415                       CMPI_Wql2Dnf::_ResolveProperty(rhs,source);
416            
417                       if (rhs.getType() != lhs.getType())
418 schuur 1.1                throw TypeMismatchException();
419            
420                       if (!_Evaluate(lhs, rhs, tr[j].op))
421                       {
422                           b = false;
423                           break;
424                       }
425                       else
426                           b = true;
427                   }
428                   if (b) return true;
429               }
430               return false;
431            }
432            
433            void CMPI_Wql2Dnf::print(void)
434            {
435 schuur 1.3 for (Uint32 i=0, n=eval_heap.size();i < n;i++) {
436                WQLOperation wop = eval_heap[i].op;
437 schuur 1.1     if (wop == WQL_IS_TRUE) continue;
438 schuur 1.4     cout << "Eval element " << i << ": ";
439                if (eval_heap[i].is_terminal1) cout << "T(";
440                else cout << "E(";
441                cout << eval_heap[i].opn1 << ") ";
442                cout << WQLOperationToString(eval_heap[i].op);
443                if (eval_heap[i].is_terminal2) cout << " T(";
444                else cout << " E(";
445                cout << eval_heap[i].opn2 << ")" << endl;
446 schuur 1.3 }
447            for (Uint32 i=0, n=terminal_heap.size();i < n;i++) {
448 schuur 1.4     cout << "Terminal expression " << i << ": ";
449                cout << terminal_heap[i].opn1.toString() << " ";
450                cout << WQLOperationToString(terminal_heap[i].op) << " "
451                     << terminal_heap[i].opn2.toString() << endl;
452 schuur 1.1 }
453            }
454            
455            void CMPI_Wql2Dnf::printTableau(void)
456            {
457               for(Uint32 i=0,n = _tableau.size(); i < n; i++)
458               {
459 schuur 1.4        cout << "Tableau " << i << endl;
460 schuur 1.1        TableauRow tr = _tableau[i];
461                   for(Uint32 j=0,m = tr.size(); j < m; j++)
462                   {
463 schuur 1.4            cout << tr[j].opn1.toString() << " ";
464                       cout << WQLOperationToString(tr[j].op) << " "
465                            << tr[j].opn2.toString() << endl;
466 schuur 1.1        }
467 schuur 1.3 
468 schuur 1.1    }
469            
470            }
471            
472            void CMPI_Wql2Dnf::_buildEvalHeap(const WQLSelectStatement * wqs)
473            {
474            
475                //WQLSelectStatement* that = (WQLSelectStatement*)wqs;
476            
477                WQLOperand dummy;
478                dummy.clear();
479                Stack<stack_el> stack;
480 schuur 1.3 
481 schuur 1.1     // Counter for Operands
482            
483                Uint32 j = 0;
484            
485                //cerr << "Build eval heap\n";
486            
487                for (Uint32 i = 0, n = wqs->_operations.size(); i < n; i++)
488                {
489                    WQLOperation op = wqs->_operations[i];
490            
491                    switch (op)
492                    {
493                        case WQL_OR:
494                        case WQL_AND:
495                        {
496                            PEGASUS_ASSERT(stack.size() >= 2);
497            
498                            stack_el op1 = stack.top();
499                            stack.pop();
500            
501                            stack_el op2 = stack.top();
502 schuur 1.1 
503                            // generate Eval expression
504 schuur 1.3                 eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
505                                             op2.opn , op2.is_terminal));
506 schuur 1.1 
507 schuur 1.3                 stack.top() = stack_el(eval_heap.size()-1, false);
508 schuur 1.1 
509                            break;
510                        }
511            
512                        case WQL_NOT:
513                        case WQL_IS_FALSE:
514                        case WQL_IS_NOT_TRUE:
515                        {
516                            PEGASUS_ASSERT(stack.size() >= 1);
517            
518                            stack_el op1 = stack.top();
519            
520                            // generate Eval expression
521 schuur 1.3                 eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
522                                             -1, true));
523 schuur 1.1 
524 schuur 1.3                 stack.top() = stack_el(eval_heap.size()-1, false);
525 schuur 1.1 
526                            break;
527                        }
528            
529                        case WQL_EQ:
530                        case WQL_NE:
531                        case WQL_LT:
532                        case WQL_LE:
533                        case WQL_GT:
534                        case WQL_GE:
535                        {
536                            PEGASUS_ASSERT(wqs->_operands.size() >= 2);
537            
538                            WQLOperand lhs = wqs->_operands[j++];
539            
540                            WQLOperand rhs = wqs->_operands[j++];
541            
542 schuur 1.3                 terminal_heap.push(term_el(false, op, lhs, rhs));
543 schuur 1.1 
544 schuur 1.3                 stack.push(stack_el(terminal_heap.size()-1, true));
545 schuur 1.1 
546                            break;
547                        }
548            
549                        case WQL_IS_TRUE:
550                        case WQL_IS_NOT_FALSE:
551                        {
552                            PEGASUS_ASSERT(stack.size() >= 1);
553                            break;
554                        }
555            
556                        case WQL_IS_NULL:
557                        {
558                            PEGASUS_ASSERT(wqs->_operands.size() >= 1);
559                            WQLOperand op = wqs->_operands[j++];
560            
561 schuur 1.3                 terminal_heap.push(term_el(false, WQL_EQ, op, dummy));
562 schuur 1.1 
563 schuur 1.3                 stack.push(stack_el(terminal_heap.size()-1, true));
564 schuur 1.1 
565                            break;
566                        }
567            
568                        case WQL_IS_NOT_NULL:
569                        {
570                            PEGASUS_ASSERT(wqs->_operands.size() >= 1);
571                            WQLOperand op = wqs->_operands[j++];
572            
573 schuur 1.3                 terminal_heap.push(term_el(false, WQL_NE, op, dummy));
574 schuur 1.1 
575 schuur 1.3                 stack.push(stack_el(terminal_heap.size()-1, true));
576 schuur 1.1 
577                            break;
578                        }
579                    }
580                }
581            
582                PEGASUS_ASSERT(stack.size() == 1);
583            }
584            
585            void CMPI_Wql2Dnf::_pushNOTDown()
586            {
587                for (int i=eval_heap.size()-1; i >= 0; i--)
588                {
589                    Boolean _found = false;
590                    int k;
591            
592                    // Order all operators, so that op1 > op2 for non-terminals
593                    // and terminals appear as second operand
594            
595                    eval_heap[i].order();
596            
597 schuur 1.1         // First solve the unary NOT operator
598            
599                    if (eval_heap[i].op == WQL_NOT ||
600                        eval_heap[i].op == WQL_IS_FALSE ||
601                        eval_heap[i].op == WQL_IS_NOT_TRUE)
602                   {
603                        // This serves as the equivalent of an empty operator
604                        eval_heap[i].op = WQL_IS_TRUE;
605            
606                        // Substitute this expression in all higher order eval statements
607                        // so that this node becomes disconnected from the tree
608            
609                        for (int j=eval_heap.size()-1; j > i;j--)
610                        {
611                           // Test first operand
612                           if ((!eval_heap[j].is_terminal1) && (eval_heap[j].opn1 == i))
613            
614                               eval_heap[j].assign_unary_to_first(eval_heap[i]);
615            
616                           // Test second operand
617                           if ((!eval_heap[j].is_terminal2) && (eval_heap[j].opn2 == i))
618 schuur 1.1 
619                               eval_heap[j].assign_unary_to_second(eval_heap[i]);
620                        }
621            
622                        // Test: Double NOT created by moving down
623            
624                        if (eval_heap[i].mark)
625                           eval_heap[i].mark = false;
626                        else
627                           _found = true;
628                        // else indicate a pending NOT to be pushed down further
629                    }
630            
631                    // Simple NOT created by moving down
632            
633                    if (eval_heap[i].mark)
634                    {
635                        // Remove the mark, indicate a pending NOT to be pushed down
636                        // further and switch operators (AND / OR)
637            
638                        eval_heap[i].mark=false;
639 schuur 1.1             if (eval_heap[i].op == WQL_OR) eval_heap[i].op = WQL_AND;
640                        else if (eval_heap[i].op == WQL_AND) eval_heap[i].op = WQL_OR;
641            
642                        // NOT operator is already ruled out
643                        _found = true;
644                    }
645            
646                    // Push a pending NOT further down
647                    if (_found)
648                    {
649                         // First operand
650            
651                         int j = eval_heap[i].opn1;
652                         if (eval_heap[i].is_terminal1)
653                             // Flip NOT mark
654                             terminal_heap[j].negate();
655                         else
656                             eval_heap[j].mark = !(eval_heap[j].mark);
657            
658                         //Second operand (if it exists)
659            
660 schuur 1.1              if ((j = eval_heap[i].opn2) >= 0)
661                         {
662                             if (eval_heap[i].is_terminal2)
663                                 // Flip NOT mark
664                                 terminal_heap[j].negate();
665                             else
666                                 eval_heap[j].mark = !(eval_heap[j].mark);
667                         }
668                    }
669                }
670            }
671            
672            void CMPI_Wql2Dnf::_factoring(void)
673            {
674                int i = 0,n = eval_heap.size();
675                //for (int i=eval_heap.size()-1; i >= 0; i--)
676                while (i < n)
677                {
678                    int _found = 0;
679                    int index = 0;
680            
681 schuur 1.1         // look for expressions (A | B) & C  ---> A & C | A & B
682                    if (eval_heap[i].op == WQL_AND)
683                    {
684                        if (!eval_heap[i].is_terminal1)
685                        {
686                            index = eval_heap[i].opn1; // remember the index
687                            if (eval_heap[index].op == WQL_OR) _found = 1;
688                        }
689            
690                        if ((_found == 0) && (!eval_heap[i].is_terminal2))
691                        {
692                            index = eval_heap[i].opn2; // remember the index
693                            if (eval_heap[index].op == WQL_OR) _found = 2;
694                        }
695            
696                        if (_found != 0)
697                        {
698                             //int u1,u1_t,u2,u2_t,u3,u3_t;
699                             stack_el s;
700            
701                             if (_found == 1)
702 schuur 1.1                      s = eval_heap[i].getSecond();
703                             else
704                                 s = eval_heap[i].getFirst();
705            
706                             // insert two new expression before entry i
707                             eval_el evl;
708            
709 schuur 1.3                  evl = eval_el(false, WQL_OR, i+1, false, i, false);
710 schuur 1.1                  if ((Uint32 )i < eval_heap.size()-1)
711                                 eval_heap.insert(i+1, evl);
712                             else
713                                 eval_heap.append(evl);
714                             eval_heap.insert(i+1, evl);
715            
716                             for (int j=eval_heap.size()-1; j > i + 2; j--)
717                             {
718                                 //eval_heap[j] = eval_heap[j-2];
719            
720                                 // adjust pointers
721            
722                                 if ((!eval_heap[j].is_terminal1)&&
723                                     (eval_heap[j].opn1 >= i))
724                                     eval_heap[j].opn1 += 2;
725                                 if ((!eval_heap[j].is_terminal2)&&
726                                     (eval_heap[j].opn2 >= i))
727                                     eval_heap[j].opn2 += 2;
728                             }
729            
730                             n+=2; // increase size of array
731 schuur 1.1 
732                             // generate the new expressions : new OR expression
733            
734            
735                             // first new AND expression
736                             eval_heap[i+1].mark = false;
737                             eval_heap[i+1].op = WQL_AND;
738                             eval_heap[i+1].setFirst(s);
739                             eval_heap[i+1].setSecond( eval_heap[index].getFirst());
740                             eval_heap[i+1].order();
741            
742            
743                             // second new AND expression
744                             eval_heap[i].mark = false;
745                             eval_heap[i].op = WQL_AND;
746                             eval_heap[i].setFirst(s);
747                             eval_heap[i].setSecond( eval_heap[index].getSecond());
748                             eval_heap[i].order();
749            
750                             // mark the indexed expression as inactive
751                             //eval_heap[index].op = WQL_IS_TRUE; possible disconnects
752 schuur 1.1                  i--;
753            
754                        } /* endif _found > 0 */
755            
756                    } /* endif found AND operator */
757            
758                    i++; // increase pointer
759                }
760            }
761            
762            void CMPI_Wql2Dnf::_gatherDisj(Array<stack_el>& stk)
763            {
764 schuur 1.3     _gather(stk, stack_el(0,true), true);
765 schuur 1.1 }
766            
767            void CMPI_Wql2Dnf::_gatherConj(Array<stack_el>& stk, stack_el sel)
768            {
769                _gather(stk, sel, false);
770            }
771            
772            void CMPI_Wql2Dnf::_gather(Array<stack_el>& stk, stack_el sel, Boolean or_flag)
773            {
774                Uint32 i = 0;
775            
776                stk.clear();
777                stk.reserveCapacity(16);
778            
779                if ((i = eval_heap.size()) == 0) return;
780            
781                while (eval_heap[i-1].op == WQL_IS_TRUE)
782                {
783                    eval_heap.remove(i-1);
784                    i--;
785                    if (i == 0) return;
786 schuur 1.1     }
787                //if (i == 0) return;
788            
789                if (or_flag)
790 schuur 1.3         stk.append(stack_el(i-1,false));
791 schuur 1.1     else
792                {
793                   if (sel.is_terminal) return;
794                   stk.append(sel);
795                }
796            
797                i = 0;
798            
799                while (i<stk.size())
800                {
801                    int k = stk[i].opn;
802            
803                    if ((k < 0) || (stk[i].is_terminal))
804                       i++;
805                    else
806                    {
807                        if ( ((eval_heap[k].op != WQL_OR) && (or_flag)) ||
808                             ((eval_heap[k].op != WQL_AND) && (!or_flag))  )
809 schuur 1.3                 i++;
810 schuur 1.1             else
811                        {
812                            // replace the element with disjunction
813                            stk[i] = eval_heap[k].getSecond();
814                            stk.insert(i, eval_heap[k].getFirst());
815                            if (or_flag)
816                                eval_heap[k].op = WQL_IS_TRUE;
817                        }
818                    }
819                }
820            }
821            
822            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2