use of org.janusgraph.graphdb.internal.InternalRelationType in project janusgraph by JanusGraph.
the class JanusGraphOperationCountingTest method testReadOperations.
@SuppressWarnings("unchecked")
public void testReadOperations(boolean cache) {
metricsPrefix = "testReadOperations" + cache;
resetEdgeCacheCounts();
makeVertexIndexedUniqueKey("uid", Integer.class);
mgmt.setConsistency(mgmt.getGraphIndex("uid"), ConsistencyModifier.LOCK);
finishSchema();
if (cache)
clopen(option(DB_CACHE), true, option(DB_CACHE_CLEAN_WAIT), 0, option(DB_CACHE_TIME), 0);
else
clopen();
JanusGraphTransaction tx = graph.buildTransaction().groupName(metricsPrefix).start();
tx.makePropertyKey("name").dataType(String.class).make();
tx.makeEdgeLabel("knows").make();
tx.makeVertexLabel("person").make();
tx.commit();
verifyStoreMetrics(EDGESTORE_NAME);
verifyLockingOverwrite(3);
verifyStoreMetrics(METRICS_STOREMANAGER_NAME, ImmutableMap.of(M_MUTATE, 1L));
resetMetrics();
metricsPrefix = GraphDatabaseConfiguration.METRICS_SCHEMA_PREFIX_DEFAULT;
resetMetrics();
// Test schema caching
for (int t = 0; t < 10; t++) {
tx = graph.buildTransaction().groupName(metricsPrefix).start();
// Retrieve name by index (one backend call each)
assertTrue(tx.containsRelationType("name"));
assertTrue(tx.containsRelationType("knows"));
assertTrue(tx.containsVertexLabel("person"));
PropertyKey name = tx.getPropertyKey("name");
EdgeLabel knows = tx.getEdgeLabel("knows");
VertexLabel person = tx.getVertexLabel("person");
PropertyKey uid = tx.getPropertyKey("uid");
// Retrieve name as property (one backend call each)
assertEquals("name", name.name());
assertEquals("knows", knows.name());
assertEquals("person", person.name());
assertEquals("uid", uid.name());
// Looking up the definition (one backend call each)
assertEquals(Cardinality.SINGLE, name.cardinality());
assertEquals(Multiplicity.MULTI, knows.multiplicity());
assertFalse(person.isPartitioned());
assertEquals(Integer.class, uid.dataType());
// Retrieving in and out relations for the relation types...
InternalRelationType nameInternal = (InternalRelationType) name;
InternalRelationType knowsInternal = (InternalRelationType) knows;
InternalRelationType uidInternal = (InternalRelationType) uid;
assertNull(nameInternal.getBaseType());
assertNull(knowsInternal.getBaseType());
IndexType index = Iterables.getOnlyElement(uidInternal.getKeyIndexes());
assertEquals(1, index.getFieldKeys().length);
assertEquals(ElementCategory.VERTEX, index.getElement());
assertEquals(ConsistencyModifier.LOCK, ((CompositeIndexType) index).getConsistencyModifier());
assertEquals(1, Iterables.size(uidInternal.getRelationIndexes()));
assertEquals(1, Iterables.size(nameInternal.getRelationIndexes()));
assertEquals(nameInternal, Iterables.getOnlyElement(nameInternal.getRelationIndexes()));
assertEquals(knowsInternal, Iterables.getOnlyElement(knowsInternal.getRelationIndexes()));
// .. and vertex labels
assertEquals(0, ((InternalVertexLabel) person).getTTL());
tx.commit();
// Needs to read on first iteration, after that it doesn't change anymore
verifyStoreMetrics(EDGESTORE_NAME, ImmutableMap.of(M_GET_SLICE, 19L));
verifyStoreMetrics(INDEXSTORE_NAME, ImmutableMap.of(M_GET_SLICE, 4L, /* name, knows, person, uid */
M_ACQUIRE_LOCK, 0L));
}
// Create some graph data
metricsPrefix = "add" + cache;
tx = graph.buildTransaction().groupName(metricsPrefix).start();
JanusGraphVertex v = tx.addVertex(), u = tx.addVertex("person");
v.property(VertexProperty.Cardinality.single, "uid", 1);
u.property(VertexProperty.Cardinality.single, "name", "juju");
Edge e = v.addEdge("knows", u);
e.property("name", "edge");
tx.commit();
verifyStoreMetrics(EDGESTORE_NAME);
verifyLockingOverwrite(1);
for (int i = 1; i <= 30; i++) {
metricsPrefix = "op" + i + cache;
tx = graph.buildTransaction().groupName(metricsPrefix).start();
v = getOnlyElement(tx.query().has("uid", 1).vertices());
assertEquals(1, v.<Integer>value("uid").intValue());
u = getOnlyElement(v.query().direction(Direction.BOTH).labels("knows").vertices());
e = getOnlyElement(u.query().direction(Direction.IN).labels("knows").edges());
assertEquals("juju", u.value("name"));
assertEquals("edge", e.value("name"));
tx.commit();
if (!cache) {
verifyStoreMetrics(EDGESTORE_NAME, ImmutableMap.of(M_GET_SLICE, 4L));
verifyStoreMetrics(INDEXSTORE_NAME, ImmutableMap.of(M_GET_SLICE, 1L));
} else if (i > 20) {
// Needs a couple of iterations for cache to be cleaned
verifyStoreMetrics(EDGESTORE_NAME);
verifyStoreMetrics(INDEXSTORE_NAME);
}
}
}
use of org.janusgraph.graphdb.internal.InternalRelationType in project janusgraph by JanusGraph.
the class ManagementSystem method getRelationIndex.
@Override
public RelationTypeIndex getRelationIndex(RelationType type, String name) {
Preconditions.checkArgument(type != null);
Preconditions.checkArgument(StringUtils.isNotBlank(name));
String composedName = composeRelationTypeIndexName(type, name);
// Don't use SchemaCache to make code more compact and since we don't need the extra performance here
JanusGraphVertex v = Iterables.getOnlyElement(QueryUtil.getVertices(transaction, BaseKey.SchemaName, JanusGraphSchemaCategory.getRelationTypeName(composedName)), null);
if (v == null)
return null;
assert v instanceof InternalRelationType;
return new RelationTypeIndexWrapper((InternalRelationType) v);
}
use of org.janusgraph.graphdb.internal.InternalRelationType 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.InternalRelationType in project janusgraph by JanusGraph.
the class StandardJanusGraph method getTTL.
/**
* The TTL of a relation (edge or property) is the minimum of:
* 1) The TTL configured of the relation type (if exists)
* 2) The TTL configured for the label any of the relation end point vertices (if exists)
*
* @param rel relation to determine the TTL for
* @return
*/
public static int getTTL(InternalRelation rel) {
assert rel.isNew();
InternalRelationType baseType = (InternalRelationType) rel.getType();
assert baseType.getBaseType() == null;
int ttl = 0;
Integer ettl = baseType.getTTL();
if (ettl > 0)
ttl = ettl;
for (int i = 0; i < rel.getArity(); i++) {
int vttl = getTTL(rel.getVertex(i));
if (vttl > 0 && (vttl < ttl || ttl <= 0))
ttl = vttl;
}
return ttl;
}
use of org.janusgraph.graphdb.internal.InternalRelationType 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");
}
Aggregations