From d5e7a0f66f639d42934074a751aa9af9f76a3ceb Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 17 Sep 2006 21:40:47 +0000 Subject: Finished replacing old query engine. --- .../carbonado/repo/indexed/IndexedRepository.java | 21 ++- .../repo/indexed/IndexedRepositoryBuilder.java | 2 +- .../carbonado/repo/indexed/IndexedStorage.java | 157 ++++++++++++--------- 3 files changed, 111 insertions(+), 69 deletions(-) (limited to 'src/main/java/com/amazon/carbonado/repo/indexed') diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepository.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepository.java index 714e938..4d6e371 100644 --- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepository.java +++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepository.java @@ -27,6 +27,7 @@ import com.amazon.carbonado.Cursor; import com.amazon.carbonado.IsolationLevel; import com.amazon.carbonado.MalformedTypeException; import com.amazon.carbonado.Repository; +import static com.amazon.carbonado.RepositoryBuilder.RepositoryReference; import com.amazon.carbonado.RepositoryException; import com.amazon.carbonado.Storable; import com.amazon.carbonado.Storage; @@ -40,6 +41,9 @@ import com.amazon.carbonado.capability.StorableInfoCapability; import com.amazon.carbonado.info.StorableIntrospector; +import com.amazon.carbonado.qe.RepositoryAccess; +import com.amazon.carbonado.qe.StorageAccess; + /** * Wraps another repository in order to make it support indexes. The wrapped * repository must support creation of new types. @@ -47,15 +51,18 @@ import com.amazon.carbonado.info.StorableIntrospector; * @author Brian S O'Neill */ class IndexedRepository implements Repository, + RepositoryAccess, IndexInfoCapability, StorableInfoCapability, IndexEntryAccessCapability { + private final RepositoryReference mRootRef; private final Repository mRepository; private final String mName; private final Map, IndexedStorage> mStorages; - IndexedRepository(String name, Repository repository) { + IndexedRepository(RepositoryReference rootRef, String name, Repository repository) { + mRootRef = rootRef; mRepository = repository; mName = name; mStorages = new IdentityHashMap, IndexedStorage>(); @@ -87,7 +94,7 @@ class IndexedRepository implements Repository, (type, "Storable cannot have any indexes: " + type + ", " + indexCount); } - return mRepository.storageFor(type); + return masterStorage; } storage = new IndexedStorage(this, masterStorage); @@ -172,6 +179,16 @@ class IndexedRepository implements Repository, mRepository.close(); } + public Repository getRootRepository() { + return mRootRef.get(); + } + + public StorageAccess storageAccessFor(Class type) + throws SupportException, RepositoryException + { + return (StorageAccess) storageFor(type); + } + Storage getIndexEntryStorageFor(Class indexEntryClass) throws RepositoryException { diff --git a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepositoryBuilder.java b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepositoryBuilder.java index cfbe128..f3ec04b 100644 --- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepositoryBuilder.java +++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedRepositoryBuilder.java @@ -65,7 +65,7 @@ public class IndexedRepositoryBuilder extends AbstractRepositoryBuilder { return wrapped; } - Repository repo = new IndexedRepository(getName(), wrapped); + Repository repo = new IndexedRepository(rootRef, getName(), wrapped); rootRef.set(repo); return repo; } 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 60a64d9..78b5f11 100644 --- a/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java +++ b/src/main/java/com/amazon/carbonado/repo/indexed/IndexedStorage.java @@ -19,6 +19,7 @@ package com.amazon.carbonado.repo.indexed; import java.util.ArrayList; +import java.util.Collection; import java.util.Comparator; import java.util.IdentityHashMap; import java.util.List; @@ -44,6 +45,9 @@ import com.amazon.carbonado.UniqueConstraintException; import com.amazon.carbonado.capability.IndexInfo; import com.amazon.carbonado.capability.IndexInfoCapability; +import com.amazon.carbonado.cursor.ArraySortBuffer; +import com.amazon.carbonado.cursor.MergeSortBuffer; + import com.amazon.carbonado.filter.Filter; import com.amazon.carbonado.info.Direction; @@ -51,11 +55,12 @@ import com.amazon.carbonado.info.StorableInfo; import com.amazon.carbonado.info.StorableIntrospector; import com.amazon.carbonado.info.StorableIndex; -import com.amazon.carbonado.cursor.MergeSortBuffer; +import com.amazon.carbonado.cursor.SortBuffer; import com.amazon.carbonado.qe.BoundaryType; +import com.amazon.carbonado.qe.QueryEngine; +import com.amazon.carbonado.qe.StorageAccess; -import com.amazon.carbonado.spi.BaseQueryEngine; import com.amazon.carbonado.spi.RepairExecutor; import com.amazon.carbonado.spi.StorableIndexSet; @@ -64,7 +69,7 @@ import com.amazon.carbonado.spi.StorableIndexSet; * * @author Brian S O'Neill */ -class IndexedStorage implements Storage { +class IndexedStorage implements Storage, StorageAccess { static StorableIndexSet gatherRequiredIndexes(StorableInfo info) { StorableIndexSet indexSet = new StorableIndexSet(); indexSet.addIndexes(info); @@ -76,9 +81,12 @@ class IndexedStorage implements Storage { final Storage mMasterStorage; private final Map, IndexInfo> mIndexInfoMap; + private final StorableIndexSet mIndexSet; private final QueryEngine mQueryEngine; + private Storage mRootStorage; + @SuppressWarnings("unchecked") IndexedStorage(IndexedRepository repository, Storage masterStorage) throws RepositoryException @@ -208,7 +216,9 @@ class IndexedStorage implements Storage { currentIndexSet.add(freeIndexes[i]); } - mQueryEngine = new QueryEngine(info, repository, this, currentIndexSet); + mIndexSet = currentIndexSet; + + mQueryEngine = new QueryEngine(masterStorage.getStorableType(), repository); } public Class getStorableType() { @@ -220,15 +230,15 @@ class IndexedStorage implements Storage { } public Query query() throws FetchException { - return mQueryEngine.getCompiledQuery(); + return mQueryEngine.query(); } public Query query(String filter) throws FetchException { - return mQueryEngine.getCompiledQuery(filter); + return mQueryEngine.query(filter); } public Query query(Filter filter) throws FetchException { - return mQueryEngine.getCompiledQuery(filter); + return mQueryEngine.query(filter); } public boolean addTrigger(Trigger trigger) { @@ -256,17 +266,87 @@ class IndexedStorage implements Storage { return accessors.toArray(new IndexEntryAccessor[accessors.size()]); } - Storage getStorageFor(StorableIndex index) { + public Collection> getAllIndexes() { + return mIndexSet; + } + + public Storage storageDelegate(StorableIndex index) { if (mIndexInfoMap.get(index) instanceof ManagedIndex) { // Index is managed by this storage, which is typical. - return this; + return null; } // Index is managed by master storage, most likely a primary key index. return mMasterStorage; } - ManagedIndex getManagedIndex(StorableIndex index) { - return (ManagedIndex) mIndexInfoMap.get(index); + public SortBuffer createSortBuffer() { + // FIXME: This is messy. If Storables had built-in serialization + // support, then MergeSortBuffer would not need a root storage. + if (mRootStorage == null) { + try { + mRootStorage = mRepository.getRootRepository().storageFor(getStorableType()); + } catch (RepositoryException e) { + LogFactory.getLog(IndexedStorage.class).warn(null, e); + return new ArraySortBuffer(); + } + } + + // FIXME: sort buffer should be on repository access. Also, create abstract + // repository access that creates the correct merge sort buffer. And more: + // create capability for managing merge sort buffers. + return new MergeSortBuffer(mRootStorage); + } + + public Cursor fetchAll() throws FetchException { + return mMasterStorage.query().fetch(); + } + + public Cursor fetchOne(StorableIndex index, + Object[] identityValues) + throws FetchException + { + // TODO: optimize fetching one by loading storable by primary key + return fetchSubset(index, identityValues, + BoundaryType.OPEN, null, + BoundaryType.OPEN, null, + false, false); + } + + public Cursor fetchSubset(StorableIndex index, + Object[] identityValues, + BoundaryType rangeStartBoundary, + Object rangeStartValue, + BoundaryType rangeEndBoundary, + Object rangeEndValue, + boolean reverseRange, + boolean reverseOrder) + throws FetchException + { + // Note: this code ignores the reverseRange parameter to avoid double + // reversal. Only the lowest storage layer should examine this + // parameter. + + ManagedIndex indexInfo = (ManagedIndex) mIndexInfoMap.get(index); + + Query query = indexInfo.getIndexEntryQueryFor + (identityValues == null ? 0 : identityValues.length, + rangeStartBoundary, rangeEndBoundary, reverseOrder); + + if (identityValues != null) { + query = query.withValues(identityValues); + } + + if (rangeStartBoundary != BoundaryType.OPEN) { + query = query.with(rangeStartValue); + } + if (rangeEndBoundary != BoundaryType.OPEN) { + query = query.with(rangeEndValue); + } + + Cursor indexEntryCursor = query.fetch(); + + return new IndexedCursor + (indexEntryCursor, IndexedStorage.this, indexInfo.getIndexEntryClassBuilder()); } private void registerIndex(ManagedIndex managedIndex) @@ -351,59 +431,4 @@ class IndexedStorage implements Storage { indexEntryStorage.query().deleteAll(); unregisterIndex(index); } - - private static class QueryEngine extends BaseQueryEngine { - - QueryEngine(StorableInfo info, - Repository repo, - IndexedStorage storage, - StorableIndexSet indexSet) { - super(info, repo, storage, null, indexSet); - } - - @Override - protected Storage getStorageFor(StorableIndex index) { - return storage().getStorageFor(index); - } - - protected Cursor openCursor(StorableIndex index, - Object[] exactValues, - BoundaryType rangeStartBoundary, - Object rangeStartValue, - BoundaryType rangeEndBoundary, - Object rangeEndValue, - boolean reverseRange, - boolean reverseOrder) - throws FetchException - { - // Note: this code ignores the reverseRange parameter to avoid - // double reversal. Only the lowest storage layer should examine - // this parameter. - - ManagedIndex indexInfo = storage().getManagedIndex(index); - Query query = indexInfo.getIndexEntryQueryFor - (exactValues == null ? 0 : exactValues.length, - rangeStartBoundary, rangeEndBoundary, reverseOrder); - - if (exactValues != null) { - query = query.withValues(exactValues); - } - - if (rangeStartBoundary != BoundaryType.OPEN) { - query = query.with(rangeStartValue); - } - if (rangeEndBoundary != BoundaryType.OPEN) { - query = query.with(rangeEndValue); - } - - Cursor indexEntryCursor = query.fetch(); - - return new IndexedCursor - (indexEntryCursor, storage(), indexInfo.getIndexEntryClassBuilder()); - } - - private IndexedStorage storage() { - return (IndexedStorage) super.getStorage(); - } - } } -- cgit v1.2.3