OMultiCollectionIterator.hasNext() takes long time in cpu profile using JMC 5.4

52 views
Skip to first unread message

Adithyan K

unread,
Nov 6, 2014, 6:20:09 AM11/6/14
to orient-...@googlegroups.com
I am using OrientDB-2.0-M2 version.

My objective is to identify whether a edge with particular label exists between a start vertex and end vertex. I am using the following method for that

private boolean existsRelationship(Relationship relationship) throws Exception
{
OrientVertex start = getVertex(relationship.getStartNodeUniqueKey());
OrientVertex end = getVertex(relationship.getEndNodeUniqueKey());
Iterator<Edge> iter = start.getEdges(end, com.tinkerpop.blueprints.Direction.OUT, relationship.getType()).iterator();
return iter.hasNext();
}
I don't know whether this approach is the efficient way to find edge existence.

In this approach, more than 60% of the CPUs time is spend in iter.hasNext() method. I am attaching the screenshot here. Pls check.
Comparing the load of millions of nodes/edges addition, I feel iter.hasNext() is tooooo expensive.

My objective is to find only the existence. For that, getting edges may not be so efficient, i feel. I am not finding OrientVertex.countEdges() method that accepts destination OrientVertex.

My Points

1. Is there any other better way of checking the existence of a edge given its startnode, end node and label???
2. You can check in the attached screenshot (taken using JMC version 5.4) whether this iter.hasNext() can be so expensive?
3. If possible, you can give some lazily loadable object in such a way that hasNext() just checks the size and current Pointer to return true or false
4. Is it possible to have OrientVertex.countEdges(OrientVertex destination, Direction direction, String... labels)
iterator.hasNext.png

Luca Garulli

unread,
Nov 6, 2014, 9:08:46 AM11/6/14
to orient-database
Hi Adithyan,
The idea of supporting a countEdges() in OrientVertex is good. Could you create a new issue for that?

Do you have lightweight edges between vertices or regular ones? Are regulars if they have at least one property. If yes you could
do:

select from E where out = ? and in = ? limit 1

This would be fast if you create a composite index on E (or the Edge class you're using) and fields out + in.

Lvc@


--

---
You received this message because you are subscribed to the Google Groups "OrientDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to orient-databa...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Adithyan K

unread,
Nov 6, 2014, 3:44:43 PM11/6/14
to orient-...@googlegroups.com
1. I have created issue for countEdges() in OrientVertex https://github.com/orientechnologies/orientdb/issues/3040
2. Mine is not lightweight edges. Becuase, I have 1 or 2 properties in Edges
3. In the query (select from E where out = ? and in = ? limit 1), how should I give the argument. is it line startOrientVertex.getId().toString() and endOrientVertex.getId().toString()?
4. I used the following code to create composite index for out and in...

g.createKeyIndex("key", Edge.class, new Parameter("class", "metoptp"), new Parameter("type", "unique_hash_index")); //This index is for uniqueKey
System.out.println("e index created");
OrientEdgeType edgeType = g.getEdgeType("metoptp");
OIndex<?> createIndex = edgeType.createIndex("out_in", OClass.INDEX_TYPE.UNIQUE, "out", "in");

Here, I am getting the below Exception

Exception in thread "main" com.orientechnologies.orient.core.index.OIndexException: Index with name : 'out_in' cannot be created on class : 'metoptp' because field: 'out' is absent in class definition.
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.createIndex(OClassImpl.java:1418)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.createIndex(OClassImpl.java:1391)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.createIndex(OClassImpl.java:1381)
at com.orientechnologies.orient.core.metadata.schema.OClassImpl.createIndex(OClassImpl.java:1377)
at com.orientechnologies.orient.core.metadata.schema.OClassAbstractDelegate.createIndex(OClassAbstractDelegate.java:291)
at com.tinkerpop.blueprints.impls.orient.OrientElementType.access$301(OrientElementType.java:35)
at com.tinkerpop.blueprints.impls.orient.OrientElementType$4.call(OrientElementType.java:80)
at com.tinkerpop.blueprints.impls.orient.OrientElementType$4.call(OrientElementType.java:77)
at com.tinkerpop.blueprints.impls.orient.OrientBaseGraph.executeOutsideTx(OrientBaseGraph.java:1488)
at com.tinkerpop.blueprints.impls.orient.OrientElementType.createIndex(OrientElementType.java:77)
at adi.orientdb.eval.OTester.setFactory(OTester.java:142)
at adi.orientdb.eval.OTester.write(OTester.java:157)
at adi.orientdb.eval.OTester.main(OTester.java:44)



W. Craig Trader

unread,
Apr 3, 2015, 12:37:00 AM4/3/15
to orient-...@googlegroups.com
Do you have any code samples for creating (1) composite indexes using the Java API, and (2) indexes on edges using the Java API?

Patrick Hoeffel

unread,
Apr 3, 2015, 5:36:32 PM4/3/15
to orient-...@googlegroups.com
There is probably a better way to do this (which I would be happy to know), but this seems to currently be working for me in a Javascript function inside OrientDB. I have not yet tried indexing the edges, but I have tried several variations of Luca's suggestion below, without any luck. I do have an index on the Id field of each Vertex (every vertex type has an Id field).

function edgeExists(fromId, toId, edgeClassName, fromClassName) {
 
var result = db.command("select FROM (select expand(out('"+edgeClassName+"').Id) from "+fromClassName+" where Id = '"+fromId+"') where value = '"+toId+"'");
 
if (result.length == 0)
   
return false;
 
else
   
return true;
}


At runtime it expands to this:

select FROM (select expand(out('REL_Account_Company').Id) from Account where Id = 'd236e1f3-5022-e411-8534-00155d016d32') where value = 'd2b03eae-4c22-e411-8534-00155d016d32'

Always open to suggestions, especially since this will get called a lot.

Patrick

Luca Garulli

unread,
Apr 3, 2015, 5:42:54 PM4/3/15
to orient-database
Hi Patrick,
In your case should work also this one:

select expand( out('REL_Account_Company').Id[value = 'd2b03eae-4c22-e411-8534-00155d016d32'] )
from Account
where Id = 'd236e1f3-5022-e411-8534-00155d016d32'

Lvc@

--

Luca Garulli

unread,
Apr 3, 2015, 5:51:40 PM4/3/15
to orient-database
Hi,
the message was:

Exception in thread "main" com.orientechnologies.orient.core.index.OIndexException: Index with name : 'out_in' cannot be created on class : 'metoptp' because field: 'out' is absent in class definition.

It means there is no "out" property on the edge. In order to create indexes you have to create properties (called also fields) first.

Run this 2 commands before creating the edge index:

create property metoptp.out LINK 
create property metoptp.in LINK 

Or also via API, it's the same.

Lvc@
Reply all
Reply to author
Forward
0 new messages