Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -18,10 +18,13 @@ package com.alibaba.csp.sentinel.slots.statistic.base; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.concurrent.atomic.AtomicReferenceArray; | |||
import java.util.concurrent.locks.ReentrantLock; | |||
import com.alibaba.csp.sentinel.util.TimeUtil; | |||
/** | |||
* Basic data structure for statistic metrics. | |||
* | |||
* @param <T> type of data wrapper | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
@@ -32,27 +35,86 @@ public abstract class LeapArray<T> { | |||
protected int sampleCount; | |||
protected int intervalInMs; | |||
protected AtomicReferenceArray<WindowWrap<T>> array; | |||
protected final AtomicReferenceArray<WindowWrap<T>> array; | |||
private final ReentrantLock updateLock = new ReentrantLock(); | |||
public LeapArray(int windowLength, int intervalInSec) { | |||
this.windowLength = windowLength; | |||
this.sampleCount = intervalInSec * 1000 / windowLength; | |||
this.intervalInMs = intervalInSec * 1000; | |||
this.sampleCount = intervalInMs / windowLength; | |||
this.array = new AtomicReferenceArray<WindowWrap<T>>(sampleCount); | |||
} | |||
/** | |||
* Get the window at current timestamp. | |||
* | |||
* @return the window at current timestamp | |||
*/ | |||
public WindowWrap<T> currentWindow() { | |||
return currentWindow(TimeUtil.currentTimeMillis()); | |||
} | |||
/** | |||
* Create a new bucket. | |||
* | |||
* @return the new empty bucket | |||
*/ | |||
public abstract T newEmptyBucket(); | |||
/** | |||
* Reset current window to provided start time and reset all counters. | |||
* | |||
* @param startTime the start time of the window | |||
* @param windowWrap current window | |||
* @return new clean window wrap | |||
*/ | |||
protected abstract WindowWrap<T> resetWindowTo(WindowWrap<T> windowWrap, long startTime); | |||
/** | |||
* Get window at provided timestamp. | |||
* | |||
* @param time a valid timestamp | |||
* @return the window at provided timestamp | |||
*/ | |||
abstract public WindowWrap<T> currentWindow(long time); | |||
public WindowWrap<T> currentWindow(long time) { | |||
long timeId = time / windowLength; | |||
// Calculate current index. | |||
int idx = (int)(timeId % array.length()); | |||
// Cut the time to current window start. | |||
time = time - time % windowLength; | |||
while (true) { | |||
WindowWrap<T> old = array.get(idx); | |||
if (old == null) { | |||
WindowWrap<T> window = new WindowWrap<T>(windowLength, time, newEmptyBucket()); | |||
if (array.compareAndSet(idx, null, window)) { | |||
return window; | |||
} else { | |||
Thread.yield(); | |||
} | |||
} else if (time == old.windowStart()) { | |||
return old; | |||
} else if (time > old.windowStart()) { | |||
if (updateLock.tryLock()) { | |||
try { | |||
// if (old is deprecated) then [LOCK] resetTo currentTime. | |||
return resetWindowTo(old, time); | |||
} finally { | |||
updateLock.unlock(); | |||
} | |||
} else { | |||
Thread.yield(); | |||
} | |||
} else if (time < old.windowStart()) { | |||
// Cannot go through here. | |||
return new WindowWrap<T>(windowLength, time, newEmptyBucket()); | |||
} | |||
} | |||
} | |||
public WindowWrap<T> getPreviousWindow(long time) { | |||
long timeId = (time - windowLength) / windowLength; | |||
@@ -87,16 +149,12 @@ public abstract class LeapArray<T> { | |||
return old.value(); | |||
} | |||
AtomicReferenceArray<WindowWrap<T>> array() { | |||
return array; | |||
} | |||
private boolean isWindowDeprecated(WindowWrap<T> windowWrap) { | |||
return TimeUtil.currentTimeMillis() - windowWrap.windowStart() >= intervalInMs; | |||
} | |||
public List<WindowWrap<T>> list() { | |||
ArrayList<WindowWrap<T>> result = new ArrayList<WindowWrap<T>>(); | |||
List<WindowWrap<T>> result = new ArrayList<WindowWrap<T>>(); | |||
for (int i = 0; i < array.length(); i++) { | |||
WindowWrap<T> windowWrap = array.get(i); | |||
@@ -110,7 +168,7 @@ public abstract class LeapArray<T> { | |||
} | |||
public List<T> values() { | |||
ArrayList<T> result = new ArrayList<T>(); | |||
List<T> result = new ArrayList<T>(); | |||
for (int i = 0; i < array.length(); i++) { | |||
WindowWrap<T> windowWrap = array.get(i); | |||
@@ -23,7 +23,7 @@ import com.alibaba.csp.sentinel.Constants; | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
*/ | |||
public class Window { | |||
public class MetricBucket { | |||
private final LongAdder pass = new LongAdder(); | |||
private final LongAdder block = new LongAdder(); | |||
@@ -33,7 +33,7 @@ public class Window { | |||
private volatile long minRt; | |||
public Window() { | |||
public MetricBucket() { | |||
initMinRt(); | |||
} | |||
@@ -46,7 +46,7 @@ public class Window { | |||
* | |||
* @return new clean window | |||
*/ | |||
public Window reset() { | |||
public MetricBucket reset() { | |||
pass.reset(); | |||
block.reset(); | |||
exception.reset(); |
@@ -20,27 +20,27 @@ import java.util.List; | |||
import com.alibaba.csp.sentinel.Constants; | |||
import com.alibaba.csp.sentinel.node.metric.MetricNode; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.Window; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; | |||
/** | |||
* The basic metric class in Sentinel using a {@link WindowLeapArray} internal. | |||
* The basic metric class in Sentinel using a {@link MetricsLeapArray} internal. | |||
* | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
*/ | |||
public class ArrayMetric implements Metric { | |||
private final WindowLeapArray data; | |||
private final MetricsLeapArray data; | |||
public ArrayMetric(int windowLength, int interval) { | |||
this.data = new WindowLeapArray(windowLength, interval); | |||
this.data = new MetricsLeapArray(windowLength, interval); | |||
} | |||
/** | |||
* For unit test. | |||
*/ | |||
public ArrayMetric(WindowLeapArray array) { | |||
public ArrayMetric(MetricsLeapArray array) { | |||
this.data = array; | |||
} | |||
@@ -49,8 +49,8 @@ public class ArrayMetric implements Metric { | |||
data.currentWindow(); | |||
long success = 0; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
success += window.success(); | |||
} | |||
return success; | |||
@@ -61,8 +61,8 @@ public class ArrayMetric implements Metric { | |||
data.currentWindow(); | |||
long success = 0; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
if (window.success() > success) { | |||
success = window.success(); | |||
} | |||
@@ -74,8 +74,8 @@ public class ArrayMetric implements Metric { | |||
public long exception() { | |||
data.currentWindow(); | |||
long exception = 0; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
exception += window.exception(); | |||
} | |||
return exception; | |||
@@ -85,8 +85,8 @@ public class ArrayMetric implements Metric { | |||
public long block() { | |||
data.currentWindow(); | |||
long block = 0; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
block += window.block(); | |||
} | |||
return block; | |||
@@ -96,9 +96,9 @@ public class ArrayMetric implements Metric { | |||
public long pass() { | |||
data.currentWindow(); | |||
long pass = 0; | |||
List<Window> list = data.values(); | |||
List<MetricBucket> list = data.values(); | |||
for (Window window : list) { | |||
for (MetricBucket window : list) { | |||
pass += window.pass(); | |||
} | |||
return pass; | |||
@@ -108,8 +108,8 @@ public class ArrayMetric implements Metric { | |||
public long rt() { | |||
data.currentWindow(); | |||
long rt = 0; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
rt += window.rt(); | |||
} | |||
return rt; | |||
@@ -119,8 +119,8 @@ public class ArrayMetric implements Metric { | |||
public long minRt() { | |||
data.currentWindow(); | |||
long rt = Constants.TIME_DROP_VALVE; | |||
List<Window> list = data.values(); | |||
for (Window window : list) { | |||
List<MetricBucket> list = data.values(); | |||
for (MetricBucket window : list) { | |||
if (window.minRt() < rt) { | |||
rt = window.minRt(); | |||
} | |||
@@ -133,7 +133,7 @@ public class ArrayMetric implements Metric { | |||
public List<MetricNode> details() { | |||
List<MetricNode> details = new ArrayList<MetricNode>(); | |||
data.currentWindow(); | |||
for (WindowWrap<Window> window : data.list()) { | |||
for (WindowWrap<MetricBucket> window : data.list()) { | |||
if (window == null) { | |||
continue; | |||
} | |||
@@ -156,38 +156,38 @@ public class ArrayMetric implements Metric { | |||
} | |||
@Override | |||
public Window[] windows() { | |||
public MetricBucket[] windows() { | |||
data.currentWindow(); | |||
return data.values().toArray(new Window[data.values().size()]); | |||
return data.values().toArray(new MetricBucket[data.values().size()]); | |||
} | |||
@Override | |||
public void addException() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap.value().addException(); | |||
} | |||
@Override | |||
public void addBlock() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap.value().addBlock(); | |||
} | |||
@Override | |||
public void addSuccess() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap.value().addSuccess(); | |||
} | |||
@Override | |||
public void addPass() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap.value().addPass(); | |||
} | |||
@Override | |||
public void addRT(long rt) { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap.value().addRT(rt); | |||
} | |||
@@ -196,7 +196,7 @@ public class ArrayMetric implements Metric { | |||
data.currentWindow(); | |||
StringBuilder sb = new StringBuilder(); | |||
sb.append(Thread.currentThread().getId()).append("_"); | |||
for (WindowWrap<Window> windowWrap : data.list()) { | |||
for (WindowWrap<MetricBucket> windowWrap : data.list()) { | |||
sb.append(windowWrap.windowStart()).append(":").append(windowWrap.value().pass()).append(":") | |||
.append(windowWrap.value().block()); | |||
@@ -208,7 +208,7 @@ public class ArrayMetric implements Metric { | |||
@Override | |||
public long previousWindowBlock() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap = data.getPreviousWindow(); | |||
if (wrap == null) { | |||
return 0; | |||
@@ -218,12 +218,11 @@ public class ArrayMetric implements Metric { | |||
@Override | |||
public long previousWindowPass() { | |||
WindowWrap<Window> wrap = data.currentWindow(); | |||
WindowWrap<MetricBucket> wrap = data.currentWindow(); | |||
wrap = data.getPreviousWindow(); | |||
if (wrap == null) { | |||
return 0; | |||
} | |||
return wrap.value().pass(); | |||
} | |||
} |
@@ -18,7 +18,7 @@ package com.alibaba.csp.sentinel.slots.statistic.metric; | |||
import java.util.List; | |||
import com.alibaba.csp.sentinel.node.metric.MetricNode; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.Window; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket; | |||
/** | |||
* Represents a basic structure recording invocation metrics of protected resources. | |||
@@ -79,7 +79,7 @@ public interface Metric { | |||
* | |||
* @return window metric array | |||
*/ | |||
Window[] windows(); | |||
MetricBucket[] windows(); | |||
/** | |||
* Increment by one the current exception count. | |||
@@ -0,0 +1,45 @@ | |||
/* | |||
* Copyright 1999-2018 Alibaba Group Holding Ltd. | |||
* | |||
* 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 com.alibaba.csp.sentinel.slots.statistic.metric; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; | |||
/** | |||
* The fundamental data structure for metric statistics in a time window. | |||
* | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
*/ | |||
public class MetricsLeapArray extends LeapArray<MetricBucket> { | |||
public MetricsLeapArray(int windowLengthInMs, int intervalInSec) { | |||
super(windowLengthInMs, intervalInSec); | |||
} | |||
@Override | |||
public MetricBucket newEmptyBucket() { | |||
return new MetricBucket(); | |||
} | |||
@Override | |||
protected WindowWrap<MetricBucket> resetWindowTo(WindowWrap<MetricBucket> w, long startTime) { | |||
w.resetTo(startTime); | |||
w.value().reset(); | |||
return w; | |||
} | |||
} |
@@ -1,88 +0,0 @@ | |||
/* | |||
* Copyright 1999-2018 Alibaba Group Holding Ltd. | |||
* | |||
* 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 com.alibaba.csp.sentinel.slots.statistic.metric; | |||
import java.util.concurrent.locks.ReentrantLock; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.LeapArray; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.Window; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; | |||
/** | |||
* The fundamental data structure for metric statistics in a time window. | |||
* | |||
* @author jialiang.linjl | |||
* @author Eric Zhao | |||
*/ | |||
public class WindowLeapArray extends LeapArray<Window> { | |||
public WindowLeapArray(int windowLengthInMs, int intervalInSec) { | |||
super(windowLengthInMs, intervalInSec); | |||
} | |||
private ReentrantLock addLock = new ReentrantLock(); | |||
/** | |||
* Reset current window to provided start time and reset all counters. | |||
* | |||
* @param startTime the start time of the window | |||
* @return new clean window wrap | |||
*/ | |||
private WindowWrap<Window> resetWindowTo(WindowWrap<Window> w, long startTime) { | |||
w.resetTo(startTime); | |||
w.value().reset(); | |||
return w; | |||
} | |||
@Override | |||
public WindowWrap<Window> currentWindow(long time) { | |||
long timeId = time / windowLength; | |||
// Calculate current index. | |||
int idx = (int)(timeId % array.length()); | |||
// Cut the time to current window start. | |||
time = time - time % windowLength; | |||
while (true) { | |||
WindowWrap<Window> old = array.get(idx); | |||
if (old == null) { | |||
WindowWrap<Window> window = new WindowWrap<Window>(windowLength, time, new Window()); | |||
if (array.compareAndSet(idx, null, window)) { | |||
return window; | |||
} else { | |||
Thread.yield(); | |||
} | |||
} else if (time == old.windowStart()) { | |||
return old; | |||
} else if (time > old.windowStart()) { | |||
if (addLock.tryLock()) { | |||
try { | |||
// if (old is deprecated) then [LOCK] resetTo currentTime. | |||
return resetWindowTo(old, time); | |||
} finally { | |||
addLock.unlock(); | |||
} | |||
} else { | |||
Thread.yield(); | |||
} | |||
} else if (time < old.windowStart()) { | |||
// Cannot go through here. | |||
return new WindowWrap<Window>(windowLength, time, new Window()); | |||
} | |||
} | |||
} | |||
} |
@@ -19,10 +19,10 @@ import java.util.ArrayList; | |||
import org.junit.Test; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.Window; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.ArrayMetric; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.WindowLeapArray; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray; | |||
import static org.junit.Assert.*; | |||
@@ -40,10 +40,10 @@ public class ArrayMetricTest { | |||
@Test | |||
public void testOperateArrayMetric() { | |||
WindowLeapArray leapArray = mock(WindowLeapArray.class); | |||
final WindowWrap<Window> windowWrap = new WindowWrap<Window>(windowLengthInMs, 0, new Window()); | |||
MetricsLeapArray leapArray = mock(MetricsLeapArray.class); | |||
final WindowWrap<MetricBucket> windowWrap = new WindowWrap<MetricBucket>(windowLengthInMs, 0, new MetricBucket()); | |||
when(leapArray.currentWindow()).thenReturn(windowWrap); | |||
when(leapArray.values()).thenReturn(new ArrayList<Window>() {{ add(windowWrap.value()); }}); | |||
when(leapArray.values()).thenReturn(new ArrayList<MetricBucket>() {{ add(windowWrap.value()); }}); | |||
ArrayMetric metric = new ArrayMetric(leapArray); | |||
@@ -21,30 +21,30 @@ import java.util.List; | |||
import java.util.Set; | |||
import java.util.concurrent.CountDownLatch; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.MetricBucket; | |||
import com.alibaba.csp.sentinel.util.TimeUtil; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.Window; | |||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.WindowLeapArray; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray; | |||
import org.junit.Test; | |||
import static org.junit.Assert.*; | |||
/** | |||
* Test cases for {@link WindowLeapArray}. | |||
* Test cases for {@link MetricsLeapArray}. | |||
* | |||
* @author Eric Zhao | |||
*/ | |||
public class WindowLeapArrayTest { | |||
public class MetricsLeapArrayTest { | |||
private final int windowLengthInMs = 1000; | |||
private final int intervalInSec = 2; | |||
@Test | |||
public void testNewWindow() { | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long time = TimeUtil.currentTimeMillis(); | |||
WindowWrap<Window> window = leapArray.currentWindow(time); | |||
WindowWrap<MetricBucket> window = leapArray.currentWindow(time); | |||
assertEquals(window.windowLength(), windowLengthInMs); | |||
assertEquals(window.windowStart(), time - time % windowLengthInMs); | |||
@@ -54,11 +54,11 @@ public class WindowLeapArrayTest { | |||
@Test | |||
public void testLeapArrayWindowStart() { | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long firstTime = TimeUtil.currentTimeMillis(); | |||
long previousWindowStart = firstTime - firstTime % windowLengthInMs; | |||
WindowWrap<Window> window = leapArray.currentWindow(firstTime); | |||
WindowWrap<MetricBucket> window = leapArray.currentWindow(firstTime); | |||
assertEquals(windowLengthInMs, window.windowLength()); | |||
assertEquals(previousWindowStart, window.windowStart()); | |||
@@ -66,15 +66,15 @@ public class WindowLeapArrayTest { | |||
@Test | |||
public void testWindowAfterOneInterval() { | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long firstTime = TimeUtil.currentTimeMillis(); | |||
long previousWindowStart = firstTime - firstTime % windowLengthInMs; | |||
WindowWrap<Window> window = leapArray.currentWindow(previousWindowStart); | |||
WindowWrap<MetricBucket> window = leapArray.currentWindow(previousWindowStart); | |||
assertEquals(windowLengthInMs, window.windowLength()); | |||
assertEquals(previousWindowStart, window.windowStart()); | |||
Window currentWindow = window.value(); | |||
MetricBucket currentWindow = window.value(); | |||
assertNotNull(currentWindow); | |||
currentWindow.addPass(); | |||
@@ -87,7 +87,7 @@ public class WindowLeapArrayTest { | |||
window = leapArray.currentWindow(middleTime); | |||
assertEquals(previousWindowStart, window.windowStart()); | |||
Window middleWindow = window.value(); | |||
MetricBucket middleWindow = window.value(); | |||
middleWindow.addPass(); | |||
assertSame(currentWindow, middleWindow); | |||
assertEquals(2L, middleWindow.pass()); | |||
@@ -106,18 +106,18 @@ public class WindowLeapArrayTest { | |||
@Deprecated | |||
public void testWindowDeprecatedRefresh() { | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
final int len = intervalInSec * 1000 / windowLengthInMs; | |||
long firstTime = TimeUtil.currentTimeMillis(); | |||
List<WindowWrap<Window>> firstIterWindowList = new ArrayList<WindowWrap<Window>>(len); | |||
List<WindowWrap<MetricBucket>> firstIterWindowList = new ArrayList<WindowWrap<MetricBucket>>(len); | |||
for (int i = 0; i < len; i++) { | |||
WindowWrap<Window> w = leapArray.currentWindow(firstTime + windowLengthInMs * i); | |||
WindowWrap<MetricBucket> w = leapArray.currentWindow(firstTime + windowLengthInMs * i); | |||
w.value().addPass(); | |||
firstIterWindowList.add(i, w); | |||
} | |||
for (int i = len; i < len * 2; i++) { | |||
WindowWrap<Window> w = leapArray.currentWindow(firstTime + windowLengthInMs * i); | |||
WindowWrap<MetricBucket> w = leapArray.currentWindow(firstTime + windowLengthInMs * i); | |||
assertNotSame(w, firstIterWindowList.get(i - len)); | |||
} | |||
} | |||
@@ -126,7 +126,7 @@ public class WindowLeapArrayTest { | |||
public void testMultiThreadUpdateEmptyWindow() throws Exception { | |||
final long time = TimeUtil.currentTimeMillis(); | |||
final int nThreads = 16; | |||
final WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
final MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
final CountDownLatch latch = new CountDownLatch(nThreads); | |||
Runnable task = new Runnable() { | |||
@Override | |||
@@ -147,9 +147,9 @@ public class WindowLeapArrayTest { | |||
@Test | |||
public void testGetPreviousWindow() { | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long time = TimeUtil.currentTimeMillis(); | |||
WindowWrap<Window> previousWindow = leapArray.currentWindow(time); | |||
WindowWrap<MetricBucket> previousWindow = leapArray.currentWindow(time); | |||
assertNull(leapArray.getPreviousWindow(time)); | |||
long nextTime = time + windowLengthInMs; | |||
@@ -165,16 +165,16 @@ public class WindowLeapArrayTest { | |||
final int intervalInSec = 1; | |||
final int intervalInMs = intervalInSec * 1000; | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long time = TimeUtil.currentTimeMillis(); | |||
Set<WindowWrap<Window>> windowWraps = new HashSet<WindowWrap<Window>>(); | |||
Set<WindowWrap<MetricBucket>> windowWraps = new HashSet<WindowWrap<MetricBucket>>(); | |||
windowWraps.add(leapArray.currentWindow(time)); | |||
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); | |||
List<WindowWrap<Window>> list = leapArray.list(); | |||
for (WindowWrap<Window> wrap : list) { | |||
List<WindowWrap<MetricBucket>> list = leapArray.list(); | |||
for (WindowWrap<MetricBucket> wrap : list) { | |||
assertTrue(windowWraps.contains(wrap)); | |||
} | |||
@@ -191,18 +191,18 @@ public class WindowLeapArrayTest { | |||
final int windowLengthInMs = 100; | |||
final int intervalInSec = 1; | |||
WindowLeapArray leapArray = new WindowLeapArray(windowLengthInMs, intervalInSec); | |||
MetricsLeapArray leapArray = new MetricsLeapArray(windowLengthInMs, intervalInSec); | |||
long time = TimeUtil.currentTimeMillis(); | |||
Set<WindowWrap<Window>> windowWraps = new HashSet<WindowWrap<Window>>(); | |||
Set<WindowWrap<MetricBucket>> windowWraps = new HashSet<WindowWrap<MetricBucket>>(); | |||
windowWraps.add(leapArray.currentWindow(time)); | |||
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); | |||
Thread.sleep(intervalInSec * 1000 + windowLengthInMs * 3); | |||
List<WindowWrap<Window>> list = leapArray.list(); | |||
for (WindowWrap<Window> wrap : list) { | |||
List<WindowWrap<MetricBucket>> list = leapArray.list(); | |||
for (WindowWrap<MetricBucket> wrap : list) { | |||
assertTrue(windowWraps.contains(wrap)); | |||
} | |||
@@ -39,12 +39,6 @@ public class WarmUpFlowTest { | |||
FlowRuleManager.loadRules(Arrays.asList(flowRule)); | |||
//ContextUtil.enter(null); | |||
//when(flowRule.selectNodeByRequsterAndStrategy(null, null, null)).thenReturn(value) | |||
// flowRule.passCheck(null, DefaultNode, acquireCount, args) | |||
// when(leapArray.values()).thenReturn(new ArrayList<Window>() {{ add(windowWrap.value()); }}); | |||
ContextUtil.enter("test"); | |||
ContextUtil.exit(); | |||