use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class HadoopScanMapper method findEntriesMatchingQuery.
private EntryList findEntriesMatchingQuery(SliceQuery query, EntryList sortedEntries) {
// Inclusive
int lowestStartMatch = sortedEntries.size();
// Inclusive
int highestEndMatch = -1;
final StaticBuffer queryStart = query.getSliceStart();
final StaticBuffer queryEnd = query.getSliceEnd();
// Find the lowest matchStart s.t. query.getSliceStart <= sortedEntries.get(matchStart)
int low = 0;
int high = sortedEntries.size() - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
Entry midVal = sortedEntries.get(mid);
int cmpStart = queryStart.compareTo(midVal.getColumn());
if (0 < cmpStart) {
// query lower bound exceeds entry (no match)
if (lowestStartMatch == mid + 1) {
// lowestStartMatch located
break;
}
// Move to higher list index
low = mid + 1;
} else /* (0 >= cmpStart) */
{
// entry equals or exceeds query lower bound (match, but not necessarily lowest match)
if (mid < lowestStartMatch) {
lowestStartMatch = mid;
}
// Move to a lower list index
high = mid - 1;
}
}
// so we can bypass the highestEndMatch search and just return an empty result.
if (sortedEntries.size() == lowestStartMatch) {
return EntryList.EMPTY_LIST;
}
// Find the highest matchEnd s.t. sortedEntries.get(matchEnd) < query.getSliceEnd
low = 0;
high = sortedEntries.size() - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
Entry midVal = sortedEntries.get(mid);
int cmpEnd = queryEnd.compareTo(midVal.getColumn());
if (0 < cmpEnd) {
// query upper bound exceeds entry (match, not necessarily highest)
if (mid > highestEndMatch) {
highestEndMatch = mid;
}
// Move to higher list index
low = mid + 1;
} else /* (0 >= cmpEnd) */
{
// entry equals or exceeds query upper bound (no match)
if (highestEndMatch == mid - 1) {
// highestEndMatch located
break;
}
// Move to a lower list index
high = mid - 1;
}
}
if (0 <= highestEndMatch - lowestStartMatch) {
// Return sublist between indices (inclusive at both indices)
// This will be passed into subList, which interprets it exclusively
int endIndex = highestEndMatch + 1;
if (query.hasLimit()) {
endIndex = Math.min(endIndex, query.getLimit() + lowestStartMatch);
}
// TODO avoid unnecessary copy here
return EntryArrayList.of(sortedEntries.subList(lowestStartMatch, endIndex));
} else {
return EntryList.EMPTY_LIST;
}
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class SimpleVertexQueryProcessor method vertexIds.
/**
* Returns the list of adjacent vertex ids for this query. By reading those ids
* from the entries directly (without creating objects) we get much better performance.
*
* @return
*/
public VertexList vertexIds() {
LongArrayList list = new LongArrayList();
long previousId = 0;
for (Long id : Iterables.transform(this, new Function<Entry, Long>() {
@Nullable
@Override
public Long apply(@Nullable Entry entry) {
return edgeSerializer.readRelation(entry, true, tx).getOtherVertexId();
}
})) {
list.add(id);
if (id >= previousId && previousId >= 0)
previousId = id;
else
previousId = -1;
}
return new VertexLongList(tx, list, previousId >= 0);
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class IndexRepairJob method process.
@Override
public void process(JanusGraphVertex vertex, ScanMetrics metrics) {
try {
BackendTransaction mutator = writeTx.getTxHandle();
if (index instanceof RelationTypeIndex) {
RelationTypeIndexWrapper wrapper = (RelationTypeIndexWrapper) index;
InternalRelationType wrappedType = wrapper.getWrappedType();
EdgeSerializer edgeSerializer = writeTx.getEdgeSerializer();
List<Entry> additions = new ArrayList<>();
for (Object relation : vertex.query().types(indexRelationTypeName).direction(Direction.OUT).relations()) {
InternalRelation janusgraphRelation = (InternalRelation) relation;
for (int pos = 0; pos < janusgraphRelation.getArity(); pos++) {
if (!wrappedType.isUnidirected(Direction.BOTH) && !wrappedType.isUnidirected(EdgeDirection.fromPosition(pos)))
// Directionality is not covered
continue;
Entry entry = edgeSerializer.writeRelation(janusgraphRelation, wrappedType, pos, writeTx);
additions.add(entry);
}
}
StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
mutator.mutateEdges(vertexKey, additions, KCVSCache.NO_DELETIONS);
metrics.incrementCustom(ADDED_RECORDS_COUNT, additions.size());
} else if (index instanceof JanusGraphIndex) {
IndexType indexType = managementSystem.getSchemaVertex(index).asIndexType();
assert indexType != null;
IndexSerializer indexSerializer = graph.getIndexSerializer();
// Gather elements to index
List<JanusGraphElement> elements;
switch(indexType.getElement()) {
case VERTEX:
elements = ImmutableList.of(vertex);
break;
case PROPERTY:
elements = Lists.newArrayList();
for (JanusGraphVertexProperty p : addIndexSchemaConstraint(vertex.query(), indexType).properties()) {
elements.add(p);
}
break;
case EDGE:
elements = Lists.newArrayList();
for (Object e : addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges()) {
elements.add((JanusGraphEdge) e);
}
break;
default:
throw new AssertionError("Unexpected category: " + indexType.getElement());
}
if (indexType.isCompositeIndex()) {
for (JanusGraphElement element : elements) {
Set<IndexSerializer.IndexUpdate<StaticBuffer, Entry>> updates = indexSerializer.reindexElement(element, (CompositeIndexType) indexType);
for (IndexSerializer.IndexUpdate<StaticBuffer, Entry> update : updates) {
log.debug("Mutating index {}: {}", indexType, update.getEntry());
mutator.mutateIndex(update.getKey(), Lists.newArrayList(update.getEntry()), KCVSCache.NO_DELETIONS);
metrics.incrementCustom(ADDED_RECORDS_COUNT);
}
}
} else {
assert indexType.isMixedIndex();
Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new HashMap<>();
for (JanusGraphElement element : elements) {
indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore);
metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
}
mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
}
} else
throw new UnsupportedOperationException("Unsupported index found: " + index);
} catch (final Exception e) {
managementSystem.rollback();
writeTx.rollback();
metrics.incrementCustom(FAILED_TX);
throw new JanusGraphException(e.getMessage(), e);
}
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class CQLResultSetKeyIteratorTest method testIterator.
@Test
public void testIterator() throws IOException {
final Array<Row> rows = Array.rangeClosed(1, 100).map(idx -> {
final Row row = mock(Row.class);
when(row.getBytes("key")).thenReturn(ByteBuffer.wrap(Integer.toString(idx / 5).getBytes()));
when(row.getBytes("column1")).thenReturn(ByteBuffer.wrap(Integer.toString(idx % 5).getBytes()));
when(row.getBytes("value")).thenReturn(ByteBuffer.wrap(Integer.toString(idx).getBytes()));
return row;
});
final ResultSet resultSet = mock(ResultSet.class);
when(resultSet.iterator()).thenReturn(rows.iterator());
final CQLColValGetter getter = new CQLColValGetter(new EntryMetaData[0]);
try (final CQLResultSetKeyIterator resultSetKeyIterator = new CQLResultSetKeyIterator(ALL_COLUMNS, getter, resultSet)) {
int i = 0;
while (resultSetKeyIterator.hasNext()) {
final StaticBuffer next = resultSetKeyIterator.next();
final RecordIterator<Entry> entries = resultSetKeyIterator.getEntries();
while (entries.hasNext()) {
final Row row = rows.get(i++);
final Entry entry = entries.next();
assertEquals(row.getBytes("key"), next.asByteBuffer());
assertEquals(row.getBytes("column1"), entry.getColumn().asByteBuffer());
assertEquals(row.getBytes("value"), entry.getValue().asByteBuffer());
}
}
}
}
use of org.janusgraph.diskstorage.Entry in project janusgraph by JanusGraph.
the class CQLResultSetKeyIteratorTest method testPartialIterateColumns.
@Test
public void testPartialIterateColumns() throws IOException {
final Random random = new Random();
final Function1<Integer, ByteBuffer> randomLong = idx -> {
final ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES).putLong(random.nextLong());
buffer.flip();
return buffer;
};
final Array<Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>>> keysMap = Array.range(0, random.nextInt(100) + 100).map(randomLong).map(key -> Tuple.of(key, Array.rangeClosed(0, random.nextInt(100) + 1).map(idx -> Tuple.of(randomLong.apply(idx), randomLong.apply(idx)))));
final Seq<Row> rows = keysMap.flatMap(tuple -> tuple._2.map(columnAndValue -> {
final Row row = mock(Row.class);
when(row.getBytes("key")).thenReturn(tuple._1);
when(row.getBytes("column1")).thenReturn(columnAndValue._1);
when(row.getBytes("value")).thenReturn(columnAndValue._2);
return row;
}));
final ResultSet resultSet = mock(ResultSet.class);
when(resultSet.iterator()).thenReturn(rows.iterator());
final CQLColValGetter getter = new CQLColValGetter(new EntryMetaData[0]);
try (final CQLResultSetKeyIterator resultSetKeyIterator = new CQLResultSetKeyIterator(ALL_COLUMNS, getter, resultSet)) {
final Iterator<Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>>> iterator = keysMap.iterator();
while (resultSetKeyIterator.hasNext()) {
final StaticBuffer next = resultSetKeyIterator.next();
try (final RecordIterator<Entry> entries = resultSetKeyIterator.getEntries()) {
final Tuple2<ByteBuffer, Array<Tuple2<ByteBuffer, ByteBuffer>>> current = iterator.next();
final ByteBuffer currentKey = current._1;
final Array<Tuple2<ByteBuffer, ByteBuffer>> columnValues = current._2;
final Iterator<Tuple2<ByteBuffer, ByteBuffer>> columnIterator = columnValues.iterator();
while (entries.hasNext()) {
final Entry entry = entries.next();
final Tuple2<ByteBuffer, ByteBuffer> columnAndValue = columnIterator.next();
assertEquals(currentKey, next.asByteBuffer());
assertEquals(columnAndValue._1, entry.getColumn().asByteBuffer());
assertEquals(columnAndValue._2, entry.getValue().asByteBuffer());
assertEquals(columnIterator.hasNext(), entries.hasNext());
// 10% of the time, don't complete the iteration
if (random.nextInt(10) == 0) {
break;
}
}
}
}
}
}
Aggregations