Skip to content

Commit c993651

Browse files
committed
[pinpoint-apm#12238] Add virtual TimeseriesWindows to TimeWindow
1 parent 5d2ce94 commit c993651

File tree

15 files changed

+208
-117
lines changed

15 files changed

+208
-117
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.navercorp.pinpoint.common.server.util.timewindow;
2+
3+
import org.springframework.util.Assert;
4+
5+
import java.util.Iterator;
6+
import java.util.NoSuchElementException;
7+
8+
/**
9+
* @author emeroad
10+
*/
11+
public class TimeSeriesIterator implements Iterator<Long> {
12+
private final int size;
13+
private final long start;
14+
private final long increment;
15+
16+
private int index = 0;
17+
18+
public TimeSeriesIterator(int size, long start, long increment) {
19+
Assert.isTrue(size >= 0, "negative size");
20+
this.size = size;
21+
this.start = start;
22+
this.increment = increment;
23+
}
24+
25+
@Override
26+
public boolean hasNext() {
27+
return index < size;
28+
}
29+
30+
@Override
31+
public Long next() {
32+
if (!hasNext()) {
33+
throw new NoSuchElementException();
34+
}
35+
return get(index++);
36+
}
37+
38+
private long get(int index) {
39+
if (index < 0 || index >= size) {
40+
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
41+
}
42+
return start + (index * increment);
43+
}
44+
}
45+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.navercorp.pinpoint.common.server.util.timewindow;
2+
3+
import org.springframework.util.Assert;
4+
5+
import java.util.AbstractList;
6+
import java.util.Iterator;
7+
8+
/**
9+
* A virtual list that represents a time series.
10+
* @author emeroad
11+
*/
12+
public class TimeSeriesVirtualList extends AbstractList<Long> {
13+
private final int size;
14+
private final long start;
15+
private final long increment;
16+
17+
public TimeSeriesVirtualList(int size, long start, long increment) {
18+
Assert.isTrue(size >= 0, "negative size");
19+
this.size = size;
20+
this.start = start;
21+
this.increment = increment;
22+
}
23+
24+
@Override
25+
public Long get(int index) {
26+
if (index < 0 || index >= size) {
27+
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
28+
}
29+
return start + (index * increment);
30+
}
31+
32+
@Override
33+
public Iterator<Long> iterator() {
34+
return new TimeSeriesIterator(this.size, this.start, this.increment);
35+
}
36+
37+
@Override
38+
public int size() {
39+
return size;
40+
}
41+
}

commons-server/src/main/java/com/navercorp/pinpoint/common/server/util/timewindow/TimeWindow.java

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,17 @@
2020

2121
import java.time.Instant;
2222
import java.util.Iterator;
23-
import java.util.NoSuchElementException;
23+
import java.util.List;
2424
import java.util.Objects;
2525

2626
/**
2727
*
2828
* @author netspider
29-
*
3029
*/
3130
public class TimeWindow implements Iterable<Long>, TimeWindowFunction {
3231

3332
private final long windowSlotSize;
3433

35-
private final Range range;
36-
3734
private final Range windowRange;
3835

3936
private final int windowRangeCount;
@@ -43,10 +40,10 @@ public TimeWindow(Range range) {
4340
}
4441

4542
public TimeWindow(Range range, TimeWindowSampler sampler) {
46-
this.range = Objects.requireNonNull(range, "range");
43+
Objects.requireNonNull(range, "range");
4744
Objects.requireNonNull(sampler, "sampler");
4845
this.windowSlotSize = sampler.getWindowSize(range);
49-
this.windowRange = createWindowRange();
46+
this.windowRange = createWindowRange(range);
5047
this.windowRangeCount = computeWindowRangeCount(windowRange.durationMillis(), windowSlotSize);
5148
}
5249

@@ -58,8 +55,19 @@ private static int computeWindowRangeCount(long duration, long slotSize) {
5855
return Math.toIntExact(count);
5956
}
6057

58+
@Override
6159
public Iterator<Long> iterator() {
62-
return new Itr();
60+
final int size = this.getWindowRangeCount();
61+
final long start = windowRange.getFrom();
62+
final long increment = getWindowSlotSize();
63+
return new TimeSeriesIterator(size, start, increment);
64+
}
65+
66+
public List<Long> getTimeseriesWindows() {
67+
final int size = this.getWindowRangeCount();
68+
final long start = windowRange.getFrom();
69+
final long increment = getWindowSlotSize();
70+
return new TimeSeriesVirtualList(size, start, increment);
6371
}
6472

6573
/**
@@ -91,45 +99,15 @@ public Range getWindowSlotRange() {
9199
return Range.between(scanFrom, Instant.ofEpochMilli(scanTo));
92100
}
93101

94-
private Range createWindowRange() {
102+
private Range createWindowRange(Range range) {
95103
long from = refineTimestamp(range.getFrom());
96104
long to = refineTimestamp(range.getTo());
97105
return Range.between(from, to);
98106
}
99107

100108
public int getWindowIndex(long time) {
101109
long index = (time - windowRange.getFrom()) / this.windowSlotSize;
102-
return (int)index;
110+
return (int) index;
103111
}
104112

105-
private class Itr implements Iterator<Long> {
106-
107-
private long cursor;
108-
private final long end;
109-
110-
public Itr() {
111-
this.cursor = windowRange.getFrom();
112-
this.end = windowRange.getTo();
113-
}
114-
115-
@Override
116-
public boolean hasNext() {
117-
return cursor <= end;
118-
}
119-
120-
@Override
121-
public Long next() {
122-
long current = cursor;
123-
if (hasNext()) {
124-
cursor += windowSlotSize;
125-
return current;
126-
}
127-
throw new NoSuchElementException();
128-
}
129-
130-
@Override
131-
public void remove() {
132-
throw new UnsupportedOperationException();
133-
}
134-
}
135113
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.navercorp.pinpoint.common.server.util.timewindow;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import com.navercorp.pinpoint.common.server.util.time.Range;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.List;
8+
9+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
10+
11+
class TimeSeriesVirtualListTest {
12+
13+
@Test
14+
void list() {
15+
TimeWindowSampler sampler = new FixedTimeWindowSampler(100);
16+
TimeWindow timeWindow = new TimeWindow(Range.between(0L, 10000L), sampler);
17+
List<Long> timeWindowList = ImmutableList.copyOf(timeWindow.iterator());
18+
19+
List<Long> list = new TimeSeriesVirtualList(timeWindow.getWindowRangeCount(), 0, timeWindow.getWindowSlotSize());
20+
21+
assertThat(list).isEqualTo(timeWindowList);
22+
}
23+
}

commons-server/src/test/java/com/navercorp/pinpoint/common/server/util/timewindow/TimeWindowTest.java

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,58 +23,74 @@
2323
import org.junit.jupiter.api.Assertions;
2424
import org.junit.jupiter.api.Test;
2525

26-
import java.util.Iterator;
26+
import java.util.List;
2727
import java.util.concurrent.TimeUnit;
2828

29+
import static org.assertj.core.api.Assertions.assertThat;
30+
2931
/**
3032
* @author emeroad
3133
*/
32-
public class TimeWindowTest {
34+
class TimeWindowTest {
3335
private final Logger logger = LogManager.getLogger(this.getClass());
3436

3537

3638
@Test
37-
public void testGetNextWindowFirst() {
39+
void testGetTimeseriesWindows() {
3840
TimeWindow window = new TimeWindow(Range.between(0L, 1000));
3941
logger.debug("{}", window.getWindowRange());
40-
Iterator<Long> iterator = window.iterator();
41-
Assertions.assertEquals(0L, iterator.next());
42+
List<Long> timeWindows = window.getTimeseriesWindows();
4243

43-
Assertions.assertThrows(Exception.class, iterator::next);
44+
assertThat(timeWindows).hasSize(1)
45+
.containsExactly(0L);
46+
}
4447

48+
@Test
49+
void testTimestampWindows2() {
4550
TimeWindow window2 = new TimeWindow(Range.between(0L, TimeUnit.MINUTES.toMillis(1)));
4651
logger.debug("{}", window2.getWindowRange());
47-
Iterator<Long> iterator2 = window2.iterator();
48-
Assertions.assertEquals(0L, iterator2.next());
49-
Assertions.assertEquals(1000*60L, iterator2.next());
50-
Assertions.assertThrows(Exception.class, iterator2::next);
52+
List<Long> timeWindows2 = window2.getTimeseriesWindows();
53+
assertThat(timeWindows2).hasSize(2)
54+
.containsExactly(0L, 1000 * 60L);
5155
}
5256

57+
5358
@Test
54-
public void testGetNextWindow() {
59+
void testTimestampWindowsSize() {
5560
Range range = Range.between(0L, TimeUnit.MINUTES.toMillis(1));
5661
TimeWindow window = new TimeWindow(range);
57-
ImmutableList<Long> longs = ImmutableList.copyOf(window.iterator());
58-
Assertions.assertEquals(2, longs.size());
62+
List<Long> timestamps = window.getTimeseriesWindows();
63+
Assertions.assertEquals(2, timestamps.size());
5964
Assertions.assertEquals(2, window.getWindowRangeCount());
6065
}
6166

6267
@Test
63-
public void testGetNextWindow2() {
68+
void testTimestampWindowsSize2() {
6469
Range range = Range.between(1L, TimeUnit.MINUTES.toMillis(1));
6570
TimeWindow window = new TimeWindow(range);
66-
ImmutableList<Long> longs = ImmutableList.copyOf(window.iterator());
67-
Assertions.assertEquals(2, longs.size());
71+
List<Long> timestamps = window.getTimeseriesWindows();
72+
Assertions.assertEquals(2, timestamps.size());
6873
Assertions.assertEquals(2, window.getWindowRangeCount());
6974
}
7075

7176
@Test
72-
public void testRefineTimestamp() {
77+
void testGetNextWindow_iter() {
78+
Range range = Range.between(1L, TimeUnit.MINUTES.toMillis(1));
79+
TimeWindow window = new TimeWindow(range);
80+
81+
List<Long> iter = ImmutableList.copyOf(window.iterator());
82+
List<Long> timestamps = window.getTimeseriesWindows();
83+
assertThat(timestamps)
84+
.isEqualTo(iter);
85+
}
86+
87+
@Test
88+
void testRefineTimestamp() {
7389

7490
}
7591

7692
@Test
77-
public void testGetWindowSize() {
93+
void testGetWindowSize() {
7894
testWindowSize(0, TimeUnit.MINUTES.toMillis(1));
7995
testWindowSize(0, TimeUnit.HOURS.toMillis(1));
8096
testWindowSize(0, TimeUnit.HOURS.toMillis(23));
@@ -88,8 +104,8 @@ private void testWindowSize(long start, long end) {
88104
}
89105

90106
@Test
91-
public void refineRange() {
92-
Range range = Range.between(1L, TimeUnit.MINUTES.toMillis(1)+1);
107+
void refineRange() {
108+
Range range = Range.between(1L, TimeUnit.MINUTES.toMillis(1) + 1);
93109
TimeWindow window = new TimeWindow(range);
94110
Range windowRange = window.getWindowRange();
95111
// 1 should be replace by 0.
@@ -100,7 +116,7 @@ public void refineRange() {
100116
}
101117

102118
@Test
103-
public void testGetWindowRangeLength() {
119+
void testGetWindowRangeLength() {
104120
Range range = Range.between(1L, 2L);
105121
TimeWindow window = new TimeWindow(range);
106122
int windowRangeLength = window.getWindowRangeCount();
@@ -110,26 +126,26 @@ public void testGetWindowRangeLength() {
110126
}
111127

112128
@Test
113-
public void testGetWindowRangeLength2() {
114-
Range range = Range.between(1L, 1000*60L + 1);
129+
void testGetWindowRangeLength2() {
130+
Range range = Range.between(1L, 1000 * 60L + 1);
115131
TimeWindow window = new TimeWindow(range);
116132
int windowRangeLength = window.getWindowRangeCount();
117133
logger.debug("{}", windowRangeLength);
118134
Assertions.assertEquals(2, windowRangeLength);
119135
}
120136

121137
@Test
122-
public void testRefineIndex1() {
123-
Range range = Range.between(1L, 1000*60L);
138+
void testRefineIndex1() {
139+
Range range = Range.between(1L, 1000 * 60L);
124140
TimeWindow window = new TimeWindow(range);
125141
long index = window.getWindowIndex(2);
126142
logger.debug("{}", index);
127143
Assertions.assertEquals(0, index);
128144
}
129145

130146
@Test
131-
public void testRefineIndex2() {
132-
Range range = Range.between(1L, 1000*60L);
147+
void testRefineIndex2() {
148+
Range range = Range.between(1L, 1000 * 60L);
133149
TimeWindow window = new TimeWindow(range);
134150
long index = window.getWindowIndex(1000 * 60L);
135151
logger.debug("{}", index);

exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/TimeSeriesUtils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionChartGroup;
2020
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView;
2121
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartView;
22-
import com.navercorp.pinpoint.metric.common.util.TimeUtils;
2322
import com.navercorp.pinpoint.metric.web.view.TimeSeriesValueView;
2423
import com.navercorp.pinpoint.metric.web.view.TimeseriesValueGroupView;
2524

@@ -48,7 +47,7 @@ public static ExceptionChartView newChartView(
4847
Objects.requireNonNull(timeWindow, "timeWindow");
4948
Objects.requireNonNull(exceptionChartValueViews, "exceptionTraceValueViews");
5049

51-
List<Long> timestampList = TimeUtils.createTimeStampList(timeWindow);
50+
List<Long> timestampList = timeWindow.getTimeseriesWindows();
5251
List<TimeseriesValueGroupView> timeSeriesValueGroupViews = new ArrayList<>();
5352
timeSeriesValueGroupViews.add(
5453
newGroupFromValueViews(groupName, exceptionChartValueViews)

0 commit comments

Comments
 (0)