Skip to content

Commit

Permalink
Clean up and format the CommunityLockManager code
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvest committed Mar 8, 2016
1 parent 26a88d2 commit d5c4ac3
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 274 deletions.
Expand Up @@ -27,7 +27,6 @@
import org.neo4j.collection.primitive.PrimitiveIntObjectVisitor;
import org.neo4j.collection.primitive.PrimitiveLongObjectMap;
import org.neo4j.collection.primitive.PrimitiveLongObjectVisitor;
import org.neo4j.helpers.collection.Visitor;
import org.neo4j.kernel.impl.locking.LockClientAlreadyClosedException;
import org.neo4j.kernel.impl.locking.LockClientStateHolder;
import org.neo4j.kernel.impl.locking.Locks;
Expand All @@ -46,6 +45,10 @@ public class CommunityLockClient implements Locks.Client

private final PrimitiveIntObjectMap<PrimitiveLongObjectMap<LockResource>> sharedLocks = Primitive.intObjectMap();
private final PrimitiveIntObjectMap<PrimitiveLongObjectMap<LockResource>> exclusiveLocks = Primitive.intObjectMap();
private final PrimitiveLongObjectVisitor<LockResource,RuntimeException> readReleaser;
private final PrimitiveLongObjectVisitor<LockResource,RuntimeException> writeReleaser;
private final PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>,RuntimeException> typeReadReleaser;
private final PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>,RuntimeException> typeWriteReleaser;

// To be able to close Locks.Client instance properly we should be able to do couple of things:
// - have a possibility to prevent new clients to come
Expand All @@ -58,6 +61,30 @@ public class CommunityLockClient implements Locks.Client
public CommunityLockClient( LockManagerImpl manager )
{
this.manager = manager;

readReleaser = ( long key, LockResource lockResource ) ->
{
manager.releaseReadLock( lockResource, lockTransaction );
return false;
};

writeReleaser = ( long key, LockResource lockResource ) ->
{
manager.releaseWriteLock( lockResource, lockTransaction );
return false;
};

typeReadReleaser = ( int key, PrimitiveLongObjectMap<LockResource> value ) ->
{
value.visitEntries( readReleaser );
return false;
};

typeWriteReleaser = ( int key, PrimitiveLongObjectMap<LockResource> value ) ->
{
value.visitEntries( writeReleaser );
return false;
};
}

@Override
Expand Down Expand Up @@ -94,8 +121,6 @@ public void acquireShared( ResourceType resourceType, long resourceId )
}
}



@Override
public void acquireExclusive( ResourceType resourceType, long resourceId )
{
Expand Down Expand Up @@ -305,14 +330,9 @@ private void releaseLocks()
// waking up and terminate all waiters that were waiting for any lock for current client
private void terminateAllWaiters()
{
manager.accept( new Visitor<RWLock,RuntimeException>()
{
@Override
public boolean visit( RWLock lock ) throws RuntimeException
{
lock.terminateLockRequestsForLockTransaction( lockTransaction );
return false;
}
manager.accept( lock -> {
lock.terminateLockRequestsForLockTransaction( lockTransaction );
return false;
} );
}

Expand All @@ -325,7 +345,7 @@ public int getLockSessionId()
private PrimitiveLongObjectMap<LockResource> localShared( ResourceType resourceType )
{
PrimitiveLongObjectMap<LockResource> map = sharedLocks.get( resourceType.typeId() );
if(map == null)
if ( map == null )
{
map = Primitive.longObjectMap();
sharedLocks.put( resourceType.typeId(), map );
Expand All @@ -336,56 +356,14 @@ private PrimitiveLongObjectMap<LockResource> localShared( ResourceType resourceT
private PrimitiveLongObjectMap<LockResource> localExclusive( ResourceType resourceType )
{
PrimitiveLongObjectMap<LockResource> map = exclusiveLocks.get( resourceType.typeId() );
if(map == null)
if ( map == null )
{
map = Primitive.longObjectMap();
exclusiveLocks.put( resourceType.typeId(), map );
}
return map;
}

private final PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>, RuntimeException> typeReadReleaser = new
PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>, RuntimeException>()
{
@Override
public boolean visited( int key, PrimitiveLongObjectMap<LockResource> value ) throws RuntimeException
{
value.visitEntries( readReleaser );
return false;
}
};

private final PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>, RuntimeException> typeWriteReleaser = new
PrimitiveIntObjectVisitor<PrimitiveLongObjectMap<LockResource>, RuntimeException>()
{
@Override
public boolean visited( int key, PrimitiveLongObjectMap<LockResource> value ) throws RuntimeException
{
value.visitEntries( writeReleaser );
return false;
}
};

private final PrimitiveLongObjectVisitor<LockResource, RuntimeException> writeReleaser = new PrimitiveLongObjectVisitor<LockResource, RuntimeException>()
{
@Override
public boolean visited( long key, LockResource lockResource ) throws RuntimeException
{
manager.releaseWriteLock( lockResource, lockTransaction );
return false;
}
};

private final PrimitiveLongObjectVisitor<LockResource, RuntimeException> readReleaser = new PrimitiveLongObjectVisitor<LockResource, RuntimeException>()
{
@Override
public boolean visited( long key, LockResource lockResource ) throws RuntimeException
{
manager.releaseReadLock( lockResource, lockTransaction );
return false;
}
};

@Override
public String toString()
{
Expand Down
Expand Up @@ -42,20 +42,15 @@ public Client newClient()
@Override
public void accept( final Visitor visitor )
{
manager.accept( new org.neo4j.helpers.collection.Visitor<RWLock, RuntimeException>()
{
@Override
public boolean visit( RWLock element ) throws RuntimeException
manager.accept( element -> {
Object resource = element.resource();
if ( resource instanceof LockResource )
{
Object resource = element.resource();
if(resource instanceof LockResource)
{
LockResource lockResource = (LockResource)resource;
visitor.visit( lockResource.type(), lockResource.resourceId(),
element.describe(), element.maxWaitTime(), System.identityHashCode( lockResource ) );
}
return false;
LockResource lockResource = (LockResource) resource;
visitor.visit( lockResource.type(), lockResource.resourceId(),
element.describe(), element.maxWaitTime(), System.identityHashCode( lockResource ) );
}
return false;
} );
}

Expand Down
Expand Up @@ -25,11 +25,6 @@
*/
public class LockException extends RuntimeException
{
public LockException()
{
super();
}

public LockException( String message )
{
super( message );
Expand Down
Expand Up @@ -37,43 +37,38 @@ public LockManagerImpl( RagManager ragManager )
this.ragManager = ragManager;
}

public long getDetectedDeadlockCount()
{
return ragManager.getDeadlockCount();
}

public boolean getReadLock( Object resource, Object tx )
throws DeadlockDetectedException, IllegalResourceException
throws DeadlockDetectedException, IllegalResourceException
{
return unusedResourceGuard( resource, tx, getRWLockForAcquiring( resource, tx ).acquireReadLock( tx ) );
}

public boolean tryReadLock( Object resource, Object tx )
throws IllegalResourceException
throws IllegalResourceException
{
return unusedResourceGuard( resource, tx, getRWLockForAcquiring( resource, tx ).tryAcquireReadLock( tx ) );
}

public boolean getWriteLock( Object resource, Object tx )
throws DeadlockDetectedException, IllegalResourceException
throws DeadlockDetectedException, IllegalResourceException
{
return unusedResourceGuard(resource, tx, getRWLockForAcquiring( resource, tx ).acquireWriteLock( tx ) );
return unusedResourceGuard( resource, tx, getRWLockForAcquiring( resource, tx ).acquireWriteLock( tx ) );
}

public boolean tryWriteLock( Object resource, Object tx )
throws IllegalResourceException
throws IllegalResourceException
{
return unusedResourceGuard( resource, tx, getRWLockForAcquiring( resource, tx ).tryAcquireWriteLock( tx ) );
}

public void releaseReadLock( Object resource, Object tx )
throws LockNotFoundException, IllegalResourceException
throws LockNotFoundException, IllegalResourceException
{
getRWLockForReleasing( resource, tx, 1, 0, true ).releaseReadLock( tx );
}

public void releaseWriteLock( Object resource, Object tx )
throws LockNotFoundException, IllegalResourceException
throws LockNotFoundException, IllegalResourceException
{
getRWLockForReleasing( resource, tx, 0, 1, true ).releaseWriteLock( tx );
}
Expand Down Expand Up @@ -102,8 +97,9 @@ public void dumpLocksOnResource( final Object resource, Logger logger )
*
* @return {@code lockObtained }
**/
private boolean unusedResourceGuard(Object resource, Object tx, boolean lockObtained) {
if (!lockObtained)
private boolean unusedResourceGuard( Object resource, Object tx, boolean lockObtained )
{
if ( !lockObtained )
{
// if lock was not acquired cleaning up optimistically allocated value
// for case when it was only used by current call, if it was used by somebody else
Expand All @@ -115,12 +111,12 @@ private boolean unusedResourceGuard(Object resource, Object tx, boolean lockObta

/**
* Visit all locks.
*
* <p/>
* The supplied visitor may not block.
*
* @param visitor visitor for visiting each lock.
*/
public void accept( Visitor<RWLock, RuntimeException> visitor )
public void accept( Visitor<RWLock,RuntimeException> visitor )
{
synchronized ( resourceLockMap )
{
Expand Down Expand Up @@ -165,24 +161,25 @@ protected RWLock createLock( Object resource )
}

private RWLock getRWLockForReleasing( Object resource, Object tx, int readCountPrerequisite,
int writeCountPrerequisite, boolean strict )
int writeCountPrerequisite, boolean strict )
{
assertValidArguments( resource, tx );
synchronized ( resourceLockMap )
{
RWLock lock = resourceLockMap.get( resource );
if (lock == null )
if ( lock == null )
{
if (!strict)
if ( !strict )
{
return null;
}
throw new LockNotFoundException( "Lock not found for: "
+ resource + " tx:" + tx );
+ resource + " tx:" + tx );
}
// we need to get info from a couple of synchronized methods
// to make it info consistent we need to synchronized lock to make sure it will not change between
// various calls
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized ( lock )
{
if ( !lock.isMarked() && lock.getReadCount() == readCountPrerequisite &&
Expand Down
Expand Up @@ -49,17 +49,8 @@ public boolean equals( Object o )
}

LockResource that = (LockResource) o;
return resourceId == that.resourceId && resourceType.equals( that.resourceType );

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

return true;
}

@Override
Expand Down

0 comments on commit d5c4ac3

Please sign in to comment.