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
|