use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.
the class FDBRecordStore method checkPossiblyRebuildRecordCounts.
protected boolean checkPossiblyRebuildRecordCounts(@Nonnull RecordMetaData metaData, @Nonnull RecordMetaDataProto.DataStoreInfo.Builder info, @Nonnull List<CompletableFuture<Void>> work, int oldFormatVersion) {
KeyExpression countKeyExpression = metaData.getRecordCountKey();
boolean rebuildRecordCounts = (oldFormatVersion > 0 && oldFormatVersion < RECORD_COUNT_ADDED_FORMAT_VERSION) || (countKeyExpression != null && formatVersion >= RECORD_COUNT_KEY_ADDED_FORMAT_VERSION && (!info.hasRecordCountKey() || !KeyExpression.fromProto(info.getRecordCountKey()).equals(countKeyExpression)));
if (rebuildRecordCounts) {
// We want to clear all record counts.
final Transaction tr = ensureContextActive();
tr.clear(getSubspace().range(Tuple.from(RECORD_COUNT_KEY)));
// Set the new record count key if we have one.
if (formatVersion >= RECORD_COUNT_KEY_ADDED_FORMAT_VERSION) {
if (countKeyExpression != null) {
info.setRecordCountKey(countKeyExpression.toKeyExpression());
} else {
info.clearRecordCountKey();
}
}
// Add the record rebuild job.
addRebuildRecordCountsJob(work);
}
return rebuildRecordCounts;
}
use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.
the class IndexFunctionHelper method getThenSubKey.
protected static KeyExpression getThenSubKey(ThenKeyExpression then, int columnStart, int columnEnd) {
final List<KeyExpression> children = then.getChildren();
int columnPosition = 0;
int startChildPosition = -1;
int startChildStart = -1;
int startChildEnd = -1;
for (int childPosition = 0; childPosition < children.size(); childPosition++) {
final KeyExpression child = children.get(childPosition);
final int childColumns = child.getColumnSize();
if (startChildPosition < 0 && columnPosition + childColumns > columnStart) {
startChildPosition = childPosition;
startChildStart = columnStart - columnPosition;
startChildEnd = childColumns;
}
if (columnPosition + childColumns >= columnEnd) {
int endChildEnd = columnEnd - columnPosition;
if (childPosition == startChildPosition) {
// Just one child spans column start, end.
if (startChildPosition == 0 && endChildEnd == childColumns) {
return child;
} else {
return getSubKey(child, startChildStart, endChildEnd);
}
}
if (startChildStart == 0 && endChildEnd == childColumns) {
return new ThenKeyExpression(children.subList(startChildPosition, childPosition + 1));
}
final List<KeyExpression> keys = new ArrayList<>(childPosition - startChildPosition + 1);
keys.add(getSubKey(children.get(startChildPosition), startChildStart, startChildEnd));
if (childPosition > startChildPosition + 1) {
keys.addAll(children.subList(startChildPosition + 1, childPosition));
}
keys.add(getSubKey(child, 0, endChildEnd));
return new ThenKeyExpression(keys);
}
columnPosition += childColumns;
}
throw new RecordCoreException("column counts are not consistent");
}
use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.
the class IndexFunctionHelper method recordFunctionIndexEntry.
/**
* Get the index entry for use by the given index to evaluate the given record function.
*
* In most cases, this is the same as {@link KeyExpression#evaluateSingleton}. But if {@code recordFunction} is
* the result of {@link #recordFunctionWithSubrecordCondition}, a matching entry will be found.
* @param store store against which function will be evaluated
* @param index index for which to evaluate
* @param context context for parameter bindings
* @param recordFunction record function for which to evaluate
* @param record record against which to evaluate
* @param groupSize grouping size for the given index
* @return an index entry or {@code null} if none matches a bound condition
*/
@Nullable
public static Key.Evaluated recordFunctionIndexEntry(@Nonnull FDBRecordStore store, @Nonnull Index index, @Nonnull EvaluationContext context, @Nullable IndexRecordFunction<?> recordFunction, @Nonnull FDBRecord<?> record, int groupSize) {
final KeyExpression expression = index.getRootExpression();
if (!(recordFunction instanceof IndexRecordFunctionWithSubrecordValues)) {
return expression.evaluateSingleton(record);
}
final IndexRecordFunctionWithSubrecordValues<?> recordFunctionWithSubrecordValues = (IndexRecordFunctionWithSubrecordValues<?>) recordFunction;
final int scalarPrefixCount = recordFunctionWithSubrecordValues.getScalarPrefixCount();
final List<Object> toMatch = recordFunctionWithSubrecordValues.getValues(store, context).values();
List<Object> prev = null;
Key.Evaluated match = null;
for (Key.Evaluated key : expression.evaluate(record)) {
final List<Object> subrecord = key.values();
for (int i = 0; i < groupSize; i++) {
if (i < scalarPrefixCount) {
if (prev != null) {
if (!Objects.equals(prev.get(i), subrecord.get(i))) {
throw new RecordCoreException("All subrecords should match for non-constrained keys");
}
}
} else {
if (toMatch.get(i - scalarPrefixCount).equals(subrecord.get(i))) {
if (match != null) {
throw new RecordCoreException("More than one matching subrecord");
}
match = key;
}
}
}
prev = subrecord;
}
return match;
}
use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.
the class JoinedRecordTypeBuilder method build.
@Nonnull
@Override
public JoinedRecordType build(@Nonnull RecordMetaData metaData, @Nonnull Descriptors.FileDescriptor fileDescriptor) {
final List<JoinedRecordType.JoinConstituent> builtConstituents = getConstituents().stream().map(constituent -> constituent.build(metaData)).collect(Collectors.toList());
final Descriptors.Descriptor descriptor = fileDescriptor.findMessageTypeByName(name);
final KeyExpression primaryKey = buildPrimaryKey();
final Map<String, JoinedRecordType.JoinConstituent> constituentsByName = builtConstituents.stream().collect(Collectors.toMap(JoinedRecordType.Constituent::getName, Function.identity()));
final List<JoinedRecordType.Join> builtJoins = joins.stream().map(join -> join.build(constituentsByName)).collect(Collectors.toList());
return new JoinedRecordType(metaData, descriptor, primaryKey, recordTypeKey, indexes, multiTypeIndexes, builtConstituents, builtJoins);
}
use of com.apple.foundationdb.record.metadata.expressions.KeyExpression in project fdb-record-layer by FoundationDB.
the class RecordMetaData method commonPrimaryKey.
@Nullable
public static KeyExpression commonPrimaryKey(@Nonnull Collection<RecordType> recordTypes) {
KeyExpression common = null;
boolean first = true;
for (RecordType recordType : recordTypes) {
if (first) {
common = recordType.getPrimaryKey();
first = false;
} else if (!common.equals(recordType.getPrimaryKey())) {
return null;
}
}
return common;
}
Aggregations