Refactor LeapArray to reuse code for current bucket
Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
ca2f4d9fae
commit
54905497d0
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue