001: package org.drools.reteoo;
002:
003: import java.lang.reflect.Field;
004:
005: import org.drools.common.InternalWorkingMemory;
006: import org.drools.reteoo.RuleTerminalNode.TerminalNodeMemory;
007: import org.drools.util.AbstractHashTable;
008: import org.drools.util.Entry;
009: import org.drools.util.FactHashTable;
010: import org.drools.util.FactHandleIndexHashTable;
011: import org.drools.util.Iterator;
012: import org.drools.util.ObjectHashMap;
013: import org.drools.util.ReflectiveVisitor;
014: import org.drools.util.FactHandleIndexHashTable.FieldIndexEntry;
015: import org.drools.util.ObjectHashMap.ObjectEntry;
016:
017: public class MemoryVisitor extends ReflectiveVisitor {
018: private InternalWorkingMemory workingMemory;
019: private int indent = 0;
020:
021: /**
022: * Constructor.
023: */
024: public MemoryVisitor(final InternalWorkingMemory workingMemory) {
025: this .workingMemory = workingMemory;
026: }
027:
028: /**
029: * RuleBaseImpl visits its Rete.
030: */
031: public void visitReteooRuleBase(final ReteooRuleBase ruleBase) {
032: visit((ruleBase).getRete());
033: }
034:
035: /**
036: * Rete visits each of its ObjectTypeNodes.
037: */
038: public void visitRete(final Rete rete) {
039: final ObjectHashMap map = rete.getObjectTypeNodes();
040:
041: final Iterator it = map.newIterator();
042: for (ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it
043: .next()) {
044: visit(entry.getValue());
045: }
046: }
047:
048: public void visitObjectTypeNode(final ObjectTypeNode node) {
049: System.out.println(indent() + node);
050:
051: final FactHashTable memory = (FactHashTable) this .workingMemory
052: .getNodeMemory(node);
053: checkObjectHashTable(memory);
054:
055: this .indent++;
056: try {
057: final Field field = ObjectSource.class
058: .getDeclaredField("sink");
059: field.setAccessible(true);
060: final ObjectSinkPropagator sink = (ObjectSinkPropagator) field
061: .get(node);
062: final ObjectSink[] sinks = sink.getSinks();
063: for (int i = 0, length = sinks.length; i < length; i++) {
064: visit(sinks[i]);
065: }
066: } catch (final Exception e) {
067: e.printStackTrace();
068: }
069: this .indent--;
070: }
071:
072: public void visitAlphaNode(final AlphaNode node) {
073: System.out.println(indent() + node);
074:
075: final FactHashTable memory = (FactHashTable) this .workingMemory
076: .getNodeMemory(node);
077: checkObjectHashTable(memory);
078:
079: this .indent++;
080: try {
081: final Field field = ObjectSource.class
082: .getDeclaredField("sink");
083: field.setAccessible(true);
084: final ObjectSinkPropagator sink = (ObjectSinkPropagator) field
085: .get(node);
086: final ObjectSink[] sinks = sink.getSinks();
087: for (int i = 0, length = sinks.length; i < length; i++) {
088: visit(sinks[i]);
089: }
090: } catch (final Exception e) {
091: e.printStackTrace();
092: }
093: this .indent--;
094: }
095:
096: public void visitLeftInputAdapterNode(
097: final LeftInputAdapterNode node) {
098: System.out.println(indent() + node);
099:
100: this .indent++;
101: try {
102: final Field field = TupleSource.class
103: .getDeclaredField("sink");
104: field.setAccessible(true);
105: final TupleSinkPropagator sink = (TupleSinkPropagator) field
106: .get(node);
107: final TupleSink[] sinks = sink.getSinks();
108: for (int i = 0, length = sinks.length; i < length; i++) {
109: visit(sinks[i]);
110: }
111: } catch (final Exception e) {
112: e.printStackTrace();
113: }
114: this .indent--;
115: }
116:
117: public void visitJoinNode(final JoinNode node) {
118: System.out.println(indent() + node);
119:
120: try {
121: final BetaMemory memory = (BetaMemory) this .workingMemory
122: .getNodeMemory(node);
123: checkObjectHashTable(memory.getFactHandleMemory());
124: checkTupleMemory(memory.getTupleMemory());
125: } catch (final Exception e) {
126: e.printStackTrace();
127: }
128:
129: this .indent++;
130: try {
131: final Field field = TupleSource.class
132: .getDeclaredField("sink");
133: field.setAccessible(true);
134: final TupleSinkPropagator sink = (TupleSinkPropagator) field
135: .get(node);
136: final TupleSink[] sinks = sink.getSinks();
137: for (int i = 0, length = sinks.length; i < length; i++) {
138: visit(sinks[i]);
139: }
140: } catch (final Exception e) {
141: e.printStackTrace();
142: }
143: this .indent--;
144: }
145:
146: public void visitNotNode(final NotNode node) {
147: System.out.println(indent() + node);
148: try {
149: final BetaMemory memory = (BetaMemory) this .workingMemory
150: .getNodeMemory(node);
151: checkObjectHashTable(memory.getFactHandleMemory());
152: checkTupleMemory(memory.getTupleMemory());
153: } catch (final Exception e) {
154: e.printStackTrace();
155: }
156:
157: this .indent++;
158: try {
159: final Field field = TupleSource.class
160: .getDeclaredField("sink");
161: field.setAccessible(true);
162: final TupleSinkPropagator sink = (TupleSinkPropagator) field
163: .get(node);
164: final TupleSink[] sinks = sink.getSinks();
165: for (int i = 0, length = sinks.length; i < length; i++) {
166: visit(sinks[i]);
167: }
168: } catch (final Exception e) {
169: e.printStackTrace();
170: }
171: this .indent--;
172: }
173:
174: public void visitTerminalNode(final RuleTerminalNode node) {
175: System.out.println(indent() + node);
176: final TerminalNodeMemory memory = (TerminalNodeMemory) this .workingMemory
177: .getNodeMemory(node);
178: checkTupleMemory(memory.getTupleMemory());
179: }
180:
181: // private void checkObjectHashMap(final ObjectHashMap map) {
182: // final Entry[] entries = map.getTable();
183: // int count = 0;
184: // for ( int i = 0, length = entries.length; i < length; i++ ) {
185: // if ( entries[i] != null ) {
186: // count++;
187: // }
188: // }
189: //
190: // System.out.println( "ObjectHashMap: " + indent() + map.size() + ":" + count );
191: // if ( map.size() != count ) {
192: // System.out.println( indent() + "error" );
193: // }
194: // }
195:
196: private void checkObjectHashTable(final FactHandleMemory memory) {
197: if (memory instanceof FactHashTable) {
198: checkFactHashTable((FactHashTable) memory);
199: } else if (memory instanceof FactHandleIndexHashTable) {
200: checkFieldIndexHashTable((FactHandleIndexHashTable) memory);
201: } else {
202: throw new RuntimeException(memory.getClass()
203: + " should not be here");
204: }
205: }
206:
207: private void checkFactHashTable(final FactHashTable memory) {
208: final Entry[] entries = memory.getTable();
209: int count = 0;
210: for (int i = 0, length = entries.length; i < length; i++) {
211: if (entries[i] != null) {
212: Entry entry = entries[i];
213: while (entry != null) {
214: count++;
215: entry = entry.getNext();
216: }
217: }
218: }
219:
220: System.out.println(indent() + "FactHashTable: " + memory.size()
221: + ":" + count);
222: if (memory.size() != count) {
223: System.out.println(indent() + "error");
224: }
225: }
226:
227: private void checkFieldIndexHashTable(
228: final FactHandleIndexHashTable memory) {
229: final Entry[] entries = memory.getTable();
230: int factCount = 0;
231: int bucketCount = 0;
232: for (int i = 0, length = entries.length; i < length; i++) {
233: if (entries[i] != null) {
234: FieldIndexEntry fieldIndexEntry = (FieldIndexEntry) entries[i];
235: while (fieldIndexEntry != null) {
236: if (fieldIndexEntry.getFirst() != null) {
237: Entry entry = fieldIndexEntry.getFirst();
238: while (entry != null) {
239: entry = entry.getNext();
240: factCount++;
241: }
242: } else {
243: System.out
244: .println("error : fieldIndexHashTable cannot have empty FieldIndexEntry objects");
245: }
246: fieldIndexEntry = (FieldIndexEntry) fieldIndexEntry
247: .getNext();
248: bucketCount++;
249: }
250: }
251: }
252:
253: try {
254: final Field field = AbstractHashTable.class
255: .getDeclaredField("size");
256: field.setAccessible(true);
257: System.out.println(indent() + "FieldIndexBuckets: "
258: + ((Integer) field.get(memory)).intValue() + ":"
259: + bucketCount);
260: if (((Integer) field.get(memory)).intValue() != bucketCount) {
261: System.out.println(indent() + "error");
262: }
263: } catch (final Exception e) {
264: e.printStackTrace();
265: }
266:
267: System.out.println(indent() + "FieldIndexFacts: "
268: + memory.size() + ":" + factCount);
269: if (memory.size() != factCount) {
270: System.out.println(indent() + "error");
271: }
272: }
273:
274: private void checkTupleMemory(final TupleMemory memory) {
275: final Entry[] entries = memory.getTable();
276: int count = 0;
277: for (int i = 0, length = entries.length; i < length; i++) {
278: if (entries[i] != null) {
279: Entry entry = entries[i];
280: while (entry != null) {
281: count++;
282: entry = entry.getNext();
283: }
284: }
285: }
286:
287: System.out.println(indent() + "TupleMemory: " + memory.size()
288: + ":" + count);
289: if (memory.size() != count) {
290: System.out.println(indent() + "error");
291: }
292: }
293:
294: private String indent() {
295: final StringBuffer buffer = new StringBuffer();
296: for (int i = 0; i < this .indent; i++) {
297: buffer.append(" ");
298: }
299: return buffer.toString();
300: }
301: }
|