All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.kernel.impl.locking.AbstractLockService Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2020 "Graph Foundation,"
 * Graph Foundation, Inc. [https://graphfoundation.org]
 *
 * This file is part of ONgDB.
 *
 * ONgDB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
/*
 * Copyright (c) 2002-2020 "Neo4j,"
 * Neo4j Sweden AB [http://neo4j.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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.kernel.impl.locking;

/**
 * Abstract implementation to keep all the boiler-plate code separate from actual locking logic.
 *
 * Diagram of how classes inter-relate:
 * 
 * ({@link LockService}) --------[returns]--------> ({@link Lock})
 *  ^                                            ^
 *  |                                            |
 *  [implements]                                 [extends]
 *  |                                            |
 * ({@link AbstractLockService}) -[contains]-> ({@link LockReference}) -[holds]-> ({@link LockedEntity})
 *  ^      |                                     |                                     ^
 *  |      |                                     [references]                          |
 *  |      |                                     |                                     [extends]
 *  |      |                                     V                                     |
 *  |      +-----------[type param]-----------> (HANDLE)                              ({@link LockedNode})
 *  |                                            ^
 *  [extends]                                    |
 *  |                                            [satisfies]
 *  |                                            |
 * ({@link ReentrantLockService})-[type param]->({@link ReentrantLockService.OwnerQueueElement})
 * 
* * @param A handle that the concrete implementation used for releasing the lock. */ abstract class AbstractLockService implements LockService { @Override public Lock acquireNodeLock( long nodeId, LockType type ) { return lock( new LockedNode( nodeId ) ); } @Override public Lock acquireRelationshipLock( long relationshipId, LockType type ) { return lock( new LockedRelationship( relationshipId ) ); } private Lock lock( LockedEntity key ) { return new LockReference( key, acquire( key ) ); } protected abstract HANDLE acquire( LockedEntity key ); protected abstract void release( LockedEntity key, HANDLE handle ); protected abstract static class LockedEntity { private LockedEntity() { // all instances defined in this class } @Override public final String toString() { StringBuilder repr = new StringBuilder( getClass().getSimpleName() ).append( '[' ); toString( repr ); return repr.append( ']' ).toString(); } abstract void toString( StringBuilder repr ); @Override public abstract int hashCode(); @Override public abstract boolean equals( Object obj ); } private class LockReference extends Lock { private final LockedEntity key; private HANDLE handle; LockReference( LockedEntity key, HANDLE handle ) { this.key = key; this.handle = handle; } @Override public String toString() { StringBuilder repr = new StringBuilder( key.getClass().getSimpleName() ).append( '[' ); key.toString( repr ); if ( handle != null ) { repr.append( "; HELD_BY=" ).append( handle ); } else { repr.append( "; RELEASED" ); } return repr.append( ']' ).toString(); } @Override public void release() { if ( handle == null ) { return; } try { AbstractLockService.this.release( key, handle ); } finally { handle = null; } } } static class LockedPropertyContainer extends LockedEntity { private final long id; LockedPropertyContainer( long id ) { this.id = id; } @Override void toString( StringBuilder repr ) { repr.append( "id=" ).append( id ); } @Override public int hashCode() { return (int) (id ^ (id >>> 32)); } @Override public boolean equals( Object obj ) { if ( obj != null && obj.getClass().equals( getClass() ) ) { LockedPropertyContainer that = (LockedPropertyContainer) obj; return this.id == that.id; } return false; } } static final class LockedNode extends LockedPropertyContainer { LockedNode( long nodeId ) { super( nodeId ); } } static final class LockedRelationship extends LockedPropertyContainer { LockedRelationship( long relationshipId ) { super( relationshipId ); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy