public static Set<String> getPropertyKeys(TitanVertex v) { final Set<String> s = new HashSet<>(); v.query().properties().forEach( p -> s.add(p.propertyKey().name())); return s; }
@Override protected Iterator<E> flatMap(final Traverser.Admin<Vertex> traverser) { if (useMultiQuery) { assert multiQueryResults != null; return (Iterator<E>) multiQueryResults.get(traverser.get()).iterator(); } else { TitanVertexQuery query = makeQuery((TitanTraversalUtil.getTitanVertex(traverser)).query()); return (Vertex.class.isAssignableFrom(getReturnClass())) ? query.vertices().iterator() : query.edges().iterator(); } }
private double testAllVertices(long vid, int numV) { long start = System.nanoTime(); TitanVertex v = getV(graph,vid); for (int i=1; i<numV; i++) { v = getOnlyElement(v.query().direction(Direction.OUT).labels("knows").vertices()); } return ((System.nanoTime()-start)/1000000.0); }
public static Iterable<Object> getValues(TitanElement element, PropertyKey key) { if (element instanceof TitanRelation) { Object value = element.valueOrNull(key); if (value==null) return Collections.EMPTY_LIST; else return ImmutableList.of(value); } else { assert element instanceof TitanVertex; return Iterables.transform((((TitanVertex) element).query()).keys(key.name()).properties(), new Function<TitanVertexProperty, Object>() { @Nullable @Override public Object apply(@Nullable TitanVertexProperty titanProperty) { return titanProperty.value(); } }); } }
private int getPartitionIDbyKey(TitanVertex vertex) { Preconditions.checkState(idManager!=null && key!=null,"PropertyPlacementStrategy has not been initialized correctly"); assert idManager.getPartitionBound()<=Integer.MAX_VALUE; int partitionBound = (int)idManager.getPartitionBound(); TitanVertexProperty p = (TitanVertexProperty)Iterables.getFirst(vertex.query().keys(key).properties(),null); if (p==null) return -1; int hashPid = Math.abs(p.value().hashCode())%partitionBound; assert hashPid>=0 && hashPid<partitionBound; if (isExhaustedPartition(hashPid)) { //We keep trying consecutive partition ids until we find a non-exhausted one int newPid=hashPid; do { newPid = (newPid+1)%partitionBound; if (newPid==hashPid) //We have gone full circle - no more ids to try throw new IDPoolExhaustedException("Could not find non-exhausted partition"); } while (isExhaustedPartition(newPid)); return newPid; } else return hashPid; } }
@Override protected void doRun() throws Exception { TitanVertex v = Iterables.<TitanVertex>getOnlyElement(tx.query().has(idKey, vertexid).vertices()); for (int i = 0; i < nodeTraversalCount; i++) { assertCount(expectedEdges, v.query().labels(label2Traverse).direction(Direction.BOTH).edges()); for (TitanEdge r : v.query().direction(Direction.OUT).labels(label2Traverse).edges()) { v = r.vertex(Direction.IN); } } } }
@Override public void process(TitanVertex vertex, ScanMetrics metrics) { long outDegree = vertex.query().labels("knows").direction(Direction.OUT).edgeCount(); assertEquals(0, vertex.query().labels("knows").direction(Direction.IN).edgeCount()); assertEquals(1, vertex.query().labels("uid").propertyCount()); assertTrue(vertex.<Integer>property("uid").orElse(0) > 0); metrics.incrementCustom(DEGREE_COUNT,outDegree); metrics.incrementCustom(VERTEX_COUNT); }
@Test public void testEdgesExceedCacheSize() { // Add a vertex with as many edges as the tx-cache-size. (20000 by default) int numEdges = graph.getConfiguration().getTxVertexCacheSize(); TitanVertex parentVertex = graph.addVertex(); for (int i = 0; i < numEdges; i++) { TitanVertex childVertex = graph.addVertex(); parentVertex.addEdge("friend", childVertex); } graph.tx().commit(); assertCount(numEdges, parentVertex.query().direction(Direction.OUT).edges()); // Remove an edge. parentVertex.query().direction(OUT).edges().iterator().next().remove(); // Check that getEdges returns one fewer. assertCount(numEdges - 1, parentVertex.query().direction(Direction.OUT).edges()); // Run the same check one more time. // This fails! (Expected: 19999. Actual: 20000.) assertCount(numEdges - 1, parentVertex.query().direction(Direction.OUT).edges()); }
/** * Tests that self-loop edges are handled and counted correctly */ @Test public void testSelfLoop() { TitanVertex v = tx.addVertex(); v.addEdge("self", v); assertCount(1, v.query().direction(Direction.OUT).labels("self").edges()); assertCount(1, v.query().direction(Direction.IN).labels("self").edges()); assertCount(2, v.query().direction(Direction.BOTH).labels("self").edges()); clopen(); v = getV(tx, v); assertNotNull(v); assertCount(1, v.query().direction(Direction.IN).labels("self").edges()); assertCount(1, v.query().direction(Direction.OUT).labels("self").edges()); assertCount(1, v.query().direction(Direction.IN).labels("self").edges()); assertCount(2, v.query().direction(Direction.BOTH).labels("self").edges()); }
@Override protected Iterator<E> flatMap(final Traverser.Admin<Element> traverser) { if (useMultiQuery) { //it is guaranteed that all elements are vertices assert multiQueryResults != null; return convertIterator(multiQueryResults.get(traverser.get())); } else if (traverser.get() instanceof Vertex) { TitanVertexQuery query = makeQuery((TitanTraversalUtil.getTitanVertex(traverser)).query()); return convertIterator(query.properties()); } else { //It is some other element (edge or vertex property) Iterator<E> iter; if (getReturnType().forValues()) { assert orders.isEmpty() && hasContainers.isEmpty(); iter = traverser.get().values(getPropertyKeys()); } else { //this asks for properties assert orders.isEmpty(); //HasContainers don't apply => empty result set if (!hasContainers.isEmpty()) return Collections.emptyIterator(); iter = (Iterator<E>) traverser.get().properties(getPropertyKeys()); } if (limit!=Query.NO_LIMIT) iter = Iterators.limit(iter,limit); return iter; } }
@Test public void testEdgeTTLWithTransactions() throws Exception { if (!features.hasCellTTL()) { return; } EdgeLabel label1 = mgmt.makeEdgeLabel("likes").make(); mgmt.setTTL(label1, Duration.ofSeconds(1)); assertEquals(Duration.ofSeconds(1), mgmt.getTTL(label1)); mgmt.commit(); TitanVertex v1 = graph.addVertex(), v2 = graph.addVertex(); v1.addEdge("likes", v2); // pre-commit state of the edge. It is not yet subject to TTL assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); Thread.sleep(1001); // the edge should have expired by now, but only if it had been committed assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); graph.tx().commit(); // still here, because we have just committed the edge. Its countdown starts at the commit assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); Thread.sleep(1001); // the edge has expired in Cassandra, but still appears alive in this transaction assertNotEmpty(v1.query().direction(Direction.OUT).vertices()); // syncing with the data store, we see that the edge has expired graph.tx().rollback(); assertEmpty(v1.query().direction(Direction.OUT).vertices()); }
@Override public void run() { while (true) { // Make or break relType between two (possibly same) random nodes TitanVertex source = Iterables.<TitanVertex>getOnlyElement(tx.query().has(idKey, 0).vertices()); TitanVertex sink = Iterables.<TitanVertex>getOnlyElement(tx.query().has(idKey, 1).vertices()); for (Edge r : source.query().direction(Direction.OUT).labels(elabel).edges()) { if (getId(r.inVertex()) == getId(sink)) { r.remove(); continue; } } source.addEdge(elabel, sink); if (Thread.interrupted()) break; } }
@Override public void run() { TitanTransaction tx = graph.newTransaction(); long ruid = random.nextInt(maxUID) + 1; getVertex(tx,"uid", ruid).property(VertexProperty.Cardinality.single, "name", fixedName); for (int t = 1; t <= trials; t++) { TitanVertex v = getVertex(tx,"uid", random.nextInt(maxUID) + 1); assertCount(2, v.properties()); int count = 0; for (TitanEdge e : v.query().direction(Direction.BOTH).edges()) { count++; assertTrue(e.<Integer>value("time") >= 0); } assertTrue(count <= 2); // if (t%(trials/10)==0) System.out.println(t); } assertEquals(fixedName, getVertex(tx,"uid", ruid).value("name")); tx.commit(); } });
private void testPartitionSpread(boolean flush, boolean batchCommit) { Object[] options = {option(GraphDatabaseConfiguration.IDS_FLUSH), flush}; clopen(options); int[] groupDegrees = {10,15,10,17,10,4,7,20,11}; int numVertices = setupGroupClusters(groupDegrees,batchCommit?CommitMode.BATCH:CommitMode.PER_VERTEX); IntSet partitionIds = new IntHashSet(numVertices); //to track the "spread" of partition ids for (int i=0;i<groupDegrees.length;i++) { TitanVertex g = getOnlyVertex(tx.query().has("groupid","group"+i)); assertCount(groupDegrees[i],g.edges(Direction.OUT,"contain")); assertCount(groupDegrees[i],g.edges(Direction.IN,"member")); assertCount(groupDegrees[i],g.query().direction(Direction.OUT).edges()); assertCount(groupDegrees[i],g.query().direction(Direction.IN).edges()); assertCount(groupDegrees[i]*2,g.query().edges()); for (TitanVertex v : g.query().direction(Direction.IN).labels("member").vertices()) { int pid = getPartitionID(v); partitionIds.add(pid); assertEquals(g, getOnlyElement(v.query().direction(Direction.OUT).labels("member").vertices())); VertexList vlist = v.query().direction(Direction.IN).labels("contain").vertexIds(); assertEquals(1,vlist.size()); assertEquals(pid,idManager.getPartitionId(vlist.getID(0))); assertEquals(g,vlist.get(0)); } } if (flush || !batchCommit) { //In these cases we would expect significant spread across partitions assertTrue(partitionIds.size()>numPartitions/2); //This is a probabilistic test that might fail } else { assertEquals(1,partitionIds.size()); //No spread in this case } }
TitanRelation findRelation(TitanTransaction tx) { TitanVertex v = ((StandardTitanTx)tx).getInternalVertex(outVertexId); if (v == null || v.isRemoved()) return null; TitanVertex typeVertex = tx.getVertex(typeId); if (typeVertex == null) return null; if (!(typeVertex instanceof RelationType)) throw new IllegalArgumentException("Invalid RelationIdentifier: typeID does not reference a type"); RelationType type = (RelationType) typeVertex; Iterable<? extends TitanRelation> rels; if (((RelationType) typeVertex).isEdgeLabel()) { Direction dir = Direction.OUT; TitanVertex other = ((StandardTitanTx)tx).getInternalVertex(inVertexId); if (other==null || other.isRemoved()) return null; if (((StandardTitanTx) tx).isPartitionedVertex(v) && !((StandardTitanTx) tx).isPartitionedVertex(other)) { //Swap for likely better performance TitanVertex tmp = other; other = v; v = tmp; dir = Direction.IN; } rels = ((VertexCentricQueryBuilder) v.query()).noPartitionRestriction().types((EdgeLabel) type).direction(dir).adjacent(other).edges(); } else { rels = ((VertexCentricQueryBuilder) v.query()).noPartitionRestriction().types((PropertyKey) type).properties(); } for (TitanRelation r : rels) { //Find current or previous relation if (r.longId() == relationId || ((r instanceof StandardRelation) && ((StandardRelation) r).getPreviousID() == relationId)) return r; } return null; }
public void testBatchLoadingLocking(boolean batchloading) { PropertyKey uid = makeKey("uid",Long.class); TitanGraphIndex uidIndex = mgmt.buildIndex("uid",Vertex.class).unique().addKey(uid).buildCompositeIndex(); mgmt.setConsistency(uid, ConsistencyModifier.LOCK); mgmt.setConsistency(uidIndex,ConsistencyModifier.LOCK); EdgeLabel knows = mgmt.makeEdgeLabel("knows").multiplicity(Multiplicity.ONE2ONE).make(); mgmt.setConsistency(knows,ConsistencyModifier.LOCK); finishSchema(); TestLockerManager.ERROR_ON_LOCKING=true; clopen(option(GraphDatabaseConfiguration.STORAGE_BATCH),batchloading, option(GraphDatabaseConfiguration.LOCK_BACKEND),"test"); int numV = 10000; long start = System.currentTimeMillis(); for (int i=0;i<numV;i++) { TitanVertex v = tx.addVertex("uid",i+1); v.addEdge("knows",v); } clopen(); // System.out.println("Time: " + (System.currentTimeMillis()-start)); for (int i=0;i<Math.min(numV,300);i++) { assertEquals(1, Iterables.size(graph.query().has("uid", i + 1).vertices())); TitanVertex v = Iterables.<TitanVertex>getOnlyElement(graph.query().has("uid", i + 1).vertices()); assertEquals(1, Iterables.size(v.query().direction(OUT).labels("knows").edges())); } }
public static void assertGraphOfTheGods(TitanGraph gotg) { assertCount(12, gotg.query().vertices()); assertCount(3, gotg.query().has(LABEL_NAME, "god").vertices()); TitanVertex h = getOnlyVertex(gotg.query().has("name", "hercules")); assertEquals(30, h.<Integer>value("age").intValue()); assertEquals("demigod", h.label()); assertCount(5, h.query().direction(Direction.BOTH).edges()); gotg.tx().commit(); }
@Test public void testKeybasedGraphPartitioning() { Object[] options = {option(GraphDatabaseConfiguration.IDS_FLUSH), false, option(VertexIDAssigner.PLACEMENT_STRATEGY), PropertyPlacementStrategy.class.getName(), option(PropertyPlacementStrategy.PARTITION_KEY), "clusterId"}; clopen(options); int[] groupDegrees = {5,5,5,5,5,5,5,5}; int numVertices = setupGroupClusters(groupDegrees,CommitMode.PER_VERTEX); IntSet partitionIds = new IntHashSet(numVertices); //to track the "spread" of partition ids for (int i=0;i<groupDegrees.length;i++) { TitanVertex g = getOnlyVertex(tx.query().has("groupid","group"+i)); int partitionId = -1; for (TitanVertex v : g.query().direction(Direction.IN).labels("member").vertices()) { if (partitionId<0) partitionId = getPartitionID(v); assertEquals(partitionId,getPartitionID(v)); partitionIds.add(partitionId); } } assertTrue(partitionIds.size()>numPartitions/2); //This is a probabilistic test that might fail }
/** * Very simple graph operation to ensure minimal functionality and cleanup */ @Test public void testBasic() { PropertyKey uid = makeVertexIndexedUniqueKey("name", String.class); finishSchema(); TitanVertex n1 = tx.addVertex(); uid = tx.getPropertyKey("name"); n1.property(uid.name(), "abcd"); clopen(); long nid = n1.longId(); uid = tx.getPropertyKey("name"); assertTrue(getV(tx, nid) != null); assertTrue(getV(tx, uid.longId()) != null); assertMissing(tx, nid + 64); uid = tx.getPropertyKey(uid.name()); n1 = getV(tx, nid); assertEquals(n1, getOnlyVertex(tx.query().has(uid.name(), "abcd"))); assertEquals(1, Iterables.size(n1.query().relations())); //TODO: how to expose relations? assertEquals("abcd", n1.value(uid.name())); assertCount(1, tx.query().vertices()); close(); TitanCleanup.clear(graph); open(config); assertEmpty(tx.query().vertices()); }