⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lockspace.java

📁 derby database source code.good for you.
💻 JAVA
字号:
/*   Derby - Class org.apache.derby.impl.services.locks.LockSpace   Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.   Licensed under the Apache License, Version 2.0 (the "License");   you may not use this file except in compliance with the License.   You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License. */package org.apache.derby.impl.services.locks;import org.apache.derby.iapi.services.locks.Lockable;import org.apache.derby.iapi.services.locks.Limit;import org.apache.derby.iapi.util.Matchable;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import java.util.Hashtable;import java.util.Enumeration;import java.util.Dictionary;import java.util.HashMap;import java.util.Iterator;/**	A LockSpace represents the complete set of locks held within	a single compatability space, broken into groups of locks.    A LockSpace is a hashtable keyed by the group reference,	the data for each key is a Hashtable of Lock's.*/class LockSpace extends Hashtable {	private final Object compatSpace;	// the object I live in	private final Dictionary holder;	private HashMap spareGroups[] = new HashMap[3];	// the Limit info.	private Object callbackGroup;	private int    limit;	private int    nextLimitCall;	private Limit  callback;	LockSpace(Dictionary holder, Object compatSpace) {		super();		this.compatSpace = compatSpace;		this.holder = holder;	}	/**		Add a lock to a group.	*/	protected synchronized void addLock(Object group, Lock lock)		throws StandardException {		Lock lockInGroup = null;		HashMap dl = (HashMap) get(group);		if (dl == null)	{			dl = getGroupMap(group);		} else if (lock.getCount() != 1) {			lockInGroup = (Lock) dl.get(lock);		}		if (lockInGroup == null) {			lockInGroup = lock.copy();			dl.put(lockInGroup, lockInGroup);		}		lockInGroup.count++;		if (inLimit)			return;		if (!group.equals(callbackGroup))			return;		int groupSize = dl.size();				if (groupSize > nextLimitCall) {			inLimit = true;			callback.reached(compatSpace, group, limit,				new LockList(java.util.Collections.enumeration(dl.keySet())), groupSize);			inLimit = false;			// see when the next callback should occur, if the callback			// failed to release a sufficent amount of locks then			// delay until another "limit" locks are obtained.			int newGroupSize = dl.size();			if (newGroupSize < (limit / 2))				nextLimitCall = limit;			else if (newGroupSize < (nextLimitCall / 2))				nextLimitCall -= limit;			else				nextLimitCall += limit;		}	}		private boolean inLimit;	/**		Unlock all the locks in a group and then remove the group.	*/	synchronized void unlockGroup(LockSet lset, Object group) {		HashMap dl = (HashMap) remove(group);		if (dl == null)			return;		for (Iterator list = dl.keySet().iterator(); list.hasNext(); ) {			lset.unlock((Lock) list.next(), 0);		}		if ((callbackGroup == null) && isEmpty())			holder.remove(compatSpace);		else if (group.equals(callbackGroup))			nextLimitCall = limit;		saveGroup(dl);	}	private HashMap getGroupMap(Object group) {		HashMap[] sg = spareGroups;		HashMap dl = null;		for (int i = 0; i < 3; i++) {			dl = sg[i];			if (dl != null) {				sg[i] = null;				break;			}		}		if (dl == null)			dl = new HashMap(5, 0.8f);		put(group, dl);		return dl;	}	private void saveGroup(HashMap dl) {		HashMap[] sg = spareGroups;		for (int i = 0; i < 3; i++) {			if (sg[i] == null) {				sg[i] = dl;				dl.clear();				break;			}		}	}	/**		Unlock all locks in the group that match the key	*/	synchronized void unlockGroup(LockSet lset, Object group, Matchable key) {		HashMap dl = (HashMap) get(group);		if (dl == null)			return; //  no group at all		boolean allUnlocked = true;		for (Iterator e = dl.keySet().iterator(); e.hasNext(); ) {			Lock lock = (Lock) e.next();			if (!key.match(lock.getLockable())) {				allUnlocked = false;				continue;			}			lset.unlock(lock, 0);			e.remove();		}		if (allUnlocked) {			remove(group);			saveGroup(dl);			if ((callbackGroup == null) && isEmpty())				holder.remove(compatSpace);			else if (group.equals(callbackGroup))				nextLimitCall = limit;		}	}	synchronized void transfer(Object oldGroup, Object newGroup) {		HashMap from = (HashMap) get(oldGroup);		if (from == null)			return;		HashMap to = (HashMap) get(newGroup);		if (to == null) {			// simple case 			put(newGroup, from);			clearLimit(oldGroup);			remove(oldGroup);			return;		}		if (to.size() < from.size()) {			// place the contents of to into from			mergeGroups(to, from);			Object oldTo = put(newGroup, from);			if (SanityManager.DEBUG) {				SanityManager.ASSERT(oldTo == to, "inconsistent state in LockSpace");			}		} else {			mergeGroups(from, to);		}				clearLimit(oldGroup);		remove(oldGroup);	}	private void mergeGroups(HashMap from, HashMap into) {		for (Iterator e = from.keySet().iterator(); e.hasNext(); ) {			Object lock = e.next();			Object lockI = into.get(lock);			if (lockI == null) {				// lock is only in from list				into.put(lock, lock);			} else {				// merge the locks				Lock fromL = (Lock) lock;				Lock intoL = (Lock) lockI;				intoL.count += fromL.getCount();			}		}	}	synchronized int unlockReference(LockSet lset, Lockable ref, Object qualifier, Object group) {		// look for locks matching our reference and qualifier.		HashMap dl = (HashMap) get(group);		if (dl == null)			return 0;		Lock lockInGroup;		synchronized (lset) {			Control control = lset.getControl(ref);			if (control == null)				return 0;			Lock setLock = control.getLock(compatSpace, qualifier);			if (setLock == null)				return 0;			lockInGroup = (Lock) dl.remove(setLock);			if (lockInGroup == null)				return 0;			setLock = null;			lset.unlock(lockInGroup, 1);		}		if (lockInGroup.getCount() == 1) {			if (dl.isEmpty()) {				remove(group);				saveGroup(dl);				if ((callbackGroup == null) && isEmpty())					holder.remove(compatSpace);				else if (group.equals(callbackGroup))					nextLimitCall = limit;			}			return 1;		}					// the lock item will be left in the group		lockInGroup.count--;		dl.put(lockInGroup, lockInGroup);		return 1;	}	/**		Return true if locks are held in a group	*/	synchronized boolean areLocksHeld(Object group) {		return  (get(group) != null);	}		synchronized boolean isLockHeld(Object group, Lockable ref, Object qualifier) {		// look for locks matching our reference and qualifier.		HashMap dl = (HashMap) get(group);		if (dl == null)			return false;		Object heldLock = dl.get(new Lock(compatSpace, ref, qualifier));		return (heldLock != null);	}	synchronized void setLimit(Object group, int limit, Limit callback) {		callbackGroup = group;		this.nextLimitCall = this.limit = limit;		this.callback = callback;	}	/**		Clear a limit set by setLimit.	*/	synchronized void clearLimit(Object group) {		if (group.equals(callbackGroup)) {			callbackGroup = null;			nextLimitCall = limit = Integer.MAX_VALUE;			callback = null;			if (isEmpty())				holder.remove(compatSpace);		}	}	/**		Return a count of the number of locks		held by this space. The argument bail		indicates at which point the counting		should bail out and return the current		count. This routine will bail if the		count is greater than bail. Thus this		routine is intended to for deadlock		code to find the space with the		fewest number of locks.	*/	synchronized int deadlockCount(int bail) {		int count = 0;		for (Enumeration groups = elements(); groups.hasMoreElements(); ) {			HashMap group = (HashMap) groups.nextElement();			for (Iterator locks = group.keySet().iterator(); locks.hasNext(); ) {					Lock lock = (Lock) locks.next();					count += lock.getCount();					if (count > bail)						return count;			}		}		return count;	}}/**	An Enumeration that returns the the Lockables	in a group.*/class LockList implements Enumeration {	private Enumeration lockGroup;	LockList(Enumeration lockGroup) {		this.lockGroup = lockGroup;	}	public boolean hasMoreElements() {		return lockGroup.hasMoreElements();	}	public Object nextElement() {		return ((Lock) lockGroup.nextElement()).getLockable();	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -