Search in sources :

Example 1 with JoinedRecordType

use of com.apple.foundationdb.record.metadata.JoinedRecordType in project fdb-record-layer by FoundationDB.

the class SyntheticRecordPlanner method forIndex.

/**
 * Construct a plan for generating synthetic records for a given index.
 *
 * The generated records will be of indexed record types.
 *
 * Used by the {@link com.apple.foundationdb.record.provider.foundationdb.OnlineIndexer} to build from a full scan of stored records.
 * @param index an index on synthetic record types
 * @return a plan that can be applied to scanned records to generate synthetic records
 */
@Nonnull
public SyntheticRecordFromStoredRecordPlan forIndex(@Nonnull Index index) {
    final Collection<RecordType> recordTypes = recordMetaData.recordTypesForIndex(index);
    if (recordTypes.size() == 1) {
        final RecordType recordType = recordTypes.iterator().next();
        if (!recordType.isSynthetic()) {
            throw new RecordCoreException("Index does not apply to synthetic record types " + index);
        }
        return forType((SyntheticRecordType<?>) recordType);
    }
    Multimap<String, SyntheticRecordFromStoredRecordPlan> byType = ArrayListMultimap.create();
    for (RecordType recordType : recordTypes) {
        if (!(recordType instanceof JoinedRecordType)) {
            throw unknownSyntheticType(recordType);
        }
        JoinedRecordType joinedRecordType = (JoinedRecordType) recordType;
        Optional<JoinedRecordType.JoinConstituent> maybeConstituent = joinedRecordType.getConstituents().stream().filter(c -> !c.isOuterJoined()).findFirst();
        if (maybeConstituent.isPresent()) {
            addToByType(byType, joinedRecordType, maybeConstituent.get());
        } else {
            for (JoinedRecordType.JoinConstituent joinConstituent : joinedRecordType.getConstituents()) {
                addToByType(byType, joinedRecordType, joinConstituent);
            }
        }
    }
    return createByType(byType);
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) HashMap(java.util.HashMap) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Multimap(com.google.common.collect.Multimap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) HashSet(java.util.HashSet) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Collection(java.util.Collection) Set(java.util.Set) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) List(java.util.List) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Index(com.apple.foundationdb.record.metadata.Index) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) Nonnull(javax.annotation.Nonnull)

Example 2 with JoinedRecordType

use of com.apple.foundationdb.record.metadata.JoinedRecordType in project fdb-record-layer by FoundationDB.

the class SyntheticRecordPlanner method storedRecordTypesForIndex.

/**
 * Determine what stored record types would be need to scanned in order to rebuild a given index.
 *
 * From those scans, queries will be executed to load other record types to complete the synthesis.
 * <p>
 * In cases such as full outer join, there is no single record type from which all joins can be produced.
 * @param index the index that needs to be built
 * @param recordTypes a subset of the index's record types or {@code null} for all
 * @return a set of stored record types that are sufficient to generate the synthesized records for the index
 */
public Set<RecordType> storedRecordTypesForIndex(@Nonnull Index index, @Nullable Collection<RecordType> recordTypes) {
    if (recordTypes == null) {
        recordTypes = recordMetaData.recordTypesForIndex(index);
    }
    Set<RecordType> result = new HashSet<>();
    for (RecordType recordType : recordTypes) {
        if (!(recordType instanceof JoinedRecordType)) {
            throw unknownSyntheticType(recordType);
        }
        JoinedRecordType joinedRecordType = (JoinedRecordType) recordType;
        Optional<JoinedRecordType.JoinConstituent> maybeConstituent = joinedRecordType.getConstituents().stream().filter(c -> !c.isOuterJoined()).findFirst();
        if (maybeConstituent.isPresent()) {
            result.add(maybeConstituent.get().getRecordType());
        } else {
            for (JoinedRecordType.JoinConstituent joinConstituent : joinedRecordType.getConstituents()) {
                result.add(joinConstituent.getRecordType());
            }
        }
    }
    return result;
}
Also used : ArrayListMultimap(com.google.common.collect.ArrayListMultimap) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) HashMap(java.util.HashMap) RecordQuery(com.apple.foundationdb.record.query.RecordQuery) Multimap(com.google.common.collect.Multimap) RecordQueryPlan(com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan) ArrayList(java.util.ArrayList) RecordQueryPlanner(com.apple.foundationdb.record.query.plan.RecordQueryPlanner) HashSet(java.util.HashSet) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) FDBRecordStore(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) Map(java.util.Map) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Collection(java.util.Collection) Set(java.util.Set) RecordCoreArgumentException(com.apple.foundationdb.record.RecordCoreArgumentException) List(java.util.List) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Index(com.apple.foundationdb.record.metadata.Index) RecordStoreState(com.apple.foundationdb.record.RecordStoreState) Optional(java.util.Optional) API(com.apple.foundationdb.annotation.API) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) HashSet(java.util.HashSet)

Example 3 with JoinedRecordType

use of com.apple.foundationdb.record.metadata.JoinedRecordType in project fdb-record-layer by FoundationDB.

the class RecordMetaData method toProto.

/**
 * Serializes the record meta-data to a <code>MetaData</code> proto message. This operates like
 * {@link #toProto()} except that any dependency in the excluded list is not included in the
 * serialized proto message. If the list is set to {@code null}, then all dependencies will be serialized
 * to the proto message including those that are execluded by default.
 *
 * @param excludedDependencies a list of dependencies not to include in the serialized proto
 * @return the serialized <code>MetaData</code> proto message
 * @throws KeyExpression.SerializationException on any serialization failures
 * @throws MetaDataException if this {@code RecordMetaData} was initialized with a
 *      {@linkplain RecordMetaDataBuilder#setLocalFileDescriptor(Descriptors.FileDescriptor) local file descriptor}
 * @see #toProto()
 */
@Nonnull
@SuppressWarnings("deprecation")
public RecordMetaDataProto.MetaData toProto(@Nullable Descriptors.FileDescriptor[] excludedDependencies) throws KeyExpression.SerializationException {
    if (usesLocalRecordsDescriptor) {
        throw new MetaDataException("cannot serialize meta-data with a local records descriptor to proto");
    }
    RecordMetaDataProto.MetaData.Builder builder = RecordMetaDataProto.MetaData.newBuilder();
    // Set the root records.
    builder.setRecords(recordsDescriptor.toProto());
    // Convert the exclusion list to a map
    Map<String, Descriptors.FileDescriptor> excludeMap = null;
    if (excludedDependencies != null) {
        excludeMap = new HashMap<>(excludedDependencies.length);
        for (Descriptors.FileDescriptor dependency : excludedDependencies) {
            excludeMap.put(dependency.getName(), dependency);
        }
    }
    // Add in the rest of dependencies.
    Map<String, Descriptors.FileDescriptor> allDependencies = new TreeMap<>();
    getDependencies(recordsDescriptor, allDependencies, excludeMap);
    for (Descriptors.FileDescriptor dependency : allDependencies.values()) {
        builder.addDependencies(dependency.toProto());
    }
    // Create builders for each index so that we can then add associated record types (etc.).
    Map<String, RecordMetaDataProto.Index.Builder> indexBuilders = new TreeMap<>();
    for (Map.Entry<String, Index> entry : indexes.entrySet()) {
        indexBuilders.put(entry.getKey(), entry.getValue().toProto().toBuilder());
    }
    for (RecordType recordType : getRecordTypes().values()) {
        // Add this record type to each appropriate index.
        for (Index index : recordType.getIndexes()) {
            indexBuilders.get(index.getName()).addRecordType(recordType.getName());
        }
        for (Index index : recordType.getMultiTypeIndexes()) {
            indexBuilders.get(index.getName()).addRecordType(recordType.getName());
        }
        RecordMetaDataProto.RecordType.Builder typeBuilder = builder.addRecordTypesBuilder().setName(recordType.getName()).setPrimaryKey(recordType.getPrimaryKey().toKeyExpression());
        if (recordType.getSinceVersion() != null) {
            typeBuilder.setSinceVersion(recordType.getSinceVersion());
        }
        if (recordType.hasExplicitRecordTypeKey()) {
            typeBuilder.setExplicitKey(LiteralKeyExpression.toProtoValue(recordType.getExplicitRecordTypeKey()));
        }
    }
    indexBuilders.values().forEach(builder::addIndexes);
    // Add in the former indexes.
    for (FormerIndex formerIndex : getFormerIndexes()) {
        builder.addFormerIndexes(formerIndex.toProto());
    }
    // Add in the final options.
    builder.setSplitLongRecords(splitLongRecords);
    builder.setStoreRecordVersions(storeRecordVersions);
    builder.setVersion(version);
    if (usesSubspaceKeyCounter()) {
        builder.setSubspaceKeyCounter(subspaceKeyCounter);
        builder.setUsesSubspaceKeyCounter(true);
    }
    if (recordCountKey != null) {
        builder.setRecordCountKey(recordCountKey.toKeyExpression());
    }
    for (SyntheticRecordType<?> syntheticRecordType : syntheticRecordTypes.values()) {
        if (syntheticRecordType instanceof JoinedRecordType) {
            builder.addJoinedRecordTypes(((JoinedRecordType) syntheticRecordType).toProto());
        }
    }
    return builder.build();
}
Also used : JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) Index(com.apple.foundationdb.record.metadata.Index) TreeMap(java.util.TreeMap) MetaDataException(com.apple.foundationdb.record.metadata.MetaDataException) FormerIndex(com.apple.foundationdb.record.metadata.FormerIndex) JoinedRecordType(com.apple.foundationdb.record.metadata.JoinedRecordType) RecordType(com.apple.foundationdb.record.metadata.RecordType) SyntheticRecordType(com.apple.foundationdb.record.metadata.SyntheticRecordType) Descriptors(com.google.protobuf.Descriptors) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) Map(java.util.Map) Nonnull(javax.annotation.Nonnull)

Aggregations

Index (com.apple.foundationdb.record.metadata.Index)3 JoinedRecordType (com.apple.foundationdb.record.metadata.JoinedRecordType)3 RecordType (com.apple.foundationdb.record.metadata.RecordType)3 SyntheticRecordType (com.apple.foundationdb.record.metadata.SyntheticRecordType)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 Nonnull (javax.annotation.Nonnull)3 API (com.apple.foundationdb.annotation.API)2 RecordCoreArgumentException (com.apple.foundationdb.record.RecordCoreArgumentException)2 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)2 RecordMetaData (com.apple.foundationdb.record.RecordMetaData)2 RecordStoreState (com.apple.foundationdb.record.RecordStoreState)2 FDBRecordStore (com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore)2 RecordQuery (com.apple.foundationdb.record.query.RecordQuery)2 RecordQueryPlanner (com.apple.foundationdb.record.query.plan.RecordQueryPlanner)2 RecordQueryPlan (com.apple.foundationdb.record.query.plan.plans.RecordQueryPlan)2 ArrayListMultimap (com.google.common.collect.ArrayListMultimap)2 Multimap (com.google.common.collect.Multimap)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2