Hi.

I tried to delete several million relationships of certain types from the reference node of an embedded graphdb, where there were several other relationshiptypes that were not to be affected. The Javadoc of Node#getRelationships(RelationshipType...) says that it returns all relationships of the given type(s), so I expected that after one call I'd really get all. That was not the case. In my test-production-db i needed about 8 iterations, haven't recreated that in the test yet. But the test shows that not returning all desired relationships doesn't seem to depend on the total number of relationships as i thought in the beginning, if one runs the test with different numbers for insertions.

Here's the log:

05.10.2011 13:36:16 test01 - create graph
05.10.2011 13:36:16 try to delete c:/_src/neo4j-test-remove-relationships
05.10.2011 13:36:16 done deleting
05.10.2011 13:36:16 create graph db at c:/_src/neo4j-test-remove-relationships
05.10.2011 13:36:22 retrieve root node and add another node
05.10.2011 13:36:22 prepare to cycle through relTypes
05.10.2011 13:36:22 loop to insert relationships by cycling through relTypes
05.10.2011 13:36:22 0 of 2097152 relationships inserted
05.10.2011 13:36:26 131072 of 2097152 relationships inserted
05.10.2011 13:36:28 262144 of 2097152 relationships inserted
05.10.2011 13:36:33 393216 of 2097152 relationships inserted
05.10.2011 13:36:35 524288 of 2097152 relationships inserted
05.10.2011 13:36:40 655360 of 2097152 relationships inserted
05.10.2011 13:36:43 786432 of 2097152 relationships inserted
05.10.2011 13:36:48 917504 of 2097152 relationships inserted
05.10.2011 13:36:53 1048576 of 2097152 relationships inserted
05.10.2011 13:36:58 1179648 of 2097152 relationships inserted
05.10.2011 13:37:02 1310720 of 2097152 relationships inserted
05.10.2011 13:37:08 1441792 of 2097152 relationships inserted
05.10.2011 13:37:12 1572864 of 2097152 relationships inserted
05.10.2011 13:37:20 1703936 of 2097152 relationships inserted
05.10.2011 13:37:25 1835008 of 2097152 relationships inserted
05.10.2011 13:37:33 1966080 of 2097152 relationships inserted
05.10.2011 13:37:37 2097152 of 2097152 relationships inserted
05.10.2011 13:37:37 finished inserting 2097152 relationships
05.10.2011 13:37:37 second part of test: deleting relationships
05.10.2011 13:37:37 get all relationships of the given type
05.10.2011 13:37:37 delete them all
05.10.2011 13:38:21 131072 relationships deleted
05.10.2011 13:38:39 262144 relationships deleted
05.10.2011 13:38:41 262153 relationships deleted in iteration 1
05.10.2011 13:38:41 get all relationships of the given type
05.10.2011 13:38:41 delete them all
05.10.2011 13:39:12 131072 relationships deleted
05.10.2011 13:39:22 262135 relationships deleted in iteration 2
05.10.2011 13:39:22 get all relationships of the given type
05.10.2011 13:39:22 delete them all
05.10.2011 13:39:22 0 relationships deleted in iteration 3
05.10.2011 13:39:22 could expect that one iteration is sufficient
05.10.2011 13:39:22 to get all relationships of the given types,
05.10.2011 13:39:22 so that it finished after the second iterations when deletions == 0 05.10.2011 13:39:22 if this line gets logged, then there were more than two iterations, which is bad


And the testcase is attached as .java-file. Could please somebody take a look at it and the log and maybe find my mistake or confirm that this is strange behaviour.

ciao,
st.p.
/**
 *
 */
package de;

import java.io.File;
import java.util.Date;

import junit.framework.TestCase;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;

import de.araneo.util.IO;

/**
 * Test to show strange behaviour concerning removal of relationships from a 
node with many relationships.
 * First a db is created with only root (reference) and another node.
 * Then they are connected with some relationships of different types.
 * Then the goal was to delete all relationships of some but not all of those 
types.
 * The method {@link Node#getRelationships(RelationshipType...)} promises to 
return <b>all</b>
 * but this test shows that it does not return all relationships of the given 
type(s) when there are many relationships.
 * @author stpa
 * 05.10.2011
 */
public class TestNeo4jRemoveRelationships extends TestCase {

        /** neo4j-path, the db will be created for the test and deleted 
afterwards. */
        private static final String LOCATION = 
"c:/_src/neo4j-test-remove-relationships";

        /** number of relationships the tested node will have */
        private static final int INSERTIONS = 1 * 1024 * 1024;

        /** number of insertions that will trigger a transaction */
        private static final int TRANSACTIONMOD = 128 * 1024;

        /** whether there shall be logging or not */
        private static final boolean LOG_TRANSACTIONS = true;

        /** the neo4j-graph itself */
        private GraphDatabaseService graph;

        /** dummy relationship types for the test */
        private enum RelType implements RelationshipType {
                REL_TYPE_ONE,
                REL_TYPE_TWO,
                REL_TYPE_THREE,
                REL_TYPE_FOUR
        }

        /**
         * wipe previous db, create db, insert relationships, try deleting all 
relationships of given types
         */
        public final void test01_create_graph() {
                log("test01 - create graph");
                try {
                        if (this.graph != null) {
                                this.graph.shutdown();
                        }
                } finally {
                        log("try to delete " + 
TestNeo4jRemoveRelationships.LOCATION);
                        IO.deleteFileOrDirectory(
                                new File(
                                        TestNeo4jRemoveRelationships.LOCATION
                                )
                        );
                        log("done deleting");
                }

                log("create graph db at " + 
TestNeo4jRemoveRelationships.LOCATION);
                this.graph = new 
EmbeddedGraphDatabase(TestNeo4jRemoveRelationships.LOCATION);
                Runtime.getRuntime().addShutdownHook(
                        new Thread() {
                                @Override
                                public final void run() {
                                        graph.shutdown();
                                }
                        }
                );
                assertNotNull(this.graph);

                log("retrieve root node and add another node");
                Transaction transaction = this.graph.beginTx();
                Node root = this.graph.getReferenceNode();
                Node otherNode = this.graph.createNode();
                assertNotNull(root);
                assertNotNull(otherNode);

                log("prepare to cycle through relTypes");
                RelationshipType relType;
                RelType[] relTypes = RelType.values();
                int relTypeCount = relTypes.length;
                assertTrue(relTypeCount > 2);
                StringBuffer s;

                log("loop to insert relationships by cycling through relTypes");
                for (int i = 0; i <= TestNeo4jRemoveRelationships.INSERTIONS; 
i++) {
                        relType = relTypes[i % relTypeCount];
//                      Relationship rel = 
root.createRelationshipTo(otherNode,relType);
//                      assertNotNull(rel);
                        root.createRelationshipTo(otherNode,relType);

                        // complete a transaction when appropriate
                        if (i % TestNeo4jRemoveRelationships.TRANSACTIONMOD == 
0) {
                                transaction.success();
                                transaction.finish();
                                transaction = this.graph.beginTx();
                                if 
(TestNeo4jRemoveRelationships.LOG_TRANSACTIONS) {
                                        s = new StringBuffer();
                                        s.append(Integer.toString(i));
                                        s.append(" of ");
                                        
s.append(TestNeo4jRemoveRelationships.INSERTIONS);
                                        s.append(" relationships inserted");
                                        log(s.toString());
                                }
                        }
                }
                transaction.success();
                transaction.finish();
                log("finished inserting " + 
TestNeo4jRemoveRelationships.INSERTIONS + " relationships");
                log("second part of test: deleting relationships");
                int deletions = 0;
                int iterations = 0;
                do {
                        iterations++;
                        deletions = 0;
                        transaction = this.graph.beginTx();
                        log("get all relationships of the given type");
                        Iterable<Relationship> relationships = 
root.getRelationships(
//                              
TestNeo4jRemoveRelationships.RelType.REL_TYPE_ONE,
                                
TestNeo4jRemoveRelationships.RelType.REL_TYPE_TWO
                        );
                        log("delete them all");
                        for (Relationship relationship : relationships) {
                                deletions++;
                                relationship.delete();
                                // complete a transaction when appropriate
                                if (deletions % 
TestNeo4jRemoveRelationships.TRANSACTIONMOD == 0) {
                                        transaction.success();
                                        transaction.finish();
                                        transaction = this.graph.beginTx();
                                        if 
(TestNeo4jRemoveRelationships.LOG_TRANSACTIONS) {
                                                s = new StringBuffer();
                                                
s.append(Integer.toString(deletions));
                                                s.append(" relationships 
deleted");
                                                log(s.toString());
                                        }
                                }
                        }
                        transaction.success();
                        transaction.finish();
                        log(deletions + " relationships deleted in iteration " 
+ iterations);
                } while (deletions > 0);
                log("could expect that one iteration is sufficient");
                log("to get all relationships of the given types,");
                log("so that it finished after the second iterations when 
deletions == 0");
                assertTrue(iterations > 2);
                log("if this line gets logged, then there were more than two 
iterations, which is bad");
        }

        /**
         * print timestamp and message to console
         * @param s {@link String}
         */
        private void log(final String s) {
                StringBuffer str = new StringBuffer();
                str.append(new Date().toLocaleString());
                str.append(" ");
                str.append(s);
                System.out.println(str.toString());
        }
}
_______________________________________________
Neo4j mailing list
User@lists.neo4j.org
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to