use of org.janusgraph.graphdb.internal.InternalRelation in project janusgraph by JanusGraph.
the class TransactionLogHeader method logRelations.
private static void logRelations(DataOutput out, final Collection<InternalRelation> relations, StandardJanusGraphTx tx) {
VariableLong.writePositive(out, relations.size());
for (InternalRelation rel : relations) {
VariableLong.writePositive(out, rel.getVertex(0).longId());
org.janusgraph.diskstorage.Entry entry = tx.getEdgeSerializer().writeRelation(rel, 0, tx);
BufferUtil.writeEntry(out, entry);
}
}
use of org.janusgraph.graphdb.internal.InternalRelation 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.graphdb.internal.InternalRelation in project janusgraph by JanusGraph.
the class VertexIDAssigner method assignIDs.
public void assignIDs(Iterable<InternalRelation> addedRelations) {
if (!placementStrategy.supportsBulkPlacement()) {
for (InternalRelation relation : addedRelations) {
for (int i = 0; i < relation.getArity(); i++) {
InternalVertex vertex = relation.getVertex(i);
if (!vertex.hasId()) {
assignID(vertex, getVertexIDType(vertex));
}
}
assignID(relation);
}
} else {
// 2) only assign ids to (user) vertices
Map<InternalVertex, PartitionAssignment> assignments = new HashMap<>();
for (InternalRelation relation : addedRelations) {
for (int i = 0; i < relation.getArity(); i++) {
InternalVertex vertex = relation.getVertex(i);
if (!vertex.hasId()) {
// Those are assigned ids immediately in the transaction
assert !(vertex instanceof JanusGraphSchemaVertex);
if (vertex.vertexLabel().isPartitioned())
// Assign partitioned vertex ids immediately
assignID(vertex, getVertexIDType(vertex));
else
assignments.put(vertex, PartitionAssignment.EMPTY);
}
}
}
log.trace("Bulk id assignment for {} vertices", assignments.size());
for (int attempt = 0; attempt < MAX_PARTITION_RENEW_ATTEMPTS && (assignments != null && !assignments.isEmpty()); attempt++) {
placementStrategy.getPartitions(assignments);
Map<InternalVertex, PartitionAssignment> leftOvers = null;
Iterator<Map.Entry<InternalVertex, PartitionAssignment>> iterator = assignments.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<InternalVertex, PartitionAssignment> entry = iterator.next();
try {
assignID(entry.getKey(), entry.getValue().getPartitionID(), getVertexIDType(entry.getKey()));
Preconditions.checkArgument(entry.getKey().hasId());
} catch (IDPoolExhaustedException e) {
if (leftOvers == null)
leftOvers = new HashMap<>();
leftOvers.put(entry.getKey(), PartitionAssignment.EMPTY);
break;
}
}
if (leftOvers != null) {
while (iterator.hasNext()) leftOvers.put(iterator.next().getKey(), PartitionAssignment.EMPTY);
log.debug("Exhausted ID Pool in bulk assignment. Left-over vertices {}", leftOvers.size());
}
assignments = leftOvers;
}
if (assignments != null && !assignments.isEmpty())
throw new IDPoolExhaustedException("Could not find non-exhausted partition ID Pool after " + MAX_PARTITION_RENEW_ATTEMPTS + " attempts");
// 3) assign ids to relations
for (InternalRelation relation : addedRelations) {
assignID(relation);
}
}
}
use of org.janusgraph.graphdb.internal.InternalRelation in project janusgraph by JanusGraph.
the class VertexIDAssigner method assignID.
private void assignID(InternalElement element, IDManager.VertexIDType vertexIDType) {
for (int attempt = 0; attempt < MAX_PARTITION_RENEW_ATTEMPTS; attempt++) {
long partitionID = -1;
if (element instanceof JanusGraphSchemaVertex) {
partitionID = IDManager.SCHEMA_PARTITION;
} else if (element instanceof JanusGraphVertex) {
if (vertexIDType == IDManager.VertexIDType.PartitionedVertex)
partitionID = IDManager.PARTITIONED_VERTEX_PARTITION;
else
partitionID = placementStrategy.getPartition(element);
} else if (element instanceof InternalRelation) {
InternalRelation relation = (InternalRelation) element;
if (attempt < relation.getLen()) {
// On the first attempts, try to use partition of incident vertices
InternalVertex incident = relation.getVertex(attempt);
Preconditions.checkArgument(incident.hasId());
if (!IDManager.VertexIDType.PartitionedVertex.is(incident.longId()) || relation.isProperty()) {
partitionID = getPartitionID(incident);
} else {
continue;
}
} else {
partitionID = placementStrategy.getPartition(element);
}
}
try {
assignID(element, partitionID, vertexIDType);
} catch (IDPoolExhaustedException e) {
// try again on a different partition
continue;
}
assert element.hasId();
// Check if we should assign a different representative of a potential partitioned vertex
if (element instanceof InternalRelation) {
InternalRelation relation = (InternalRelation) element;
if (relation.isProperty() && isPartitionedAt(relation, 0)) {
// Always assign properties to the canonical representative of a partitioned vertex
InternalVertex vertex = relation.getVertex(0);
((ReassignableRelation) relation).setVertexAt(0, vertex.tx().getInternalVertex(idManager.getCanonicalVertexId(vertex.longId())));
} else if (relation.isEdge()) {
for (int pos = 0; pos < relation.getArity(); pos++) {
if (isPartitionedAt(relation, pos)) {
InternalVertex incident = relation.getVertex(pos);
long newPartition;
int otherPosition = (pos + 1) % 2;
if (((InternalRelationType) relation.getType()).multiplicity().isUnique(EdgeDirection.fromPosition(pos))) {
// If the relation is unique in the direction, we assign it to the canonical vertex...
newPartition = idManager.getPartitionId(idManager.getCanonicalVertexId(incident.longId()));
} else if (!isPartitionedAt(relation, otherPosition)) {
// ...else, we assign it to the partition of the non-partitioned vertex...
newPartition = getPartitionID(relation.getVertex(otherPosition));
} else {
// ...and if such does not exists (i.e. both end vertices are partitioned) we use the hash of the relation id
newPartition = idManager.getPartitionHashForId(relation.longId());
}
if (idManager.getPartitionId(incident.longId()) != newPartition) {
((ReassignableRelation) relation).setVertexAt(pos, incident.tx().getOtherPartitionVertex(incident, newPartition));
}
}
}
}
}
return;
}
throw new IDPoolExhaustedException("Could not find non-exhausted partition ID Pool after " + MAX_PARTITION_RENEW_ATTEMPTS + " attempts");
}
use of org.janusgraph.graphdb.internal.InternalRelation in project janusgraph by JanusGraph.
the class CacheVertexProperty method it.
@Override
public InternalRelation it() {
InternalRelation it = null;
InternalVertex startVertex = getVertex(0);
if (startVertex.hasAddedRelations() && startVertex.hasRemovedRelations()) {
// Test whether this relation has been replaced
final long id = super.longId();
it = Iterables.getOnlyElement(startVertex.getAddedRelations(internalRelation -> (internalRelation instanceof StandardVertexProperty) && ((StandardVertexProperty) internalRelation).getPreviousID() == id), null);
}
return (it != null) ? it : super.it();
}
Aggregations