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 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 ApproximateIndexSelectionStrategy method selectIndices.
/**
* Iterate over all potential indexes and compute a score based on how many clauses
* this index covers. The index with the highest score (as long as it covers at least one
* additional clause) is picked and added to the joint query for as long as such exist.
*/
@Override
public SelectedIndexQuery selectIndices(final Set<IndexType> rawCandidates, final MultiCondition<JanusGraphElement> conditions, final Set<Condition> coveredClauses, OrderList orders, IndexSerializer serializer) {
final JointIndexQuery jointQuery = new JointIndexQuery();
boolean isSorted = orders.isEmpty();
while (true) {
IndexCandidate bestCandidate = null;
boolean candidateSupportsSort = false;
for (final IndexType index : rawCandidates) {
final IndexCandidate indexCandidate = createIndexCandidate(index, conditions, serializer);
if (indexCandidate == null) {
continue;
}
boolean supportsSort = orders.isEmpty() || coveredClauses.isEmpty() && index.isMixedIndex() && IndexSelectionUtil.indexCoversOrder((MixedIndexType) index, orders);
indexCandidate.setScore(calculateIndexCandidateScore(indexCandidate, coveredClauses, supportsSort));
if (!coveredClauses.containsAll(indexCandidate.getSubCover()) && (bestCandidate == null || indexCandidate.getScore() > bestCandidate.getScore())) {
bestCandidate = indexCandidate;
candidateSupportsSort = supportsSort;
}
}
if (bestCandidate != null) {
if (coveredClauses.isEmpty()) {
isSorted = candidateSupportsSort;
}
coveredClauses.addAll(bestCandidate.getSubCover());
addToJointQuery(bestCandidate, jointQuery, serializer, orders);
} else {
break;
}
}
return new SelectedIndexQuery(jointQuery, isSorted);
}
use of org.janusgraph.graphdb.types.MixedIndexType in project atlas by apache.
the class AtlasJanusGraphManagement method reindex.
@Override
public void reindex(String indexName, List<AtlasElement> elements) throws Exception {
try {
JanusGraphIndex index = management.getGraphIndex(indexName);
if (index == null || !(management instanceof ManagementSystem) || !(graph.getGraph() instanceof StandardJanusGraph)) {
LOG.error("Could not retrieve index for name: {} ", indexName);
return;
}
ManagementSystem managementSystem = (ManagementSystem) management;
IndexType indexType = managementSystem.getSchemaVertex(index).asIndexType();
if (!(indexType instanceof MixedIndexType)) {
LOG.warn("Index: {}: Not of MixedIndexType ", indexName);
return;
}
IndexSerializer indexSerializer = ((StandardJanusGraph) graph.getGraph()).getIndexSerializer();
reindexElement(managementSystem, indexSerializer, (MixedIndexType) indexType, elements);
} catch (Exception exception) {
throw exception;
} finally {
management.commit();
}
}
use of org.janusgraph.graphdb.types.MixedIndexType in project atlas by apache.
the class RepairIndex method reindexVertex.
private static void reindexVertex(String indexName, IndexSerializer indexSerializer, Set<String> entityGUIDs) throws Exception {
Map<String, Map<String, List<IndexEntry>>> documentsPerStore = new java.util.HashMap<>();
ManagementSystem mgmt = (ManagementSystem) graph.openManagement();
StandardJanusGraphTx tx = mgmt.getWrappedTx();
BackendTransaction mutator = tx.getTxHandle();
JanusGraphIndex index = mgmt.getGraphIndex(indexName);
MixedIndexType indexType = (MixedIndexType) mgmt.getSchemaVertex(index).asIndexType();
for (String entityGuid : entityGUIDs) {
for (int attemptCount = 1; attemptCount <= MAX_TRIES_ON_FAILURE; attemptCount++) {
AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(entityGuid);
try {
indexSerializer.reindexElement(vertex.getWrappedElement(), indexType, documentsPerStore);
break;
} catch (Exception e) {
displayCrlf("Exception: " + e.getMessage());
displayCrlf("Pausing before retry..");
Thread.sleep(2000 * attemptCount);
}
}
}
mutator.getIndexTransaction(indexType.getBackingIndexName()).restore(documentsPerStore);
}
Aggregations