use of com.apple.foundationdb.record.TupleRange in project fdb-record-layer by FoundationDB.
the class FunctionKeyIndexTest method testIndexScan.
@Test
public void testIndexScan() throws Exception {
// Note: the substr() function is defined by KeyExpressionTest.java
Index index = new Index("substr_index", function("substr", concat(field("str_value"), value(0), value(3))));
Records records = Records.create();
for (int i = 0; i < 10; i++) {
records.add(i, "ab" + Character.toString((char) ('c' + i)) + "_" + i);
}
saveRecords(records, index);
try (FDBRecordContext context = openContext()) {
openRecordStore(context, index);
TupleRange range = new TupleRange(Tuple.from("abd"), Tuple.from("abg_5"), EndpointType.RANGE_INCLUSIVE, EndpointType.RANGE_INCLUSIVE);
List<FDBIndexedRecord<Message>> results = recordStore.getRecordContext().asyncToSync(FDBStoreTimer.Waits.WAIT_SCAN_INDEX_RECORDS, recordStore.scanIndexRecords(index.getName(), IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).asList());
assertEquals(4, results.size());
for (FDBIndexedRecord<Message> indexedRecord : results) {
TypesRecord record = fromMessage(indexedRecord.getRecord());
assertTrue(records.contains(record), "Record does not exist");
assertEquals(record.getStrValue().substring(0, 3), indexedRecord.getIndexEntry().getKey().getString(0));
}
}
}
use of com.apple.foundationdb.record.TupleRange in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method joinIndex.
@Test
public void joinIndex() 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");
metaDataBuilder.addIndex(joined, new Index("simple.str_value_other.num_value_3", concat(field("simple").nest("str_value"), field("other").nest("num_value_3"))));
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).create();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < i; j++) {
TestRecordsJoinIndexProto.MySimpleRecord.Builder simple = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder();
simple.setRecNo(100 * i + j).setOtherRecNo(1000 + i);
simple.setStrValue((i + j) % 2 == 0 ? "even" : "odd");
recordStore.saveRecord(simple.build());
}
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
other.setNumValue3(i);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final Index index = recordStore.getRecordMetaData().getIndex("simple.str_value_other.num_value_3");
final TupleRange range = new ScanComparisons.Builder().addEqualityComparison(new Comparisons.SimpleComparison(Comparisons.Type.EQUALS, "even")).addInequalityComparison(new Comparisons.SimpleComparison(Comparisons.Type.GREATER_THAN, 1)).build().toTupleRange();
List<Tuple> expected1 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)));
List<Tuple> results1 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected1, results1);
FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(201));
TestRecordsJoinIndexProto.MySimpleRecord.Builder recordBuilder = TestRecordsJoinIndexProto.MySimpleRecord.newBuilder().mergeFrom(record.getRecord());
recordBuilder.setStrValue("even");
recordStore.saveRecord(recordBuilder.build());
List<Tuple> expected2 = Arrays.asList(Tuple.from("even", 2, -1, Tuple.from(200), Tuple.from(1002)), Tuple.from("even", 2, -1, Tuple.from(201), Tuple.from(1002)));
List<Tuple> results2 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected2, results2);
recordStore.deleteRecord(Tuple.from(1002));
List<Tuple> expected3 = Arrays.asList();
List<Tuple> results3 = recordStore.scanIndex(index, IndexScanType.BY_VALUE, range, null, ScanProperties.FORWARD_SCAN).map(IndexEntry::getKey).asList().join();
assertEquals(expected3, results3);
}
}
use of com.apple.foundationdb.record.TupleRange 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.TupleRange 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.TupleRange in project fdb-record-layer by FoundationDB.
the class FDBRecordStoreIndexTest method testNoBoundaryPrimaryKeysImpl.
public void testNoBoundaryPrimaryKeysImpl() {
final FDBDatabaseFactory factory = FDBDatabaseFactory.instance();
factory.setLocalityProvider(MockedLocalityUtil.instance());
FDBDatabase database = FDBDatabaseFactory.instance().getDatabase();
final String indexName = "MySimpleRecord$num_value_unique";
try (FDBRecordContext context = database.openContext()) {
openSimpleRecordStore(context, TEST_SPLIT_HOOK);
recordStore.markIndexWriteOnly(indexName).join();
commit(context);
}
String bigOlString = Strings.repeat("x", SplitHelper.SPLIT_RECORD_SIZE + 2);
saveAndSplitSimpleRecord(1, bigOlString, 1);
saveAndSplitSimpleRecord(2, bigOlString, 2);
OnlineIndexer indexer;
List<Tuple> boundaryPrimaryKeys;
TupleRange range;
try (FDBRecordContext context = database.openContext()) {
openSimpleRecordStore(context, TEST_SPLIT_HOOK);
Index index = recordStore.getRecordMetaData().getIndex(indexName);
// The indexer only uses recordStore as a prototype so does not require the original record store is still
// active.
indexer = OnlineIndexer.newBuilder().setDatabase(fdb).setRecordStore(recordStore).setIndex(index).build();
range = recordStore.context.asyncToSync(FDBStoreTimer.Waits.WAIT_BUILD_ENDPOINTS, indexer.buildEndpoints());
logger.info("The endpoints are " + range);
MockedLocalityUtil.init(new ArrayList<>(Arrays.asList(recordStore.recordsSubspace().pack(1), recordStore.recordsSubspace().pack(2))), 0);
boundaryPrimaryKeys = recordStore.context.asyncToSync(FDBStoreTimer.Waits.WAIT_GET_BOUNDARY, recordStore.getPrimaryKeyBoundaries(range.getLow(), range.getHigh()).asList());
assertEquals(0, boundaryPrimaryKeys.size());
logger.info("The boundary primary keys are " + boundaryPrimaryKeys);
commit(context);
}
// Test splitIndexBuildRange.
assertEquals(1, indexer.splitIndexBuildRange(Integer.MAX_VALUE, Integer.MAX_VALUE).size());
indexer.close();
database.close();
}
Aggregations