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

📄 resourcedispatcher.java

📁 jxta_src_2.41b jxta 2.41b 最新版源码 from www.jxta.org
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		// That's asking too much. Denied.		return false;	    }	    if (quantity > nbReserved) {		// We need to get some or all of it from the extra items.		long toAsk = nbReserved > 0 ? quantity - nbReserved : quantity;		long res = holdExtra(toAsk);		if (res != toAsk) {		    // Could not get enough. We got nothing.		    releaseExtra(res);		    return false;		}	    }	    // Now record it.	    nbReserved -= quantity;            if (LOG.isEnabledFor(Level.ERROR)) {                if (nbReserved > fromReservedItems + fromExtraItems) {                    LOG.error("Incorrect values after obtaining " + quantity + " : [" + this.toString() + "]");                }            }	    return true;	}	/**	 * {@inheritDoc}	 */	public boolean obtainItem() {	    // Set it for consistency. It will get cleared when	    // the item is used to satisfy the need.	    needs = true;	    if (nbReserved > 0) {		notEligible();		--nbReserved;		return true;  // Its pre-reserved.	    }	    // This account may deliberately limit the number of extra	    // items it uses. this translates into a lower limit for	    // nbReserved when <= 0.	    if (nbReserved <= extraLimit) {		notEligible();		return false;	    }	    if (holdExtra(1) == 1) { // Need authorization.		notEligible();		--nbReserved;		return true;	    }	    // We are out of luck but eligible.	    beEligible();	    return false;	}	/**	 * {@inheritDoc}	 */	public void releaseQuantity(long quantity) {	    if (nbReserved < 0) {		releaseExtra(quantity < -nbReserved ? quantity : -nbReserved);	    }	    nbReserved += quantity;            if (LOG.isEnabledFor(Level.ERROR)) {                if (nbReserved > fromReservedItems + fromExtraItems) {                    LOG.error("Incorrect values after releasing " + quantity + " : [" + this.toString() + "]");                }            }	}        /**         *  {@inheritDoc}         */	public ResourceAccount releaseItem() {	    if (nbReserved < 0) {		if (eligibles == null) {		    // RoundRobin is OFF either we reuse it or we let		    // it go.		    if (needs) return this;		    ++nbReserved; 		    releaseExtra(1);		    return null;		}		// RoundRobin is ON, we compete with others for this item.		++nbReserved;		// Update our eligibility which depends on extraLimit and		// whether we have a use for the item or not.		if ((nbReserved > extraLimit) && needs) {		    beEligible();		}		ClientAccount next = mostEligible();		if (next == null) {		    releaseExtra(1); // noone wants it. return to main pool		} else {		    next.granted();		}		return next;	    }	    // Since we are (back) in our reserved range, we can't be eligible	    // for extra.	    notEligible();	    // In reserved range; we keep using the item if we need it.	    if (needs) return this;	    ++nbReserved;	    return null;	}        /**         *  {@inheritDoc}         */	public void inNeed(boolean needs) {	    this.needs = needs;	    if ((nbReserved < 0) && (nbReserved > extraLimit) && needs) {		beEligible();	    } else {		notEligible();	    }	}        /**         *  {@inheritDoc}         */	public Object getUserObject() {	    return userObject;	}        /**         *  {@inheritDoc}         */	public void setUserObject(Object object) {	    userObject = object;	}        /**         *  {@inheritDoc}         */	public long getNbReserved() {	    return nbReserved;	}        /**         *  {@inheritDoc}         *         *  <p/>Returns some human-readable status and identity information useful for debugging.         */        public String toString() {            return super.toString()+" : needs="+needs+" nbReserved="+nbReserved+" fromReservedItems="+fromReservedItems+" fromExtraItems="+fromExtraItems+" extraLimit="+extraLimit;        }    }    /**     * The list of eligible accounts.     */    private Dlist eligibles;    /**     * Construct a Fair Resource Allocator with the given parameters:     * @param minAccounts The minimum number of client accounts that we want to     * garantee we can handle. <0 means 0     *     * @param minReservedPerAccount The minimum reservation request that we will     * always grant to accounts as long as we have less than minAccounts <0 means     * 0.     * @param maxReservedPerAccount The maximum reservation request that we ever     * will grant to any given account. <minReservedPerAccount means ==     * @param extraItems The total number of items that we will authorize     * beyond what has been reserved. <0 means 0.     * @param maxExtraPerAccount The maximum number of extra items we will ever     * let any given account occupy. <0 or >extraItems means ==extraItems.     * @param minExtraPoolSize The number of extra items that can never be     * taken out of the extra pool to satisfy a reservation request.     * @param roundRobin If true, when there is no items available, all     * eligible accounts are put in a FIFO. Accounts release items often, and the     * oldest account in the FIFO will get it. If false, accounts always keep     * items for as long as they can use them, and there is no FIFO of eligible     * accounts. Accounts can obtain new resources only if available at the time     * they try to aquire it. RoundRobin is more fair but has more overhead.     * Neither mode will cause starvation as long as accounts reserve at least     * one item each. RoundRobin is most useful when allocating threads.     */    public ResourceDispatcher(long minAccounts, long minReservedPerAccount,			      long maxReservedPerAccount, long extraItems,			      long maxExtraPerAccount, long minExtraPoolSize,			      boolean roundRobin,                              String dispatcherName)    {	if (minAccounts < 0) minAccounts = 0;	if (minReservedPerAccount < 0) minReservedPerAccount = 0;	if (maxReservedPerAccount < minReservedPerAccount) {	    maxReservedPerAccount = minReservedPerAccount;	}	if (extraItems < 0) extraItems = 0;        if (minExtraPoolSize < 0) minExtraPoolSize = 0;	if ((maxExtraPerAccount < 0) || (maxExtraPerAccount > extraItems)) {	    maxExtraPerAccount = extraItems;	}	this.extraItems = extraItems;	this.minExtraPoolSize = minExtraPoolSize;	this.maxReservedPerAccount = maxReservedPerAccount;	this.minReservedPerAccount = minReservedPerAccount;	this.reservedItems = minAccounts * minReservedPerAccount;	this.maxExtraPerAccount = maxExtraPerAccount;	nbEligibles = 0;	if (roundRobin) eligibles = new Dlist();        this.myName = dispatcherName;    }    private long holdReserved(long req) {	if (req > reservedItems) req = reservedItems;	reservedItems -= req;	return req;    }    private void releaseReserved(long nb) {	reservedItems += nb;    }    private long holdExtra(long req) {	if (req > extraItems) req = extraItems;	extraItems -= req;	return req;    }    // Get items from the extra pool but only if there is at least    // minExtraPoolSize item    // left after that. The goal is to make sure we keep at least one    // un-reserved item when granting reserved items from the extra pool.    // Thanks to that, even accounts that could not get a single reserved    // item still stand a chance to make progress by taking turns using    // the one extra item left.    private long holdExtraKeepSome(long req) {        if (extraItems <= minExtraPoolSize) {            return 0;        }        long allowed = extraItems - minExtraPoolSize;	if (req > allowed) req = allowed;	extraItems -= req;	return req;    }    private void releaseExtra(long nb) {	extraItems += nb;    }    private void newEligible(ClientAccount account) {	++nbEligibles;	eligibles.putLast(account);    }    private ClientAccount mostEligible() {	if (nbEligibles == 0) return null;	return (ClientAccount) eligibles.getFirst();    }    private void unEligible(ClientAccount account) {	--nbEligibles;	account.unlink();    }    // Not synch; it's just a snapshot for trace purposes.    public int getNbEligibles() {	return nbEligibles;    }    /**     * Creates and returns a new client account.     *     * @param nbReq the number of reserved items requested (may not be     * always granted in full). A negative value is taken to mean 0.      * @param maxExtra the number of additional items that this account     * authorizes to be allocated in addition to the reserved ones. This     * is typically usefull if the items are threads and if some accounts     * are not re-entrant. Then nbReq would be 1 and maxExtra would be 0.     * It is also permitted to have some accounts receive no items at all     * ever by setting nbReq and maxExtra both to zero. A negative maxExtra     * is taken as meaning no specified limit, in which case an actual limit     * may be set silently.     * @param userObject An opaque cookie that the account object will return     * when requested. This is usefull to relate an account returned by     * ClientAccount.releaseItem() to an invoking code relevant object.     * @return ResourceAccount An account with this allocator.     */    public ResourceAccount newAccount(long nbReq, long maxExtra,				      Object userObject) {	long extra = 0;    // reserved from extra pool	long reserved = 0; // reserved from reserved pool	if (nbReq > maxReservedPerAccount) nbReq = maxReservedPerAccount;	// Anything beyond the minimum comes from extra items if there's	// enough.	if (nbReq > minReservedPerAccount) {	    extra = holdExtraKeepSome(nbReq - minReservedPerAccount);	    nbReq = minReservedPerAccount;	}	// Then the minimum comes from reserved items, if we can.	reserved = holdReserved(nbReq);	nbReq -= reserved;	// If there's some letf to be had, it means that we're getting	// short on reserved items, we'll try to compensate by getting	// more items from extra, but the app should start getting rid	// of stale accounts if it can.	if (nbReq > 0) {	    if (LOG.isEnabledFor(Level.INFO)) {		LOG.info("Accepting extra account on a best effort basis.");	    }	    	    extra += holdExtraKeepSome(nbReq);	    if (extra + reserved < minReservedPerAccount) {		// Even that was not enough to reach our minimal commitment.		// The app should realy consider some cleanup.		if (LOG.isEnabledFor(Level.WARN)) {		    LOG.warn("[" + myName + "] Accepting extra account with below-minimal commitement:[" + userObject + "]");		}	    }	}	if ((maxExtra > maxExtraPerAccount) || (maxExtra < 0)) {	    maxExtra = maxExtraPerAccount;	}	return new ClientAccount(reserved, extra, maxExtra, userObject);    }}

⌨️ 快捷键说明

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