diff options
Diffstat (limited to 'src/main/java/com/amazon/carbonado')
6 files changed, 52 insertions, 142 deletions
diff --git a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java index 71aaf5b..7762885 100644 --- a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java +++ b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java @@ -38,7 +38,6 @@ import org.cojen.util.ClassInjector; import org.cojen.util.WeakIdentityMap;
import com.amazon.carbonado.Cursor;
-import com.amazon.carbonado.Query;
import com.amazon.carbonado.Storable;
import com.amazon.carbonado.filter.AndFilter;
@@ -168,11 +167,7 @@ class FilteredCursorGenerator { isAllowedBuilder.storeLocal(storableVar);
}
- CodeGen<S> cg = new CodeGen<S>(cf, ctorBuilder, isAllowedBuilder, storableVar);
- filter.accept(cg, null);
-
- // Finish static initializer. (if any)
- cg.finish();
+ filter.accept(new CodeGen<S>(cf, ctorBuilder, isAllowedBuilder, storableVar), null);
// Finish constructor.
ctorBuilder.returnVoid();
@@ -241,7 +236,6 @@ class FilteredCursorGenerator { private static class CodeGen<S extends Storable> extends Visitor<S, Object, Object> {
private static String FIELD_PREFIX = "value$";
- private static String FILTER_FIELD_PREFIX = "filter$";
private final ClassFile mClassFile;
private final CodeBuilder mCtorBuilder;
@@ -252,8 +246,6 @@ class FilteredCursorGenerator { private int mPropertyOrdinal;
- private CodeBuilder mInitBuilder;
-
CodeGen(ClassFile cf,
CodeBuilder ctorBuilder,
CodeBuilder isAllowedBuilder, LocalVariable storableVar) {
@@ -265,12 +257,6 @@ class FilteredCursorGenerator { mScopeStack.push(new Scope(null, null));
}
- public void finish() {
- if (mInitBuilder != null) {
- mInitBuilder.returnVoid();
- }
- }
-
public Object visit(OrFilter<S> filter, Object param) {
Label failLocation = mIsAllowedBuilder.createLabel();
// Inherit success location to short-circuit if 'or' test succeeds.
@@ -316,72 +302,25 @@ class FilteredCursorGenerator { b = mIsAllowedBuilder;
b.loadLocal(mStorableVar);
loadProperty(b, chained.getPrimeProperty());
+ for (int i=0; i<chained.getChainCount(); i++) {
+ // Check if last loaded property was null, and fail if so.
+ b.dup();
+ Label notNull = b.createLabel();
+ b.ifNullBranch(notNull, false);
+ b.pop();
+ getScope().fail(b);
+ notNull.setLocation();
- if (chained.getPrimeProperty().isQuery()) {
- Filter tail = Filter.getOpenFilter(chained.getPrimeProperty().getJoinedType())
- .and(chained.tail().toString(), filter.getOperator());
-
- String filterFieldName = addStaticFilterField(tail);
-
- TypeDesc filterType = TypeDesc.forClass(Filter.class);
- TypeDesc queryType = TypeDesc.forClass(Query.class);
-
- b.loadStaticField(filterFieldName, filterType);
- b.invokeInterface(queryType, "and", queryType, new TypeDesc[] {filterType});
- b.loadThis();
- b.loadField(fieldName, fieldType);
- TypeDesc withType = fieldType;
- if (!withType.isPrimitive()) {
- withType = TypeDesc.OBJECT;
- }
- b.invokeInterface(queryType, "with", queryType, new TypeDesc[] {withType});
- b.invokeInterface(queryType, "exists", TypeDesc.BOOLEAN, null);
-
- // Success if boolean value is true (non-zero).
- getScope().successIfZeroComparisonElseFail(b, RelOp.NE);
- } else {
- for (int i=0; i<chained.getChainCount(); i++) {
- // Check if last loaded property was null, and fail if so.
- b.dup();
- Label notNull = b.createLabel();
- b.ifNullBranch(notNull, false);
- b.pop();
- getScope().fail(b);
- notNull.setLocation();
-
- // Now load next property in chain.
- loadProperty(b, chained.getChainedProperty(i));
- }
-
- addPropertyFilter(b, type, filter.getOperator());
+ // Now load next property in chain.
+ loadProperty(b, chained.getChainedProperty(i));
}
+ addPropertyFilter(b, type, filter.getOperator());
+
mPropertyOrdinal++;
return null;
}
- private String addStaticFilterField(Filter filter) {
- String fieldName = FILTER_FIELD_PREFIX + mPropertyOrdinal;
-
- TypeDesc filterType = TypeDesc.forClass(Filter.class);
- TypeDesc classType = TypeDesc.forClass(Class.class);
-
- mClassFile.addField(Modifiers.PRIVATE.toStatic(true).toFinal(true),
- fieldName, filterType);
-
- if (mInitBuilder == null) {
- mInitBuilder = new CodeBuilder(mClassFile.addInitializer());
- }
-
- mInitBuilder.loadConstant(TypeDesc.forClass(filter.getStorableType()));
- mInitBuilder.loadConstant(filter.toString());
- mInitBuilder.invokeStatic(Filter.class.getName(), "filterFor", filterType,
- new TypeDesc[] {classType, TypeDesc.STRING});
- mInitBuilder.storeStaticField(fieldName, filterType);
-
- return fieldName;
- }
-
private Scope getScope() {
return mScopeStack.peek();
}
diff --git a/src/main/java/com/amazon/carbonado/filter/AndFilter.java b/src/main/java/com/amazon/carbonado/filter/AndFilter.java index fb158f3..be38800 100644 --- a/src/main/java/com/amazon/carbonado/filter/AndFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/AndFilter.java @@ -67,24 +67,17 @@ public class AndFilter<S extends Storable> extends BinaryOpFilter<S> { }
@Override
- NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
- NotJoined left = mLeft.notJoinedFromCNF(joinProperty);
- NotJoined right = mRight.notJoinedFromCNF(joinProperty);
+ NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
+ Class<? extends Storable> joinPropertyType)
+ {
+ NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType);
+ NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType);
// Remove wildcards to shut the compiler up.
Filter leftNotJoined = left.getNotJoinedFilter();
Filter rightNotJoined = right.getNotJoinedFilter();
- Filter notJoined;
- if (leftNotJoined == null) {
- notJoined = rightNotJoined;
- } else if (rightNotJoined == null) {
- notJoined = leftNotJoined;
- } else {
- notJoined = leftNotJoined.and(rightNotJoined);
- }
-
- return new NotJoined(notJoined,
+ return new NotJoined(leftNotJoined.and(rightNotJoined),
left.getRemainderFilter().and(right.getRemainderFilter()));
}
diff --git a/src/main/java/com/amazon/carbonado/filter/Filter.java b/src/main/java/com/amazon/carbonado/filter/Filter.java index 79f0435..cbc37dc 100644 --- a/src/main/java/com/amazon/carbonado/filter/Filter.java +++ b/src/main/java/com/amazon/carbonado/filter/Filter.java @@ -574,18 +574,19 @@ public abstract class Filter<S extends Storable> implements Appender { *
* @param joinProperty property to not join from
* @return not join result
- * @throws IllegalArgumentException if property is not a join
+ * @throws IllegalArgumentException if property does not refer to a Storable
*/
public final NotJoined notJoinedFrom(ChainedProperty<S> joinProperty) {
- Class<? extends Storable> type = joinProperty.getLastProperty().getJoinedType();
- if (type == null) {
- throw new IllegalArgumentException("Not a join property: " + joinProperty);
+ Class<?> type = joinProperty.getType();
+ if (!Storable.class.isAssignableFrom(type)) {
+ throw new IllegalArgumentException
+ ("Join property type is not a Storable: " + joinProperty);
}
Filter<S> cnf = conjunctiveNormalForm();
- NotJoined nj = cnf.notJoinedFromCNF(joinProperty);
+ NotJoined nj = cnf.notJoinedFrom(joinProperty, (Class<Storable>) type);
- if (nj.getNotJoinedFilter() == null) {
+ if (nj.getNotJoinedFilter() instanceof OpenFilter) {
// Remainder filter should be same as original, but it might have
// expanded with conjunctive normal form. If so, restore to
// original, but still bind it to ensure consistent side-effects.
@@ -599,17 +600,11 @@ public abstract class Filter<S extends Storable> implements Appender { // conversion from disjunctive normal form to conjunctive normal
// form may make major changes. If original was dnf, restore the
// result filters to dnf.
-
- boolean isNotJoinedDNF = nj.getNotJoinedFilter() == null
- || nj.getNotJoinedFilter().isDisjunctiveNormalForm();
-
- boolean isRemainerDNF = nj.getRemainderFilter().isDisjunctiveNormalForm();
-
- if (!isNotJoinedDNF || !isRemainerDNF) {
- Filter<?> notJoinedDNF = nj.getNotJoinedFilter() == null ? null
- : nj.getNotJoinedFilter().disjunctiveNormalForm();
-
- nj = new NotJoined(notJoinedDNF,
+
+ if (!(nj.getNotJoinedFilter().isDisjunctiveNormalForm()) ||
+ !(nj.getRemainderFilter().isDisjunctiveNormalForm()))
+ {
+ nj = new NotJoined(nj.getNotJoinedFilter().disjunctiveNormalForm(),
nj.getRemainderFilter().disjunctiveNormalForm());
}
}
@@ -620,8 +615,10 @@ public abstract class Filter<S extends Storable> implements Appender { /**
* Should only be called on a filter in conjunctive normal form.
*/
- NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
- return new NotJoined(null, this);
+ NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
+ Class<? extends Storable> joinPropertyType)
+ {
+ return new NotJoined(getOpenFilter(joinPropertyType), this);
}
abstract Filter<S> buildDisjunctiveNormalForm();
@@ -692,11 +689,8 @@ public abstract class Filter<S extends Storable> implements Appender { /**
* Returns the filter which is no longer as from a join.
*
- * @return not joined filter or <i>null</i> if none
+ * @return not joined filter or open filter if none
*/
- // Design note: Return value might be null since not all join
- // properties have an open filter representation. For example, some
- // joins return Query objects.
public Filter<?> getNotJoinedFilter() {
return mNotJoined;
}
@@ -704,18 +698,14 @@ public abstract class Filter<S extends Storable> implements Appender { /**
* Returns the filter which could not be separated.
*
- * @return remainder filter or <i>open filter</i> if none
+ * @return remainder filter or open filter if none
*/
public Filter<S> getRemainderFilter() {
return mRemainder;
}
public int hashCode() {
- if (mNotJoined == null) {
- return mRemainder.hashCode();
- } else {
- return mNotJoined.hashCode() * 31 + mRemainder.hashCode();
- }
+ return mNotJoined.hashCode() * 31 + mRemainder.hashCode();
}
public boolean equals(Object obj) {
@@ -724,9 +714,7 @@ public abstract class Filter<S extends Storable> implements Appender { }
if (obj instanceof Filter.NotJoined) {
NotJoined other = (NotJoined) obj;
- return (mNotJoined == null ? other.mNotJoined == null
- : mNotJoined.equals(other.mNotJoined))
- && mRemainder.equals(other.mRemainder);
+ return mNotJoined.equals(other.mNotJoined) && mRemainder.equals(other.mRemainder);
}
return false;
}
diff --git a/src/main/java/com/amazon/carbonado/filter/FilterParser.java b/src/main/java/com/amazon/carbonado/filter/FilterParser.java index aa01ba9..a0a178d 100644 --- a/src/main/java/com/amazon/carbonado/filter/FilterParser.java +++ b/src/main/java/com/amazon/carbonado/filter/FilterParser.java @@ -220,7 +220,7 @@ class FilterParser<S extends Storable> { }
List<StorableProperty<?>> chain = new ArrayList<StorableProperty<?>>(4);
- Class<?> type = prime.isJoin() ? prime.getJoinedType() : prime.getType();
+ Class<?> type = prime.getType();
while (true) {
ident = parseIdentifier();
diff --git a/src/main/java/com/amazon/carbonado/filter/OrFilter.java b/src/main/java/com/amazon/carbonado/filter/OrFilter.java index 67da5ba..d5748aa 100644 --- a/src/main/java/com/amazon/carbonado/filter/OrFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/OrFilter.java @@ -67,9 +67,11 @@ public class OrFilter<S extends Storable> extends BinaryOpFilter<S> { }
@Override
- NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
- NotJoined left = mLeft.notJoinedFromCNF(joinProperty);
- NotJoined right = mRight.notJoinedFromCNF(joinProperty);
+ NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
+ Class<? extends Storable> joinPropertyType)
+ {
+ NotJoined left = mLeft.notJoinedFrom(joinProperty, joinPropertyType);
+ NotJoined right = mRight.notJoinedFrom(joinProperty, joinPropertyType);
// Assert that our child nodes are only OrFilter or PropertyFilter.
if (!isConjunctiveNormalForm()) {
@@ -86,23 +88,14 @@ public class OrFilter<S extends Storable> extends BinaryOpFilter<S> { if (!(left.getRemainderFilter() instanceof OpenFilter) ||
!(right.getRemainderFilter() instanceof OpenFilter))
{
- return super.notJoinedFromCNF(joinProperty);
+ return super.notJoinedFrom(joinProperty, joinPropertyType);
}
// Remove wildcards to shut the compiler up.
Filter leftNotJoined = left.getNotJoinedFilter();
Filter rightNotJoined = right.getNotJoinedFilter();
- Filter notJoined;
- if (leftNotJoined == null) {
- notJoined = rightNotJoined;
- } else if (rightNotJoined == null) {
- notJoined = leftNotJoined;
- } else {
- notJoined = leftNotJoined.or(rightNotJoined);
- }
-
- return new NotJoined(notJoined, getOpenFilter(getStorableType()));
+ return new NotJoined(leftNotJoined.or(rightNotJoined), getOpenFilter(getStorableType()));
}
Filter<S> buildDisjunctiveNormalForm() {
diff --git a/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java b/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java index deb1f21..9f12095 100644 --- a/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java +++ b/src/main/java/com/amazon/carbonado/filter/PropertyFilter.java @@ -189,12 +189,7 @@ public class PropertyFilter<S extends Storable> extends Filter<S> { }
public <T extends Storable> PropertyFilter<T> asJoinedFrom(ChainedProperty<T> joinProperty) {
- Class<?> type = joinProperty.getLastProperty().getJoinedType();
- if (type == null) {
- type = joinProperty.getType();
- }
-
- if (type != getStorableType()) {
+ if (joinProperty.getType() != getStorableType()) {
throw new IllegalArgumentException
("Property is not of type \"" + getStorableType().getName() + "\": " +
joinProperty);
@@ -210,7 +205,9 @@ public class PropertyFilter<S extends Storable> extends Filter<S> { }
@Override
- NotJoined notJoinedFromCNF(ChainedProperty<S> joinProperty) {
+ NotJoined notJoinedFrom(ChainedProperty<S> joinProperty,
+ Class<? extends Storable> joinPropertyType)
+ {
ChainedProperty<?> notJoinedProp = getChainedProperty();
ChainedProperty<?> jp = joinProperty;
@@ -224,7 +221,7 @@ public class PropertyFilter<S extends Storable> extends Filter<S> { }
if (jp != null || notJoinedProp.equals(getChainedProperty())) {
- return super.notJoinedFromCNF(joinProperty);
+ return super.notJoinedFrom(joinProperty, joinPropertyType);
}
PropertyFilter<?> notJoinedFilter;
|