use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.
the class SyntheticRecordPlannerTest method outerJoins.
@Test
public void outerJoins() throws Exception {
metaDataBuilder.addIndex("MySimpleRecord", "other_rec_no");
final JoinedRecordTypeBuilder innerJoined = metaDataBuilder.addJoinedRecordType("InnerJoined");
innerJoined.addConstituent("simple", "MySimpleRecord");
innerJoined.addConstituent("other", "MyOtherRecord");
innerJoined.addJoin("simple", "other_rec_no", "other", "rec_no");
final JoinedRecordTypeBuilder leftJoined = metaDataBuilder.addJoinedRecordType("LeftJoined");
leftJoined.addConstituent("simple", "MySimpleRecord");
leftJoined.addConstituent("other", metaDataBuilder.getRecordType("MyOtherRecord"), true);
leftJoined.addJoin("simple", "other_rec_no", "other", "rec_no");
final JoinedRecordTypeBuilder fullOuterJoined = metaDataBuilder.addJoinedRecordType("FullOuterJoined");
fullOuterJoined.addConstituent("simple", metaDataBuilder.getRecordType("MySimpleRecord"), true);
fullOuterJoined.addConstituent("other", metaDataBuilder.getRecordType("MyOtherRecord"), true);
fullOuterJoined.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(1001 + i);
recordStore.saveRecord(simple.build());
TestRecordsJoinIndexProto.MyOtherRecord.Builder other = TestRecordsJoinIndexProto.MyOtherRecord.newBuilder();
other.setRecNo(1000 + i);
recordStore.saveRecord(other.build());
}
context.commit();
}
try (FDBRecordContext context = openContext()) {
final FDBRecordStore recordStore = recordStoreBuilder.setContext(context).open();
final SyntheticRecordPlanner planner = new SyntheticRecordPlanner(recordStore);
SyntheticRecordPlan plan1 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("InnerJoined"));
Multiset<Tuple> expected1 = ImmutableMultiset.of(Tuple.from(-1, Tuple.from(0), Tuple.from(1001)), Tuple.from(-1, Tuple.from(1), Tuple.from(1002)));
Multiset<Tuple> results1 = HashMultiset.create(plan1.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected1, results1);
SyntheticRecordPlan plan2 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("LeftJoined"));
Multiset<Tuple> expected2 = ImmutableMultiset.of(Tuple.from(-2, Tuple.from(0), Tuple.from(1001)), Tuple.from(-2, Tuple.from(1), Tuple.from(1002)), Tuple.from(-2, Tuple.from(2), null));
Multiset<Tuple> results2 = HashMultiset.create(plan2.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected2, results2);
SyntheticRecordPlan plan3 = planner.scanForType(recordStore.getRecordMetaData().getSyntheticRecordType("FullOuterJoined"));
Multiset<Tuple> expected3 = ImmutableMultiset.of(Tuple.from(-3, null, Tuple.from(1000)), Tuple.from(-3, Tuple.from(0), Tuple.from(1001)), Tuple.from(-3, Tuple.from(1), Tuple.from(1002)), Tuple.from(-3, Tuple.from(2), null));
Multiset<Tuple> results3 = HashMultiset.create(plan3.execute(recordStore).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected3, results3);
FDBStoredRecord<Message> record = recordStore.loadRecord(Tuple.from(2));
SyntheticRecordFromStoredRecordPlan plan4 = planner.fromStoredType(record.getRecordType(), false);
Multiset<Tuple> expected4 = ImmutableMultiset.of(Tuple.from(-2, Tuple.from(2), null), Tuple.from(-3, Tuple.from(2), null));
Multiset<Tuple> results4 = HashMultiset.create(plan4.execute(recordStore, record).map(FDBSyntheticRecord::getPrimaryKey).asList().join());
assertEquals(expected4, results4);
}
}
use of com.apple.foundationdb.tuple.Tuple 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.tuple.Tuple in project fdb-record-layer by FoundationDB.
the class LuceneIndexMaintainer method update.
@Nonnull
@Override
public <M extends Message> CompletableFuture<Void> update(@Nullable FDBIndexableRecord<M> oldRecord, @Nullable FDBIndexableRecord<M> newRecord) {
LOG.trace("update oldRecord={}, newRecord={}", oldRecord, newRecord);
// Extract information for grouping from old and new records
final KeyExpression root = state.index.getRootExpression();
final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> oldRecordFields = LuceneDocumentFromRecord.getRecordFields(root, oldRecord);
final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> newRecordFields = LuceneDocumentFromRecord.getRecordFields(root, newRecord);
final Set<Tuple> unchanged = new HashSet<>();
for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : oldRecordFields.entrySet()) {
if (entry.getValue().equals(newRecordFields.get(entry.getKey()))) {
unchanged.add(entry.getKey());
}
}
for (Tuple t : unchanged) {
newRecordFields.remove(t);
oldRecordFields.remove(t);
}
LOG.trace("update oldFields={}, newFields{}", oldRecordFields, newRecordFields);
// delete old
try {
for (Tuple t : oldRecordFields.keySet()) {
deleteDocument(t, oldRecord.getPrimaryKey().pack());
}
} catch (IOException e) {
throw new RecordCoreException("Issue deleting old index keys", "oldRecord", oldRecord, e);
}
// There's actually no possibility of a NPE here. (line 304/306)
if (newRecord == null) {
return AsyncUtil.DONE;
}
// update new
try {
for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : newRecordFields.entrySet()) {
writeDocument(entry.getValue(), entry.getKey(), newRecord.getPrimaryKey().pack());
}
} catch (IOException e) {
throw new RecordCoreException("Issue updating new index keys", e).addLogInfo("newRecord", newRecord);
}
return AsyncUtil.DONE;
}
use of com.apple.foundationdb.tuple.Tuple in project YCSB by brianfrankcooper.
the class FoundationDBClient method convTupleToMap.
private Status convTupleToMap(Tuple tuple, Set<String> fields, Map<String, ByteIterator> result) {
for (int i = 0; i < tuple.size(); i++) {
Tuple v = tuple.getNestedTuple(i);
String field = v.getString(0);
String value = v.getString(1);
// System.err.println(field + " : " + value);
result.put(field, new StringByteIterator(value));
}
if (fields != null) {
for (String field : fields) {
if (result.get(field) == null) {
logger.debug("field not fount: {}", field);
return Status.NOT_FOUND;
}
}
}
return Status.OK;
}
use of com.apple.foundationdb.tuple.Tuple in project YCSB by brianfrankcooper.
the class FoundationDBClient method read.
@Override
public Status read(String table, String key, Set<String> fields, Map<String, ByteIterator> result) {
String rowKey = getRowKey(dbName, table, key);
logger.debug("read key = {}", rowKey);
try {
byte[] row = db.run(tr -> {
byte[] r = tr.get(Tuple.from(rowKey).pack()).join();
return r;
});
Tuple t = Tuple.fromBytes(row);
if (t.size() == 0) {
logger.debug("key not fount: {}", rowKey);
return Status.NOT_FOUND;
}
return convTupleToMap(t, fields, result);
} catch (FDBException e) {
logger.error(MessageFormatter.format("Error reading key: {}", rowKey).getMessage(), e);
e.printStackTrace();
} catch (Exception e) {
logger.error(MessageFormatter.format("Error reading key: {}", rowKey).getMessage(), e);
e.printStackTrace();
}
return Status.ERROR;
}
Aggregations