
package org.neo4j.kernel.impl.locking.community;

import org.neo4j.kernel.impl.locking.Locks;

public class LockResource
{
    private final Locks.ResourceType resourceType;
    private final LockResourceId resourceId;

    /** Local reference count, used for each client to count references to a lock. */
    private int refCount = 1;

    public LockResource( Locks.ResourceType resourceType, LockResourceId resourceId )
    {
        this.resourceType = resourceType;
        this.resourceId = resourceId;
    }

    // for tests only
    LockResource( Locks.ResourceType resourceType, long resourceId )
    {
        this.resourceType = resourceType;
        this.resourceId = new LockResourceId.Normal(resourceId);
    }

    @Override
    public boolean equals( Object o )
    {
        if ( this == o )
        {
            return true;
        }
        if ( o == null || getClass() != o.getClass() )
        {
            return false;
        }

        LockResource that = (LockResource) o;

        if ( !resourceId.equals(that.resourceId ))
        {
            return false;
        }
        if ( !resourceType.equals( that.resourceType ) )
        {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode()
    {
        int result = resourceType.hashCode();
        result = 31 * result + (int) (resourceId.get() ^ (resourceId.get() >>> 32));
        return result;
    }

    @Override
    public String toString()
    {
        return String.format( "%s(%s)", resourceType, resourceId );
    }

    public void acquireReference()
    {
        refCount++;
    }

    public int releaseReference()
    {
        return --refCount;
    }

    public LockResourceId resourceId()
    {
        return resourceId;
    }

    public Locks.ResourceType type()
    {
        return resourceType;
    }
}
