From 68a8d99c15a723dd62bf3f4e5de23519f326713d Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 20 Sep 2006 20:32:19 +0000 Subject: Comments and label changes. --- .../com/amazon/carbonado/cursor/GroupedCursor.java | 2 + .../carbonado/cursor/JoinedCursorFactory.java | 248 +++++++++++---------- .../carbonado/cursor/MultiTransformedCursor.java | 3 + .../amazon/carbonado/cursor/TransformedCursor.java | 3 + 4 files changed, 136 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/main/java/com/amazon/carbonado/cursor/GroupedCursor.java b/src/main/java/com/amazon/carbonado/cursor/GroupedCursor.java index bf838b1..5ec8a56 100644 --- a/src/main/java/com/amazon/carbonado/cursor/GroupedCursor.java +++ b/src/main/java/com/amazon/carbonado/cursor/GroupedCursor.java @@ -35,6 +35,8 @@ import com.amazon.carbonado.FetchInterruptedException; * * @author Brian S O'Neill * @see SortedCursor + * @param source type, can be anything + * @param aggregate type, can be anything */ public abstract class GroupedCursor extends AbstractCursor { private final Cursor mCursor; diff --git a/src/main/java/com/amazon/carbonado/cursor/JoinedCursorFactory.java b/src/main/java/com/amazon/carbonado/cursor/JoinedCursorFactory.java index ae98a95..b689c7e 100644 --- a/src/main/java/com/amazon/carbonado/cursor/JoinedCursorFactory.java +++ b/src/main/java/com/amazon/carbonado/cursor/JoinedCursorFactory.java @@ -56,12 +56,13 @@ import com.amazon.carbonado.spi.CodeBuilderUtil; import static com.amazon.carbonado.spi.CommonMethodNames.*; /** - * Given two joined types A and B, this factory converts a cursor - * over type A into a cursor over type B. For example, consider - * two storable types, Employer and Person. A query filter for persons with a - * given employer might look like: {@code "employer.name = ?" } The join can be - * manually implemented by querying for employers and then using this factory - * to produce persons: + * Given two joined types source and target, this factory + * converts a cursor over type source into a cursor over type + * target. For example, consider two storable types, Employer and + * Person. A query filter for persons with a given employer might look like: + * {@code "employer.name = ?" } The join can be manually implemented by + * querying for employers (the source) and then using this factory to produce + * persons (the target): * *
  * JoinedCursorFactory<Employer, Person> factory = new JoinedCursorFactory<Employer, Person>
@@ -88,12 +89,16 @@ import static com.amazon.carbonado.spi.CommonMethodNames.*;
  * 
* * @author Brian S O'Neill + * @see TransformedCursor + * @see MultiTransformedCursor + * @param source type, can be anything + * @param target type, must be a Storable */ -public class JoinedCursorFactory { +public class JoinedCursorFactory { private static final String STORAGE_FIELD_NAME = "storage"; private static final String QUERY_FIELD_NAME = "query"; private static final String QUERY_FILTER_FIELD_NAME = "queryFilter"; - private static final String ACTIVE_A_FIELD_NAME = "active"; + private static final String ACTIVE_SOURCE_FIELD_NAME = "active"; private static final Map cJoinerCursorClassCache; @@ -101,63 +106,63 @@ public class JoinedCursorFactory { cJoinerCursorClassCache = new SoftValuedHashMap(); } - private static synchronized Joiner - newBasicJoiner(StorableProperty bToAProperty, Storage bStorage) + private static synchronized Joiner + newBasicJoiner(StorableProperty targetToSourceProperty, Storage targetStorage) throws FetchException { - Class aType = bToAProperty.getType(); + Class sourceType = targetToSourceProperty.getType(); final Object key = KeyFactory.createKey - (new Object[] {aType, - bToAProperty.getEnclosingType(), - bToAProperty.getName()}); + (new Object[] {sourceType, + targetToSourceProperty.getEnclosingType(), + targetToSourceProperty.getName()}); Class clazz = cJoinerCursorClassCache.get(key); if (clazz == null) { - clazz = generateBasicJoinerCursor(aType, bToAProperty); + clazz = generateBasicJoinerCursor(sourceType, targetToSourceProperty); cJoinerCursorClassCache.put(key, clazz); } // Transforming cursor class may need a Query to operate on. - Query bQuery = null; + Query targetQuery = null; try { String filter = (String) clazz.getField(QUERY_FILTER_FIELD_NAME).get(null); - bQuery = bStorage.query(filter); + targetQuery = targetStorage.query(filter); } catch (NoSuchFieldException e) { } catch (IllegalAccessException e) { } - BasicJoiner.Factory factory = (BasicJoiner.Factory) QuickConstructorGenerator + BasicJoiner.Factory factory = (BasicJoiner.Factory) QuickConstructorGenerator .getInstance(clazz, BasicJoiner.Factory.class); - return new BasicJoiner(factory, bStorage, bQuery); + return new BasicJoiner(factory, targetStorage, targetQuery); } - private static Class> - generateBasicJoinerCursor(Class aType, StorableProperty bToAProperty) + private static Class> + generateBasicJoinerCursor(Class sourceType, StorableProperty targetToSourceProperty) { - final int propCount = bToAProperty.getJoinElementCount(); + final int propCount = targetToSourceProperty.getJoinElementCount(); // Determine if join is one-to-one, in which case slightly more optimal // code can be generated. boolean isOneToOne = true; for (int i=0; i bType = bToAProperty.getEnclosingType(); + Class targetType = targetToSourceProperty.getEnclosingType(); String packageName; { - String name = bType.getName(); + String name = targetType.getName(); int index = name.lastIndexOf('.'); if (index >= 0) { packageName = name.substring(0, index); @@ -166,7 +171,7 @@ public class JoinedCursorFactory { } } - ClassLoader loader = bType.getClassLoader(); + ClassLoader loader = targetType.getClassLoader(); ClassInjector ci = ClassInjector.create(packageName + ".JoinedCursor", loader); Class superclass = isOneToOne ? TransformedCursor.class : MultiTransformedCursor.class; @@ -183,15 +188,16 @@ public class JoinedCursorFactory { if (isOneToOne) { cf.addField(Modifiers.PRIVATE.toFinal(true), STORAGE_FIELD_NAME, storageType); } else { - // Field to hold query which fetches type B. + // Field to hold query which fetches type T. cf.addField(Modifiers.PRIVATE.toFinal(true), QUERY_FIELD_NAME, queryType); } - boolean canSetAReference = bToAProperty.getWriteMethod() != null; + boolean canSetSourceReference = targetToSourceProperty.getWriteMethod() != null; - if (canSetAReference && !isOneToOne) { - // Field to hold active A storable. - cf.addField(Modifiers.PRIVATE, ACTIVE_A_FIELD_NAME, TypeDesc.forClass(aType)); + if (canSetSourceReference && !isOneToOne) { + // Field to hold active S storable. + cf.addField(Modifiers.PRIVATE, ACTIVE_SOURCE_FIELD_NAME, + TypeDesc.forClass(sourceType)); } // Constructor accepts a Storage and Query, but Storage is only used @@ -202,16 +208,16 @@ public class JoinedCursorFactory { CodeBuilder b = new CodeBuilder(mi); b.loadThis(); - b.loadLocal(b.getParameter(0)); // pass A cursor to superclass + b.loadLocal(b.getParameter(0)); // pass S cursor to superclass b.invokeSuperConstructor(new TypeDesc[] {cursorType}); if (isOneToOne) { b.loadThis(); - b.loadLocal(b.getParameter(1)); // push B storage to stack + b.loadLocal(b.getParameter(1)); // push T storage to stack b.storeField(STORAGE_FIELD_NAME, storageType); } else { b.loadThis(); - b.loadLocal(b.getParameter(2)); // push B query to stack + b.loadLocal(b.getParameter(2)); // push T query to stack b.storeField(QUERY_FIELD_NAME, queryType); } @@ -227,7 +233,7 @@ public class JoinedCursorFactory { if (i > 0) { queryBuilder.append(" & "); } - queryBuilder.append(bToAProperty.getInternalJoinElement(i).getName()); + queryBuilder.append(targetToSourceProperty.getInternalJoinElement(i).getName()); queryBuilder.append(" = ?"); } @@ -243,32 +249,32 @@ public class JoinedCursorFactory { mi.addException(TypeDesc.forClass(FetchException.class)); CodeBuilder b = new CodeBuilder(mi); - LocalVariable aVar = b.createLocalVariable(null, storableType); + LocalVariable sourceVar = b.createLocalVariable(null, storableType); b.loadLocal(b.getParameter(0)); - b.checkCast(TypeDesc.forClass(aType)); - b.storeLocal(aVar); + b.checkCast(TypeDesc.forClass(sourceType)); + b.storeLocal(sourceVar); - // Prepare B storable. + // Prepare T storable. b.loadThis(); b.loadField(STORAGE_FIELD_NAME, storageType); b.invokeInterface(storageType, PREPARE_METHOD_NAME, storableType, null); - LocalVariable bVar = b.createLocalVariable(null, storableType); - b.checkCast(TypeDesc.forClass(bType)); - b.storeLocal(bVar); + LocalVariable targetVar = b.createLocalVariable(null, storableType); + b.checkCast(TypeDesc.forClass(targetType)); + b.storeLocal(targetVar); - // Copy pk property values from A to B. + // Copy pk property values from S to T. for (int i=0; i internal = bToAProperty.getInternalJoinElement(i); - StorableProperty external = bToAProperty.getExternalJoinElement(i); + StorableProperty internal = targetToSourceProperty.getInternalJoinElement(i); + StorableProperty external = targetToSourceProperty.getExternalJoinElement(i); - b.loadLocal(bVar); - b.loadLocal(aVar); + b.loadLocal(targetVar); + b.loadLocal(sourceVar); b.invoke(external.getReadMethod()); b.invoke(internal.getWriteMethod()); } - // tryLoad b. - b.loadLocal(bVar); + // tryLoad target. + b.loadLocal(targetVar); b.invokeInterface(storableType, TRY_LOAD_METHOD_NAME, TypeDesc.BOOLEAN, null); Label wasLoaded = b.createLabel(); b.ifZeroComparisonBranch(wasLoaded, "!="); @@ -278,13 +284,13 @@ public class JoinedCursorFactory { wasLoaded.setLocation(); - if (canSetAReference) { - b.loadLocal(bVar); - b.loadLocal(aVar); - b.invoke(bToAProperty.getWriteMethod()); + if (canSetSourceReference) { + b.loadLocal(targetVar); + b.loadLocal(sourceVar); + b.invoke(targetToSourceProperty.getWriteMethod()); } - b.loadLocal(bVar); + b.loadLocal(targetVar); b.returnValue(storableType); } else { MethodInfo mi = cf.addMethod(Modifiers.PROTECTED, "transform", cursorType, @@ -292,15 +298,15 @@ public class JoinedCursorFactory { mi.addException(TypeDesc.forClass(FetchException.class)); CodeBuilder b = new CodeBuilder(mi); - LocalVariable aVar = b.createLocalVariable(null, storableType); + LocalVariable sourceVar = b.createLocalVariable(null, storableType); b.loadLocal(b.getParameter(0)); - b.checkCast(TypeDesc.forClass(aType)); - b.storeLocal(aVar); + b.checkCast(TypeDesc.forClass(sourceType)); + b.storeLocal(sourceVar); - if (canSetAReference) { + if (canSetSourceReference) { b.loadThis(); - b.loadLocal(aVar); - b.storeField(ACTIVE_A_FIELD_NAME, TypeDesc.forClass(aType)); + b.loadLocal(sourceVar); + b.storeField(ACTIVE_SOURCE_FIELD_NAME, TypeDesc.forClass(sourceType)); } // Populate query parameters. @@ -308,8 +314,8 @@ public class JoinedCursorFactory { b.loadField(QUERY_FIELD_NAME, queryType); for (int i=0; i external = bToAProperty.getExternalJoinElement(i); - b.loadLocal(aVar); + StorableProperty external = targetToSourceProperty.getExternalJoinElement(i); + b.loadLocal(sourceVar); b.invoke(external.getReadMethod()); TypeDesc bindType = CodeBuilderUtil.bindQueryParam(external.getType()); @@ -323,8 +329,8 @@ public class JoinedCursorFactory { b.returnValue(cursorType); } - if (canSetAReference && !isOneToOne) { - // Override the "next" method to set A object on B. + if (canSetSourceReference && !isOneToOne) { + // Override the "next" method to set S object on T. MethodInfo mi = cf.addMethod(Modifiers.PUBLIC, "next", TypeDesc.OBJECT, null); mi.addException(TypeDesc.forClass(FetchException.class)); CodeBuilder b = new CodeBuilder(mi); @@ -332,128 +338,130 @@ public class JoinedCursorFactory { b.loadThis(); b.invokeSuper(TypeDesc.forClass(MultiTransformedCursor.class), "next", TypeDesc.OBJECT, null); - b.checkCast(TypeDesc.forClass(bType)); + b.checkCast(TypeDesc.forClass(targetType)); b.dup(); b.loadThis(); - b.loadField(ACTIVE_A_FIELD_NAME, TypeDesc.forClass(aType)); - b.invoke(bToAProperty.getWriteMethod()); + b.loadField(ACTIVE_SOURCE_FIELD_NAME, TypeDesc.forClass(sourceType)); + b.invoke(targetToSourceProperty.getWriteMethod()); b.returnValue(storableType); } - return (Class>) ci.defineClass(cf); + return (Class>) ci.defineClass(cf); } - private final Joiner mJoiner; + private final Joiner mJoiner; /** * @param repo access to storage instances for properties - * @param bType type of B instances - * @param bToAProperty property of B type which maps to instances of - * A type. - * @param aType type of A instances - * @throws IllegalArgumentException if property type is not A + * @param targetType type of target instances + * @param targetToSourceProperty property of target type which maps + * to instances of source type. + * @param sourceType type of source instances + * @throws IllegalArgumentException if property type is not source */ public JoinedCursorFactory(Repository repo, - Class bType, - String bToAProperty, - Class aType) + Class targetType, + String targetToSourceProperty, + Class sourceType) throws SupportException, FetchException, RepositoryException { this(repo, - ChainedProperty.parse(StorableIntrospector.examine(bType), bToAProperty), - aType); + ChainedProperty.parse(StorableIntrospector.examine(targetType), + targetToSourceProperty), + sourceType); } /** * @param repo access to storage instances for properties - * @param bToAProperty property of B type which maps to instances of - * A type. - * @param aType type of A instances - * @throws IllegalArgumentException if property type is not A + * @param targetToSourceProperty property of target type which maps + * to instances of source type. + * @param sourceType type of source instances + * @throws IllegalArgumentException if property type is not source */ public JoinedCursorFactory(Repository repo, - ChainedProperty bToAProperty, - Class aType) + ChainedProperty targetToSourceProperty, + Class sourceType) throws SupportException, FetchException, RepositoryException { - if (bToAProperty.getType() != aType) { + if (targetToSourceProperty.getType() != sourceType) { throw new IllegalArgumentException - ("Property is not of type \"" + aType.getName() + "\": " + - bToAProperty); + ("Property is not of type \"" + sourceType.getName() + "\": " + + targetToSourceProperty); } - StorableProperty primeB = bToAProperty.getPrimeProperty(); - Storage primeBStorage = repo.storageFor(primeB.getEnclosingType()); + StorableProperty primeTarget = targetToSourceProperty.getPrimeProperty(); + Storage primeTargetStorage = repo.storageFor(primeTarget.getEnclosingType()); - Joiner joiner = newBasicJoiner(primeB, primeBStorage); + Joiner joiner = newBasicJoiner(primeTarget, primeTargetStorage); - int chainCount = bToAProperty.getChainCount(); + int chainCount = targetToSourceProperty.getChainCount(); for (int i=0; i) joiner; + mJoiner = (Joiner) joiner; } /** - * Given a cursor over A, returns a new cursor over joined property - * of type B. + * Given a cursor over type source, returns a new cursor over joined + * property of type target. */ - public Cursor join(Cursor cursor) { + public Cursor join(Cursor cursor) { return mJoiner.join(cursor); } - private static interface Joiner { - Cursor join(Cursor cursor); + private static interface Joiner { + Cursor join(Cursor cursor); } /** * Support for joins without an intermediate hop. */ - private static class BasicJoiner implements Joiner { - private final Factory mJoinerFactory; - private final Storage mBStorage; - private final Query mBQuery; + private static class BasicJoiner implements Joiner { + private final Factory mJoinerFactory; + private final Storage mTargetStorage; + private final Query mTargetQuery; - BasicJoiner(Factory factory, Storage bStorage, Query bQuery) { + BasicJoiner(Factory factory, Storage targetStorage, Query targetQuery) { mJoinerFactory = factory; - mBStorage = bStorage; - mBQuery = bQuery; + mTargetStorage = targetStorage; + mTargetQuery = targetQuery; } - public Cursor join(Cursor cursor) { - return mJoinerFactory.newJoinedCursor(cursor, mBStorage, mBQuery); + public Cursor join(Cursor cursor) { + return mJoinerFactory.newJoinedCursor(cursor, mTargetStorage, mTargetQuery); } /** * Needs to be public for {@link QuickConstructorGenerator}. */ - public static interface Factory { - Cursor newJoinedCursor(Cursor cursor, Storage bStorage, Query bQuery); + public static interface Factory { + Cursor newJoinedCursor(Cursor cursor, + Storage targetStorage, Query targetQuery); } } /** * Support for joins with an intermediate hop -- multi-way joins. */ - private static class MultiJoiner - implements Joiner + private static class MultiJoiner + implements Joiner { - private final Joiner mAToMid; - private final Joiner mMidToB; + private final Joiner mSourceToMid; + private final Joiner mMidToTarget; - MultiJoiner(Joiner aToMidJoiner, Joiner midToBJoiner) { - mAToMid = aToMidJoiner; - mMidToB = midToBJoiner; + MultiJoiner(Joiner sourceToMidJoiner, Joiner midToTargetJoiner) { + mSourceToMid = sourceToMidJoiner; + mMidToTarget = midToTargetJoiner; } - public Cursor join(Cursor cursor) { - return mMidToB.join(mAToMid.join(cursor)); + public Cursor join(Cursor cursor) { + return mMidToTarget.join(mSourceToMid.join(cursor)); } } } diff --git a/src/main/java/com/amazon/carbonado/cursor/MultiTransformedCursor.java b/src/main/java/com/amazon/carbonado/cursor/MultiTransformedCursor.java index feeb414..3f06421 100644 --- a/src/main/java/com/amazon/carbonado/cursor/MultiTransformedCursor.java +++ b/src/main/java/com/amazon/carbonado/cursor/MultiTransformedCursor.java @@ -31,6 +31,9 @@ import com.amazon.carbonado.FetchInterruptedException; * joins. * * @author Brian S O'Neill + * @see JoinedCursorFactory + * @param source type, can be anything + * @param target type, can be anything */ public abstract class MultiTransformedCursor extends AbstractCursor { private final Cursor mCursor; diff --git a/src/main/java/com/amazon/carbonado/cursor/TransformedCursor.java b/src/main/java/com/amazon/carbonado/cursor/TransformedCursor.java index 9f9efe7..428e74e 100644 --- a/src/main/java/com/amazon/carbonado/cursor/TransformedCursor.java +++ b/src/main/java/com/amazon/carbonado/cursor/TransformedCursor.java @@ -30,6 +30,9 @@ import com.amazon.carbonado.FetchInterruptedException; * one-to-one joins. Use {@link MultiTransformedCursor} for one-to-many joins. * * @author Brian S O'Neill + * @see JoinedCursorFactory + * @param source type, can be anything + * @param target type, can be anything */ public abstract class TransformedCursor extends AbstractCursor { private final Cursor mCursor; -- cgit v1.2.3