001: package org.drools.common;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.Serializable;
020:
021: import org.drools.RuleBaseConfiguration;
022: import org.drools.base.evaluators.Operator;
023: import org.drools.reteoo.BetaMemory;
024: import org.drools.reteoo.FactHandleMemory;
025: import org.drools.reteoo.ReteTuple;
026: import org.drools.reteoo.TupleMemory;
027: import org.drools.rule.ContextEntry;
028: import org.drools.rule.VariableConstraint;
029: import org.drools.spi.BetaNodeFieldConstraint;
030: import org.drools.util.FactHashTable;
031: import org.drools.util.FactHandleIndexHashTable;
032: import org.drools.util.LinkedList;
033: import org.drools.util.LinkedListEntry;
034: import org.drools.util.TupleHashTable;
035: import org.drools.util.TupleIndexHashTable;
036: import org.drools.util.AbstractHashTable.FieldIndex;
037:
038: public class SingleBetaConstraints implements Serializable,
039: BetaConstraints {
040:
041: /**
042: *
043: */
044: private static final long serialVersionUID = 400L;
045:
046: private final BetaNodeFieldConstraint constraint;
047:
048: private ContextEntry context;
049:
050: private boolean indexed;
051:
052: private RuleBaseConfiguration conf;
053:
054: public SingleBetaConstraints(
055: final BetaNodeFieldConstraint[] constraint,
056: final RuleBaseConfiguration conf) {
057: this (constraint[0], conf, false);
058: }
059:
060: public SingleBetaConstraints(
061: final BetaNodeFieldConstraint constraint,
062: final RuleBaseConfiguration conf) {
063: this (constraint, conf, false);
064: }
065:
066: public SingleBetaConstraints(
067: final BetaNodeFieldConstraint constraint,
068: final RuleBaseConfiguration conf, final boolean disableIndex) {
069: this .conf = conf;
070: if ((disableIndex)
071: || (!conf.isIndexLeftBetaMemory() && !conf
072: .isIndexRightBetaMemory())) {
073: this .indexed = false;
074: } else {
075: final int depth = conf.getCompositeKeyDepth();
076: // Determine if this constraint is indexable
077: this .indexed = depth >= 1 && isIndexable(constraint);
078: }
079:
080: this .constraint = constraint;
081: this .context = constraint.getContextEntry();
082: }
083:
084: private boolean isIndexable(final BetaNodeFieldConstraint constraint) {
085: if (constraint instanceof VariableConstraint) {
086: final VariableConstraint variableConstraint = (VariableConstraint) constraint;
087: return (variableConstraint.getEvaluator().getOperator() == Operator.EQUAL);
088: } else {
089: return false;
090: }
091: }
092:
093: /* (non-Javadoc)
094: * @see org.drools.common.BetaNodeConstraints#updateFromTuple(org.drools.reteoo.ReteTuple)
095: */
096: public void updateFromTuple(
097: final InternalWorkingMemory workingMemory,
098: final ReteTuple tuple) {
099: this .context.updateFromTuple(workingMemory, tuple);
100: }
101:
102: /* (non-Javadoc)
103: * @see org.drools.common.BetaNodeConstraints#updateFromFactHandle(org.drools.common.InternalFactHandle)
104: */
105: public void updateFromFactHandle(
106: final InternalWorkingMemory workingMemory,
107: final InternalFactHandle handle) {
108: this .context.updateFromFactHandle(workingMemory, handle);
109: }
110:
111: /* (non-Javadoc)
112: * @see org.drools.common.BetaNodeConstraints#isAllowedCachedLeft(java.lang.Object)
113: */
114: public boolean isAllowedCachedLeft(final Object object) {
115: return this .indexed
116: || this .constraint.isAllowedCachedLeft(this .context,
117: object);
118: }
119:
120: /* (non-Javadoc)
121: * @see org.drools.common.BetaNodeConstraints#isAllowedCachedRight(org.drools.reteoo.ReteTuple)
122: */
123: public boolean isAllowedCachedRight(final ReteTuple tuple) {
124: return this .constraint
125: .isAllowedCachedRight(tuple, this .context);
126: }
127:
128: public boolean isIndexed() {
129: return this .indexed;
130: }
131:
132: public int getIndexCount() {
133: return (this .indexed ? 1 : 0);
134: }
135:
136: public boolean isEmpty() {
137: return false;
138: }
139:
140: public BetaMemory createBetaMemory(
141: final RuleBaseConfiguration config) {
142: BetaMemory memory;
143: if (this .indexed) {
144: final VariableConstraint variableConstraint = (VariableConstraint) this .constraint;
145: final FieldIndex index = new FieldIndex(variableConstraint
146: .getFieldExtractor(), variableConstraint
147: .getRequiredDeclarations()[0], variableConstraint
148: .getEvaluator());
149: TupleMemory tupleMemory;
150: if (this .conf.isIndexLeftBetaMemory()) {
151: tupleMemory = new TupleIndexHashTable(
152: new FieldIndex[] { index });
153: } else {
154: tupleMemory = new TupleHashTable();
155: }
156:
157: FactHandleMemory factHandleMemory;
158: if (this .conf.isIndexRightBetaMemory()) {
159: factHandleMemory = new FactHandleIndexHashTable(
160: new FieldIndex[] { index });
161: } else {
162: factHandleMemory = new FactHashTable();
163: }
164: memory = new BetaMemory(config.isSequential() ? null
165: : tupleMemory, factHandleMemory);
166: } else {
167: memory = new BetaMemory(config.isSequential() ? null
168: : new TupleHashTable(), new FactHashTable());
169: }
170:
171: return memory;
172: }
173:
174: public int hashCode() {
175: return this .constraint.hashCode();
176: }
177:
178: /* (non-Javadoc)
179: * @see org.drools.common.BetaNodeConstraints#getConstraints()
180: */
181: public LinkedList getConstraints() {
182: final LinkedList list = new LinkedList();
183: list.add(new LinkedListEntry(this .constraint));
184: return list;
185: }
186:
187: /**
188: * Determine if another object is equal to this.
189: *
190: * @param object
191: * The object to test.
192: *
193: * @return <code>true</code> if <code>object</code> is equal to this,
194: * otherwise <code>false</code>.
195: */
196: public boolean equals(final Object object) {
197: if (this == object) {
198: return true;
199: }
200:
201: if (object == null || getClass() != object.getClass()) {
202: return false;
203: }
204:
205: final SingleBetaConstraints other = (SingleBetaConstraints) object;
206:
207: return this.constraint == other.constraint
208: || this.constraint.equals(other);
209: }
210:
211: }
|