>From Ali Alsuliman <[email protected]>: Ali Alsuliman has uploaded this change for review. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21683?usp=email )
Change subject: [ASTERIXDB-3817][STO] Name the search cursor instead of flagging it ...................................................................... [ASTERIXDB-3817][STO] Name the search cursor instead of flagging it Which class implemented a vector search was decided by a Boolean under USE_TOPK_SEARCH in the index-access-parameters map: the search operator put it there, and LSMVTreeIndexAccessor overrode createSearchCursor to read it back and hand out the top-K cursor. Two layers apart, through an untyped map, for a decision the operator makes. IndexSearchOperatorNodePushable already has the hook for this -- createCursor(IIndex, IIndexAccessor) -- so VTreeSearchOperatorNodePushable overrides it and calls the public createTopKSearchCursor directly. The flag, its constant, and the accessor subclass are gone; LSMVTreeIndexAccessor existed for nothing else, so LSMVTree now returns a plain LSMTreeIndexAccessor. This also settles the concern that cursor selection and the index's quantization were independent flags that had to agree with nothing checking they did. There is no selection flag now. The cursor still verifies the index is quantized, because being asked for still does not establish it -- the caller chooses the cursor, the index decides its own layout -- but the message no longer blames a parameter that no longer exists. The two test paths that used the flag to pick a cursor now name it the same way. That reads better than it did: LSMVTreeCursorAgreementTest compares two implementations, and saying which two is the point of the test, rather than leaving it to an access-parameter lookup. Ext-ref: MB-73194 Co-Authored-By: Claude Opus 5 <[email protected]> Change-Id: Iaa22c8d92458e0fedd30edf13b629e84cb8f2731 --- M hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/dataflow/VTreeSearchOperatorNodePushable.java M hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTree.java D hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeIndexAccessor.java M hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeTopKSearchCursor.java M hyracks-fullstack/hyracks/hyracks-storage-am-vtree/src/main/java/org/apache/hyracks/storage/am/vector/utils/VTreeSearchParameters.java M hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/vector/VectorTreeTestUtils.java M hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-vtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/vector/LSMVTreeCursorAgreementTest.java 7 files changed, 46 insertions(+), 103 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/83/21683/1 diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/dataflow/VTreeSearchOperatorNodePushable.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/dataflow/VTreeSearchOperatorNodePushable.java index 91571e9..7de4b81 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/dataflow/VTreeSearchOperatorNodePushable.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/dataflow/VTreeSearchOperatorNodePushable.java @@ -35,14 +35,16 @@ import org.apache.hyracks.storage.am.common.api.ITupleFilterFactory; import org.apache.hyracks.storage.am.common.dataflow.IIndexDataflowHelperFactory; import org.apache.hyracks.storage.am.common.dataflow.IndexSearchOperatorNodePushable; +import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor; import org.apache.hyracks.storage.am.lsm.vector.impls.IVectorSearchCursor; -import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTreeTopKSearchCursor; +import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTree; import org.apache.hyracks.storage.am.vector.api.IVTreeBinaryAccessorFactory; import org.apache.hyracks.storage.am.vector.api.IVTreeDistanceFunctionFactory; import org.apache.hyracks.storage.am.vector.api.IVTreeQuantizerFactory; import org.apache.hyracks.storage.am.vector.impls.VTreeSearchPredicate; import org.apache.hyracks.storage.common.IIndex; import org.apache.hyracks.storage.common.IIndexAccessParameters; +import org.apache.hyracks.storage.common.IIndexAccessor; import org.apache.hyracks.storage.common.IIndexCursor; import org.apache.hyracks.storage.common.ISearchPredicate; import org.apache.hyracks.storage.common.projection.ITupleProjectorFactory; @@ -323,8 +325,8 @@ protected ITupleReference writeTupleToOutput(ITupleReference tuple) throws IOException { double dqx = Double.NaN; if (indexOnly) { - // Search always uses the pruned top-K cursor (addAdditionalIndexAccessorParams sets - // USE_TOPK_SEARCH), which is the only IVectorSearchCursor; the streaming LSMVTreeSearchCursor + // Search always uses the pruned top-K cursor (createCursor names it), which is the only + // IVectorSearchCursor; the streaming LSMVTreeSearchCursor // serves merges, full scans, and tests and never backs an index-only plan. A genuine NaN here // (e.g. the cosine distance of a zero-magnitude vector) is a real value and flows through. dqx = ((IVectorSearchCursor) activeCursor).getCurrentDistance(); @@ -358,10 +360,19 @@ // Task context for the spillable top-K buffer (follows inverted-index pattern). iap.getParameters().put(HyracksConstants.HYRACKS_TASK_CONTEXT, ctx); + } - // Production ANN search always uses the quantized top-K cursor. Without this flag, - // LSMVTreeIndexAccessor defaults to the streaming LSMVTreeSearchCursor (used by component - // merges and by test fixtures that verify through full-scan iteration). - iap.getParameters().put(LSMVTreeTopKSearchCursor.IAP_KEY, Boolean.TRUE); + /** + * Production ANN search runs on the quantized top-K cursor. Named here rather than requested through + * a {@code Boolean} in the access-parameters map: which class implements the search is a decision this + * operator makes, so making it a call the compiler can see keeps it with the operator that makes it + * instead of two layers away in an accessor branching on an untyped flag. + * <p> + * The streaming {@code LSMVTreeSearchCursor} that {@code createSearchCursor} would return stays what + * component merges use. + */ + @Override + protected IIndexCursor createCursor(IIndex index, IIndexAccessor indexAccessor) throws HyracksDataException { + return ((LSMVTree) index).createTopKSearchCursor(((LSMTreeIndexAccessor) indexAccessor).getOpContext()); } } diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTree.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTree.java index cc971c3..bdcd8b5 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTree.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTree.java @@ -62,6 +62,7 @@ import org.apache.hyracks.storage.am.lsm.common.impls.LSMComponentFileReferences; import org.apache.hyracks.storage.am.lsm.common.impls.LSMComponentFilterManager; import org.apache.hyracks.storage.am.lsm.common.impls.LSMIndexDiskComponentBulkLoader; +import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor; import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor.ICursorFactory; import org.apache.hyracks.storage.am.lsm.common.impls.LSMVTreeComponentFileReferences; import org.apache.hyracks.storage.am.lsm.common.impls.LoadOperation; @@ -536,7 +537,9 @@ } public ILSMIndexAccessor createAccessor(AbstractLSMIndexOperationContext opCtx) { - return new LSMVTreeIndexAccessor(getHarness(), opCtx, getCursorFactory(), this); + // LSMVTreeIndexAccessor existed only to branch on an access-parameter flag and hand back the top-K + // cursor; callers that want that cursor now ask for it by name via createTopKSearchCursor. + return new LSMTreeIndexAccessor(getHarness(), opCtx, getCursorFactory()); } @Override diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeIndexAccessor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeIndexAccessor.java deleted file mode 100644 index 1cf27e1..0000000 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeIndexAccessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.apache.hyracks.storage.am.lsm.vector.impls; - -import org.apache.hyracks.storage.am.lsm.common.api.ILSMHarness; -import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexOperationContext; -import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor; -import org.apache.hyracks.storage.common.IIndexAccessParameters; -import org.apache.hyracks.storage.common.IIndexCursor; - -/** - * LSM Vector Clustering Tree Index Accessor. - * - * <p>Default search routes through the streaming {@link LSMVTreeSearchCursor} (registered on the - * parent accessor as the {@code cursorFactory}). Production ANN queries opt in to the quantized - * top-K cursor by setting {@link LSMVTreeTopKSearchCursor#IAP_KEY} to {@code Boolean.TRUE} in the - * index-access parameters; the test fixtures that don't set the flag get the streaming cursor, - * which is the same cursor used by component merges. - */ -public class LSMVTreeIndexAccessor extends LSMTreeIndexAccessor { - - private final LSMVTree lsmVTree; - - public LSMVTreeIndexAccessor(ILSMHarness lsmHarness, ILSMIndexOperationContext ctx, ICursorFactory cursorFactory, - LSMVTree lsmVTree) { - super(lsmHarness, ctx, cursorFactory); - this.lsmVTree = lsmVTree; - } - - @Override - public IIndexCursor createSearchCursor(boolean exclusive) { - if (ctx instanceof LSMVTreeOpContext) { - IIndexAccessParameters iap = ((LSMVTreeOpContext) ctx).getIndexAccessParameters(); - if (iap != null) { - Boolean useTopK = iap.getParameter(LSMVTreeTopKSearchCursor.IAP_KEY, Boolean.class); - if (Boolean.TRUE.equals(useTopK)) { - return lsmVTree.createTopKSearchCursor(ctx); - } - } - } - return super.createSearchCursor(exclusive); - } -} diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeTopKSearchCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeTopKSearchCursor.java index 0b4c391..4ca01ca 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeTopKSearchCursor.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-lsm-vtree/src/main/java/org/apache/hyracks/storage/am/lsm/vector/impls/LSMVTreeTopKSearchCursor.java @@ -74,15 +74,6 @@ */ public class LSMVTreeTopKSearchCursor extends EnforcedIndexCursor implements IVectorSearchCursor { - /** - * Index-access-parameters key — set {@code Boolean.TRUE} under this key to route search to - * this cursor (the quantized top-K window cursor used by production ANN queries). When absent - * or false, {@link LSMVTreeIndexAccessor#createSearchCursor(boolean)} returns the streaming - * {@link LSMVTreeSearchCursor} — also the cursor used by component merges and by test - * fixtures that verify inserts/deletes through full-scan iteration. - */ - public static final String IAP_KEY = "USE_TOPK_SEARCH"; - private static final Logger LOGGER = LogManager.getLogger(); // Operation context @@ -183,14 +174,13 @@ this.numPrimaryKeyFields = ((LSMVTree) opCtx.getIndex()).getNumPrimaryKeyFields(); // This cursor is quantized-only: dataAccessor is fixed to the quantized layout, so it reads field 3 - // as the quantized embedding and locates the PKs at pkStartField = 4. It is selected purely by the - // USE_TOPK_SEARCH access parameter, which is independent of the index's quantization — so check the - // assumption instead of inheriting it. On a non-quantized index field 3 is a PK/INCLUDE field and the - // whole read would be silent garbage. + // as the quantized embedding and locates the PKs at pkStartField = 4. Nothing about being asked for + // this cursor establishes that the index is quantized — the caller chooses it, the index decides its + // own layout — so check the assumption instead of inheriting it. On a non-quantized index field 3 is + // a PK/INCLUDE field and the whole read would be silent garbage. if (!((LSMVTree) opCtx.getIndex()).isQuantized()) { throw HyracksDataException.create(ErrorCode.ILLEGAL_STATE, - "LSMVTreeTopKSearchCursor requires a quantized VTree index (USE_TOPK_SEARCH was requested for a " - + "non-quantized index)"); + "LSMVTreeTopKSearchCursor requires a quantized VTree index, but this index is not quantized"); } LSMVTreeUtils.validateKeyComparators(cmp, pkStartField, numPrimaryKeyFields); @@ -274,8 +264,8 @@ } // computeApproximateDistance() dequantizes every candidate with these two, and they arrive - // independently of the USE_TOPK_SEARCH flag that selected this cursor (from a quantizer factory - // or instance in the index access parameters). Fail here rather than NPE per candidate. + // separately from the decision to use this cursor — from a quantizer factory or instance in the + // index access parameters. Fail here rather than NPE per candidate. if (this.quantizer == null || this.quantizedQueryVector == null) { throw HyracksDataException.create(ErrorCode.ILLEGAL_STATE, "LSMVTreeTopKSearchCursor requires a quantizer and a quantized query vector; none was supplied " diff --git a/hyracks-fullstack/hyracks/hyracks-storage-am-vtree/src/main/java/org/apache/hyracks/storage/am/vector/utils/VTreeSearchParameters.java b/hyracks-fullstack/hyracks/hyracks-storage-am-vtree/src/main/java/org/apache/hyracks/storage/am/vector/utils/VTreeSearchParameters.java index 35272dd..f98326d 100644 --- a/hyracks-fullstack/hyracks/hyracks-storage-am-vtree/src/main/java/org/apache/hyracks/storage/am/vector/utils/VTreeSearchParameters.java +++ b/hyracks-fullstack/hyracks/hyracks-storage-am-vtree/src/main/java/org/apache/hyracks/storage/am/vector/utils/VTreeSearchParameters.java @@ -75,9 +75,10 @@ * {@code LSMVTreeLocalResource} the way the distance-function factory already is. That is a wider change * than taking a value the index is already holding. * <p> - * Cursor selection ({@code USE_TOPK_SEARCH}) is deliberately not here: it is read by - * {@code LSMVTreeIndexAccessor} in the LSM layer, which is the only place that can act on it, and that - * layer is not visible from this module. + * Cursor selection used to travel this way too, as a {@code Boolean} under {@code USE_TOPK_SEARCH} that + * an accessor branched on. It does not any more: {@code VTreeSearchOperatorNodePushable} names the cursor + * it wants by overriding {@code createCursor}. Which class implements a search is a decision the caller + * makes, so it belongs in a call the compiler can see rather than in this map. */ @AiProvenance(agent = AiProvenance.Agent.CLAUDE_OPUS_5, tool = AiProvenance.Tool.CLAUDE_CODE_UI, contributionKind = AiProvenance.ContributionKind.REFACTORED, notes = "Typed reads replacing unchecked casts on the IAP map") public final class VTreeSearchParameters { diff --git a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/vector/VectorTreeTestUtils.java b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/vector/VectorTreeTestUtils.java index 6f52f5e..19784b0 100644 --- a/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/vector/VectorTreeTestUtils.java +++ b/hyracks-fullstack/hyracks/hyracks-test-support/src/main/java/org/apache/hyracks/storage/am/vector/VectorTreeTestUtils.java @@ -50,9 +50,9 @@ import org.apache.hyracks.storage.am.common.TreeIndexTestUtils; import org.apache.hyracks.storage.am.common.impls.IndexAccessParameters; import org.apache.hyracks.storage.am.common.impls.NoOpIndexAccessParameters; +import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor; import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTree; import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTreeDiskComponent; -import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTreeTopKSearchCursor; import org.apache.hyracks.storage.am.vector.api.IVTreeBinaryAccessorFactory; import org.apache.hyracks.storage.am.vector.api.IVTreeDistanceFunction; import org.apache.hyracks.storage.am.vector.api.IVTreeQuantizer; @@ -352,19 +352,17 @@ new IndexAccessParameters(TestOperationCallback.INSTANCE, TestOperationCallback.INSTANCE); iap.getParameters().put(IVTreeBinaryAccessorFactory.IAP_KEY, TestDoubleArrayVectorAccessor.Factory.INSTANCE); iap.getParameters().put(IVTreeQuantizer.IAP_KEY, NoOpVectorQuantizer.INSTANCE); - // Opt in to LSMVTreeTopKSearchCursor — this test exercises the production top-K search - // path. Other test verification paths (e.g. verifyInsertedRecords) leave the flag unset - // and get the streaming LSMVTreeSearchCursor. - iap.getParameters().put(LSMVTreeTopKSearchCursor.IAP_KEY, Boolean.TRUE); // LSMVTreeTopKSearchCursor's SpillableTopKBuffer requires a real IHyracksTaskContext for // frame allocation and disk spill. Tests must populate ctx.setHyracksTaskContext(...) // from the test harness; otherwise SpillableTopKBuffer's ctor will NPE on getInitialFrameSize(). iap.getParameters().put(HyracksConstants.HYRACKS_TASK_CONTEXT, ctx.getHyracksTaskContext()); IIndexAccessor accessor = ctx.getIndex().createAccessor(iap); - IIndexCursor cursor = accessor.createSearchCursor(false); + // The production top-K cursor, asked for by name — the same call VTreeSearchOperatorNodePushable + // makes. createSearchCursor() would give the streaming cursor that component merges use. + IIndexCursor cursor = + ((LSMVTree) ctx.getIndex()).createTopKSearchCursor(((LSMTreeIndexAccessor) accessor).getOpContext()); - // Verify we got the naive blocked cursor LOGGER.info("Created cursor type: {}", cursor.getClass().getSimpleName()); try { diff --git a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-vtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/vector/LSMVTreeCursorAgreementTest.java b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-vtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/vector/LSMVTreeCursorAgreementTest.java index 39c948c..6cbd3e2 100644 --- a/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-vtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/vector/LSMVTreeCursorAgreementTest.java +++ b/hyracks-fullstack/hyracks/hyracks-tests/hyracks-storage-am-lsm-vtree-test/src/test/java/org/apache/hyracks/storage/am/lsm/vector/LSMVTreeCursorAgreementTest.java @@ -39,8 +39,8 @@ import org.apache.hyracks.storage.am.lsm.common.api.ILSMIOOperation; import org.apache.hyracks.storage.am.lsm.common.api.ILSMIOOperation.LSMIOOperationStatus; import org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexAccessor; +import org.apache.hyracks.storage.am.lsm.common.impls.LSMTreeIndexAccessor; import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTree; -import org.apache.hyracks.storage.am.lsm.vector.impls.LSMVTreeTopKSearchCursor; import org.apache.hyracks.storage.am.lsm.vector.util.LSMVTreeTestContext; import org.apache.hyracks.storage.am.lsm.vector.util.LSMVTreeTestHarness; import org.apache.hyracks.storage.am.lsm.vector.util.QuantizedSearchTestDriver; @@ -271,14 +271,14 @@ IndexAccessParameters iap = new IndexAccessParameters(TestOperationCallback.INSTANCE, TestOperationCallback.INSTANCE); - iap.getParameters().put(LSMVTreeTopKSearchCursor.IAP_KEY, Boolean.TRUE); iap.getParameters().put(IVTreeQuantizer.IAP_KEY, NoOpVectorQuantizer.INSTANCE); if (!HyracksConstants.HYRACKS_TASK_CONTEXT.equals(omittedKey)) { iap.getParameters().put(HyracksConstants.HYRACKS_TASK_CONTEXT, ctx.getHyracksTaskContext()); } IIndexAccessor accessor = ctx.getIndex().createAccessor(iap); - IIndexCursor cursor = accessor.createSearchCursor(false); + IIndexCursor cursor = + ((LSMVTree) ctx.getIndex()).createTopKSearchCursor(((LSMTreeIndexAccessor) accessor).getOpContext()); try { accessor.search(cursor, predicate); } finally { @@ -326,12 +326,12 @@ iap.getParameters().put(IVTreeBinaryAccessorFactory.IAP_KEY, TestDoubleArrayVectorAccessor.Factory.INSTANCE); iap.getParameters().put(IVTreeQuantizer.IAP_KEY, NoOpVectorQuantizer.INSTANCE); iap.getParameters().put(HyracksConstants.HYRACKS_TASK_CONTEXT, ctx.getHyracksTaskContext()); - if (useTopK) { - iap.getParameters().put(LSMVTreeTopKSearchCursor.IAP_KEY, Boolean.TRUE); - } - IIndexAccessor accessor = ctx.getIndex().createAccessor(iap); - IIndexCursor cursor = accessor.createSearchCursor(false); + // Each cursor is named rather than selected by a flag, so the test says which two implementations + // it is comparing instead of leaving that to an access-parameter lookup. + IIndexCursor cursor = useTopK + ? ((LSMVTree) ctx.getIndex()).createTopKSearchCursor(((LSMTreeIndexAccessor) accessor).getOpContext()) + : accessor.createSearchCursor(false); Set<String> primaryKeys = new LinkedHashSet<>(); try { accessor.search(cursor, predicate); -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21683?usp=email To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings?usp=email Gerrit-MessageType: newchange Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Change-Id: Iaa22c8d92458e0fedd30edf13b629e84cb8f2731 Gerrit-Change-Number: 21683 Gerrit-PatchSet: 1 Gerrit-Owner: Ali Alsuliman <[email protected]>
