Skip to content

Commit 5b2a445

Browse files
author
edelgadoh
committed
Adding labels to split StopWatch feature
1 parent 7d14157 commit 5b2a445

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

src/main/java/org/apache/commons/lang3/time/StopWatch.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
import java.time.Duration;
2121
import java.time.Instant;
22+
import java.util.ArrayList;
23+
import java.util.Collections;
24+
import java.util.List;
2225
import java.util.Objects;
2326
import java.util.concurrent.TimeUnit;
2427
import java.util.function.Supplier;
@@ -27,6 +30,7 @@
2730
import org.apache.commons.lang3.function.FailableConsumer;
2831
import org.apache.commons.lang3.function.FailableRunnable;
2932
import org.apache.commons.lang3.function.FailableSupplier;
33+
import org.apache.commons.lang3.tuple.ImmutablePair;
3034

3135
/**
3236
* {@link StopWatch} provides a convenient API for timings.
@@ -248,6 +252,11 @@ public static StopWatch createStarted() {
248252
*/
249253
private long stopTimeNanos;
250254

255+
/**
256+
* The split history list.
257+
*/
258+
private List<Split> splitHistory;
259+
251260
/**
252261
* Constructs a new instance.
253262
*/
@@ -326,6 +335,16 @@ public String getMessage() {
326335
return message;
327336
}
328337

338+
/**
339+
* Gets the split history list.
340+
*
341+
* @return the list of splits.
342+
* @since 3.19.0
343+
*/
344+
public List<Split> getSplitHistory() {
345+
return Collections.unmodifiableList(splitHistory);
346+
}
347+
329348
/**
330349
* Gets the <em>elapsed</em> time in nanoseconds.
331350
*
@@ -557,6 +576,7 @@ private long nanosToMillis(final long nanos) {
557576
public void reset() {
558577
runningState = State.UNSTARTED;
559578
splitState = SplitState.UNSPLIT;
579+
splitHistory = new ArrayList<>();
560580
}
561581

562582
/**
@@ -626,6 +646,23 @@ public void split() {
626646
splitState = SplitState.SPLIT;
627647
}
628648

649+
/**
650+
* <p>
651+
* Captures the time in ns and records in a history list.
652+
* The label specified is used to identify the current split.
653+
* </p>
654+
*
655+
* @param label A message for string presentation.
656+
* @throws IllegalStateException if the StopWatch is not running.
657+
* @since 3.19.0
658+
*/
659+
public void recordSplit(final String label) {
660+
if (runningState != State.RUNNING) {
661+
throw new IllegalStateException("Stopwatch is not running.");
662+
}
663+
splitHistory.add(new Split(label, System.nanoTime()));
664+
}
665+
629666
/**
630667
* Starts this StopWatch.
631668
*
@@ -645,6 +682,7 @@ public void start() {
645682
startTimeNanos = System.nanoTime();
646683
startInstant = Instant.now();
647684
runningState = State.RUNNING;
685+
splitHistory = new ArrayList<>();
648686
}
649687

650688
/**
@@ -746,4 +784,45 @@ public void unsplit() {
746784
splitState = SplitState.UNSPLIT;
747785
}
748786

787+
/**
788+
* Class to store details of each split.
789+
* @since 3.19.0
790+
*/
791+
public static final class Split extends ImmutablePair<String, Long> {
792+
793+
/**
794+
* Constructor with label and duration.
795+
* @param label Label for this split.
796+
* @param timeNanos time in ns.
797+
*/
798+
public Split(String label, Long timeNanos) {
799+
super(label, timeNanos);
800+
}
801+
802+
/**
803+
* Get the label of this split.
804+
* @return label.
805+
*/
806+
public String getLabel() {
807+
return getLeft();
808+
}
809+
810+
/**
811+
* Get the time in nanoseconds.
812+
* @return time in ns.
813+
*/
814+
public Long getTimeNanos() {
815+
return getRight();
816+
}
817+
818+
/**
819+
* Converts this instance to a handy string.
820+
* @return this instance as a string.
821+
*/
822+
@Override
823+
public String toString() {
824+
return String.format("Split [label=%s, timeNanos=%d])", getLabel(), getTimeNanos());
825+
}
826+
}
827+
749828
}

src/test/java/org/apache/commons/lang3/time/StopWatchTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.IOException;
2727
import java.time.Duration;
2828
import java.time.Instant;
29+
import java.util.List;
2930
import java.util.concurrent.TimeUnit;
3031
import java.util.concurrent.atomic.AtomicInteger;
3132

@@ -500,6 +501,32 @@ void testToStringWithMessage() throws InterruptedException {
500501
assertEquals(SPLIT_CLOCK_STR_LEN + MESSAGE.length() + 1, splitStr.length(), "Formatted split string not the correct length");
501502
}
502503

504+
@Test
505+
void testSplitsWithStringLabels() {
506+
final StopWatch watch = new StopWatch();
507+
final String firstLabel = "one";
508+
final String secondLabel = "two";
509+
final String thirdLabel = "three";
510+
watch.start();
511+
// starting splits
512+
watch.recordSplit(firstLabel);
513+
watch.recordSplit(secondLabel);
514+
watch.recordSplit(thirdLabel);
515+
watch.stop();
516+
// getting splits
517+
final List<StopWatch.Split> splits = watch.getSplitHistory();
518+
// check size
519+
assertEquals(3, splits.size());
520+
// check labels
521+
assertEquals(firstLabel, splits.get(0).getLabel());
522+
assertEquals(secondLabel, splits.get(1).getLabel());
523+
assertEquals(thirdLabel, splits.get(2).getLabel());
524+
// check time in nanos
525+
assertTrue(splits.get(0).getTimeNanos() > 0);
526+
assertTrue(splits.get(1).getTimeNanos() > 0);
527+
assertTrue(splits.get(2).getTimeNanos() > 0);
528+
}
529+
503530
private int throwIOException() throws IOException {
504531
throw new IOException("A");
505532
}

0 commit comments

Comments
 (0)