Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
import com.apple.foundationdb.record.metadata.expressions.KeyExpression;
import com.apple.foundationdb.record.metadata.expressions.LiteralKeyExpression;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerRegistry;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerRegistryImpl;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerFactoryRegistryImpl;
import com.apple.foundationdb.record.provider.foundationdb.MetaDataProtoEditor;
import com.apple.foundationdb.record.query.plan.cascades.UserDefinedFunction;
import com.apple.foundationdb.record.query.plan.serialization.DefaultPlanSerializationRegistry;
Expand Down Expand Up @@ -146,7 +146,7 @@ public class RecordMetaDataBuilder implements RecordMetaDataProvider {
formerIndexes = new ArrayList<>();
unionFields = new HashMap<>();
explicitDependencies = new TreeMap<>();
indexMaintainerRegistry = IndexMaintainerRegistryImpl.instance();
indexMaintainerRegistry = IndexMaintainerFactoryRegistryImpl.instance();
evolutionValidator = MetaDataEvolutionValidator.getDefaultInstance();
syntheticRecordTypes = new HashMap<>();
userDefinedFunctionMap = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
import com.apple.foundationdb.annotation.API;
import com.apple.foundationdb.record.RecordMetaData;
import com.apple.foundationdb.record.logging.LogMessageKeys;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerFactoryRegistry;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerRegistry;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerRegistryImpl;
import com.apple.foundationdb.record.provider.foundationdb.IndexMaintainerFactoryRegistryImpl;
import com.apple.foundationdb.record.util.pair.NonnullPair;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
Expand Down Expand Up @@ -90,7 +91,7 @@ public class MetaDataEvolutionValidator {
private static final MetaDataEvolutionValidator DEFAULT_INSTANCE = new MetaDataEvolutionValidator();

@Nonnull
private final IndexMaintainerRegistry indexMaintainerRegistry;
private final IndexValidatorRegistry indexValidatorRegistry;
private final boolean allowNoVersionChange;
private final boolean allowNoSinceVersion;
private final boolean allowIndexRebuilds;
Expand All @@ -100,7 +101,7 @@ public class MetaDataEvolutionValidator {
private final boolean disallowTypeRenames;

private MetaDataEvolutionValidator() {
this.indexMaintainerRegistry = IndexMaintainerRegistryImpl.instance();
this.indexValidatorRegistry = IndexMaintainerFactoryRegistryImpl.instance();
this.allowNoVersionChange = false;
this.allowNoSinceVersion = false;
this.allowIndexRebuilds = false;
Expand All @@ -111,7 +112,7 @@ private MetaDataEvolutionValidator() {
}

private MetaDataEvolutionValidator(@Nonnull Builder builder) {
this.indexMaintainerRegistry = builder.indexMaintainerRegistry;
this.indexValidatorRegistry = builder.indexValidatorRegistry;
this.allowNoVersionChange = builder.allowNoVersionChange;
this.allowNoSinceVersion = builder.allowNoSinceVersion;
this.allowIndexRebuilds = builder.allowIndexRebuilds;
Expand Down Expand Up @@ -668,22 +669,22 @@ private void validateIndex(@Nonnull RecordMetaData oldMetaData, @Nonnull Index o
// If there have been any changes to the index options, ask the index validator for that type
// to validate the changed options.
if (!oldIndex.getOptions().equals(newIndex.getOptions())) {
IndexValidator validatorForIndex = indexMaintainerRegistry.getIndexValidator(newIndex);
IndexValidator validatorForIndex = indexValidatorRegistry.getIndexValidator(newIndex);
validatorForIndex.validateChangedOptions(oldIndex);
}
}

/**
* Get the registry of index maintainers used to validate indexes. This registry should generally
* be the same registry as the registry that will be used by any record stores that may use
* the meta-data. By default, this uses the default {@link IndexMaintainerRegistryImpl} instance.
* the meta-data. By default, this uses the default {@link IndexMaintainerFactoryRegistryImpl} instance.
*
* @return the index maintainer registry used to validate indexes
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerRegistry)
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerFactoryRegistry)
*/
@Nonnull
public IndexMaintainerRegistry getIndexMaintainerRegistry() {
return indexMaintainerRegistry;
public IndexValidatorRegistry getIndexValidatorRegistry() {
return indexValidatorRegistry;
}

/**
Expand Down Expand Up @@ -823,7 +824,7 @@ public static MetaDataEvolutionValidator getDefaultInstance() {
*/
public static class Builder {
@Nonnull
private IndexMaintainerRegistry indexMaintainerRegistry;
private IndexValidatorRegistry indexValidatorRegistry;
private boolean allowNoVersionChange;
private boolean allowNoSinceVersion;
private boolean allowIndexRebuilds;
Expand All @@ -833,7 +834,7 @@ public static class Builder {
private boolean disallowTypeRenames;

private Builder(@Nonnull MetaDataEvolutionValidator validator) {
this.indexMaintainerRegistry = validator.indexMaintainerRegistry;
this.indexValidatorRegistry = validator.indexValidatorRegistry;
this.allowNoVersionChange = validator.allowNoVersionChange;
this.allowNoSinceVersion = validator.allowNoSinceVersion;
this.allowIndexRebuilds = validator.allowIndexRebuilds;
Expand All @@ -844,29 +845,29 @@ private Builder(@Nonnull MetaDataEvolutionValidator validator) {
}

/**
* Set the registry of index maintainers used to validate indexes.
* Set the registry of index validators used to validate indexes.
*
* @param indexMaintainerRegistry the index maintainer registry used to validate indexes
* @param indexValidatorRegistry the index validator registry used to validate indexes
* @return this builder
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerRegistry)
* @see MetaDataEvolutionValidator#getIndexMaintainerRegistry()
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerFactoryRegistry)
* @see MetaDataEvolutionValidator#getIndexValidatorRegistry()
*/
@Nonnull
public Builder setIndexMaintainerRegistry(@Nonnull IndexMaintainerRegistry indexMaintainerRegistry) {
this.indexMaintainerRegistry = indexMaintainerRegistry;
public Builder setIndexValidatorRegistry(@Nonnull IndexMaintainerRegistry indexValidatorRegistry) {
this.indexValidatorRegistry = indexValidatorRegistry;
return this;
}

/**
* Get the registry of index maintainers used to validate indexes.
* Get the registry of index validators used to validate indexes.
*
* @return the index maintainer registry used to validate indexes
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerRegistry)
* @see MetaDataEvolutionValidator#getIndexMaintainerRegistry()
* @see com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.BaseBuilder#setIndexMaintainerRegistry(IndexMaintainerFactoryRegistry)
* @see MetaDataEvolutionValidator#getIndexValidatorRegistry()
*/
@Nonnull
public IndexMaintainerRegistry getIndexMaintainerRegistry() {
return indexMaintainerRegistry;
public IndexValidatorRegistry getIndexValidatorRegistry() {
return indexValidatorRegistry;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public class FDBRecordStore extends FDBStoreBase implements FDBRecordStoreBase<M
protected final RecordSerializer<Message> serializer;

@Nonnull
protected final IndexMaintainerRegistry indexMaintainerRegistry;
protected final IndexMaintainerFactoryRegistry indexMaintainerRegistry;

@Nonnull
protected final IndexMaintenanceFilter indexMaintenanceFilter;
Expand Down Expand Up @@ -322,7 +322,7 @@ protected FDBRecordStore(@Nonnull FDBRecordContext context,
@Nonnull FormatVersion formatVersion,
@Nonnull RecordMetaDataProvider metaDataProvider,
@Nonnull RecordSerializer<Message> serializer,
@Nonnull IndexMaintainerRegistry indexMaintainerRegistry,
@Nonnull IndexMaintainerFactoryRegistry indexMaintainerRegistry,
@Nonnull IndexMaintenanceFilter indexMaintenanceFilter,
@Nonnull PipelineSizer pipelineSizer,
@Nullable FDBRecordStoreStateCache storeStateCache,
Expand Down Expand Up @@ -463,8 +463,9 @@ public RecordSerializer<Message> getSerializer() {
return serializer;
}

@Override
@Nonnull
public IndexMaintainerRegistry getIndexMaintainerRegistry() {
public IndexMaintainerFactoryRegistry getIndexMaintainerRegistry() {
return indexMaintainerRegistry;
}

Expand Down Expand Up @@ -5326,7 +5327,7 @@ public static class Builder implements BaseBuilder<Message, FDBRecordStore> {
private FDBRecordStoreBase.UserVersionChecker userVersionChecker;

@Nonnull
private IndexMaintainerRegistry indexMaintainerRegistry = IndexMaintainerRegistryImpl.instance();
private IndexMaintainerFactoryRegistry indexMaintainerRegistry = IndexMaintainerFactoryRegistryImpl.instance();

@Nonnull
private IndexMaintenanceFilter indexMaintenanceFilter = IndexMaintenanceFilter.NORMAL;
Expand Down Expand Up @@ -5523,13 +5524,13 @@ public Builder setUserVersionChecker(@Nullable UserVersionChecker userVersionChe

@Override
@Nonnull
public IndexMaintainerRegistry getIndexMaintainerRegistry() {
public IndexMaintainerFactoryRegistry getIndexMaintainerRegistry() {
return indexMaintainerRegistry;
}

@Override
@Nonnull
public Builder setIndexMaintainerRegistry(@Nonnull IndexMaintainerRegistry indexMaintainerRegistry) {
public Builder setIndexMaintainerRegistry(@Nonnull IndexMaintainerFactoryRegistry indexMaintainerRegistry) {
this.indexMaintainerRegistry = indexMaintainerRegistry;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import com.apple.foundationdb.record.query.expressions.QueryComponent;
import com.apple.foundationdb.record.query.plan.RecordQueryPlanner;
import com.apple.foundationdb.record.query.plan.RecordQueryPlannerConfiguration;
import com.apple.foundationdb.record.query.plan.cascades.CascadesPlanner;
import com.apple.foundationdb.record.query.plan.plans.QueryResult;
import com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan;
import com.apple.foundationdb.subspace.Subspace;
Expand Down Expand Up @@ -186,6 +187,8 @@ default FDBStoreTimer getTimer() {
@Nonnull
RecordSerializer<M> getSerializer();

@Nonnull
IndexMaintainerFactoryRegistry getIndexMaintainerRegistry();

/**
* Returns the index maintainer for a given index.
Expand Down Expand Up @@ -2118,6 +2121,18 @@ default RecordCursor<QueryResult> executeQuery(@Nonnull RecordQueryPlan plan,
return plan.executePlan(this, evaluationContext, continuation, executeProperties);
}

/**
* Create a {@link CascadesPlanner} to use to plan queries on this record store. It will be
* initialized with the context necessary to generate query plans for the store, like the
* set of available types and indexes.
*
* @return a {@link CascadesPlanner} implementation initialized with state from this record store
*/
@Nonnull
default CascadesPlanner getCascadesPlanner() {
return new CascadesPlanner(getRecordMetaData(), getRecordStoreState(), getIndexMaintainerRegistry());
}

/**
* Plan a query.
* @param query the query to plan
Expand Down Expand Up @@ -2328,7 +2343,7 @@ default BaseBuilder<M, R> setFormatVersion(FormatVersion formatVersion) {
* @return the index registry to use
*/
@Nonnull
IndexMaintainerRegistry getIndexMaintainerRegistry();
IndexMaintainerFactoryRegistry getIndexMaintainerRegistry();

/**
* Set the registry of index maintainers to be used by the record store.
Expand All @@ -2338,7 +2353,7 @@ default BaseBuilder<M, R> setFormatVersion(FormatVersion formatVersion) {
* @see RecordMetaDataBuilder#setIndexMaintainerRegistry
*/
@Nonnull
BaseBuilder<M, R> setIndexMaintainerRegistry(@Nonnull IndexMaintainerRegistry indexMaintainerRegistry);
BaseBuilder<M, R> setIndexMaintainerRegistry(@Nonnull IndexMaintainerFactoryRegistry indexMaintainerRegistry);

/**
* Get the {@link IndexMaintenanceFilter index filter} to be used by the record store.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ public RecordSerializer<M> getSerializer() {
return typedSerializer;
}


@Nonnull
@Override
public IndexMaintainerFactoryRegistry getIndexMaintainerRegistry() {
return untypedStore.getIndexMaintainerRegistry();
}

@Nonnull
@Override
public IndexMaintainer getIndexMaintainer(@Nonnull final Index index) {
Expand Down Expand Up @@ -497,13 +504,13 @@ public Builder<M> setUserVersionChecker(@Nullable UserVersionChecker userVersion

@Nonnull
@Override
public IndexMaintainerRegistry getIndexMaintainerRegistry() {
public IndexMaintainerFactoryRegistry getIndexMaintainerRegistry() {
return untypedStoreBuilder.getIndexMaintainerRegistry();
}

@Nonnull
@Override
public Builder<M> setIndexMaintainerRegistry(@Nonnull IndexMaintainerRegistry indexMaintainerRegistry) {
public Builder<M> setIndexMaintainerRegistry(@Nonnull IndexMaintainerFactoryRegistry indexMaintainerRegistry) {
untypedStoreBuilder.setIndexMaintainerRegistry(indexMaintainerRegistry);
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,13 @@
package com.apple.foundationdb.record.provider.foundationdb;

import com.apple.foundationdb.annotation.API;
import com.apple.foundationdb.record.RecordMetaData;
import com.apple.foundationdb.record.metadata.Index;
import com.apple.foundationdb.record.metadata.IndexValidator;
import com.apple.foundationdb.record.query.plan.cascades.MatchCandidate;

import javax.annotation.Nonnull;
import java.util.Collections;

/**
* A factory for {@link IndexMaintainer}.
Expand Down Expand Up @@ -68,4 +71,49 @@ public interface IndexMaintainerFactory {
*/
@Nonnull
IndexMaintainer getIndexMaintainer(@Nonnull IndexMaintainerState state);

/**
* Create {@link MatchCandidate}s to use for the given {@link Index}.
* Implementors can assume that the index is one of this factory's
* {@linkplain #getIndexTypes() supported types}. Note that this is
* structured as a method on the maintainer factory so that indexes
* defined outside the core repository can define the structure
* used by the planner to match them. However, use cases should be
* aware that the planner does not provide a stable API (yet) for
* what these match candidates should contain, and so outside
* implementors should be mindful that it is on them to keep up
* with the planner as it changes. For that reason, this should only
* be overridden by users who know what they are doing.
*
* <p>
* By default, this returns an empty collection. This means that the
* index will not be matchable by the {@link com.apple.foundationdb.record.query.plan.cascades.CascadesPlanner}.
* Index types that want to be used in plans should implement this
* method. Utility methods in {@link MatchCandidate} can be used to
* create, for example, canonical expansions of indexes that behave like
* indexes defined in the core repository (e.g., {@link com.apple.foundationdb.record.metadata.IndexTypes#VALUE}
* indexes).
* </p>
*
* <p>
* Indexes may return more than one {@link MatchCandidate}. This can be
* useful for index types that have more than one way of being scanned.
* For example, the {@link com.apple.foundationdb.record.metadata.IndexTypes#RANK}
* index can be scanned {@link com.apple.foundationdb.record.IndexScanType#BY_VALUE},
* at which point it behaves just like a {@link com.apple.foundationdb.record.metadata.IndexTypes#VALUE}
* index, or it can be scanned {@link com.apple.foundationdb.record.IndexScanType#BY_RANK},
* at which point it behaves very differently. The different scan types are reflected
* in different {@link MatchCandidate} which encode different information about
* the index and how it should be scanned.
* </p>
*
* @param metaData the meta-data in which the index is defined
* @param index the index to expend
* @param reverse whether the index is to be scanned in reverse
* @return a collection of {@link MatchCandidate}s to match the index against
*/
@Nonnull
default Iterable<MatchCandidate> createMatchCandidates(@Nonnull RecordMetaData metaData, @Nonnull Index index, boolean reverse) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot remember the specifics but the reverse here seems odd.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked it up and it's only the planning of RecordQuerys that need this. Annoying...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I did notice that, but I didn't look too deeply into it. I'm not actually sure why we can't rely on the sort order on the sort descriptor. If we could, I'd be happy to remove this parameter

return Collections.emptyList();
}
}
Loading