protected override long reserveEarliestAvailable(int requiredPermits, long nowMicros)
        {
            //重新计算桶内令牌数storedPermits
            lock (mutex())
            {
                resync(nowMicros);
            }

            lock (mutex())
            {
                long returnValue = nextFreeTicketMicros;                                     //下一次请求可以获取令牌的起始时间
                                                                                             //本次消耗的令牌数
                double storedPermitsToSpend = Math.Min(requiredPermits, this.storedPermits); //本次消耗的令牌数=min(申请令牌数,当前存储令牌数)
                #region 预支逻辑                                                                 //重新计算下次可获取时间nextFreeTicketMicros
                double freshPermits = requiredPermits - storedPermitsToSpend;                //缺少令牌数=申请令牌数-本次可以消耗的令牌数
                long   waitMicros   =
                    storedPermitsToWaitTime(this.storedPermits, storedPermitsToSpend)
                    + (long)(freshPermits * stableIntervalMicros);                                     //缺少令牌数*生成令牌的时间间隔(提前预支)

                this.nextFreeTicketMicros = LongHelper.SaturatedAdd(nextFreeTicketMicros, waitMicros); //防止溢出 下一次分配时间+预支分配令牌的时间
                #endregion                                                                             //Console.WriteLine("nextFreeTicketMicros:" + this.nextFreeTicketMicros+"_"+ waitMicros);
                this.storedPermits -= storedPermitsToSpend;
                return(returnValue);
            }
        }
Esempio n. 2
0
        public void SaturateCalculationTest()
        {
            Assert.IsTrue(LongHelper.SaturatedAdd(5, 5) == 10);
            Assert.IsTrue(LongHelper.SaturatedAdd(long.MaxValue, 5) == long.MaxValue);
            Assert.IsTrue(LongHelper.SaturatedAdd(long.MinValue, -5) == long.MinValue);

            Assert.IsTrue(LongHelper.SaturatedSubtract(long.MinValue, 5) == long.MinValue);

            Assert.IsTrue(LongHelper.SaturatedMultiply(5, 5) == 25);
            Assert.IsTrue(LongHelper.SaturatedMultiply(long.MaxValue / 2, 3) == long.MaxValue);
        }