Package org.neo4j.kernel.impl.core

Source Code of org.neo4j.kernel.impl.core.NodeManager

/**
* 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 org.neo4j.kernel.impl.core;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.transaction.TransactionManager;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.NotFoundException;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.event.TransactionData;
import org.neo4j.helpers.Pair;
import org.neo4j.kernel.impl.cache.AdaptiveCacheManager;
import org.neo4j.kernel.impl.cache.Cache;
import org.neo4j.kernel.impl.cache.LruCache;
import org.neo4j.kernel.impl.cache.NoCache;
import org.neo4j.kernel.impl.cache.SoftLruCache;
import org.neo4j.kernel.impl.cache.StrongReferenceCache;
import org.neo4j.kernel.impl.cache.WeakLruCache;
import org.neo4j.kernel.impl.nioneo.store.PropertyData;
import org.neo4j.kernel.impl.nioneo.store.PropertyIndexData;
import org.neo4j.kernel.impl.nioneo.store.RelationshipChainPosition;
import org.neo4j.kernel.impl.nioneo.store.RelationshipData;
import org.neo4j.kernel.impl.nioneo.store.RelationshipTypeData;
import org.neo4j.kernel.impl.persistence.EntityIdGenerator;
import org.neo4j.kernel.impl.persistence.PersistenceManager;
import org.neo4j.kernel.impl.transaction.LockException;
import org.neo4j.kernel.impl.transaction.LockManager;
import org.neo4j.kernel.impl.transaction.LockType;
import org.neo4j.kernel.impl.util.ArrayMap;
import org.neo4j.kernel.impl.util.RelIdArray;

public class NodeManager
{
    private static Logger log = Logger.getLogger( NodeManager.class.getName() );

    private long referenceNodeId = 0;

    private final GraphDatabaseService graphDbService;
    private final Cache<Long,NodeImpl> nodeCache;
    private final Cache<Long,RelationshipImpl> relCache;
    private final AdaptiveCacheManager cacheManager;
    private final CacheType cacheType;
    private final LockManager lockManager;
    private final TransactionManager transactionManager;
    private final LockReleaser lockReleaser;
    private final PropertyIndexManager propertyIndexManager;
    private final RelationshipTypeHolder relTypeHolder;
    private final PersistenceManager persistenceManager;
    private final EntityIdGenerator idGenerator;

    private boolean useAdaptiveCache = false;
    private float adaptiveCacheHeapRatio = 0.77f;
    private int minNodeCacheSize = 0;
    private int minRelCacheSize = 0;
    private int maxNodeCacheSize = 1500;
    private int maxRelCacheSize = 3500;

    private static final int LOCK_STRIPE_COUNT = 32;
    private final ReentrantLock loadLocks[] =
        new ReentrantLock[LOCK_STRIPE_COUNT];

    NodeManager( GraphDatabaseService graphDb,
            AdaptiveCacheManager cacheManager, LockManager lockManager,
            LockReleaser lockReleaser, TransactionManager transactionManager,
            PersistenceManager persistenceManager, EntityIdGenerator idGenerator,
            RelationshipTypeCreator relTypeCreator, CacheType cacheType )
    {
        this.graphDbService = graphDb;
        this.cacheManager = cacheManager;
        this.lockManager = lockManager;
        this.transactionManager = transactionManager;
        this.propertyIndexManager = new PropertyIndexManager(
            transactionManager, persistenceManager, idGenerator );
        this.lockReleaser = lockReleaser;
        lockReleaser.setNodeManager( this );
        lockReleaser.setPropertyIndexManager( propertyIndexManager );
        this.persistenceManager = persistenceManager;
        this.idGenerator = idGenerator;
        this.relTypeHolder = new RelationshipTypeHolder( transactionManager,
            persistenceManager, idGenerator, relTypeCreator );

        this.cacheType = cacheType;
        this.nodeCache = cacheType.node( cacheManager );
        this.relCache = cacheType.relationship( cacheManager );
        for ( int i = 0; i < loadLocks.length; i++ )
        {
            loadLocks[i] = new ReentrantLock();
        }
    }

    public GraphDatabaseService getGraphDbService()
    {
        return graphDbService;
    }

    public CacheType getCacheType()
    {
        return this.cacheType;
    }

    private void parseParams( Map<Object,Object> params )
    {
        if ( params.containsKey( "use_adaptive_cache" ) )
        {
            String value = (String) params.get( "use_adaptive_cache" );
            if ( value.toLowerCase().equals( "yes" ) )
            {
                useAdaptiveCache = true;
            }
            else if ( value.toLowerCase().equals( "no" ) )
            {
                useAdaptiveCache = false;
            }
            else
            {
                log.warning( "Unable to parse use_adaptive_cache=" + value );
            }
        }
        if ( params.containsKey( "adaptive_cache_heap_ratio" ) )
        {
            Object value = params.get( "adaptive_cache_heap_ratio" );
            try
            {
                adaptiveCacheHeapRatio = Float.parseFloat( (String) value );
            }
            catch ( NumberFormatException e )
            {
                log.warning( "Unable to parse adaptive_cache_heap_ratio "
                    + value );
            }
            if ( adaptiveCacheHeapRatio < 0.1f )
            {
                adaptiveCacheHeapRatio = 0.1f;
            }
            if ( adaptiveCacheHeapRatio > 0.95f )
            {
                adaptiveCacheHeapRatio = 0.95f;
            }
        }
        if ( params.containsKey( "min_node_cache_size" ) )
        {
            Object value = params.get( "min_node_cache_size" );
            try
            {
                minNodeCacheSize = Integer.parseInt( (String) value );
            }
            catch ( NumberFormatException e )
            {
                log.warning( "Unable to parse min_node_cache_size " + value );
            }
        }
        if ( params.containsKey( "min_relationship_cache_size" ) )
        {
            Object value = params.get( "min_relationship_cache_size" );
            try
            {
                minRelCacheSize = Integer.parseInt( (String) value );
            }
            catch ( NumberFormatException e )
            {
                log.warning( "Unable to parse min_relationship_cache_size "
                    + value );
            }
        }
        if ( params.containsKey( "max_node_cache_size" ) )
        {
            Object value = params.get( "max_node_cache_size" );
            try
            {
                maxNodeCacheSize = Integer.parseInt( (String) value );
            }
            catch ( NumberFormatException e )
            {
                log.warning( "Unable to parse max_node_cache_size " + value );
            }
        }
        if ( params.containsKey( "max_relationship_cache_size" ) )
        {
            Object value = params.get( "max_relationship_cache_size" );
            try
            {
                maxRelCacheSize = Integer.parseInt( (String) value );
            }
            catch ( NumberFormatException e )
            {
                log.warning( "Unable to parse max_relationship_cache_size "
                    + value );
            }
        }
    }

    public void start( Map<Object,Object> params )
    {
        parseParams( params );
        nodeCache.resize( maxNodeCacheSize );
        relCache.resize( maxRelCacheSize );
        if ( useAdaptiveCache && cacheType.needsCacheManagerRegistration )
        {
            cacheManager.registerCache( nodeCache, adaptiveCacheHeapRatio,
                minNodeCacheSize );
            cacheManager.registerCache( relCache, adaptiveCacheHeapRatio,
                minRelCacheSize );
            cacheManager.start( params );
        }
    }

    public void stop()
    {
        if ( useAdaptiveCache && cacheType.needsCacheManagerRegistration )
        {
            cacheManager.stop();
            cacheManager.unregisterCache( nodeCache );
            cacheManager.unregisterCache( relCache );
        }
        relTypeHolder.clear();
    }

    public Node createNode()
    {
        long id = idGenerator.nextId( Node.class );
        NodeImpl node = new NodeImpl( id, true );
        acquireLock( node, LockType.WRITE );
        boolean success = false;
        try
        {
            persistenceManager.nodeCreate( id );
            nodeCache.put( id, node );
            success = true;
            return new NodeProxy( id, this );
        }
        finally
        {
            releaseLock( node, LockType.WRITE );
            if ( !success )
            {
                setRollbackOnly();
            }
        }
    }

    public Relationship createRelationship( NodeImpl startNode, Node endNode,
        RelationshipType type )
    {
        if ( startNode == null || endNode == null || type == null )
        {
            throw new IllegalArgumentException( "Null parameter, startNode="
                + startNode + ", endNode=" + endNode + ", type=" + type );
        }

        if ( !relTypeHolder.isValidRelationshipType( type ) )
        {
            relTypeHolder.addValidRelationshipType( type.name(), true );
        }
        long startNodeId = startNode.getId();
        NodeImpl firstNode = getLightNode( startNodeId );
        if ( firstNode == null )
        {
            setRollbackOnly();
            throw new NotFoundException( "First node[" + startNode.getId()
                + "] deleted" );
        }
        long endNodeId = endNode.getId();
        NodeImpl secondNode = getLightNode( endNodeId );
        if ( secondNode == null )
        {
            setRollbackOnly();
            throw new NotFoundException( "Second node[" + endNode.getId()
                + "] deleted" );
        }
        long id = idGenerator.nextId( Relationship.class );
        RelationshipImpl rel = new RelationshipImpl( id, startNodeId, endNodeId, type, true );
        boolean firstNodeTaken = false;
        boolean secondNodeTaken = false;
        acquireLock( rel, LockType.WRITE );
        boolean success = false;
        try
        {
            acquireLock( firstNode, LockType.WRITE );
            firstNodeTaken = true;
            acquireLock( secondNode, LockType.WRITE );
            secondNodeTaken = true;
            int typeId = getRelationshipTypeIdFor( type );
            persistenceManager.relationshipCreate( id, typeId, startNodeId,
                endNodeId );
            firstNode.addRelationship( this, type, id );
            secondNode.addRelationship( this, type, id );
            relCache.put( rel.getId(), rel );
            success = true;
            return new RelationshipProxy( id, this );
        }
        finally
        {
            boolean releaseFailed = false;
            if ( firstNodeTaken )
            {
                try
                {
                    releaseLock( firstNode, LockType.WRITE );
                }
                catch ( Exception e )
                {
                    releaseFailed = true;
                    e.printStackTrace();
                    log.severe( "Failed to release lock" );
                }
            }
            if ( secondNodeTaken )
            {
                try
                {
                    releaseLock( secondNode, LockType.WRITE );
                }
                catch ( Exception e )
                {
                    releaseFailed = true;
                    e.printStackTrace();
                    log.severe( "Failed to release lock" );
                }
            }
            releaseLock( rel, LockType.WRITE );
            if ( !success )
            {
                setRollbackOnly();
            }
            if ( releaseFailed )
            {
                throw new LockException( "Unable to release locks ["
                    + startNode + "," + endNode + "] in relationship create->"
                    + rel );
            }
        }
    }

    private ReentrantLock lockId( long id )
    {
        // TODO: Change stripe mod for new 4B+
        int stripe = (int) (id / 32768) % LOCK_STRIPE_COUNT;
        if ( stripe < 0 )
        {
            stripe *= -1;
        }
        ReentrantLock lock = loadLocks[stripe];
        lock.lock();
        return lock;
    }

    public Node getNodeById( long nodeId ) throws NotFoundException
    {
        NodeImpl node = nodeCache.get( nodeId );
        if ( node != null )
        {
            return new NodeProxy( nodeId, this );
        }
        ReentrantLock loadLock = lockId( nodeId );
        try
        {
            if ( nodeCache.get( nodeId ) != null )
            {
                return new NodeProxy( nodeId, this );
            }
            if ( !persistenceManager.loadLightNode( nodeId ) )
            {
                throw new NotFoundException( "Node[" + nodeId + "]" );
            }
            node = new NodeImpl( nodeId );
            nodeCache.put( nodeId, node );
            return new NodeProxy( nodeId, this );
        }
        finally
        {
            loadLock.unlock();
        }
    }

    NodeImpl getLightNode( long nodeId )
    {
        NodeImpl node = nodeCache.get( nodeId );
        if ( node != null )
        {
            return node;
        }
        ReentrantLock loadLock = lockId( nodeId );
        try
        {
            node = nodeCache.get( nodeId );
            if ( node != null )
            {
                return node;
            }
            if ( !persistenceManager.loadLightNode( nodeId ) )
            {
                return null;
            }
            node = new NodeImpl( nodeId );
            nodeCache.put( nodeId, node );
            return node;
        }
        finally
        {
            loadLock.unlock();
        }
    }

    NodeImpl getNodeForProxy( long nodeId )
    {
        NodeImpl node = nodeCache.get( nodeId );
        if ( node != null )
        {
            return node;
        }
        ReentrantLock loadLock = lockId( nodeId );
        try
        {
            node = nodeCache.get( nodeId );
            if ( node != null )
            {
                return node;
            }
            if ( !persistenceManager.loadLightNode( nodeId ) )
            {
                throw new NotFoundException( "Node[" + nodeId + "] not found." );
            }
            node = new NodeImpl( nodeId );
            nodeCache.put( nodeId, node );
            return node;
        }
        finally
        {
            loadLock.unlock();
        }
    }

    public Node getReferenceNode() throws NotFoundException
    {
        if ( referenceNodeId == -1 )
        {
            throw new NotFoundException( "No reference node set" );
        }
        return getNodeById( referenceNodeId );
    }

    void setReferenceNodeId( long nodeId )
    {
        this.referenceNodeId = nodeId;
    }

    public Relationship getRelationshipById( long relId )
        throws NotFoundException
    {
        RelationshipImpl relationship = relCache.get( relId );
        if ( relationship != null )
        {
            return new RelationshipProxy( relId, this );
        }
        ReentrantLock loadLock = lockId( relId );
        try
        {
            relationship = relCache.get( relId );
            if ( relationship != null )
            {
                return new RelationshipProxy( relId, this );
            }
            RelationshipData data = persistenceManager.loadLightRelationship(
                relId );
            if ( data == null )
            {
                throw new NotFoundException( "Relationship[" + relId + "]" );
            }
            int typeId = data.relationshipType();
            RelationshipType type = getRelationshipTypeById( typeId );
            if ( type == null )
            {
                throw new NotFoundException( "Relationship[" + data.getId()
                    + "] exist but relationship type[" + typeId
                    + "] not found." );
            }
            final long startNodeId = data.firstNode();
            final long endNodeId = data.secondNode();
            relationship = new RelationshipImpl( relId, startNodeId, endNodeId, type, false );
            relCache.put( relId, relationship );
            return new RelationshipProxy( relId, this );
        }
        finally
        {
            loadLock.unlock();
        }
    }

    RelationshipType getRelationshipTypeById( int id )
    {
        return relTypeHolder.getRelationshipType( id );
    }

    RelationshipImpl getRelForProxy( long relId )
    {
        RelationshipImpl relationship = relCache.get( relId );
        if ( relationship != null )
        {
            return relationship;
        }
        ReentrantLock loadLock = lockId( relId );
        try
        {
            relationship = relCache.get( relId );
            if ( relationship != null )
            {
                return relationship;
            }
            RelationshipData data = persistenceManager.loadLightRelationship(
                relId );
            if ( data == null )
            {
                throw new NotFoundException( "Relationship[" + relId
                    + "] not found." );
            }
            int typeId = data.relationshipType();
            RelationshipType type = getRelationshipTypeById( typeId );
            if ( type == null )
            {
                throw new NotFoundException( "Relationship[" + data.getId()
                    + "] exist but relationship type[" + typeId
                    + "] not found." );
            }
            relationship = new RelationshipImpl( relId, data.firstNode(), data.secondNode(), type,
                    false );
            relCache.put( relId, relationship );
            return relationship;
        }
        finally
        {
            loadLock.unlock();
        }
    }

    public void removeNodeFromCache( long nodeId )
    {
        nodeCache.remove( nodeId );
    }

    public void removeRelationshipFromCache( long id )
    {
        relCache.remove( id );
    }

    Object loadPropertyValue( long id )
    {
        return persistenceManager.loadPropertyValue( id );
    }

    RelationshipChainPosition getRelationshipChainPosition( NodeImpl node )
    {
        return persistenceManager.getRelationshipChainPosition( node.getId() );
    }

    Pair<ArrayMap<String,RelIdArray>,Map<Long,RelationshipImpl>> getMoreRelationships( NodeImpl node )
    {
        long nodeId = node.getId();
        RelationshipChainPosition position = node.getRelChainPosition();
        Iterable<RelationshipData> rels =
            persistenceManager.getMoreRelationships( nodeId, position );
        ArrayMap<String,RelIdArray> newRelationshipMap =
            new ArrayMap<String,RelIdArray>();
        Map<Long,RelationshipImpl> relsMap = new HashMap<Long,RelationshipImpl>( 150 );
        for ( RelationshipData rel : rels )
        {
            long relId = rel.getId();
            RelationshipImpl relImpl = relCache.get( relId );
            RelationshipType type = null;
            if ( relImpl == null )
            {
                type = getRelationshipTypeById( rel.relationshipType() );
                assert type != null;
                relImpl = new RelationshipImpl( relId, rel.firstNode(), rel.secondNode(), type,
                        false );
                relsMap.put( relId, relImpl );
                // relCache.put( relId, relImpl );
            }
            else
            {
                type = relImpl.getType();
            }
            RelIdArray relationshipSet = newRelationshipMap.get(
                type.name() );
            if ( relationshipSet == null )
            {
                relationshipSet = new RelIdArray();
                newRelationshipMap.put( type.name(), relationshipSet );
            }
            relationshipSet.add( relId );
        }
        // relCache.putAll( relsMap );
        return Pair.of( newRelationshipMap, relsMap );
    }

    void putAllInRelCache( Map<Long,RelationshipImpl> map )
    {
         relCache.putAll( map );
    }

    ArrayMap<Integer,PropertyData> loadProperties( NodeImpl node,
            boolean light )
    {
        return persistenceManager.loadNodeProperties( node.getId(), light );
    }

    ArrayMap<Integer,PropertyData> loadProperties(
            RelationshipImpl relationship, boolean light )
    {
        return persistenceManager.loadRelProperties( relationship.getId(), light );
    }

    public int getNodeCacheSize()
    {
        return nodeCache.size();
    }

    public int getRelationshipCacheSize()
    {
        return relCache.size();
    }

    public void clearCache()
    {
        nodeCache.clear();
        relCache.clear();
    }

    void setRollbackOnly()
    {
        try
        {
            transactionManager.setRollbackOnly();
        }
        catch ( IllegalStateException e )
        {
            // this exception always get generated in a finally block and
            // when it happens another exception has already been thrown
            // (most likley NotInTransactionException)
            log.log( Level.FINE, "Failed to set transaction rollback only", e );
        }
        catch ( javax.transaction.SystemException se )
        {
            // our TM never throws this exception
            log.log( Level.SEVERE, "Failed to set transaction rollback only",
                se );
        }
    }

    void acquireLock( Primitive resource, LockType lockType )
    {
        PropertyContainer container;
        if ( resource instanceof NodeImpl )
        {
            container = new NodeProxy( resource.id, this );
        }
        else if ( resource instanceof RelationshipImpl )
        {
            container = new RelationshipProxy( resource.id, this );
        }
        else
        {
            throw new LockException( "Unkown primitivite type: " + resource );
        }
        if ( lockType == LockType.READ )
        {
            lockManager.getReadLock( container );
        }
        else if ( lockType == LockType.WRITE )
        {
            lockManager.getWriteLock( container );
        }
        else
        {
            throw new LockException( "Unknown lock type: " + lockType );
        }
    }

    void releaseLock( Primitive resource, LockType lockType )
    {
        PropertyContainer container;
        if ( resource instanceof NodeImpl )
        {
            container = new NodeProxy( resource.id, this );
        }
        else if ( resource instanceof RelationshipImpl )
        {
            container = new RelationshipProxy( resource.id, this );
        }
        else
        {
            throw new LockException( "Unkown primitivite type: " + resource );
        }
        if ( lockType == LockType.READ )
        {
            lockManager.releaseReadLock( container, null );
        }
        else if ( lockType == LockType.WRITE )
        {
            lockReleaser.addLockToTransaction( container, lockType );
        }
        else
        {
            throw new LockException( "Unknown lock type: " + lockType );
        }
    }

    public long getHighestPossibleIdInUse( Class<?> clazz )
    {
        return idGenerator.getHighestPossibleIdInUse( clazz );
    }

    public long getNumberOfIdsInUse( Class<?> clazz )
    {
        return idGenerator.getNumberOfIdsInUse( clazz );
    }

    public void removeRelationshipTypeFromCache( int id )
    {
        relTypeHolder.removeRelType( id );
    }

    void addPropertyIndexes( PropertyIndexData[] propertyIndexes )
    {
        propertyIndexManager.addPropertyIndexes( propertyIndexes );
    }

    void setHasAllpropertyIndexes( boolean hasAll )
    {
        propertyIndexManager.setHasAll( hasAll );
    }

    void clearPropertyIndexes()
    {
        propertyIndexManager.clear();
    }

    PropertyIndex getIndexFor( int keyId )
    {
        return propertyIndexManager.getIndexFor( keyId );
    }

    Iterable<PropertyIndex> index( String key )
    {
        return propertyIndexManager.index( key );
    }

    boolean hasAllPropertyIndexes()
    {
        return propertyIndexManager.hasAll();
    }

    boolean hasIndexFor( int keyId )
    {
        return propertyIndexManager.hasIndexFor( keyId );
    }

    PropertyIndex createPropertyIndex( String key )
    {
        return propertyIndexManager.createPropertyIndex( key );
    }

    int getRelationshipTypeIdFor( RelationshipType type )
    {
        return relTypeHolder.getIdFor( type );
    }

    void addRawRelationshipTypes( RelationshipTypeData[] relTypes )
    {
        relTypeHolder.addRawRelationshipTypes( relTypes );
    }

    Iterable<RelationshipType> getRelationshipTypes()
    {
        return relTypeHolder.getRelationshipTypes();
    }

    ArrayMap<Integer,PropertyData> deleteNode( NodeImpl node )
    {
        deletePrimitive( node );
        return persistenceManager.nodeDelete( node.getId() );
        // remove from node cache done via event
    }

    long nodeAddProperty( NodeImpl node, PropertyIndex index, Object value )
    {
        return persistenceManager.nodeAddProperty( node.getId(), index, value );
    }

    void nodeChangeProperty( NodeImpl node, long propertyId, Object value )
    {
        persistenceManager.nodeChangeProperty( node.getId(), propertyId, value );
    }

    void nodeRemoveProperty( NodeImpl node, long propertyId )
    {
        persistenceManager.nodeRemoveProperty( node.getId(), propertyId );
    }

    ArrayMap<Integer,PropertyData> deleteRelationship( RelationshipImpl rel )
    {
        deletePrimitive( rel );
        return persistenceManager.relDelete( rel.getId() );
        // remove in rel cache done via event
    }

    long relAddProperty( RelationshipImpl rel, PropertyIndex index,
        Object value )
    {
        return persistenceManager.relAddProperty( rel.getId(), index, value );
    }

    void relChangeProperty( RelationshipImpl rel, long propertyId, Object value )
    {
        persistenceManager.relChangeProperty( rel.getId(), propertyId, value );
    }

    void relRemoveProperty( RelationshipImpl rel, long propertyId )
    {
        persistenceManager.relRemoveProperty( rel.getId(), propertyId );
    }

    public RelIdArray getCowRelationshipRemoveMap( NodeImpl node, String type )
    {
        return lockReleaser.getCowRelationshipRemoveMap( node, type );
    }

    public RelIdArray getCowRelationshipRemoveMap( NodeImpl node, String type,
        boolean create )
    {
        return lockReleaser.getCowRelationshipRemoveMap( node, type, create );
    }

    public ArrayMap<String,RelIdArray> getCowRelationshipAddMap( NodeImpl node )
    {
        return lockReleaser.getCowRelationshipAddMap( node );
    }

    public RelIdArray getCowRelationshipAddMap( NodeImpl node, String string )
    {
        return lockReleaser.getCowRelationshipAddMap( node, string );
    }

    public RelIdArray getCowRelationshipAddMap( NodeImpl node, String string,
        boolean create )
    {
        return lockReleaser.getCowRelationshipAddMap( node, string, create );
    }

    public NodeImpl getNodeIfCached( long nodeId )
    {
        return nodeCache.get( nodeId );
    }

    public RelationshipImpl getRelIfCached( long nodeId )
    {
        return relCache.get( nodeId );
    }

    public ArrayMap<Integer,PropertyData> getCowPropertyRemoveMap(
        Primitive primitive )
    {
        return lockReleaser.getCowPropertyRemoveMap( primitive );
    }

    private void deletePrimitive( Primitive primitive )
    {
        lockReleaser.deletePrimitive( primitive );
    }

    public ArrayMap<Integer,PropertyData> getCowPropertyAddMap(
        Primitive primitive )
    {
        return lockReleaser.getCowPropertyAddMap( primitive );
    }

    public ArrayMap<Integer,PropertyData> getCowPropertyAddMap(
        Primitive primitive, boolean create )
    {
        return lockReleaser.getCowPropertyAddMap( primitive, create );
    }

    public ArrayMap<Integer,PropertyData> getCowPropertyRemoveMap(
        Primitive primitive, boolean create )
    {
        return lockReleaser.getCowPropertyRemoveMap( primitive, create );
    }

    LockReleaser getLockReleaser()
    {
        return this.lockReleaser;
    }

    void addRelationshipType( RelationshipTypeData type )
    {
        relTypeHolder.addRawRelationshipType( type );
    }

    void addPropertyIndex( PropertyIndexData index )
    {
        propertyIndexManager.addPropertyIndex( index );
    }

    public TransactionData getTransactionData()
    {
        return lockReleaser.getTransactionData();
    }

    RelIdArray getCreatedNodes()
    {
        return persistenceManager.getCreatedNodes();
    }

    boolean nodeCreated( long nodeId )
    {
        return persistenceManager.isNodeCreated( nodeId );
    }

    boolean relCreated( long relId )
    {
        return persistenceManager.isRelationshipCreated( relId );
    }

    public String getKeyForProperty( long propertyId )
    {
        int keyId = persistenceManager.getKeyIdForProperty( propertyId );
        return propertyIndexManager.getIndexFor( keyId ).getKey();
    }

    public RelationshipTypeHolder getRelationshipTypeHolder()
    {
        return this.relTypeHolder;
    }

    public static enum CacheType
    {
        weak( false, "weak reference cache" )
        {
            @Override
            Cache<Long, NodeImpl> node( AdaptiveCacheManager cacheManager )
            {
                return new WeakLruCache<Long,NodeImpl>( NODE_CACHE_NAME );
            }

            @Override
            Cache<Long, RelationshipImpl> relationship( AdaptiveCacheManager cacheManager )
            {
                return new WeakLruCache<Long,RelationshipImpl>( RELATIONSHIP_CACHE_NAME );
            }
        },
        soft( false, "soft reference cache" )
        {
            @Override
            Cache<Long, NodeImpl> node( AdaptiveCacheManager cacheManager )
            {
                return new SoftLruCache<Long,NodeImpl>( NODE_CACHE_NAME );
            }

            @Override
            Cache<Long, RelationshipImpl> relationship( AdaptiveCacheManager cacheManager )
            {
                return new SoftLruCache<Long,RelationshipImpl>( RELATIONSHIP_CACHE_NAME );
            }
        },
        old( true, "lru cache" )
        {
            @Override
            Cache<Long, NodeImpl> node( AdaptiveCacheManager cacheManager )
            {
                return new LruCache<Long,NodeImpl>( NODE_CACHE_NAME, 1500, cacheManager );
            }

            @Override
            Cache<Long, RelationshipImpl> relationship( AdaptiveCacheManager cacheManager )
            {
                return new LruCache<Long,RelationshipImpl>(
                        RELATIONSHIP_CACHE_NAME, 3500, cacheManager );
            }
        },
        none( false, "no cache" )
        {
            @Override
            Cache<Long, NodeImpl> node( AdaptiveCacheManager cacheManager )
            {
                return new NoCache<Long, NodeImpl>( NODE_CACHE_NAME );
            }

            @Override
            Cache<Long, RelationshipImpl> relationship( AdaptiveCacheManager cacheManager )
            {
                return new NoCache<Long, RelationshipImpl>( RELATIONSHIP_CACHE_NAME );
            }
        },
        strong( false, "strong reference cache" )
        {
            @Override
            Cache<Long, NodeImpl> node( AdaptiveCacheManager cacheManager )
            {
                return new StrongReferenceCache<Long,NodeImpl>( NODE_CACHE_NAME );
            }

            @Override
            Cache<Long, RelationshipImpl> relationship( AdaptiveCacheManager cacheManager )
            {
                return new StrongReferenceCache<Long,RelationshipImpl>( RELATIONSHIP_CACHE_NAME );
            }
        };

        private static final String NODE_CACHE_NAME = "NodeCache";
        private static final String RELATIONSHIP_CACHE_NAME = "RelationshipCache";

        final boolean needsCacheManagerRegistration;
        private final String description;

        private CacheType( boolean needsCacheManagerRegistration, String description )
        {
            this.needsCacheManagerRegistration = needsCacheManagerRegistration;
            this.description = description;
        }

        abstract Cache<Long,NodeImpl> node( AdaptiveCacheManager cacheManager );

        abstract Cache<Long,RelationshipImpl> relationship( AdaptiveCacheManager cacheManager );

        public String getDescription()
        {
            return this.description;
        }
    }
}
TOP

Related Classes of org.neo4j.kernel.impl.core.NodeManager

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.