Package slavetest

Source Code of slavetest.CommonJobs$TransactionalJob

/**
* Copyright (c) 2002-2011 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package slavetest;

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Map;

import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;
import org.neo4j.ha.StandaloneDatabase;
import org.neo4j.kernel.Config;
import org.neo4j.kernel.DeadlockDetectedException;
import org.neo4j.kernel.IdType;
import org.neo4j.kernel.ha.LockableNode;
import org.neo4j.kernel.impl.core.LockReleaser;
import org.neo4j.kernel.impl.nioneo.store.IdGenerator;
import org.neo4j.kernel.impl.transaction.LockManager;
import org.neo4j.kernel.impl.transaction.LockType;

public abstract class CommonJobs
{
    public static final RelationshipType REL_TYPE = DynamicRelationshipType.withName( "HA_TEST" );
    public static final RelationshipType KNOWS = DynamicRelationshipType.withName( "KNOWS" );

    public static abstract class AbstractJob<T> implements Job<T>
    {
        protected Config getConfig( GraphDatabaseService db )
        {
            Config config = null;
            try
            {
                return (Config) db.getClass().getDeclaredMethod( "getConfig" ).invoke( db );
            }
            catch ( Exception e )
            {
                // Won't happen
                throw new RuntimeException( e );
            }
        }
    }

    public static abstract class TransactionalJob<T> extends AbstractJob<T>
    {
        public final T execute( GraphDatabaseService db ) throws RemoteException
        {
            Transaction tx = db.beginTx();
            try
            {
                return executeInTransaction( db, tx );
            }
            catch ( RuntimeException e )
            {
                e.printStackTrace( System.out );
                throw e;
            }
            finally
            {
                beforeFinish();
                tx.finish();
            }
        }

        protected void beforeFinish()
        {
        }

        protected abstract T executeInTransaction( GraphDatabaseService db, Transaction tx );
    }

    public static class CreateSubRefNodeJob extends TransactionalJob<Long>
    {
        private final String type;
        private final String key;
        private final Object value;

        public CreateSubRefNodeJob( String type, String key, Object value )
        {
            this.type = type;
            this.key = key;
            this.value = value;
        }

        @Override
        protected Long executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node node = db.createNode();
            Relationship rel = db.getReferenceNode().createRelationshipTo( node,
                    DynamicRelationshipType.withName( type ) );
            rel.setProperty( "something else", "Somewhat different" );
            if ( value != null )
            {
                node.setProperty( key, value );
            }
            tx.success();
            return node.getId();
        }
    }

    public static class CreateSubRefNodeWithRelCountJob extends TransactionalJob<Integer>
    {
        private final String type;
        private final String[] typesToAsk;

        public CreateSubRefNodeWithRelCountJob( String type,
                String... typesToAsk )
        {
            this.type = type;
            this.typesToAsk = typesToAsk;
        }

        @Override
        protected Integer executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node node = db.createNode();
            db.getReferenceNode().createRelationshipTo( node,
                    DynamicRelationshipType.withName( type ) );
            int counter = 0;
            for ( Relationship rel : db.getReferenceNode().getRelationships(
                    toRelationshipTypes( typesToAsk ) ) )
            {
                counter++;
            }
            tx.success();
            return counter;
        }
    }

    public static class CreateSubRefNodeMasterFailJob implements Job<Serializable[]>
    {
        private final CommonJobs.ShutdownDispatcher shutdownDispatcher;

        public CreateSubRefNodeMasterFailJob( CommonJobs.ShutdownDispatcher shutdownDispatcher )
        {
            this.shutdownDispatcher = shutdownDispatcher;
        }

        public Serializable[] execute( GraphDatabaseService db ) throws RemoteException
        {
            Transaction tx = db.beginTx();
            boolean successful = false;
            long nodeId = 0;
            try
            {
                Node node = db.createNode();
                nodeId = node.getId();
                db.getReferenceNode().createRelationshipTo( node, REL_TYPE );
                tx.success();
            }
            finally
            {
                this.shutdownDispatcher.doShutdown();
                try
                {
                    tx.finish();
                    successful = true;
                }
                catch ( RuntimeException e )
                {
                }
            }
            return new Serializable[] { successful, nodeId };
        }
    }

    public static class SetSubRefPropertyJob extends TransactionalJob<Object>
    {
        private final String key;
        private final Object value;

        public SetSubRefPropertyJob( String key, Object value )
        {
            this.key = key;
            this.value = value;
        }

        @Override
        protected Object executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node refNode = db.getReferenceNode();
            // To force it to pull updates
            refNode.removeProperty( "yoyoyoyo" );
            Node node = refNode.getSingleRelationship( REL_TYPE,
                    Direction.OUTGOING ).getEndNode();
            Object oldValue = node.getProperty( key, null );
            node.setProperty( key, value );
            tx.success();
            return oldValue;
        }
    }

    public static class CreateSomeEntitiesJob extends TransactionalJob<Void>
    {
        @Override
        protected Void executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node node1 = db.createNode();
            Relationship rel1 = db.getReferenceNode().createRelationshipTo( node1, REL_TYPE );
            node1.setProperty( "name", "Mattias" );
            rel1.setProperty( "something else", "Somewhat different" );

            Node node2 = db.createNode();
            Relationship rel2 = node1.createRelationshipTo( node2, REL_TYPE );
            node2.setProperty( "why o why", "Stuff" );
            rel2.setProperty( "random integer", "4" );
            tx.success();
            return null;
        }
    }

    public static class GetNodeByIdJob implements Job<Boolean>
    {
        private final long id;

        public GetNodeByIdJob( long id )
        {
            this.id = id;
        }

        public Boolean execute( GraphDatabaseService db )
        {
            try
            {
                db.getNodeById( id );
                return Boolean.TRUE;
            }
            catch ( NotFoundException e )
            {
                return Boolean.FALSE;
            }
        }
    }

    public interface ShutdownDispatcher extends Remote
    {
        void doShutdown() throws RemoteException;
    }

    public static class ShutdownJvm extends UnicastRemoteObject implements ShutdownDispatcher
    {
        private final StandaloneDatabase jvm;

        public ShutdownJvm( StandaloneDatabase jvm ) throws RemoteException
        {
            super();
            this.jvm = jvm;
        }

        public void doShutdown()
        {
            this.jvm.shutdown();
        }
    }

    public static class DeleteNodeJob implements Job<Boolean>
    {
        private final long id;
        private final boolean deleteIndexing;

        public DeleteNodeJob( long id, boolean deleteIndexing )
        {
            this.id = id;
            this.deleteIndexing = deleteIndexing;
        }

        public Boolean execute( GraphDatabaseService db ) throws RemoteException
        {
            Transaction tx = db.beginTx();
            boolean successful = false;
            try
            {
                Node node = db.getNodeById( id );
//                if ( deleteIndexing )
//                {
//                    IndexService index = ((HighlyAvailableGraphDatabase) db).getIndexService();
//                    for ( String key : node.getPropertyKeys() )
//                    {
//                        index.removeIndex( node, key, node.getProperty( key ) );
//                    }
//                }
                node.delete();
                tx.success();
            }
            finally
            {
                try
                {
                    tx.finish();
                    successful = true;
                }
                catch ( RuntimeException e )
                {
                }
            }
            return successful;
        }
    }

    public static class GetRelationshipCountJob implements Job<Integer>
    {
        private final String[] types;

        public GetRelationshipCountJob( String... types )
        {
            this.types = types;
        }

        public Integer execute( GraphDatabaseService db )
        {
            int counter = 0;
            for ( Relationship rel : db.getReferenceNode().getRelationships(
                    toRelationshipTypes( types ) ) )
            {
                counter++;
            }
            return counter;
        }
    }

    private static RelationshipType[] toRelationshipTypes( String... names )
    {
        RelationshipType[] types = new RelationshipType[names.length];
        for ( int i = 0; i < names.length; i++ )
        {
            types[i] = DynamicRelationshipType.withName( names[i] );
        }
        return types;
    }

    public static class CreateNodeOutsideOfTxJob implements Job<Boolean>
    {
        public Boolean execute( GraphDatabaseService db ) throws RemoteException
        {
            try
            {
                db.getReferenceNode().createRelationshipTo( db.createNode(), REL_TYPE );
                return Boolean.TRUE;
            }
            catch ( Exception e )
            {
                return Boolean.FALSE;
            }
        }
    }

    public static class CreateNodeJob extends TransactionalJob<Long>
    {
        @Override
        protected Long executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node node = db.createNode();
            tx.success();
            return node.getId();
        }
    }

    public static class SetNodePropertyJob extends TransactionalJob<Boolean>
    {
        private final long id;
        private final String key;
        private final Object value;

        public SetNodePropertyJob( long id, String key, Object value )
        {
            this.id = id;
            this.key = key;
            this.value = value;
        }

        @Override
        protected Boolean executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            try
            {
                db.getNodeById( id ).setProperty( key, value );
                tx.success();
                return Boolean.TRUE;
            }
            catch ( Exception e )
            {
                return Boolean.FALSE;
            }
        }
    }

    public static class CreateNodesJob extends TransactionalJob<Long[]>
    {
        private final int count;

        public CreateNodesJob( int count )
        {
            this.count = count;
        }

        @Override
        protected Long[] executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Long[] result = new Long[count];
            for ( int i = 0; i < count; i++ )
            {
                result[i] = db.createNode().getId();
            }
            tx.success();
            return result;
        }
    }

    public static class Worker1Job extends TransactionalJob<Boolean[]>
    {
        private final long node1;
        private final long node2;
        private final Fetcher<DoubleLatch> fetcher;

        public Worker1Job( long node1, long node2, Fetcher<DoubleLatch> fetcher )
        {
            this.node1 = node1;
            this.node2 = node2;
            this.fetcher = fetcher;
        }

        @Override
        protected Boolean[] executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            boolean success = false;
            boolean deadlock = false;
            try
            {
                DoubleLatch latch = fetcher.fetch();
                db.getNodeById( node1 ).setProperty( "1", "T1 1" );
                latch.countDownSecond();
                latch.awaitFirst();
                db.getNodeById( node2 ).removeProperty( "2" );
                db.getNodeById( node1 ).removeProperty( "1" );
                tx.success();
                success = true;
            }
            catch ( DeadlockDetectedException e )
            {
                deadlock = true;
            }
            catch ( Exception e )
            {
                throw new RuntimeException( e );
            }
            return new Boolean[] { success, deadlock };
        }
    }

    public static class Worker2Job extends TransactionalJob<Boolean[]>
    {
        private final long node1;
        private final long node2;
        private final Fetcher<DoubleLatch> fetcher;

        public Worker2Job( long node1, long node2, Fetcher<DoubleLatch> fetcher )
        {
            this.node1 = node1;
            this.node2 = node2;
            this.fetcher = fetcher;
        }

        @Override
        protected Boolean[] executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            boolean success = false;
            boolean deadlock = false;
            try
            {
                DoubleLatch latch = fetcher.fetch();
                db.getNodeById( node2 ).setProperty( "2", "T2 2" );
                latch.countDownFirst();
                latch.awaitSecond();
                db.getNodeById( node1 ).setProperty( "1", "T2 2" );
                tx.success();
                success = true;
            }
            catch ( DeadlockDetectedException e )
            {
                deadlock = true;
            }
            catch ( Exception e )
            {
                throw new RuntimeException( e );
            }
            return new Boolean[] { success, deadlock };
        }
    }

    public static class PerformanceAcquireWriteLocksJob extends TransactionalJob<Void>
    {
        private final int amount;

        public PerformanceAcquireWriteLocksJob( int amount )
        {
            this.amount = amount;
        }

        @Override
        protected Void executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Config config = getConfig( db );
            LockManager lockManager = config.getLockManager();
            LockReleaser lockReleaser = config.getLockReleaser();
            for ( int i = 0; i < amount; i++ )
            {
                Object resource = new LockableNode( i );
                lockManager.getWriteLock( resource );
                lockReleaser.addLockToTransaction( resource, LockType.WRITE );
            }
            return null;
        }
    }

    public static class PerformanceIdAllocationJob extends AbstractJob<Void>
    {
        private final int count;

        public PerformanceIdAllocationJob( int count )
        {
            this.count = count;
        }

        public Void execute( GraphDatabaseService db )
        {
            Config config = getConfig( db );
            IdGenerator generator = config.getIdGeneratorFactory().get( IdType.NODE );
            for ( int i = 0; i < count; i++ )
            {
                generator.nextId();
            }
            return null;
        }
    }

    public static class PerformanceCreateNodesJob extends AbstractJob<Void>
    {
        private final int numTx;
        private final int numNodesInEach;

        public PerformanceCreateNodesJob( int numTx, int numNodesInEach )
        {
            this.numTx = numTx;
            this.numNodesInEach = numNodesInEach;
        }

        public Void execute( GraphDatabaseService db ) throws RemoteException
        {
            for ( int i = 0; i < numTx; i++ )
            {
                Transaction tx = db.beginTx();
                try
                {
                    for ( int ii = 0; ii < numNodesInEach; ii++ )
                    {
                        db.createNode();
                    }
                    tx.success();
                }
                finally
                {
                    tx.finish();
                }
            }
            return null;
        }
    }

    public static class CreateNodeAndIndexJob extends TransactionalJob<Long>
    {
        private final String key;
        private final Object value;

        public CreateNodeAndIndexJob( String key, Object value )
        {
            this.key = key;
            this.value = value;
        }

        @Override
        protected Long executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
//            IndexService index = db instanceof HighlyAvailableGraphDatabase ?
//                    ((HighlyAvailableGraphDatabase) db).getIndexService() :
//                    new LuceneIndexService( db );
            Node node = db.createNode();
            node.setProperty( key, value );
//            index.index( node, key, value );
            tx.success();
            return node.getId();
        }
    }

    public static class CreateNodeAndNewIndexJob extends TransactionalJob<Long>
    {
        private final String key;
        private final Object value;
        private final String indexName;
        private final String key2;
        private final Object value2;

        public CreateNodeAndNewIndexJob( String indexName,
                String key, Object value, String key2, Object value2 )
        {
            this.indexName = indexName;
            this.key = key;
            this.value = value;
            this.key2 = key2;
            this.value2 = value2;
        }

        @Override
        protected Long executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
            Node node = db.createNode();
            node.setProperty( key, value );
            node.setProperty( key2, value2 );
            Index<Node> index = db.index().forNodes( indexName );
            index.add( node, key, value );
            index.add( node, key2, value2 );
            tx.success();
            return node.getId();
        }
    }

    public static class AddIndex extends TransactionalJob<Void>
    {
        private final Map<String, Object> properties;
        private final long nodeId;

        public AddIndex( long nodeId, Map<String, Object> properties )
        {
            this.nodeId = nodeId;
            this.properties = properties;
        }

        @Override
        protected Void executeInTransaction( GraphDatabaseService db, Transaction tx )
        {
//            IndexService index = ((HighlyAvailableGraphDatabase) db).getIndexService();
            Node node = db.getNodeById( nodeId );
            for ( Map.Entry<String, Object> entry : properties.entrySet() )
            {
//                index.index( node, entry.getKey(), entry.getValue() );
            }
            tx.success();
            return null;
        }
    }

    public static class LargeTransactionJob extends AbstractJob<Void>
    {
        private final int txSizeMb;
        private final int numTxs;

        public LargeTransactionJob( int txSizeMb, int numTxs )
        {
            this.txSizeMb = txSizeMb;
            this.numTxs = numTxs;
        }

        public Void execute( GraphDatabaseService db ) throws RemoteException
        {
            byte[] largeArray = new byte[1*1024*1021]; /* 1021 So that it doesn't align with block size in BlockLogBuffer and all that :) */
            for ( int t = 0; t < numTxs; t++ )
            {
                Transaction tx = db.beginTx();
                try
                {
                    for ( int i = 0; i < largeArray.length; i++ )
                    {
                        largeArray[i] = (byte) (i % 256);
                    }
                    for ( int i = 0; i < txSizeMb; i++ )
                    {
                        Node node = db.createNode();
                        node.setProperty( "data", largeArray );
                    }
                    tx.success();
                }
                finally
                {
                    tx.finish();
                }
            }
            return null;
        }
    }
}
TOP

Related Classes of slavetest.CommonJobs$TransactionalJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.