use of org.janusgraph.graphdb.types.MixedIndexType 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> outAdditions = new ArrayList<>();
Map<StaticBuffer, List<Entry>> inAdditionsMap = new HashMap<>();
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);
if (pos == 0) {
outAdditions.add(entry);
} else {
assert pos == 1;
InternalVertex otherVertex = janusgraphRelation.getVertex(1);
StaticBuffer otherVertexKey = writeTx.getIdInspector().getKey(otherVertex.longId());
inAdditionsMap.computeIfAbsent(otherVertexKey, k -> new ArrayList<>()).add(entry);
}
}
}
// Mutating all OUT relationships for the current vertex
StaticBuffer vertexKey = writeTx.getIdInspector().getKey(vertex.longId());
mutator.mutateEdges(vertexKey, outAdditions, KCVSCache.NO_DELETIONS);
// Mutating all IN relationships for the current vertex
int totalInAdditions = 0;
for (Map.Entry<StaticBuffer, List<Entry>> entry : inAdditionsMap.entrySet()) {
StaticBuffer otherVertexKey = entry.getKey();
List<Entry> inAdditions = entry.getValue();
totalInAdditions += inAdditions.size();
mutator.mutateEdges(otherVertexKey, inAdditions, KCVSCache.NO_DELETIONS);
}
metrics.incrementCustom(ADDED_RECORDS_COUNT, outAdditions.size() + totalInAdditions);
} 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 = Collections.singletonList(vertex);
break;
case PROPERTY:
elements = new ArrayList<>();
addIndexSchemaConstraint(vertex.query(), indexType).properties().forEach(elements::add);
break;
case EDGE:
elements = new ArrayList<>();
addIndexSchemaConstraint(vertex.query().direction(Direction.OUT), indexType).edges().forEach(elements::add);
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(), new ArrayList<Entry>(1) {
{
add(update.getEntry());
}
}, KCVSCache.NO_DELETIONS);
metrics.incrementCustom(ADDED_RECORDS_COUNT);
}
}
} else {
assert indexType.isMixedIndex();
for (JanusGraphElement element : elements) {
if (indexSerializer.reindexElement(element, (MixedIndexType) indexType, documentsPerStore)) {
metrics.incrementCustom(DOCUMENT_UPDATES_COUNT);
}
}
}
} 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.graphdb.types.MixedIndexType in project janusgraph by JanusGraph.
the class StandardTransactionLogProcessor method restoreExternalIndexes.
private void restoreExternalIndexes(Predicate<String> isFailedIndex, TransactionLogHeader.Entry entry) {
// 1) Collect all elements (vertices and relations) and the indexes for which they need to be restored
SetMultimap<String, IndexRestore> indexRestores = HashMultimap.create();
BackendOperation.execute(() -> {
final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
try {
entry.getContentAsModifications(serializer).stream().map(m -> ModificationDeserializer.parseRelation(m, tx)).forEach(rel -> {
// Collect affected vertex indexes
for (final MixedIndexType index : getMixedIndexes(rel.getType())) {
if (index.getElement() == ElementCategory.VERTEX && isFailedIndex.apply(index.getBackingIndexName())) {
assert rel.isProperty();
indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.getVertex(0).longId(), ElementCategory.VERTEX, getIndexId(index)));
}
}
// See if relation itself is affected
for (final RelationType relType : rel.getPropertyKeysDirect()) {
for (final MixedIndexType index : getMixedIndexes(relType)) {
if (index.getElement().isInstance(rel) && isFailedIndex.apply(index.getBackingIndexName())) {
assert rel.id() instanceof RelationIdentifier;
indexRestores.put(index.getBackingIndexName(), new IndexRestore(rel.id(), ElementCategory.getByClazz(rel.getClass()), getIndexId(index)));
}
}
}
});
} finally {
if (tx.isOpen())
tx.rollback();
}
return true;
}, readTime);
// 2) Restore elements per backing index
for (final String indexName : indexRestores.keySet()) {
final StandardJanusGraphTx tx = (StandardJanusGraphTx) graph.newTransaction();
try {
BackendTransaction btx = tx.getTxHandle();
final IndexTransaction indexTx = btx.getIndexTransaction(indexName);
BackendOperation.execute(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Map<String, Map<String, List<IndexEntry>>> restoredDocs = Maps.newHashMap();
indexRestores.get(indexName).forEach(restore -> {
JanusGraphSchemaVertex indexV = (JanusGraphSchemaVertex) tx.getVertex(restore.indexId);
MixedIndexType index = (MixedIndexType) indexV.asIndexType();
JanusGraphElement element = restore.retrieve(tx);
if (element != null) {
graph.getIndexSerializer().reindexElement(element, index, restoredDocs);
} else {
// Element is deleted
graph.getIndexSerializer().removeElement(restore.elementId, index, restoredDocs);
}
});
indexTx.restore(restoredDocs);
indexTx.commit();
return true;
}
@Override
public String toString() {
return "IndexMutation";
}
}, persistenceTime);
} finally {
if (tx.isOpen())
tx.rollback();
}
}
}
use of org.janusgraph.graphdb.types.MixedIndexType in project janusgraph by JanusGraph.
the class IndexSerializer method executeQuery.
public Stream<RawQuery.Result> executeQuery(IndexQueryBuilder query, final ElementCategory resultType, final BackendTransaction backendTx, final StandardJanusGraphTx transaction) {
final MixedIndexType index = getMixedIndex(query.getIndex(), transaction);
final String queryStr = createQueryString(query, resultType, transaction, index);
ImmutableList<IndexQuery.OrderEntry> orders = getOrders(query, resultType, transaction, index);
final RawQuery rawQuery = new RawQuery(index.getStoreName(), queryStr, orders, query.getParameters());
if (query.hasLimit())
rawQuery.setLimit(query.getLimit());
rawQuery.setOffset(query.getOffset());
return backendTx.rawQuery(index.getBackingIndexName(), rawQuery).map(result -> new RawQuery.Result(string2ElementId(result.getResult()), result.getScore()));
}
use of org.janusgraph.graphdb.types.MixedIndexType in project janusgraph by JanusGraph.
the class IndexSerializer method getIndexUpdates.
public Collection<IndexUpdate> getIndexUpdates(InternalRelation relation) {
assert relation.isNew() || relation.isRemoved();
final Set<IndexUpdate> updates = Sets.newHashSet();
final IndexUpdate.Type updateType = getUpdateType(relation);
final int ttl = updateType == IndexUpdate.Type.ADD ? StandardJanusGraph.getTTL(relation) : 0;
for (final PropertyKey type : relation.getPropertyKeysDirect()) {
if (type == null)
continue;
for (final IndexType index : ((InternalRelationType) type).getKeyIndexes()) {
if (!indexAppliesTo(index, relation))
continue;
IndexUpdate update;
if (index instanceof CompositeIndexType) {
final CompositeIndexType iIndex = (CompositeIndexType) index;
final RecordEntry[] record = indexMatch(relation, iIndex);
if (record == null)
continue;
update = new IndexUpdate<>(iIndex, updateType, getIndexKey(iIndex, record), getIndexEntry(iIndex, record, relation), relation);
} else {
assert relation.valueOrNull(type) != null;
if (((MixedIndexType) index).getField(type).getStatus() == SchemaStatus.DISABLED)
continue;
update = getMixedIndexUpdate(relation, type, relation.valueOrNull(type), (MixedIndexType) index, updateType);
}
if (ttl > 0)
update.setTTL(ttl);
updates.add(update);
}
}
return updates;
}
use of org.janusgraph.graphdb.types.MixedIndexType in project janusgraph by JanusGraph.
the class IndexSerializer method executeTotals.
public Long executeTotals(IndexQueryBuilder query, final ElementCategory resultType, final BackendTransaction backendTx, final StandardJanusGraphTx transaction) {
final MixedIndexType index = getMixedIndex(query.getIndex(), transaction);
final String queryStr = createQueryString(query, resultType, transaction, index);
final RawQuery rawQuery = new RawQuery(index.getStoreName(), queryStr, query.getParameters());
if (query.hasLimit())
rawQuery.setLimit(query.getLimit());
rawQuery.setOffset(query.getOffset());
return backendTx.totals(index.getBackingIndexName(), rawQuery);
}
Aggregations