diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java index f0357f7b..51aae33d 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.locks.ReentrantLock; +import com.alibaba.csp.sentinel.util.AssertUtil; import com.alibaba.csp.sentinel.util.TimeUtil; /** @@ -57,8 +58,14 @@ public abstract class LeapArray { * @param intervalInSec the total time span of this {@link LeapArray} in seconds. */ public LeapArray(int windowLengthInMs, int intervalInSec) { + AssertUtil.isTrue(windowLengthInMs > 0, "bucket length is invalid: " + windowLengthInMs); + int intervalInMs = intervalInSec * 1000; + AssertUtil.isTrue(intervalInSec * 1000 > windowLengthInMs, + "total time span of the window should be greater than bucket length"); + AssertUtil.isTrue(intervalInMs % windowLengthInMs == 0, "time span needs to be evenly divided"); + this.windowLengthInMs = windowLengthInMs; - this.intervalInMs = intervalInSec * 1000; + this.intervalInMs = intervalInMs; this.sampleCount = intervalInMs / windowLengthInMs; this.array = new AtomicReferenceArray>(sampleCount); @@ -93,9 +100,12 @@ public abstract class LeapArray { * Get bucket item at provided timestamp. * * @param time a valid timestamp - * @return current bucket item at provided timestamp + * @return current bucket item at provided timestamp if the time is valid; null if time is invalid */ public WindowWrap currentWindow(long time) { + if (time < 0) { + return null; + } long timeId = time / windowLengthInMs; // Calculate current index so we can map the timestamp to the leap array. int idx = (int)(timeId % array.length()); @@ -189,6 +199,9 @@ public abstract class LeapArray { * @return the previous bucket item before provided timestamp */ public WindowWrap getPreviousWindow(long time) { + if (time < 0) { + return null; + } long timeId = (time - windowLengthInMs) / windowLengthInMs; int idx = (int)(timeId % array.length()); time = time - windowLengthInMs; @@ -221,6 +234,9 @@ public abstract class LeapArray { * @return the statistic value if bucket for provided timestamp is up-to-date; otherwise null */ public T getWindowValue(long time) { + if (time < 0) { + return null; + } long timeId = time / windowLengthInMs; int idx = (int)(timeId % array.length());