From b66fb3db6951b2b6d3ace72ca3e197c7c2048e86 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Thu, 18 Dec 2008 20:58:00 +0000 Subject: Fixes for excessive class generation and memory usage when opening multiple repositories. --- .../SyntheticStorableReferenceAccess.java | 152 +++++++++++++++++++++ .../SyntheticStorableReferenceBuilder.java | 110 +++++---------- 2 files changed, 186 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceAccess.java (limited to 'src/main/java/com/amazon/carbonado/synthetic') diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceAccess.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceAccess.java new file mode 100644 index 0000000..778b4ac --- /dev/null +++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceAccess.java @@ -0,0 +1,152 @@ +/* + * Copyright 2008 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.amazon.carbonado.synthetic; + +import java.lang.reflect.Method; +import java.lang.reflect.UndeclaredThrowableException; + +import java.util.Comparator; +import java.util.Iterator; + +import com.amazon.carbonado.Storable; + +import com.amazon.carbonado.cursor.SortedCursor; + +import com.amazon.carbonado.util.ThrowUnchecked; + +/** + * Provides access to the generated storable reference class and utility + * methods. + * + * @author Brian S O'Neill + * @see SyntheticStorableReferenceBuilder + * @since 1.2.1 + */ +public class SyntheticStorableReferenceAccess { + private final Class mMasterClass; + private final Class mReferenceClass; + + private final Comparator mComparator; + + private final Method mCopyFromMasterMethod; + private final Method mIsConsistentMethod; + private final Method mCopyToMasterPkMethod; + + SyntheticStorableReferenceAccess(Class masterClass, + Class referenceClass, + SyntheticStorableReferenceBuilder builder) + { + mMasterClass = masterClass; + mReferenceClass = referenceClass; + + // We need a comparator which follows the same order as the generated + // storable. + SyntheticKey pk = builder.mPrimaryKey; + String[] orderBy = new String[pk.getPropertyCount()]; + int i=0; + Iterator it = pk.getProperties(); + while (it.hasNext()) { + orderBy[i++] = it.next(); + } + mComparator = SortedCursor.createComparator(referenceClass, orderBy); + + try { + mCopyFromMasterMethod = + referenceClass.getMethod(builder.mCopyFromMasterMethodName, masterClass); + + mIsConsistentMethod = + referenceClass.getMethod(builder.mIsConsistentMethodName, masterClass); + + mCopyToMasterPkMethod = + referenceClass.getMethod(builder.mCopyToMasterPkMethodName, masterClass); + } catch (NoSuchMethodException e) { + throw new UndeclaredThrowableException(e); + } + } + + /** + * Returns the storable class which is referenced. + */ + public Class getMasterClass() { + return mMasterClass; + } + + /** + * Returns the generated storable reference class. + */ + public Class getReferenceClass() { + return mReferenceClass; + } + + /** + * Returns a comparator for ordering storable reference instances. This + * order matches the primary key of the master storable. + */ + public Comparator getComparator() { + return mComparator; + } + + /** + * Sets all the primary key properties of the given master, using the + * applicable properties of the given reference. + * + * @param reference source of property values + * @param master master whose primary key properties will be set + */ + public void copyToMasterPrimaryKey(Storable reference, S master) { + try { + mCopyToMasterPkMethod.invoke(reference, master); + } catch (Exception e) { + ThrowUnchecked.fireFirstDeclaredCause(e); + } + } + + /** + * Sets all the properties of the given reference, using the applicable + * properties of the given master. + * + * @param reference reference whose properties will be set + * @param master source of property values + */ + public void copyFromMaster(Storable reference, S master) { + try { + mCopyFromMasterMethod.invoke(reference, master); + } catch (Exception e) { + ThrowUnchecked.fireFirstDeclaredCause(e); + } + } + + /** + * Returns true if the properties of the given reference match those + * contained in the master, excluding any version property. This will + * always return true after a call to copyFromMaster. + * + * @param reference reference whose properties will be tested + * @param master source of property values + */ + public boolean isConsistent(Storable reference, S master) { + try { + return (Boolean) mIsConsistentMethod.invoke(reference, master); + } catch (Exception e) { + ThrowUnchecked.fireFirstDeclaredCause(e); + // Not reached. + return false; + } + } +} diff --git a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java index 4fddcd5..a06c557 100644 --- a/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java +++ b/src/main/java/com/amazon/carbonado/synthetic/SyntheticStorableReferenceBuilder.java @@ -18,7 +18,6 @@ package com.amazon.carbonado.synthetic; import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -29,13 +28,11 @@ import java.util.Set; import com.amazon.carbonado.Storable; import com.amazon.carbonado.SupportException; -import com.amazon.carbonado.cursor.SortedCursor; import com.amazon.carbonado.info.Direction; import com.amazon.carbonado.info.StorableInfo; import com.amazon.carbonado.info.StorableIntrospector; import com.amazon.carbonado.info.StorableProperty; import com.amazon.carbonado.gen.CodeBuilderUtil; -import com.amazon.carbonado.util.ThrowUnchecked; import org.cojen.classfile.ClassFile; import org.cojen.classfile.CodeBuilder; @@ -80,7 +77,7 @@ public class SyntheticStorableReferenceBuilder // Information about the storable from which this one is derived // private StorableInfo mBaseStorableInfo; - private Class mMasterStorableClass; + private Class mMasterStorableClass; // Stashed copy of the results of calling StorableIntrospector.examine(...) // on the master storable class. @@ -90,7 +87,7 @@ public class SyntheticStorableReferenceBuilder private SyntheticStorableBuilder mBuilder; // Primary key of generated storable. - private SyntheticKey mPrimaryKey; + SyntheticKey mPrimaryKey; // Elements added to primary key to ensure uniqueness private Set mExtraPkProps; @@ -99,9 +96,6 @@ public class SyntheticStorableReferenceBuilder // uniquely identify a unique instance of the referent. private boolean mIsUnique = true; - // The result of building - private Class mSyntheticClass; - // The list of properties explicitly added to this reference builder private List mUserProps; @@ -110,16 +104,12 @@ public class SyntheticStorableReferenceBuilder // are retrieved from the master. private List mCommonProps; - private String mCopyFromMasterMethodName; - private Method mCopyFromMasterMethod; - - private String mIsConsistentMethodName; - private Method mIsConsistentMethod; - - private String mCopyToMasterPkMethodName; - private Method mCopyToMasterPkMethod; + String mCopyFromMasterMethodName; + String mIsConsistentMethodName; + String mCopyToMasterPkMethodName; - private Comparator mComparator; + // The result of building. + private SyntheticStorableReferenceAccess mReferenceAccess; /** * @param storableClass @@ -210,26 +200,27 @@ public class SyntheticStorableReferenceBuilder return cfg; } + /** + * Build and return access to the generated storable reference class. + * + * @since 1.2.1 + */ + public SyntheticStorableReferenceAccess getReferenceAccess() { + if (mReferenceAccess == null) { + Class referenceClass = mBuilder.getStorableClass(); + mReferenceAccess = new SyntheticStorableReferenceAccess + (mMasterStorableClass, referenceClass, this); + } + return mReferenceAccess; + } + /* * (non-Javadoc) * * @see com.amazon.carbonado.synthetic.SyntheticBuilder#getStorableClass() */ public Class getStorableClass() throws IllegalStateException { - if (mSyntheticClass == null) { - mSyntheticClass = mBuilder.getStorableClass(); - - // We need a comparator which follows the same order as the generated - // storable. We can't construct it until we get here. - String[] orderBy = new String[mPrimaryKey.getPropertyCount()]; - int i=0; - Iterator it = mPrimaryKey.getProperties(); - while (it.hasNext()) { - orderBy[i++] = it.next(); - } - mComparator = SortedCursor.createComparator(mSyntheticClass, orderBy); - } - return mSyntheticClass; + return getReferenceAccess().getReferenceClass(); } /* @@ -356,22 +347,11 @@ public class SyntheticStorableReferenceBuilder * * @param indexEntry source of property values * @param master master whose primary key properties will be set + * @deprecated call getReferenceAccess */ + @Deprecated public void copyToMasterPrimaryKey(Storable indexEntry, S master) { - if (mCopyToMasterPkMethod == null) { - try { - mCopyToMasterPkMethod = - mSyntheticClass.getMethod(mCopyToMasterPkMethodName, mMasterStorableClass); - } catch (NoSuchMethodException e) { - throw new UndeclaredThrowableException(e); - } - } - - try { - mCopyToMasterPkMethod.invoke(indexEntry, master); - } catch (Exception e) { - ThrowUnchecked.fireFirstDeclaredCause(e); - } + getReferenceAccess().copyToMasterPrimaryKey(indexEntry, master); } /** @@ -380,22 +360,11 @@ public class SyntheticStorableReferenceBuilder * * @param indexEntry index entry whose properties will be set * @param master source of property values + * @deprecated call getReferenceAccess */ + @Deprecated public void copyFromMaster(Storable indexEntry, S master) { - if (mCopyFromMasterMethod == null) { - try { - mCopyFromMasterMethod = - mSyntheticClass.getMethod(mCopyFromMasterMethodName, mMasterStorableClass); - } catch (NoSuchMethodException e) { - throw new UndeclaredThrowableException(e); - } - } - - try { - mCopyFromMasterMethod.invoke(indexEntry, master); - } catch (Exception e) { - ThrowUnchecked.fireFirstDeclaredCause(e); - } + getReferenceAccess().copyFromMaster(indexEntry, master); } /** @@ -407,31 +376,20 @@ public class SyntheticStorableReferenceBuilder * index entry whose properties will be tested * @param master * source of property values + * @deprecated call getReferenceAccess */ + @Deprecated public boolean isConsistent(Storable indexEntry, S master) { - if (mIsConsistentMethod == null) { - try { - mIsConsistentMethod = - mSyntheticClass.getMethod(mIsConsistentMethodName, mMasterStorableClass); - } catch (NoSuchMethodException e) { - throw new UndeclaredThrowableException(e); - } - } - - try { - return (Boolean) mIsConsistentMethod.invoke(indexEntry, master); - } catch (Exception e) { - ThrowUnchecked.fireFirstDeclaredCause(e); - // Not reached. - return false; - } + return getReferenceAccess().isConsistent(indexEntry, master); } /** * Returns a comparator for ordering index entries. + * @deprecated call getReferenceAccess */ + @Deprecated public Comparator getComparator() { - return mComparator; + return getReferenceAccess().getComparator(); } /** -- cgit v1.2.3