use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method buildJoinIndex.
@Test
public void buildJoinIndex() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("Simple_Other");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 3; i++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(i).setOtherRecNo(1000 + i);
simple.setNumValue2(i * 2);
recordStore.saveRecord(simple.build());
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
other.setNumValue3(i * 3);
recordStore.saveRecord(other.build());
}
context.commit();
}
metaDataBuilder.addIndex(joined, new Index("simple.num_value_2_other.num_value_3", concat(field("simple").nest("num_value_2"), field("other").nest("num_value_3"))));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final Index index = recordStore.getRecordMetaData().getIndex("simple.num_value_2_other.num_value_3");
final TupleRange range = new ScanComparisons.Builder().addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 2)).addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, 3)).build().toTupleRange();
List<Tuple> expected1 = Arrays.asList(Tuple.from(2, 3, -1, Tuple.from(1), Tuple.from(1001)));
List<Tuple> results1 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected1, results1);
}
}
use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method rankJoinIndex.
@Test
public void rankJoinIndex() throws Exception {
final JoinedRecordTypeBuilder joined = metaDataBuilder.addJoinedRecordType("JoinedForRank");
joined.addConstituent("simple", "MySimpleRecord");
joined.addConstituent("other", "MyOtherRecord");
joined.addJoin("simple", "other_rec_no", "other", "rec_no");
final GroupingKeyExpression group = field("simple").nest("num_value_2").groupBy(field("other").nest("num_value"));
metaDataBuilder.addIndex(joined, new Index("simple.num_value_2_by_other.num_value", group, IndexTypes.RANK));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < i; j++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(100 * i + j).setOtherRecNo(1000 + i);
simple.setNumValue2(i + j);
recordStore.saveRecord(simple.build());
}
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
other.setNumValue(i % 2);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
Index index = recordStore.getRecordMetaData().getIndex("simple.num_value_2_by_other.num_value");
RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, IndexScanType.BY_RANK, TupleRange.allOf(Tuple.from(0, 1)), null, ScanProperties.FORWARD_SCAN);
Tuple pkey = cursor.first().get().map(IndexEntry::getPrimaryKey).orElse(null);
assertFalse(cursor.getNext().hasNext());
// 201, 1002 and 200, 1003 both have score 3, but in different groups.
assertEquals(Tuple.from(-1, Tuple.from(201), Tuple.from(1002)), pkey);
FDBSyntheticRecord record = recordStore.loadSyntheticRecord(pkey).join();
IndexRecordFunction<Long> rankFunction = ((IndexRecordFunction<Long>) Query.rank(group).getFunction()).cloneWithIndex(index.getName());
assertEquals(1, recordStore.evaluateRecordFunction(rankFunction, record).join().longValue());
}
}
use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreTest method testOverlappingPrimaryKey.
@Test
public void testOverlappingPrimaryKey() {
try (FDBRecordContext context = openContext()) {
RecordMetaDataBuilder builder = RecordMetaData.newBuilder().setRecords(TestRecordsWithHeaderProto.getDescriptor());
builder.getRecordType("MyRecord").setPrimaryKey(field("header").nest(concatenateFields("path", "rec_no")));
builder.addIndex("MyRecord", "MyRecord$path_str", concat(field("header").nest("path"), field("str_value")));
RecordMetaData metaData = builder.getRecordMetaData();
createOrOpenRecordStore(context, metaData);
TestRecordsWithHeaderProto.MyRecord.Builder recBuilder = TestRecordsWithHeaderProto.MyRecord.newBuilder();
TestRecordsWithHeaderProto.HeaderRecord.Builder headerBuilder = recBuilder.getHeaderBuilder();
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(1);
recBuilder.setStrValue("hello");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("aaa");
headerBuilder.setRecNo(2);
recBuilder.setStrValue("goodbye");
recordStore.saveRecord(recBuilder.build());
headerBuilder.setPath("zzz");
headerBuilder.setRecNo(3);
recBuilder.setStrValue("end");
recordStore.saveRecord(recBuilder.build());
List<List<Object>> rows = new ArrayList<>();
Index index = metaData.getIndex("MyRecord$path_str");
ScanComparisons comparisons = ScanComparisons.from(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "aaa"));
TupleRange range = comparisons.toTupleRange();
try (RecordCursor<IndexEntry> cursor = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN)) {
cursor.forEach(row -> rows.add(row.getKey().getItems())).join();
}
assertEquals(Arrays.asList(Arrays.asList("aaa", "goodbye", 2L), Arrays.asList("aaa", "hello", 1L)), rows);
}
}
use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreIndexTest method setUpIndexOrphanValidation.
private Set<IndexEntry> setUpIndexOrphanValidation() throws Exception {
final int nRecords = 20;
try (FDBRecordContext context = openContext()) {
uncheckedOpenSimpleRecordStore(context);
for (int i = 0; i < nRecords; i++) {
TestRecords1Proto.MySimpleRecord.Builder recBuilder = TestRecords1Proto.MySimpleRecord.newBuilder();
recBuilder.setRecNo(i);
recBuilder.setStrValueIndexed(Integer.toString(i));
recordStore.saveRecord(recBuilder.build());
}
commit(context);
}
// Delete the even numbered records with the index removed.
Set<IndexEntry> expectedInvalidEntries = new HashSet<>();
try (FDBRecordContext context = openContext()) {
final Index index = recordStore.getRecordMetaData().getIndex("MySimpleRecord$str_value_indexed");
uncheckedOpenSimpleRecordStore(context, builder -> builder.removeIndex("MySimpleRecord$str_value_indexed"));
for (int i = 0; i < nRecords; i += 2) {
recordStore.deleteRecord(Tuple.from(i));
expectedInvalidEntries.add(new IndexEntry(index, Tuple.from(Integer.toString(i), i), TupleHelpers.EMPTY));
}
commit(context);
}
return expectedInvalidEntries;
}
use of com.apple.foundationdb.record.IndexEntry in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreReplaceIndexTest method buildReplacement.
@Test
public void buildReplacement() {
final String recordTypeName = "MySimpleRecord";
final Index origIndex = new Index("MySimpleRecord$(num_value_2, str_value_indexed)", "num_value_2", "str_value_indexed");
final Index newIndex = new Index("MySimpleRecord$(str_value_indexed, num_value_2)", "str_value_indexed", "num_value_2");
final RecordMetaDataHook addBothIndexes = composeHooks(addIndexHook(recordTypeName, origIndex), addIndexHook(recordTypeName, newIndex));
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, addBothIndexes);
assertTrue(disableIndex(newIndex));
assertTrue(recordStore.isIndexReadable(origIndex), "Old index should be readable at start");
recordStore.saveRecord(TestRecords1Proto.MySimpleRecord.newBuilder().setRecNo(1066L).setNumValue2(32).setStrValueIndexed("hello").build());
commit(context);
}
final RecordMetaDataHook withReplacementsHook = composeHooks(addIndexAndReplacements(recordTypeName, origIndex, newIndex), bumpMetaDataVersionHook());
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, withReplacementsHook);
assertTrue(recordStore.isIndexReadable(origIndex.getName()), "Old index should be readable until replacement index is built");
final List<IndexEntry> oldIndexEntries = scanIndex(origIndex);
assertThat(oldIndexEntries, hasSize(1));
assertEquals(Tuple.from(1066L), oldIndexEntries.get(0).getPrimaryKey());
assertEquals(Tuple.from(32, "hello", 1066L), oldIndexEntries.get(0).getKey());
buildIndex(newIndex);
commit(context);
}
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, withReplacementsHook);
assertTrue(recordStore.isIndexDisabled(origIndex.getName()), "Old index should be disabled once replacement index is built");
commit(context);
}
// scan the index
try (FDBRecordContext context = openContext()) {
openSimpleRecordStore(context, composeHooks(addBothIndexes, bumpMetaDataVersionHook(), bumpMetaDataVersionHook()));
assertTrue(uncheckedMarkIndexReadable(origIndex));
final List<IndexEntry> oldIndexEntries = scanIndex(origIndex);
assertThat("Index data should have been deleted", oldIndexEntries, empty());
}
}
Aggregations