[
https://issues.apache.org/jira/browse/LANG-1373?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16342358#comment-16342358
]
ASF GitHub Bot commented on LANG-1373:
--------------------------------------
Github user ottobackwards commented on a diff in the pull request:
https://github.com/apache/commons-lang/pull/311#discussion_r164283887
--- Diff: src/main/java/org/apache/commons/lang3/time/TimingRecordNode.java
---
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.commons.lang3.time;
+
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * The tree node to track time and children.
+ * The {@code StopWatch} class is used for timings
+ */
+public class TimingRecordNode {
+
+ /**
+ * The format String for creating paths.
+ */
+ private static final String PATH_FMT = "%s/%s";
+
+ /**
+ * This nodes parent's path.
+ */
+ private String parentTimingPath;
+
+ /**
+ * The name of this node.
+ */
+ private String timingName;
+
+ /**
+ * The tags associated with this timing.
+ */
+ private String[] tags;
+
+ /**
+ * The child nodes of this node.
+ */
+ private List<TimingRecordNode> children = new LinkedList<>();
+
+ /**
+ * The {@code StopWatch} for this node.
+ */
+ private StopWatch stopWatch = new StopWatch();
+
+ /**
+ * <p>
+ * Constructor.
+ * </p>
+ * <p>
+ * Creates a new TimingRecordNode for a given parent name, with a
given name.
+ * </p>
+ *
+ * @param parentTimingPath the path of the parent, may be null
+ * @param timingName the name of the timing
+ * @param tags the tags to associate with this timing
+ * @throws IllegalArgumentException if the timingName is null or empty.
+ */
+ public TimingRecordNode(String parentTimingPath, String timingName,
String... tags) {
+ if (StringUtils.isEmpty(timingName)) {
+ throw new IllegalArgumentException("Argument name is missing");
+ }
+ this.timingName = timingName;
+
+ if (StringUtils.isNotEmpty(parentTimingPath)) {
+ this.parentTimingPath = parentTimingPath;
+ }
+
+ this.tags = tags;
+ }
+
+ /**
+ * Returns the node's parent's path.
+ * The parent node path may be null
+ *
+ * @return the parent node path
+ */
+ public String getParentPath() {
+ return parentTimingPath;
+ }
+
+ /**
+ * Returns the node's timing name.
+ *
+ * @return the node timing name
+ */
+ public String getTimingName() {
+ return timingName;
+ }
+
+ /**
+ * Return if the node's StopWatch is running.
+ *
+ * @return true if it is running, false if not
+ */
+ public boolean isRunning() {
+ return stopWatch.isStarted();
+ }
+
+ /**
+ * Starts the StopWatch.
+ */
+ public void start() {
+ if (!stopWatch.isStarted()) {
+ stopWatch.start();
+ }
+ }
+
+ /**
+ * <p>
+ * Stops the StopWatch.
+ * </p>
+ * <p>
+ * If this node has running children, an {@code IllegalStateException}
will result.
+ * </p>
+ *
+ * @throws IllegalStateException if stop is called on a node with
running children
+ */
+ public void stop() {
+ for (TimingRecordNode child : children) {
+ if (child.isRunning()) {
+ throw new IllegalStateException("Cannot stop a timing with
running children");
+ }
+ }
+ stopWatch.stop();
+ }
+
+ /**
+ * Returns the {@code StopWatch} for this node.
+ *
+ * @return {@code StopWatch}
+ */
+ public StopWatch getStopWatch() {
+ return stopWatch;
+ }
+
+ /**
+ * The tags associated with this timing.
+ *
+ * @return tags array
+ */
+ public String[] getTags() {
+ return tags == null ? new String[]{} : ArrayUtils.clone(tags);
+ }
+
+
+ /**
+ * Returns the node's path, made up by combining it's parent's name
and the node's name.
+ * The path is '/' delimited.
+ * <p>
+ * If the parent path is null, then the name only is returned.
+ * </p>
+ *
+ * @return the path as String
+ */
+ public String getPath() {
+ if (parentTimingPath == null) {
+ return timingName;
+ }
+ return String.format(PATH_FMT, parentTimingPath, timingName);
+ }
+
+ /**
+ * Returns the child nodes of this node.
+ *
+ * @return Iterable of the child nodes.
+ */
+ public Iterable<TimingRecordNode> getChildren() {
+ return children;
--- End diff --
done.
> Stopwatch based capability for nested, named, timings in a call stack
> ---------------------------------------------------------------------
>
> Key: LANG-1373
> URL: https://issues.apache.org/jira/browse/LANG-1373
> Project: Commons Lang
> Issue Type: New Feature
> Components: lang.time.*
> Reporter: Otto Fowler
> Priority: Major
>
> While working on adding some timing functionality to a Metron feature, I came
> across the
> Stopwatch class, but found that it didn’t suite my needs.
> What I wanted to do was to create a timing from a top level function in our
> Stellar dsl, and have have a group of related timings, such that the end
> result was the overall time of the call, and nested timings of other calls
> executed during the dsl execution of that function. These timings would all
> be named, and have a path for identification and include timing the language
> compiler/execution as well as the function execution itself. It would be
> helpful if they were tagged in some way as well, such that the consumer could
> filter during visitation.
> So I have written StackWatch to provide this functionality, and submitted it
> in a Metron PR.
> From the PR description:
> StackWatch
> A set of utility classes under the new package stellar.common.timing have
> been added. These provide the StackWatch functionality.
> StackWatch provides an abstraction over the Apache Commons StopWatch class
> that allows callers to create multiple named and possibly nested timing
> operations.
> <…>
> This class may be more generally useful to this and other projects, but I am
> not sure where it would live since we wouldn’t want it in common.
> StackWatch uses a combination of Deque and a custom Tree implementation to
> create, start and end timing operations.
> A Visitor pattern is also implemented to allow for retrieving the results
> after the completion of the operation.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)