summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-12-22 19:35:56 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-12-22 19:35:56 +0000
commit9d219c6af6ce718a282a00fd2a93dc0e08ccf548 (patch)
treeba161961f6bb2a30d8328fd452d13c5805f4686f
parentbeffd324a69aab98494839098f32c57de34e101e (diff)
Eliminate level of indirection when accessing indexes.
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/IndexAnalysis.java9
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/IndexEntryGenerator.java137
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java20
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java2
-rw-r--r--src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java24
5 files changed, 72 insertions, 120 deletions
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexAnalysis.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexAnalysis.java
index 241f297..5175488 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexAnalysis.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexAnalysis.java
@@ -51,6 +51,8 @@ import com.amazon.carbonado.info.StorableProperty;
import com.amazon.carbonado.qe.FilteringScore;
import com.amazon.carbonado.qe.StorableIndexSet;
+import com.amazon.carbonado.synthetic.SyntheticStorableReferenceAccess;
+
/**
* Builds various sets of indexes for a Storable type.
*
@@ -275,11 +277,12 @@ class IndexAnalysis<S extends Storable> {
ManagedIndex<S>[] managedIndexes = new ManagedIndex[managedIndexSet.size()];
int i = 0;
for (StorableIndex<S> index : managedIndexSet) {
- IndexEntryGenerator<S> builder = IndexEntryGenerator.getInstance(index);
- Class<? extends Storable> indexEntryClass = builder.getIndexEntryClass();
+ SyntheticStorableReferenceAccess<S> accessor =
+ IndexEntryGenerator.getIndexAccess(index);
+ Class<? extends Storable> indexEntryClass = accessor.getReferenceClass();
Storage<?> indexEntryStorage = repository.getIndexEntryStorageFor(indexEntryClass);
ManagedIndex managedIndex = new ManagedIndex<S>
- (repository, masterStorage, index, builder, indexEntryStorage);
+ (repository, masterStorage, index, accessor, indexEntryStorage);
allIndexInfoMap.put(index, managedIndex);
managedIndexes[i++] = managedIndex;
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexEntryGenerator.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexEntryGenerator.java
index 7fb80dc..19bfa8c 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexEntryGenerator.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexEntryGenerator.java
@@ -41,138 +41,83 @@ import com.amazon.carbonado.synthetic.SyntheticStorableReferenceBuilder;
*/
class IndexEntryGenerator <S extends Storable> {
- // cache for generators
- private static Map<StorableIndex, Reference<IndexEntryGenerator>> cCache =
- new WeakHashMap<StorableIndex, Reference<IndexEntryGenerator>>();
-
+ // cache for access classes
+ private static Map<StorableIndex, Reference<SyntheticStorableReferenceAccess>> cCache =
+ new WeakHashMap<StorableIndex, Reference<SyntheticStorableReferenceAccess>>();
/**
- * Returns a new or cached generator instance. The caching of generators is
- * soft, so if no references remain to a given instance it may be garbage
- * collected. A subsequent call will return a newly created instance.
+ * Returns a new or cached index access instance. The caching of accessors
+ * is soft, so if no references remain to a given instance it may be
+ * garbage collected. A subsequent call will return a newly created
+ * instance.
*
- * <p>In addition to generating an index entry storable, this class
+ * <p>In addition to generating an index entry storable, the accessor
* contains methods to operate on it. Care must be taken to ensure that the
- * index entry instances are of the same type that the generator expects.
- * Since the generator may be garbage collected freely of the generated
+ * index entry instances are of the same type that the accessor expects.
+ * Since the accessor may be garbage collected freely of the generated
* index entry class, it is possible for index entries to be passed to a
- * generator instance that does not understand it. For example:
+ * accessor instance that does not understand it. For example:
*
* <pre>
* StorableIndex index = ...
- * Class indexEntryClass = IndexEntryGenerator.getInstance(index).getIndexEntryClass();
+ * Class indexEntryClass = IndexEntryGenerator.getIndexAccess(index).getReferenceClass();
* ...
* garbage collection
* ...
* Storable indexEntry = instance of indexEntryClass
* // Might fail because generator instance is new
- * IndexEntryGenerator.getInstance(index).setAllProperties(indexEntry, source);
+ * IndexEntryGenerator.getIndexAccess(index).copyFromMaster(indexEntry, master);
* </pre>
*
- * The above code can be fixed by saving a local reference to the generator:
+ * The above code can be fixed by saving a local reference to the accessor:
*
* <pre>
* StorableIndex index = ...
- * IndexEntryGenerator generator = IndexEntryGenerator.getInstance(index);
- * Class indexEntryClass = generator.getIndexEntryClass();
+ * SyntheticStorableReferenceAccess access = IndexEntryGenerator.getIndexAccess(index);
+ * Class indexEntryClass = access.getReferenceClass();
* ...
* Storable indexEntry = instance of indexEntryClass
- * generator.setAllProperties(indexEntry, source);
+ * access.copyFromMaster(indexEntry, master);
* </pre>
*
* @throws SupportException if any non-primary key property doesn't have a
* public read method.
*/
- public static <S extends Storable> IndexEntryGenerator<S>
- getInstance(StorableIndex<S> index) throws SupportException
+ public static <S extends Storable>
+ SyntheticStorableReferenceAccess<S> getIndexAccess(StorableIndex<S> index)
+ throws SupportException
{
- synchronized(cCache) {
- IndexEntryGenerator<S> generator;
- Reference<IndexEntryGenerator> ref = cCache.get(index);
+ synchronized (cCache) {
+ SyntheticStorableReferenceAccess<S> access;
+ Reference<SyntheticStorableReferenceAccess> ref = cCache.get(index);
if (ref != null) {
- generator = ref.get();
- if (generator != null) {
- return generator;
+ access = ref.get();
+ if (access != null) {
+ return access;
}
}
- generator = new IndexEntryGenerator<S>(index);
- cCache.put(index, new SoftReference<IndexEntryGenerator>(generator));
- return generator;
- }
- }
-
- private SyntheticStorableReferenceAccess<S> mIndexAccess;
- /**
- * Convenience class for gluing new "builder" style synthetics to the traditional
- * generator style.
- * @param index Generator style index specification
- */
- public IndexEntryGenerator(StorableIndex<S> index) throws SupportException {
- // Need to try to find the base type. This is an awkward way to do it,
- // but we have nothing better available to us
- Class<S> type = index.getProperty(0).getEnclosingType();
+ // Need to try to find the base type. This is an awkward way to do
+ // it, but we have nothing better available to us
+ Class<S> type = index.getProperty(0).getEnclosingType();
- SyntheticStorableReferenceBuilder<S> builder =
- new SyntheticStorableReferenceBuilder<S>(type, index.isUnique());
-
- for (int i=0; i<index.getPropertyCount(); i++) {
- StorableProperty source = index.getProperty(i);
- builder.addKeyProperty(source.getName(), index.getPropertyDirection(i));
- }
+ SyntheticStorableReferenceBuilder<S> builder =
+ new SyntheticStorableReferenceBuilder<S>(type, index.isUnique());
- builder.build();
-
- mIndexAccess = builder.getReferenceAccess();
- }
-
- /**
- * Returns generated index entry class, which is abstract.
- *
- * @return class of index entry, which is a custom Storable
- */
- public Class<? extends Storable> getIndexEntryClass() {
- return mIndexAccess.getReferenceClass();
- }
+ for (int i=0; i<index.getPropertyCount(); i++) {
+ StorableProperty<S> source = index.getProperty(i);
+ builder.addKeyProperty(source.getName(), index.getPropertyDirection(i));
+ }
- /**
- * Sets all the primary key properties of the given master, using the
- * applicable properties of the given index entry.
- *
- * @param indexEntry source of property values
- * @param master master whose primary key properties will be set
- */
- public void copyToMasterPrimaryKey(Storable indexEntry, S master) {
- mIndexAccess.copyToMasterPrimaryKey(indexEntry, master);
- }
+ builder.build();
+ access = builder.getReferenceAccess();
- /**
- * Sets all the properties of the given index entry, using the applicable
- * properties of the given master.
- *
- * @param indexEntry index entry whose properties will be set
- * @param master source of property values
- */
- public void copyFromMaster(Storable indexEntry, S master) {
- mIndexAccess.copyFromMaster(indexEntry, master);
- }
+ cCache.put(index, new SoftReference<SyntheticStorableReferenceAccess>(access));
- /**
- * Returns true if the properties of the given index entry match those
- * contained in the master. This will always return true after a call to
- * setAllProperties.
- *
- * @param indexEntry index entry whose properties will be tested
- * @param master source of property values
- */
- public boolean isConsistent(Storable indexEntry, S master) {
- return mIndexAccess.isConsistent(indexEntry, master);
+ return access;
+ }
}
- /**
- * Returns a comparator for ordering index entries.
- */
- public Comparator<? extends Storable> getComparator() {
- return mIndexAccess.getComparator();
+ private IndexEntryGenerator() {
}
}
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
index 79895c4..de105cc 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedCursor.java
@@ -34,6 +34,8 @@ import com.amazon.carbonado.cursor.AbstractCursor;
import com.amazon.carbonado.spi.RepairExecutor;
+import com.amazon.carbonado.synthetic.SyntheticStorableReferenceAccess;
+
/**
* Wraps another cursor which contains index entries and extracts master
* objects from them.
@@ -43,16 +45,16 @@ import com.amazon.carbonado.spi.RepairExecutor;
class IndexedCursor<S extends Storable> extends AbstractCursor<S> {
private final Cursor<? extends Storable> mCursor;
private final IndexedStorage<S> mStorage;
- private final IndexEntryGenerator<S> mGenerator;
+ private final SyntheticStorableReferenceAccess<S> mAccessor;
private S mNext;
IndexedCursor(Cursor<? extends Storable> indexEntryCursor,
IndexedStorage<S> storage,
- IndexEntryGenerator<S> indexEntryGenerator) {
+ SyntheticStorableReferenceAccess<S> indexAccessor) {
mCursor = indexEntryCursor;
mStorage = storage;
- mGenerator = indexEntryGenerator;
+ mAccessor = indexAccessor;
}
public void close() throws FetchException {
@@ -68,13 +70,13 @@ class IndexedCursor<S extends Storable> extends AbstractCursor<S> {
final Storable indexEntry = mCursor.next();
S master = mStorage.mMasterStorage.prepare();
- mGenerator.copyToMasterPrimaryKey(indexEntry, master);
+ mAccessor.copyToMasterPrimaryKey(indexEntry, master);
if (!master.tryLoad()) {
LogFactory.getLog(getClass()).warn
("Master is missing for index entry: " + indexEntry);
} else {
- if (mGenerator.isConsistent(indexEntry, master)) {
+ if (mAccessor.isConsistent(indexEntry, master)) {
mNext = master;
return true;
}
@@ -85,9 +87,9 @@ class IndexedCursor<S extends Storable> extends AbstractCursor<S> {
try {
final IndexedRepository repo = mStorage.mRepository;
final Storage<?> indexEntryStorage =
- repo.getIndexEntryStorageFor(mGenerator.getIndexEntryClass());
+ repo.getIndexEntryStorageFor(mAccessor.getReferenceClass());
Storable newIndexEntry = indexEntryStorage.prepare();
- mGenerator.copyFromMaster(newIndexEntry, master);
+ mAccessor.copyFromMaster(newIndexEntry, master);
if (newIndexEntry.tryLoad()) {
// Good, the correct index entry exists. We'll see
@@ -108,11 +110,11 @@ class IndexedCursor<S extends Storable> extends AbstractCursor<S> {
try {
// Reload master and verify inconsistency.
S master = mStorage.mMasterStorage.prepare();
- mGenerator.copyToMasterPrimaryKey(indexEntry, master);
+ mAccessor.copyToMasterPrimaryKey(indexEntry, master);
if (master.tryLoad()) {
Storable newIndexEntry = indexEntryStorage.prepare();
- mGenerator.copyFromMaster(newIndexEntry, master);
+ mAccessor.copyFromMaster(newIndexEntry, master);
newIndexEntry.tryInsert();
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java
index 1abb064..b4440c9 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java
@@ -356,7 +356,7 @@ class IndexedStorage<S extends Storable> implements Storage<S>, StorageAccess<S>
}
Class<? extends Storable> indexEntryClass =
- IndexEntryGenerator.getInstance(index).getIndexEntryClass();
+ IndexEntryGenerator.getIndexAccess(index).getReferenceClass();
Storage<?> indexEntryStorage;
try {
diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
index 2d0617e..8219ac1 100644
--- a/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
+++ b/src/main/java/com/amazon/carbonado/repo/indexed/ManagedIndex.java
@@ -52,6 +52,8 @@ import com.amazon.carbonado.cursor.MergeSortBuffer;
import com.amazon.carbonado.spi.RepairExecutor;
+import com.amazon.carbonado.synthetic.SyntheticStorableReferenceAccess;
+
import com.amazon.carbonado.util.Throttle;
/**
@@ -85,7 +87,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
private final IndexedRepository mRepository;
private final Storage<S> mMasterStorage;
private final StorableIndex mIndex;
- private final IndexEntryGenerator<S> mGenerator;
+ private final SyntheticStorableReferenceAccess<S> mAccessor;
private final Storage<?> mIndexEntryStorage;
private Query<?> mSingleMatchQuery;
@@ -93,14 +95,14 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
ManagedIndex(IndexedRepository repository,
Storage<S> masterStorage,
StorableIndex<S> index,
- IndexEntryGenerator<S> generator,
+ SyntheticStorableReferenceAccess<S> accessor,
Storage<?> indexEntryStorage)
throws SupportException
{
mRepository = repository;
mMasterStorage = masterStorage;
mIndex = index;
- mGenerator = generator;
+ mAccessor = accessor;
mIndexEntryStorage = indexEntryStorage;
}
@@ -145,17 +147,17 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
// Required by IndexEntryAccessor interface.
public void copyToMasterPrimaryKey(Storable indexEntry, S master) {
- mGenerator.copyToMasterPrimaryKey(indexEntry, master);
+ mAccessor.copyToMasterPrimaryKey(indexEntry, master);
}
// Required by IndexEntryAccessor interface.
public void copyFromMaster(Storable indexEntry, S master) {
- mGenerator.copyFromMaster(indexEntry, master);
+ mAccessor.copyFromMaster(indexEntry, master);
}
// Required by IndexEntryAccessor interface.
public boolean isConsistent(Storable indexEntry, S master) {
- return mGenerator.isConsistent(indexEntry, master);
+ return mAccessor.isConsistent(indexEntry, master);
}
// Required by IndexEntryAccessor interface.
@@ -165,7 +167,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
// Required by IndexEntryAccessor interface.
public Comparator<? extends Storable> getComparator() {
- return mGenerator.getComparator();
+ return mAccessor.getComparator();
}
Cursor<S> fetchOne(IndexedStorage storage, Object[] identityValues)
@@ -188,7 +190,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
Cursor<S> fetchFromIndexEntryQuery(IndexedStorage storage, Query<?> indexEntryQuery)
throws FetchException
{
- return new IndexedCursor<S>(indexEntryQuery.fetch(), storage, mGenerator);
+ return new IndexedCursor<S>(indexEntryQuery.fetch(), storage, mAccessor);
}
@Override
@@ -534,7 +536,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
private Storable makeIndexEntry(S userStorable) throws PersistException {
try {
Storable indexEntry = mIndexEntryStorage.prepare();
- mGenerator.copyFromMaster(indexEntry, userStorable);
+ mAccessor.copyFromMaster(indexEntry, userStorable);
return indexEntry;
} catch (UndeclaredThrowableException e) {
Throwable cause = e.getCause();
@@ -561,7 +563,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
// If index entry already exists, then index might be corrupt.
{
Storable freshEntry = mIndexEntryStorage.prepare();
- mGenerator.copyFromMaster(freshEntry, userStorable);
+ mAccessor.copyFromMaster(freshEntry, userStorable);
indexEntry.copyVersionProperty(freshEntry);
if (freshEntry.equals(indexEntry)) {
// Existing entry is exactly what we expect. Return false
@@ -591,7 +593,7 @@ class ManagedIndex<S extends Storable> implements IndexEntryAccessor<S> {
}
Storable freshEntry = mIndexEntryStorage.prepare();
- mGenerator.copyFromMaster(freshEntry, freshUserStorable);
+ mAccessor.copyFromMaster(freshEntry, freshUserStorable);
// Blow it away entry and re-insert. Don't simply update
// the entry, since record version number may prevent