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

📄 clock.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
		try {			// this can be approximate			int itemCount = holders.size();			int itemsToCheck;			if (itemCount < 20)				itemsToCheck = 2 * itemCount;			else				itemsToCheck = (int) (((float) itemCount) * percentOfClock);			// if we can grow then shrinking is OK too, if we can't grow			// then shrinking the cache won't help us find an item.			long toShrink = shrinkSize(getCurrentSize());restartClock:			for (; itemsToCheck > 0;) {				CachedItem item = null;				synchronized (this) {					if (SanityManager.DEBUG) {					  if (SanityManager.DEBUG_ON(ClockFactory.CacheTrace))					  {						SanityManager.DEBUG(ClockFactory.CacheTrace, name + " rotateClock starting " +											clockHand + " itemsToCheck " + itemsToCheck);					  }					}					// size of holders cannot change while in the synchronized block.					int size = holders.size();					for (; itemsToCheck > 0; item = null, itemsToCheck--, incrClockHand())					{						//						// This uses a very simple clock algorithm.						//						// The cache consist of a circular list of cachedItems.  Each cached item						// has a 'recentlyUsed' bit which is set every time that item is kept.						// Each clock cache manager keeps a global variable clockHand which						// refers to the item that is most recently replaced.						//						// to find a free item, the clock Hand moves to the next cached Item.						// If it is kept, or in the middle of being created, the clock hand						// moves on.  						// If it is recentlyUsed, clear the recently used bit and moves on. 						// If it is not recentlyUsed, clean the item and use						//						// If all the cached item is kept, then create a new entry.						// So it is possible, although very unlikely,  that, in time, the cache						// will grow beyond the maximum size.												if (clockHand >= size) {							if (size == 0)								break;							clockHand = 0;						}						item = (CachedItem) holders.get(clockHand);						if (item.isKept())						{							if (SanityManager.DEBUG) // stats only in debug mode								iskept++;							continue;						}						if (!item.isValid()) // found a free item, just use it						{                            if( null != availableItem)                                // We have found an available item, now we are looking for bytes                                continue;							if (SanityManager.DEBUG) {							  if (SanityManager.DEBUG_ON(ClockFactory.CacheTrace))							  {								SanityManager.DEBUG(ClockFactory.CacheTrace,													name + " found free item at " + clockHand + " item " + item);							  }							}							item.keepForCreate();							if( useByteCount && getCurrentSize() > maximumSize)                            {                                availableItem = item;                                // now look for bytes.                                continue;                            }							// since we are using this item, move the clock past it.							incrClockHand();							return item;						}						if (item.recentlyUsed())						{							if (SanityManager.DEBUG) // stats only in debug mode								resetUsed++;							item.setUsed(false);							continue;						}						if (toShrink > 0) {							if (!cleanerRunning) {								// try an get the cleaner to shrink the cache								kickCleaner = true;								cleanerRunning = true;								needService = true;							}						}						// we are seeing valid, not recently used buffers. Evict this.						if (SanityManager.DEBUG) {							evictions++;							if (SanityManager.DEBUG_ON(ClockFactory.CacheTrace))							{								SanityManager.DEBUG(ClockFactory.CacheTrace,													name + " evicting item at " +													clockHand + " item " + item);							}						}						if (!item.getEntry().isDirty()) {							if (SanityManager.DEBUG) {							  if (SanityManager.DEBUG_ON(ClockFactory.CacheTrace)) 							  {								SanityManager.DEBUG(ClockFactory.CacheTrace,													name + " Evicting Item " +													item + ", not dirty");							  }							}							// a valid, unkept, clean item, clear its identity							// and use it.                            long itemSize = removeIdentity(item);                            if( useByteCount)                            {                                toShrink -= itemSize;                                if( getCurrentSize() > maximumSize && 0 < toShrink)                                {                                    if( null == availableItem)                                    {                                        item.keepForCreate();                                        availableItem = item;                                    }                                    continue;                                }                            }							// since we are using it move the clock past it							incrClockHand();                            if( null != availableItem)                                return availableItem;							// item is kept but not valid when returned							item.keepForCreate();							return item;						}						// item is valid, unkept, and dirty. clean it.						if ((cleaner != null) && !cleanerRunning) {							kickCleaner = true;							wokenToClean = true;							cleanerRunning = true; // at least it soon will be						}						item.keepForClean();						// leave the clock hand where it is so that we will pick it						// up if no-one else uses the cache. Other hunters will						// skip over it as it is kept, and thus move the clock						// hand past it.						break;					}					if (item == null) {						return availableItem;					}				} // out of synchronized block				// clean the entry outside of a sync block				    				try 				{					if ( SanityManager.DEBUG) {						if (SanityManager.DEBUG_ON(ClockFactory.CacheTrace)) {						SanityManager.DEBUG(ClockFactory.CacheTrace,name + " cleaning item " + item);						}					}					item.clean(false);					if (SanityManager.DEBUG) // stats only in debug mode					{						cleaned++;					}				}				finally {					release(item);					item = null;				}				// at this point the item we cleaned could be in any state				// so we can't just re-use it. Continue searching				continue restartClock;			}			return availableItem;		} finally {			if (SanityManager.DEBUG)			{				// report statistics				if (					SanityManager.DEBUG_ON(ClockFactory.CacheTrace))					SanityManager.DEBUG(ClockFactory.CacheTrace, name + " evictions " + evictions +										", cleaned " + cleaned + 										", resetUsed " + resetUsed +										", isKept " + iskept +										", size " + holders.size());			}			if (kickCleaner && (cleaner != null))			{				if (SanityManager.DEBUG) {					if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {					SanityManager.DEBUG(DaemonService.DaemonTrace, name + " client # " + myClientNumber + " calling cleaner ");					}				}				cleaner.serviceNow(myClientNumber);				if (SanityManager.DEBUG) {				  if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {					SanityManager.DEBUG(DaemonService.DaemonTrace, name + Thread.currentThread().getName() + " cleaner called");				  }				}			}		}    } // end of rotateClock	/**		Synchronously increment clock hand position	*/	private int incrClockHand()	{		if (++clockHand >= holders.size())			clockHand = 0;		return clockHand;	}	/*	 * Serviceable methods	 */	public int performWork(ContextManager contextMgr /* ignored */) {		int ret = performWork(false);		synchronized (this) {			cleanerRunning = false;		}		return ret;	}		/**		<P>MT - read only. 	*/	public boolean serviceASAP()	{		return needService;	}		// @return true, if this work needs to be done on a user thread immediately	public boolean serviceImmediately()	{		return false;	}		public synchronized int getNumberInUse() {			int size = holders.size();			int inUse = 0;			for (int position = 0; position < size; position++) {				CachedItem item = (CachedItem) holders.get(position);				if (item.isValid()) {					inUse++;				}			}			return inUse;	}/*	public int getNumberKept() {		synchronized (this) {			int size = holders.size();			int inUse = 0;			for (int position = 0; position < size; position++) {				CachedItem item = (CachedItem) holders.get(position);				if (item.isValid() && item.isKept()) {					inUse++;				}			}			return inUse;		}	}*/	/**		Grow the cache and return a unused, kept item.		@exception StandardException Thrown if the cache cannot be grown.	*/	private CachedItem growCache()  {		CachedItem item = new CachedItem();        item.keepForCreate();		// if we run out of memory below here we don't		// know what state the holders could be in		// so don't trap it		synchronized (this) {			holders.add(item);            // Do not adjust currentByteCount until we put the entry into the CachedItem.		}		return item;	}	/**		Clear an item's identity. Item must be 		unkept and valid. This is called for		dirty items from the discard code.		Caller must hold the cache synchronization.        @return the amount by which this shrinks the cache.	*/	protected long removeIdentity(CachedItem item) {        long shrink = 1;        		if (SanityManager.DEBUG) {			SanityManager.ASSERT(!item.isKept(), "item is kept");			SanityManager.ASSERT(item.isValid(), "item is not valid");		}        if( useByteCount)            shrink = ((SizedCacheable) item.getEntry()).getSize();		remove(item.getEntry().getIdentity());						item.setValidState(false);        validItemCount--;		item.getEntry().clearIdentity();        if( useByteCount)        {            shrink -= ((SizedCacheable) item.getEntry()).getSize();            currentByteCount -= shrink;        }        return shrink;	}	/**		Write out all dirty buffers.		<P>MT - must be MT safe.		Single thread on the part that finds the next dirty buffer to write		out, the synchronization of cleaning of the individual cachable is		provided by the cacheable itself.	 */	protected void cleanCache(Matchable partialKey) throws StandardException {			int position;		synchronized(this)		{			// this is at many dirty buffers as the cleaner is ever going to			// see 			position = holders.size() - 1;		}outerscan:		for (;;) {			CachedItem item = null;			synchronized (this) {				// the cache may have shrunk by quite a bit since we last came				// in here				int size = holders.size();				if (position >= size)					position = size - 1;innerscan:				// go from position (the last cached item in the holder array				// to 0 (the first).  Otherwise, if we go from 0 to				// position, some other thread may come in and shrink items				// which is between 0 and position.  Since a shrink move all				// items up, we may skip some items without cleaning.				for ( ;  position >= 0; position--, item = null) {					item = (CachedItem) holders.get(position);					if (!item.isValid())						continue innerscan;					if (!item.getEntry().isDirty())						continue innerscan;					if (partialKey != null) {						Object key = item.getEntry().getIdentity();						if (!partialKey.match(key))							continue;					}					item.keepForClean();					break innerscan;				}			} // end of synchronized block			if (position < 0)			{				return;			}			try {				item.clean(false);			} finally {				release(item);			}			position--;					} // for (;;)	}	protected long shrinkSize(long currentSize) {		long maxSize = getMaximumSize();

⌨️ 快捷键说明

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