blob: c54c608afd54986d4f1332adb6eda55fd912394a [file] [log] [blame]
/*-
* Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle Berkeley
* DB Java Edition made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
* license and additional information.
*/
package com.sleepycat.je.txn;
import java.util.List;
import java.util.Set;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.dbi.DatabaseImpl;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.utilint.StatGroup;
/**
* DummyLockManager performs minimal locking and is used when
* {@link com.sleepycat.je.EnvironmentConfig#ENV_IS_LOCKING} is false.
*/
public class DummyLockManager extends LockManager {
/*
* Even though a user may specify isNoLocking for performance reasons, JE
* will sometimes still need to use locking internally (e.g. handle locks,
* and transactional access to internal db's). So we can not completely
* eliminate the Lock Manager. Instead, when isNoLocking is specified, we
* keep a standard Lock Manager around for use by cursors that access
* internal databases. Delegate to that as needed.
* [#16453]
*/
private final LockManager superiorLockManager;
DummyLockManager(EnvironmentImpl envImpl,
LockManager superiorLockManager) {
super(envImpl);
this.superiorLockManager = superiorLockManager;
}
@Override
public Set<LockInfo> getOwners(Long lsn) {
return superiorLockManager.getOwners(lsn);
}
@Override
public List<LockInfo> getWaiters(Long lsn) {
return superiorLockManager.getWaiters(lsn);
}
@Override
public LockType getOwnedLockType(Long lsn, Locker locker) {
return superiorLockManager.getOwnedLockType(lsn, locker);
}
@Override
public boolean isLockUncontended(Long lsn) {
return superiorLockManager.isLockUncontended(lsn);
}
@Override
public boolean ownsOrSharesLock(Locker locker, Long lsn) {
return superiorLockManager.ownsOrSharesLock(locker, lsn);
}
@Override
Lock lookupLock(Long lsn)
throws DatabaseException {
Lock ret = superiorLockManager.lookupLock(lsn);
return ret;
}
@Override
LockAttemptResult attemptLock(Long lsn,
Locker locker,
LockType type,
boolean nonBlockingRequest,
boolean jumpAheadOfWaiters)
throws DatabaseException {
if (locker.lockingRequired()) {
return superiorLockManager.attemptLock
(lsn, locker, type, nonBlockingRequest, jumpAheadOfWaiters);
}
return new LockAttemptResult(null, LockGrantType.NEW, true);
}
@Override
TimeoutInfo getTimeoutInfo(
boolean isLockNotTxnTimeout,
Locker locker,
long lsn,
LockType type,
LockGrantType grantType,
Lock useLock,
long timeout,
long start,
long now,
DatabaseImpl database,
Set<LockInfo> owners,
List<LockInfo> waiters)
throws DatabaseException {
if (locker.lockingRequired()) {
return superiorLockManager.getTimeoutInfo(
isLockNotTxnTimeout, locker, lsn, type, grantType, useLock,
timeout, start, now, database, owners, waiters);
}
return null;
}
@Override
Set<Locker> releaseAndFindNotifyTargets(long lsn, Locker locker)
throws DatabaseException {
/*
* Unconditionally release the lock. This does not detract from the
* performance benefit of disabled locking, since this method is only
* called if a lock was previously acquired, i.e., it is held by a
* Locker.
*
* The comment below is now obsolete because handle locks are no longer
* transferred.
* If the release of the lock were conditional, a lock transferred
* between Lockers (as we do with Database handle locks) would never
* be released, since the destination Locker's lockingRequired
* property is not set to true. In general, it is safer to
* unconditionally release locks than to rely on the lockingRequired
* property. [#17985]
*/
return superiorLockManager.releaseAndFindNotifyTargets(lsn, locker);
}
@Override
void demote(long lsn, Locker locker)
throws DatabaseException {
if (locker.lockingRequired()) {
superiorLockManager.demote(lsn, locker);
} else {
return;
}
}
@Override
boolean isLocked(Long lsn)
throws DatabaseException {
return superiorLockManager.isLocked(lsn);
}
@Override
boolean isOwner(Long lsn, Locker locker, LockType type)
throws DatabaseException {
return superiorLockManager.isOwner(lsn, locker, type);
}
@Override
boolean isWaiter(Long lsn, Locker locker)
throws DatabaseException {
return superiorLockManager.isWaiter(lsn, locker);
}
@Override
int nWaiters(Long lsn)
throws DatabaseException {
return superiorLockManager.nWaiters(lsn);
}
@Override
int nOwners(Long lsn)
throws DatabaseException {
return superiorLockManager.nOwners(lsn);
}
@Override
public Locker getWriteOwnerLocker(Long lsn)
throws DatabaseException {
return superiorLockManager.getWriteOwnerLocker(lsn);
}
@Override
boolean validateOwnership(Long lsn,
Locker locker,
LockType type,
boolean getOwnersAndWaiters,
boolean flushFromWaiters,
Set<LockInfo> owners,
List<LockInfo> waiters)
throws DatabaseException {
if (locker.lockingRequired()) {
return superiorLockManager.validateOwnership(
lsn, locker, type, getOwnersAndWaiters, flushFromWaiters,
owners, waiters);
}
return true;
}
@Override
public LockAttemptResult stealLock(Long lsn,
Locker locker,
LockType lockType)
throws DatabaseException {
if (locker.lockingRequired()) {
return superiorLockManager.stealLock
(lsn, locker, lockType);
}
return null;
}
@Override
void dumpLockTable(StatGroup stats, boolean clear)
throws DatabaseException {
superiorLockManager.dumpLockTable(stats, clear);
}
}