From 8925e05f93c33c44dcfb119b327aa28772671e41 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Fri, 28 Mar 2008 16:55:16 +0000 Subject: Prevent duplicate field generation. --- .../carbonado/cursor/FilteredCursorGenerator.java | 87 ++++++++++++---------- 1 file changed, 49 insertions(+), 38 deletions(-) (limited to 'src/main/java/com/amazon/carbonado/cursor') diff --git a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java index dba2062..4e58361 100644 --- a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java +++ b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java @@ -24,6 +24,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Stack; @@ -271,7 +272,10 @@ class FilteredCursorGenerator { private final Stack mScopeStack; + private final Map mGeneratedPropertyFilters; + private List mSubFilters; + private Map mGeneratedSubFilters; private CodeBuilder mSubFilterInitBuilder; CodeGen(Map propertyOrdinalMap, @@ -287,6 +291,7 @@ class FilteredCursorGenerator { mStorableVar = storableVar; mScopeStack = new Stack(); mScopeStack.push(new Scope(null, null)); + mGeneratedPropertyFilters = new IdentityHashMap(); } public List finishSubFilterInit() { @@ -322,29 +327,10 @@ class FilteredCursorGenerator { } public Object visit(PropertyFilter filter, Object param) { - final int propertyOrdinal = mPropertyOrdinalMap.get(filter); - final TypeDesc type = TypeDesc.forClass(filter.getChainedProperty().getType()); - final TypeDesc fieldType = actualFieldType(type); - final String fieldName = FIELD_PREFIX + propertyOrdinal; - - // Define storage field. - mClassFile.addField(Modifiers.PRIVATE.toFinal(true), fieldName, fieldType); - - // Add code to constructor to store value into field. - { - CodeBuilder b = mCtorBuilder; - b.loadThis(); - b.loadLocal(b.getParameter(1)); - b.loadConstant(propertyOrdinal); - b.loadFromArray(OBJECT); - b.checkCast(type.toObjectType()); - convertProperty(b, type.toObjectType(), fieldType); - b.storeField(fieldName, fieldType); - } - + TypeDesc type = TypeDesc.forClass(filter.getChainedProperty().getType()); + String fieldName = addFilterField(filter, type); loadChainedProperty(mIsAllowedBuilder, filter.getChainedProperty()); - addPropertyFilter(mIsAllowedBuilder, propertyOrdinal, type, filter.getOperator()); - + addPropertyFilter(mIsAllowedBuilder, fieldName, type, filter.getOperator()); return null; } @@ -387,20 +373,7 @@ class FilteredCursorGenerator { b.invokeInterface(queryType, "and", queryType, new TypeDesc[] {filterType}); for (PropertyFilter subPropFilter : subPropFilters) { - final int propertyOrdinal = mPropertyOrdinalMap.get(subPropFilter); - final ChainedProperty chained = subPropFilter.getChainedProperty(); - final String fieldName = FIELD_PREFIX + propertyOrdinal; - - // Define storage for sub-filter. - mClassFile.addField(Modifiers.PRIVATE.toFinal(true), fieldName, OBJECT); - - // Assign value passed from constructor. - mCtorBuilder.loadThis(); - mCtorBuilder.loadLocal(mCtorBuilder.getParameter(1)); - mCtorBuilder.loadConstant(propertyOrdinal); - mCtorBuilder.loadFromArray(OBJECT); - mCtorBuilder.storeField(fieldName, OBJECT); - + String fieldName = addFilterField(subPropFilter, OBJECT); // Pass value to Query. b.loadThis(); b.loadField(fieldName, OBJECT); @@ -418,9 +391,44 @@ class FilteredCursorGenerator { return null; } + private String addFilterField(PropertyFilter filter, TypeDesc type) { + final int propertyOrdinal = mPropertyOrdinalMap.get(filter); + final String fieldName = FIELD_PREFIX + propertyOrdinal; + + if (mGeneratedPropertyFilters.containsKey(filter)) { + return fieldName; + } + + final TypeDesc fieldType = actualFieldType(type); + + mClassFile.addField(Modifiers.PRIVATE.toFinal(true), fieldName, fieldType); + + // Add code to constructor to store value into field. + { + CodeBuilder b = mCtorBuilder; + b.loadThis(); + b.loadLocal(b.getParameter(1)); + b.loadConstant(propertyOrdinal); + b.loadFromArray(OBJECT); + if (type != OBJECT) { + b.checkCast(type.toObjectType()); + convertProperty(b, type.toObjectType(), fieldType); + } + b.storeField(fieldName, fieldType); + } + + mGeneratedPropertyFilters.put(filter, filter); + return fieldName; + } + private String addStaticFilterField(Filter filter) { if (mSubFilters == null) { mSubFilters = new ArrayList(); + mGeneratedSubFilters = new IdentityHashMap(); + } + + if (mGeneratedSubFilters.containsKey(filter)) { + return mGeneratedSubFilters.get(filter); } final int filterOrdinal = mSubFilters.size(); @@ -455,6 +463,8 @@ class FilteredCursorGenerator { mSubFilterInitBuilder.loadFromArray(filterType); mSubFilterInitBuilder.storeStaticField(fieldName, filterType); + mGeneratedSubFilters.put(filter, fieldName); + return fieldName; } @@ -504,9 +514,10 @@ class FilteredCursorGenerator { b.invoke(readMethod); } - private void addPropertyFilter(CodeBuilder b, int ordinal, TypeDesc type, RelOp relOp) { + private void addPropertyFilter(CodeBuilder b, + String fieldName, TypeDesc type, RelOp relOp) + { TypeDesc fieldType = actualFieldType(type); - String fieldName = FIELD_PREFIX + ordinal; if (type.getTypeCode() == OBJECT_CODE) { // Check if actual property being examined is null. -- cgit v1.2.3