[jboss-svn-commits] JBL Code SVN: r6901 - in labs/jbossrules/trunk/drools-core: . src/main/java/org/drools/common src/main/java/org/drools/reteoo src/main/java/org/drools/util src/test/java/org/drools/examples/manners
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Oct 18 18:04:54 EDT 2006
Author: mark.proctor at jboss.com
Date: 2006-10-18 18:04:45 -0400 (Wed, 18 Oct 2006)
New Revision: 6901
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/CompositeFieldIndexHashTable.java
Modified:
labs/jbossrules/trunk/drools-core/.classpath
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityAssertMapComparator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityKeyComparator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/IdentityAssertMapComparator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/AbstractHashTable.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FieldIndexHashTable.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java
Log:
JBRULES-526 Implement a CompositeIndex for Facts
Modified: labs/jbossrules/trunk/drools-core/.classpath
===================================================================
--- labs/jbossrules/trunk/drools-core/.classpath 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/.classpath 2006-10-18 22:04:45 UTC (rev 6901)
@@ -13,5 +13,6 @@
<classpathentry kind="var" path="M2_REPO/jung/jung/1.7.2/jung-1.7.2.jar"/>
<classpathentry kind="var" path="M2_REPO/xerces/xercesImpl/2.6.2/xercesImpl-2.6.2.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar"/>
+ <classpathentry kind="lib" path="jess.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DefaultBetaConstraints.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -36,11 +36,13 @@
import org.drools.spi.AlphaNodeFieldConstraint;
import org.drools.spi.FieldExtractor;
import org.drools.spi.Tuple;
+import org.drools.util.CompositeFieldIndexHashTable;
import org.drools.util.FactHashTable;
import org.drools.util.FieldIndexHashTable;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListEntry;
import org.drools.util.TupleHashTable;
+import org.drools.util.CompositeFieldIndexHashTable.FieldIndex;
public class DefaultBetaConstraints
implements
@@ -158,9 +160,9 @@
if ( this.indexed ) {
Constraint constraint = ( Constraint ) this.constraints.getFirst();
VariableConstraint variableConstraint = (VariableConstraint) constraint;
+ FieldIndex index = new FieldIndex(variableConstraint.getFieldExtractor(), variableConstraint.getRequiredDeclarations()[0]);
memory = new BetaMemory( new TupleHashTable(),
- new FieldIndexHashTable( variableConstraint.getFieldExtractor(),
- variableConstraint.getRequiredDeclarations()[0] ) );
+ new CompositeFieldIndexHashTable( new FieldIndex[] { index } ) );
} else {
memory = new BetaMemory( new TupleHashTable(),
new FactHashTable() );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/DoubleBetaConstraints.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -17,7 +17,9 @@
*/
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import org.drools.WorkingMemory;
@@ -42,6 +44,8 @@
import org.drools.util.LinkedListEntry;
import org.drools.util.LinkedListNode;
import org.drools.util.TupleHashTable;
+import org.drools.util.CompositeFieldIndexHashTable;
+import org.drools.util.CompositeFieldIndexHashTable.FieldIndex;
public class DoubleBetaConstraints
implements
@@ -59,21 +63,23 @@
private ContextEntry context0;
private ContextEntry context1;
- private boolean indexed;
+ private boolean indexed0;
+ private boolean indexed1;
public DoubleBetaConstraints(final BetaNodeFieldConstraint[] constraints) {
- // find the first instrumental
- for ( int i = 0, length = constraints.length; i < length; i++ ) {
- if ( isIndexable( constraints[i] ) ) {
- if ( i > 0) {
- // swap the constraint to the first position
- BetaNodeFieldConstraint temp = constraints[0];
- constraints[0] = constraints[i];
- constraints[i] = temp;
- }
- this.indexed = true;
- break;
+ boolean i0 = isIndexable( constraints[0] );
+ boolean i1 = isIndexable( constraints[1] );
+
+ if ( i0 ) {
+ this.indexed0 = true;
+ if ( i1 ) {
+ this.indexed1 = true;
}
+ } else if ( i1 ) {
+ this.indexed0 = true;
+ BetaNodeFieldConstraint temp = constraints[0];
+ constraints[0] = constraints[1];
+ constraints[1] = temp;
}
this.constraint0 = constraints[0];
@@ -112,9 +118,9 @@
* @see org.drools.common.BetaNodeConstraints#isAllowedCachedLeft(java.lang.Object)
*/
public boolean isAllowedCachedLeft(Object object) {
- return ( this.indexed || this.constraint0.isAllowedCachedLeft( context0,
- object ) ) && this.constraint1.isAllowedCachedLeft( context1,
- object );
+ return (this.indexed0 || this.constraint0.isAllowedCachedLeft( context0,
+ object )) && (this.indexed1 || this.constraint1.isAllowedCachedLeft( context1,
+ object ));
}
/* (non-Javadoc)
@@ -127,7 +133,7 @@
}
public boolean isIndexed() {
- return this.indexed;
+ return this.indexed0;
}
public boolean isEmpty() {
@@ -136,11 +142,27 @@
public BetaMemory createBetaMemory() {
BetaMemory memory;
- if ( this.indexed ) {
+
+ List list = new ArrayList( 2 );
+ if ( this.indexed0 ) {
VariableConstraint variableConstraint = (VariableConstraint) this.constraint0;
+ FieldIndex index = new FieldIndex( variableConstraint.getFieldExtractor(),
+ variableConstraint.getRequiredDeclarations()[0] );
+ list.add( index );
+
+ }
+
+ if ( this.indexed1 ) {
+ VariableConstraint variableConstraint = (VariableConstraint) this.constraint1;
+ FieldIndex index = new FieldIndex( variableConstraint.getFieldExtractor(),
+ variableConstraint.getRequiredDeclarations()[0] );
+ list.add( index );
+ }
+
+ if ( !list.isEmpty() ) {
+ FieldIndex[] indexes = (FieldIndex[]) list.toArray( new FieldIndex[list.size()] );
memory = new BetaMemory( new TupleHashTable(),
- new FieldIndexHashTable( variableConstraint.getFieldExtractor(),
- variableConstraint.getRequiredDeclarations()[0] ) );
+ new CompositeFieldIndexHashTable( indexes ) );
} else {
memory = new BetaMemory( new TupleHashTable(),
new FactHashTable() );
@@ -194,14 +216,14 @@
final DoubleBetaConstraints other = (DoubleBetaConstraints) object;
- if ( this.constraint0 != other.constraint0 && this.constraint0.equals( other.constraint0 ) ) {
+ if ( this.constraint0 != other.constraint0 && this.constraint0.equals( other.constraint0 ) ) {
return false;
}
-
- if ( this.constraint1 != other.constraint1 && this.constraint1.equals( other.constraint1 ) ) {
+
+ if ( this.constraint1 != other.constraint1 && this.constraint1.equals( other.constraint1 ) ) {
return false;
}
-
+
return true;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityAssertMapComparator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityAssertMapComparator.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityAssertMapComparator.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -34,10 +34,18 @@
public int hashCodeOf(final Object obj) {
if ( obj.getClass() == this.factHandleClass ) {
- return ((InternalFactHandle) obj).getObjectHashCode();
+ return rehash( ((InternalFactHandle) obj).getObjectHashCode() );
}
- return obj.hashCode();
+ return rehash( obj.hashCode() );
}
+
+ public int rehash(int h) {
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
/**
* Special comparator that allows FactHandles to be keys, but always checks
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityKeyComparator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityKeyComparator.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/EqualityKeyComparator.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -34,12 +34,15 @@
}
public int hashCodeOf(Object key) {
- int h = key.hashCode();
+ return rehash( key.hashCode() );
+ }
+
+ public int rehash(int h) {
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
- return h;
+ return h;
}
/**
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/IdentityAssertMapComparator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/IdentityAssertMapComparator.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/IdentityAssertMapComparator.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -34,10 +34,18 @@
public int hashCodeOf(final Object obj) {
if ( obj.getClass() == this.factHandleClass ) {
- return ((InternalFactHandle) obj).getObjectHashCode();
+ return rehash( ((InternalFactHandle) obj).getObjectHashCode() );
}
- return obj.hashCode();
+ return rehash( obj.hashCode());
}
+
+ public int rehash(int h) {
+ h += ~(h << 9);
+ h ^= (h >>> 14);
+ h += (h << 4);
+ h ^= (h >>> 10);
+ return h;
+ }
/**
* Special comparator that allows FactHandles to be keys, but always checks
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/SingleBetaConstraints.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -23,11 +23,13 @@
import org.drools.rule.ContextEntry;
import org.drools.rule.VariableConstraint;
import org.drools.spi.BetaNodeFieldConstraint;
+import org.drools.util.CompositeFieldIndexHashTable;
import org.drools.util.FactHashTable;
import org.drools.util.FieldIndexHashTable;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListEntry;
import org.drools.util.TupleHashTable;
+import org.drools.util.CompositeFieldIndexHashTable.FieldIndex;
public class SingleBetaConstraints
implements
@@ -106,9 +108,9 @@
BetaMemory memory;
if ( this.indexed ) {
VariableConstraint variableConstraint = (VariableConstraint) this.constraint;
+ FieldIndex index = new FieldIndex(variableConstraint.getFieldExtractor(), variableConstraint.getRequiredDeclarations()[0]);
memory = new BetaMemory( new TupleHashTable(),
- new FieldIndexHashTable( variableConstraint.getFieldExtractor(),
- variableConstraint.getRequiredDeclarations()[0] ) );
+ new CompositeFieldIndexHashTable( new FieldIndex[] { index } ) );
} else {
memory = new BetaMemory( new TupleHashTable(),
new FactHashTable() );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/TripleBetaConstraints.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -17,7 +17,9 @@
*/
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import org.drools.WorkingMemory;
@@ -36,12 +38,14 @@
import org.drools.spi.AlphaNodeFieldConstraint;
import org.drools.spi.FieldExtractor;
import org.drools.spi.Tuple;
+import org.drools.util.CompositeFieldIndexHashTable;
import org.drools.util.FactHashTable;
import org.drools.util.FieldIndexHashTable;
import org.drools.util.LinkedList;
import org.drools.util.LinkedListEntry;
import org.drools.util.LinkedListNode;
import org.drools.util.TupleHashTable;
+import org.drools.util.CompositeFieldIndexHashTable.FieldIndex;
public class TripleBetaConstraints
implements
@@ -61,31 +65,72 @@
private ContextEntry context1;
private ContextEntry context2;
- private boolean indexed;
+ private boolean indexed0;
+ private boolean indexed1;
+ private boolean indexed2;
public TripleBetaConstraints(final BetaNodeFieldConstraint[] constraints) {
- // find the first instrumental
- for ( int i = 0, length = constraints.length; i < length; i++ ) {
- if ( isIndexable( constraints[i] ) ) {
- if ( i > 0) {
- // swap the constraint to the first position
- BetaNodeFieldConstraint temp = constraints[0];
- constraints[0] = constraints[i];
- constraints[i] = temp;
- }
- this.indexed = true;
- break;
+ // // find the first instrumental
+ // for ( int i = 0, length = constraints.length; i < length; i++ ) {
+ // if ( isIndexable( constraints[i] ) ) {
+ // if ( i > 0) {
+ // // swap the constraint to the first position
+ // BetaNodeFieldConstraint temp = constraints[0];
+ // constraints[0] = constraints[i];
+ // constraints[i] = temp;
+ // }
+ // this.indexed = true;
+ // break;
+ // }
+ // }
+ //
+ // this.constraint0 = constraints[0];
+ // this.context0 = this.constraint0.getContextEntry();
+ //
+ // this.constraint1 = constraints[1];
+ // this.context1 = this.constraint1.getContextEntry();
+ //
+ // this.constraint2 = constraints[2];
+ // this.context2 = this.constraint2.getContextEntry();
+
+ boolean i0 = isIndexable( constraints[0] );
+ boolean i1 = isIndexable( constraints[1] );
+ boolean i2 = isIndexable( constraints[2] );
+
+ if ( i0 ) {
+ this.indexed0 = true;
+ if ( i1 ) {
+ this.indexed1 = true;
}
+ } else if ( i1 ) {
+ this.indexed0 = true;
+ BetaNodeFieldConstraint temp = constraints[0];
+ constraints[0] = constraints[1];
+ constraints[1] = temp;
}
+
+ if ( i2 ) {
+ if (i0) {
+ this.indexed1 = true;
+ BetaNodeFieldConstraint temp = constraints[1];
+ constraints[1] = constraints[2];
+ constraints[2] = temp;
+ } else {
+ this.indexed0 = true;
+ BetaNodeFieldConstraint temp = constraints[0];
+ constraints[0] = constraints[2];
+ constraints[2] = temp;
+ }
+ }
this.constraint0 = constraints[0];
this.context0 = this.constraint0.getContextEntry();
this.constraint1 = constraints[1];
this.context1 = this.constraint1.getContextEntry();
-
+
this.constraint2 = constraints[2];
- this.context2 = this.constraint2.getContextEntry();
+ this.context2 = this.constraint2.getContextEntry();
}
private boolean isIndexable(final BetaNodeFieldConstraint constraint) {
@@ -119,10 +164,15 @@
* @see org.drools.common.BetaNodeConstraints#isAllowedCachedLeft(java.lang.Object)
*/
public boolean isAllowedCachedLeft(Object object) {
- return ( this.indexed || this.constraint0.isAllowedCachedLeft( context0,
- object ) ) && this.constraint1.isAllowedCachedLeft( context1,
- object ) && this.constraint2.isAllowedCachedLeft( context2,
- object );
+ // return ( this.indexed0 || this.constraint0.isAllowedCachedLeft( context0,
+ // object ) ) && this.constraint1.isAllowedCachedLeft( context1,
+ // object ) && this.constraint2.isAllowedCachedLeft( context2,
+ // object );
+
+ return (this.indexed0 || this.constraint0.isAllowedCachedLeft( context0,
+ object )) && (this.indexed1 || this.constraint1.isAllowedCachedLeft( context1,
+ object )) && (this.indexed2 || this.constraint2.isAllowedCachedLeft( context2,
+ object ) );
}
/* (non-Javadoc)
@@ -136,7 +186,7 @@
}
public boolean isIndexed() {
- return this.indexed;
+ return this.indexed0;
}
public boolean isEmpty() {
@@ -144,12 +194,48 @@
}
public BetaMemory createBetaMemory() {
+ // BetaMemory memory;
+ // if ( this.indexed ) {
+ // VariableConstraint variableConstraint = (VariableConstraint) this.constraint0;
+ // Index index = new Index(variableConstraint.getFieldExtractor(), variableConstraint.getRequiredDeclarations()[0]);
+ // memory = new BetaMemory( new TupleHashTable(),
+ // new CompositeFieldIndexHashTable( new Index[] { index } ) );
+ // } else {
+ // memory = new BetaMemory( new TupleHashTable(),
+ // new FactHashTable() );
+ // }
+ //
+ // return memory;
+
BetaMemory memory;
- if ( this.indexed ) {
+
+ List list = new ArrayList( 2 );
+ if ( this.indexed0 ) {
VariableConstraint variableConstraint = (VariableConstraint) this.constraint0;
+ FieldIndex index = new FieldIndex( variableConstraint.getFieldExtractor(),
+ variableConstraint.getRequiredDeclarations()[0] );
+ list.add( index );
+
+ }
+
+ if ( this.indexed1 ) {
+ VariableConstraint variableConstraint = (VariableConstraint) this.constraint1;
+ FieldIndex index = new FieldIndex( variableConstraint.getFieldExtractor(),
+ variableConstraint.getRequiredDeclarations()[0] );
+ list.add( index );
+ }
+
+ if ( this.indexed2 ) {
+ VariableConstraint variableConstraint = (VariableConstraint) this.constraint2;
+ FieldIndex index = new FieldIndex( variableConstraint.getFieldExtractor(),
+ variableConstraint.getRequiredDeclarations()[0] );
+ list.add( index );
+ }
+
+ if ( !list.isEmpty() ) {
+ FieldIndex[] indexes = (FieldIndex[]) list.toArray( new FieldIndex[list.size()] );
memory = new BetaMemory( new TupleHashTable(),
- new FieldIndexHashTable( variableConstraint.getFieldExtractor(),
- variableConstraint.getRequiredDeclarations()[0] ) );
+ new CompositeFieldIndexHashTable( indexes ) );
} else {
memory = new BetaMemory( new TupleHashTable(),
new FactHashTable() );
@@ -204,18 +290,18 @@
final TripleBetaConstraints other = (TripleBetaConstraints) object;
- if ( this.constraint0 != other.constraint0 && this.constraint0.equals( other.constraint0 ) ) {
+ if ( this.constraint0 != other.constraint0 && this.constraint0.equals( other.constraint0 ) ) {
return false;
}
-
- if ( this.constraint1 != other.constraint1 && this.constraint1.equals( other.constraint1 ) ) {
+
+ if ( this.constraint1 != other.constraint1 && this.constraint1.equals( other.constraint1 ) ) {
return false;
}
-
- if ( this.constraint2 != other.constraint2 && this.constraint2.equals( other.constraint2 ) ) {
+
+ if ( this.constraint2 != other.constraint2 && this.constraint2.equals( other.constraint2 ) ) {
return false;
- }
-
+ }
+
return true;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/MemoryVisitor.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -8,15 +8,16 @@
import org.drools.examples.manners.Context;
import org.drools.reteoo.TerminalNode.TerminalNodeMemory;
import org.drools.util.AbstractHashTable;
+import org.drools.util.CompositeFieldIndexHashTable;
import org.drools.util.Entry;
import org.drools.util.FactHashTable;
-import org.drools.util.FieldIndexHashTable;
+//import org.drools.util.FieldIndexHashTable;
import org.drools.util.Iterator;
import org.drools.util.ObjectHashMap;
import org.drools.util.ReflectiveVisitor;
import org.drools.util.TupleHashTable;
import org.drools.util.AbstractHashTable.FactEntry;
-import org.drools.util.FieldIndexHashTable.FieldIndexEntry;
+import org.drools.util.CompositeFieldIndexHashTable.FieldIndexEntry;
import org.drools.util.ObjectHashMap.ObjectEntry;
public class MemoryVisitor extends ReflectiveVisitor {
@@ -131,9 +132,13 @@
System.out.println( indent() + node );
- BetaMemory memory = ( BetaMemory ) this.workingMemory.getNodeMemory( node );
- checkObjectHashTable( memory.getObjectMemory() );
- checkTupleMemory( memory.getTupleMemory() );
+ try {
+ BetaMemory memory = ( BetaMemory ) this.workingMemory.getNodeMemory( node );
+ checkObjectHashTable( memory.getObjectMemory() );
+ checkTupleMemory( memory.getTupleMemory() );
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
indent++;
try {
@@ -152,10 +157,13 @@
public void visitNotNode(final NotNode node) {
System.out.println( indent() + node );
-
- BetaMemory memory = ( BetaMemory ) this.workingMemory.getNodeMemory( node );
- checkObjectHashTable( memory.getObjectMemory() );
- checkTupleMemory( memory.getTupleMemory() );
+ try {
+ BetaMemory memory = ( BetaMemory ) this.workingMemory.getNodeMemory( node );
+ checkObjectHashTable( memory.getObjectMemory() );
+ checkTupleMemory( memory.getTupleMemory() );
+ } catch ( Exception e ) {
+ e.printStackTrace();
+ }
indent++;
try {
@@ -196,8 +204,8 @@
private void checkObjectHashTable(ObjectHashTable memory) {
if ( memory instanceof FactHashTable) {
checkFactHashTable( (FactHashTable )memory);
- } else if ( memory instanceof FieldIndexHashTable ) {
- checkFieldIndexHashTable( ( FieldIndexHashTable )memory);
+ } else if ( memory instanceof CompositeFieldIndexHashTable ) {
+ checkFieldIndexHashTable( ( CompositeFieldIndexHashTable )memory);
} else {
throw new RuntimeException( memory.getClass() + " should not be here" );
}
@@ -222,7 +230,7 @@
}
}
- private void checkFieldIndexHashTable(FieldIndexHashTable memory) {
+ private void checkFieldIndexHashTable(CompositeFieldIndexHashTable memory) {
Entry[] entries = memory.getTable();
int factCount = 0;
int bucketCount = 0;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -58,7 +58,7 @@
private static final long serialVersionUID = 320L;
static int notAssertObject = 0;
static int notAssertTuple = 0;
-
+
// ------------------------------------------------------------
// Instance methods
// ------------------------------------------------------------
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/Rete.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -21,14 +21,19 @@
import java.util.List;
import org.drools.FactException;
+import org.drools.FactHandle;
import org.drools.RuleBaseConfiguration;
+import org.drools.base.ShadowProxy;
import org.drools.common.BaseNode;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.common.NodeMemory;
import org.drools.facttemplates.Fact;
import org.drools.facttemplates.FactImpl;
+import org.drools.rule.Rule;
+import org.drools.spi.Activation;
import org.drools.spi.PropagationContext;
+import org.drools.util.FactHashTable;
import org.drools.util.Iterator;
import org.drools.util.ObjectHashMap;
import org.drools.util.ObjectHashMap.ObjectEntry;
@@ -80,7 +85,7 @@
// ------------------------------------------------------------
// Instance methods
// ------------------------------------------------------------
-
+
/**
* This is the entry point into the network for all asserted Facts. Iterates a cache
* of matching <code>ObjectTypdeNode</code>s asserting the Fact. If the cache does not
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteTuple.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -140,6 +140,18 @@
return this.hashCode;
}
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+
+ ReteTuple entry = this;
+ while ( entry != null ) {
+ //buffer.append( entry.handle );
+ buffer.append( entry.handle + "\n" );
+ entry = entry.parent;
+ }
+ return buffer.toString();
+ }
+
/**
* We use this equals method to avoid the cast
* @param tuple
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/AbstractHashTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/AbstractHashTable.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/AbstractHashTable.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -179,6 +179,8 @@
public interface ObjectComparator {
public int hashCodeOf(Object object);
+ public int rehash(int hashCode);
+
public boolean equal(Object object1,
Object object2);
}
@@ -242,12 +244,15 @@
}
public int hashCodeOf(Object key) {
- int h = key.hashCode();
+ return rehash( key.hashCode() );
+ }
+
+ public int rehash(int h) {
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
- return h;
+ return h;
}
private InstanceEquals() {
@@ -270,12 +275,15 @@
}
public int hashCodeOf(Object key) {
- int h = key.hashCode();
+ return rehash( key.hashCode() );
+ }
+
+ public int rehash(int h) {
h += ~(h << 9);
h ^= (h >>> 14);
h += (h << 4);
h ^= (h >>> 10);
- return h;
+ return h;
}
private EqualityEquals() {
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/CompositeFieldIndexHashTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/CompositeFieldIndexHashTable.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/CompositeFieldIndexHashTable.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -0,0 +1,411 @@
+/**
+ *
+ */
+package org.drools.util;
+
+import org.drools.common.InternalFactHandle;
+import org.drools.reteoo.ObjectHashTable;
+import org.drools.reteoo.ReteTuple;
+import org.drools.rule.Declaration;
+import org.drools.spi.FieldExtractor;
+import org.drools.util.AbstractHashTable.ObjectComparator;
+import org.drools.util.ObjectHashMap.ObjectEntry;
+
+public class CompositeFieldIndexHashTable extends AbstractHashTable
+ implements
+ ObjectHashTable {
+ public static final int PRIME = 31;
+
+ private int startResult;
+
+ private FieldIndexHashTableIterator tupleValueIterator;
+
+ private int factSize;
+
+ private DefaultCompositeIndex index;
+
+ public CompositeFieldIndexHashTable(FieldIndex[] index) {
+ this( 16,
+ 0.75f,
+ index );
+ }
+
+ public CompositeFieldIndexHashTable(int capacity,
+ float loadFactor,
+ FieldIndex[] index) {
+ super( capacity,
+ loadFactor );
+
+ this.startResult = PRIME;
+ for ( int i = 0, length = index.length; i < length; i++ ) {
+ this.startResult += index[i].getExtractor().getIndex();
+ }
+ this.index = new DefaultCompositeIndex( index,
+ this.startResult,
+ this.comparator );
+ }
+
+ public Iterator iterator() {
+ throw new UnsupportedOperationException( "FieldIndexHashTable does not support iterator()" );
+ }
+
+ public Iterator iterator(ReteTuple tuple) {
+ if ( this.tupleValueIterator == null ) {
+ this.tupleValueIterator = new FieldIndexHashTableIterator();
+ }
+ FieldIndexEntry entry = (FieldIndexEntry) get( tuple );
+ this.tupleValueIterator.reset( (entry != null) ? entry.first : null );
+ return this.tupleValueIterator;
+ }
+
+ public boolean isIndexed() {
+ return true;
+ }
+
+ public Entry getBucket(Object object) {
+ int hashCode = this.index.hashCodeOf( object );
+ int index = indexOf( hashCode,
+ table.length );
+
+ return (ObjectEntry) this.table[index];
+ }
+
+ /**
+ * Fast re-usable iterator
+ *
+ */
+ public static class FieldIndexHashTableIterator
+ implements
+ Iterator {
+ private Entry entry;
+
+ public FieldIndexHashTableIterator() {
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.util.Iterator#next()
+ */
+ public Entry next() {
+ Entry current = this.entry;
+ this.entry = (this.entry != null) ? this.entry.getNext() : null;
+ return current;
+ }
+
+ /* (non-Javadoc)
+ * @see org.drools.util.Iterator#reset()
+ */
+ public void reset(Entry entry) {
+ this.entry = entry;
+ }
+ }
+
+ public boolean add(InternalFactHandle handle) {
+ FieldIndexEntry entry = getOrCreate( handle.getObject() );
+ entry.add( handle );
+ this.factSize++;
+ return true;
+ }
+
+ public boolean add(InternalFactHandle handle,
+ boolean checkExists) {
+ throw new UnsupportedOperationException( "FieldIndexHashTable does not support add(InternalFactHandle handle, boolean checkExists)" );
+ }
+
+ public boolean remove(InternalFactHandle handle) {
+ Object object = handle.getObject();
+ int hashCode = this.index.hashCodeOf( object );
+
+ int index = indexOf( hashCode,
+ table.length );
+
+ // search the table for the Entry, we need to track previous and next, so if the
+ // Entry is empty after its had the FactEntry removed, we must remove it from the table
+ FieldIndexEntry previous = (FieldIndexEntry) this.table[index];
+ FieldIndexEntry current = previous;
+ while ( current != null ) {
+ FieldIndexEntry next = (FieldIndexEntry) current.next;
+ if ( current.matches( object,
+ hashCode ) ) {
+ current.remove( handle );
+ this.factSize--;
+ // If the FactEntryIndex is empty, then remove it from the hash map
+ if ( current.first == null ) {
+ if ( previous == current ) {
+ this.table[index] = next;
+ } else {
+ previous.next = next;
+ }
+ current.next = null;
+ this.size--;
+ }
+ return true;
+ }
+ previous = current;
+ current = next;
+ }
+ return false;
+ }
+
+ public boolean contains(InternalFactHandle handle) {
+ Object object = handle.getObject();
+ int hashCode = this.index.hashCodeOf( object );
+
+ int index = indexOf( hashCode,
+ table.length );
+
+ FieldIndexEntry current = (FieldIndexEntry) this.table[index];
+ while ( current != null ) {
+ if ( current.matches( object,
+ hashCode ) ) {
+ return true;
+ }
+ current = (FieldIndexEntry) current.next;
+ }
+ return false;
+ }
+
+ public FieldIndexEntry get(ReteTuple tuple) {
+ int hashCode = this.index.hashCodeOf( tuple );
+
+ int index = indexOf( hashCode,
+ table.length );
+ FieldIndexEntry entry = (FieldIndexEntry) this.table[index];
+
+ while ( entry != null ) {
+ if ( entry.matches( tuple,
+ hashCode ) ) {
+ return entry;
+ }
+ entry = (FieldIndexEntry) entry.getNext();
+ }
+
+ return entry;
+ }
+
+ /**
+ * We use this method to aviod to table lookups for the same hashcode; which is what we would have to do if we did
+ * a get and then a create if the value is null.
+ *
+ * @param value
+ * @return
+ */
+ private FieldIndexEntry getOrCreate(Object object) {
+ int hashCode = this.index.hashCodeOf( object );
+ int index = indexOf( hashCode,
+ table.length );
+ FieldIndexEntry entry = (FieldIndexEntry) this.table[index];
+
+ while ( entry != null ) {
+ if ( entry.matches( object,
+ hashCode ) ) {
+ return entry;
+ }
+ entry = (FieldIndexEntry) entry.next;
+ }
+
+ if ( entry == null ) {
+ entry = new FieldIndexEntry( this.index,
+ hashCode );
+ entry.next = this.table[index];
+ this.table[index] = entry;
+
+ if ( this.size++ >= this.threshold ) {
+ resize( 2 * this.table.length );
+ }
+ }
+ return entry;
+ }
+
+ public int size() {
+ return this.factSize;
+ }
+
+ public static class FieldIndexEntry
+ implements
+ Entry {
+ private Entry next;
+ private FactEntry first;
+ private final int hashCode;
+ private CompositeIndex index;
+
+ public FieldIndexEntry(CompositeIndex index,
+ int hashCode) {
+ this.index = index;
+ this.hashCode = hashCode;
+ }
+
+ public Entry getNext() {
+ return next;
+ }
+
+ public void setNext(Entry next) {
+ this.next = next;
+ }
+
+ public FactEntry getFirst() {
+ return this.first;
+ }
+
+ public void add(InternalFactHandle handle) {
+ FactEntry entry = new FactEntry( handle );
+ entry.next = this.first;
+ this.first = entry;
+ }
+
+ public FactEntry get(InternalFactHandle handle) {
+ long id = handle.getId();
+ FactEntry current = first;
+ while ( current != null ) {
+ if ( current.handle.getId() == id ) {
+ return current;
+ }
+ current = (FactEntry) current.next;
+ }
+ return null;
+ }
+
+ public FactEntry remove(InternalFactHandle handle) {
+ long id = handle.getId();
+
+ FactEntry previous = this.first;
+ FactEntry current = previous;
+ while ( current != null ) {
+ FactEntry next = (FactEntry) current.next;
+ if ( current.handle.getId() == id ) {
+ if ( this.first == current ) {
+ this.first = next;
+ } else {
+ previous.next = next;
+ }
+ current.next = null;
+ return current;
+ }
+ previous = current;
+ current = next;
+ }
+ return current;
+ }
+
+ public boolean matches(Object object,
+ int objectHashCode) {
+ return this.hashCode == objectHashCode && this.index.equal( this.first.getFactHandle().getObject(),
+ object );
+ }
+
+ public boolean matches(ReteTuple tuple,
+ int tupleHashCode) {
+ return this.hashCode == tupleHashCode && this.index.equal( this.first.getFactHandle().getObject(),
+ tuple );
+ }
+
+ public int hashCode() {
+ return this.hashCode;
+ }
+
+ public boolean equals(Object object) {
+ FieldIndexEntry other = (FieldIndexEntry) object;
+ return this.hashCode == other.hashCode && this.index == other.index;
+ }
+ }
+
+ private static interface CompositeIndex {
+ public int hashCodeOf(ReteTuple tuple);
+
+ public int hashCodeOf(Object object);
+
+ public boolean equal(Object object1,
+ Object object2);
+
+ public boolean equal(Object object1,
+ ReteTuple tuple);
+ }
+
+ private static class DefaultCompositeIndex
+ implements
+ CompositeIndex {
+ private FieldIndex[] indexes;
+ private int startResult;
+ private ObjectComparator comparator;
+
+ public DefaultCompositeIndex(FieldIndex[] indexes,
+ int startResult,
+ ObjectComparator comparator) {
+ this.startResult = startResult;
+ this.indexes = indexes;
+ this.comparator = comparator;
+ }
+
+ public int hashCodeOf(Object object) {
+ int hashCode = startResult;
+ for ( int i = 0, length = this.indexes.length; i < length; i++ ) {
+ Object value = indexes[i].getExtractor().getValue( object );
+ hashCode += CompositeFieldIndexHashTable.PRIME * hashCode + ((value == null) ? 0 : value.hashCode() );
+ }
+ return this.comparator.rehash( hashCode );
+ }
+
+ public int hashCodeOf(ReteTuple tuple) {
+ int hashCode = startResult;
+ for ( int i = 0, length = this.indexes.length; i < length; i++ ) {
+ Object value = indexes[i].declaration.getValue( tuple.get( indexes[i].declaration ).getObject() );
+ hashCode += CompositeFieldIndexHashTable.PRIME * hashCode + ((value == null) ? 0 : value.hashCode() );
+ }
+ return this.comparator.rehash( hashCode );
+ }
+
+ public boolean equal(Object object1,
+ ReteTuple tuple) {
+ for ( int i = 0, length = this.indexes.length; i < length; i++ ) {
+ Object value1 = indexes[i].extractor.getValue( object1 );
+ Object value2 = indexes[i].declaration.getValue( tuple.get( indexes[i].declaration ).getObject() );
+ if ( !this.comparator.equal( value1,
+ value2 ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean equal(Object object1,
+ Object object2) {
+ for ( int i = 0, length = this.indexes.length; i < length; i++ ) {
+ Object value1 = indexes[i].getExtractor().getValue( object1 );
+ Object value2 = indexes[i].getExtractor().getValue( object2 );
+ if ( !this.comparator.equal( value1,
+ value2 ) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ public static class FieldIndex {
+ private FieldExtractor extractor;
+ private Declaration declaration;
+
+ public FieldIndex(FieldExtractor extractor,
+ Declaration declaration) {
+ super();
+ this.extractor = extractor;
+ this.declaration = declaration;
+ }
+
+ public Declaration getDeclaration() {
+ return declaration;
+ }
+
+ public void setDeclaration(Declaration declaration) {
+ this.declaration = declaration;
+ }
+
+ public FieldExtractor getExtractor() {
+ return extractor;
+ }
+
+ public void setExtractor(FieldExtractor extractor) {
+ this.extractor = extractor;
+ }
+ }
+}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FieldIndexHashTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FieldIndexHashTable.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/FieldIndexHashTable.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -161,7 +161,7 @@
FieldIndexEntry current = (FieldIndexEntry) this.table[index];
while ( current != null ) {
- if ( hashCode == current.hashCode && value.equals( current.getValue() ) ) {
+ if ( hashCode == current.hashCode && this.comparator.equal( value, current.getValue() ) ) {
return true;
}
current = (FieldIndexEntry) current.next;
@@ -178,7 +178,7 @@
FieldIndexEntry entry = (FieldIndexEntry) this.table[index];
while ( entry != null ) {
- if ( hashCode == entry.hashCode && value.equals( entry.getValue() ) ) {
+ if ( hashCode == entry.hashCode && this.comparator.equal( value, entry.getValue() ) ) {
return entry;
}
entry = (FieldIndexEntry) entry.getNext();
@@ -201,7 +201,8 @@
FieldIndexEntry entry = (FieldIndexEntry) this.table[index];
while ( entry != null ) {
- if ( hashCode == entry.hashCode && value.equals( entry.getValue() ) ) {
+
+ if ( hashCode == entry.hashCode && this.comparator.equal( value, entry.getValue() ) ) {
return entry;
}
entry = (FieldIndexEntry) entry.next;
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java 2006-10-18 21:57:43 UTC (rev 6900)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/BaseMannersTest.java 2006-10-18 22:04:45 UTC (rev 6901)
@@ -763,6 +763,7 @@
context );
//System.err.println( "path done" + seating );
} catch ( Exception e ) {
+ e.printStackTrace();
throw new ConsequenceException( e );
}
}
More information about the jboss-svn-commits
mailing list