1 /***********************************************************************
2  * Copyright (c) 2013-2024 Commonwealth Computer Research, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Apache License, Version 2.0
5  * which accompanies this distribution and is available at
6  * http://www.opensource.org/licenses/apache2.0.php.
7  ***********************************************************************/
8 
9 package org.locationtech.geomesa.utils.stats
10 
11 import com.typesafe.scalalogging.LazyLogging
12 
13 import java.util.concurrent.atomic.AtomicLong
14 
15 trait MethodProfiling extends LazyLogging {
16 
17   protected def profile[R](onComplete: Long => Unit)(code: => R): R = {
18     val start = System.currentTimeMillis
19     val result: R = code
20     onComplete(System.currentTimeMillis - start)
21     result
22   }
23 
24   protected def profile[R](onComplete: (R, Long) => Unit)(code: => R): R = {
25     val start = System.currentTimeMillis
26     val result: R = code
27     onComplete(result, System.currentTimeMillis - start)
28     result
29   }
30 
31   protected def profile[R](message: String)(code: => R): R =
32     profile(time => logger.debug(s"$message in ${time}ms"))(code)
33 }
34 
35 /**
36  * Class to hold timing results
37  */
38 class Timing extends Serializable {
39 
40   private var total = 0L
41   private var count = 0L
42 
43   /**
44    * Updates this instance with a new timing
45    *
46    * @param time time in millis
47    * @return
48    */
49   def occurrence(time: Long): Unit = {
50     total += time
51     count += 1
52   }
53 
54   /**
55    * Gets the total time
56    *
57    * @return
58    */
59   def time: Long = total
60 
61   /**
62    * Gets the number of event occurrences
63    *
64    * @return
65    */
66   def occurrences: Long = count
67 
68   /**
69    * Computes the average for this instance
70    *
71    * @return
72    */
73   def average(): Double = total / count.toDouble
74 }
75 
76 trait Timings extends Serializable {
77 
78   /**
79    * Updates the given identifier with a new timing
80    *
81    * @param identifier identifier
82    * @param time time in millis
83    */
84   def occurrence(identifier: String, time: Long): Unit
85 
86   /**
87    * Gets the total time for the given identifier
88    *
89    * @param identifier identifier
90    * @return
91    */
92   def time(identifier: String): Long
93 
94   /**
95    * Gets the total occurrences for the given identifier
96    *
97    * @param identifier identifier
98    * @return
99    */
100   def occurrences(identifier: String): Long
101 
102   /**
103    * Creates a printed string with the computed averages
104    *
105    * @return
106    */
107   def averageOccurrences(): String
108 
109   /**
110    * Creates a printed string with the computed averages
111    *
112    * @return
113    */
114   def averageTimes(): String
115 }
116 
117 /**
118  * Class to hold timing results. Not thread-safe.
119  */
120 class TimingsImpl extends Timings {
121 
122   private val map = scala.collection.mutable.Map.empty[String, Timing]
123 
124   override def occurrence(identifier: String, time: Long): Unit =
125     map.getOrElseUpdate(identifier, new Timing).occurrence(time)
126 
127   override def time(identifier: String): Long = map.getOrElseUpdate(identifier, new Timing).time
128 
129   override def occurrences(identifier: String): Long = map.getOrElseUpdate(identifier, new Timing).occurrences
130 
131   override def averageOccurrences(): String = if (map.isEmpty) {
132     "No occurrences"
133   } else {
134     val entries = map.toList.sortBy(_._1)
135     val total = entries.map(_._2.occurrences).sum
136     val percentOccurrences = entries.map { case (id, timing) =>
137       s"$id: ${(timing.occurrences * 100 / total.toDouble).formatted("%.1f%%")}"
138     }
139     percentOccurrences.mkString(s"Total occurrences: $total. Percent of occurrences - ", ", ", "")
140   }
141 
142   override def averageTimes(): String = if (map.isEmpty) {
143     "No occurrences"
144   } else {
145     val entries = map.toList.sortBy(_._1)
146     val total = entries.map(_._2.time).sum
147     val percentTimes = entries.map { case (id, timing) =>
148       s"$id: ${(timing.time * 100 / total.toDouble).formatted("%.1f%%")}" +
149           s" ${timing.occurrences} times at ${timing.average().formatted("%.4f")} ms avg"
150     }
151     percentTimes.mkString(s"Total time: $total ms. Percent of time - ", ", ", "")
152   }
153 }
154 
155 /**
156  * Class to hold timing results. Thread-safe.
157  */
158 class ThreadSafeTimingsImpl extends Timings {
159 
160   private val map = scala.collection.mutable.Map.empty[String, Timing]
161 
162   override def occurrence(identifier: String, time: Long): Unit = {
163     val timing = map.synchronized(map.getOrElseUpdate(identifier, new Timing))
164     timing.synchronized(timing.occurrence(time))
165   }
166 
167   override def time(identifier: String): Long =
168     map.synchronized(map.getOrElseUpdate(identifier, new Timing)).time
169 
170   override def occurrences(identifier: String): Long =
171     map.synchronized(map.getOrElseUpdate(identifier, new Timing)).occurrences
172 
173   override def averageOccurrences(): String = if (map.isEmpty) {
174     "No occurrences"
175   } else {
176     val entries = map.synchronized(map.toList).sortBy(_._1)
177     val total = entries.map(_._2.occurrences).sum
178     val percentOccurrences = entries.map { case (id, timing) =>
179       s"$id: ${(timing.occurrences * 100 / total.toDouble).formatted("%.1f%%")}"
180     }
181     percentOccurrences.mkString(s"Total occurrences: $total. Percent of occurrences - ", ", ", "")
182   }
183 
184   override def averageTimes(): String = if (map.isEmpty) {
185     "No occurrences"
186   } else {
187     val entries = map.synchronized(map.toList).sortBy(_._1)
188     val total = entries.map(_._2.time).sum
189     val percentTimes = entries.map { case (id, timing) =>
190       timing.synchronized(s"$id: ${(timing.time * 100 / total.toDouble).formatted("%.1f%%")}" +
191           s" ${timing.occurrences} times at ${timing.average().formatted("%.4f")} ms avg")
192     }
193     percentTimes.mkString(s"Total time: $total ms. Percent of time - ", ", ", "")
194   }
195 }
196 
197 /**
198  * Useful for sharing timings between instances of a certain class
199  *
200  * @param moduloToLog how many events to skip between logging
201  */
202 class AutoLoggingTimings(moduloToLog: Int = 1000) extends ThreadSafeTimingsImpl with LazyLogging {
203 
204   val count = new AtomicLong()
205 
206   override def occurrence(identifier: String, time: Long): Unit = {
207     super.occurrence(identifier, time)
208     if (count.incrementAndGet() % moduloToLog == 0) {
209       logger.debug(averageTimes())
210     }
211   }
212 }
213 
214 object NoOpTimings extends Timings {
215 
216   override def occurrence(identifier: String, time: Long): Unit = {}
217 
218   override def occurrences(identifier: String) = 0L
219 
220   override def time(identifier: String) = 0L
221 
222   override def averageTimes() = ""
223 
224   override def averageOccurrences() = ""
225 }
Line Stmt Id Pos Tree Symbol Tests Code
18 13788 737 - 761 Apply java.lang.System.currentTimeMillis java.lang.System.currentTimeMillis()
20 13789 802 - 834 Apply scala.Long.- java.lang.System.currentTimeMillis().-(start)
20 13790 791 - 835 Apply scala.Function1.apply onComplete.apply(java.lang.System.currentTimeMillis().-(start))
25 13791 945 - 969 Apply java.lang.System.currentTimeMillis java.lang.System.currentTimeMillis()
27 13792 1018 - 1050 Apply scala.Long.- java.lang.System.currentTimeMillis().-(start)
27 13793 999 - 1051 Apply scala.Function2.apply onComplete.apply(result, java.lang.System.currentTimeMillis().-(start))
32 13794 1133 - 1194 Apply org.locationtech.geomesa.utils.stats.MethodProfiling.profile MethodProfiling.this.profile[R](((time: Long) => (if (MethodProfiling.this.logger.underlying.isDebugEnabled()) MethodProfiling.this.logger.underlying.debug("{} in {}ms", (scala.Array.apply[AnyRef]((message: AnyRef), time.asInstanceOf[AnyRef])((ClassTag.AnyRef: scala.reflect.ClassTag[AnyRef])): _*)) else (): Unit)))(code)
40 13795 1297 - 1299 Literal <nosymbol> 0L
41 13796 1322 - 1324 Literal <nosymbol> 0L
50 13797 1476 - 1489 Apply scala.Long.+ Timing.this.total.+(time)
50 13798 1476 - 1489 Apply org.locationtech.geomesa.utils.stats.Timing.total_= Timing.this.total_=(Timing.this.total.+(time))
51 13799 1494 - 1504 Apply scala.Long.+ Timing.this.count.+(1)
51 13800 1494 - 1504 Apply org.locationtech.geomesa.utils.stats.Timing.count_= Timing.this.count_=(Timing.this.count.+(1))
59 13801 1584 - 1589 Select org.locationtech.geomesa.utils.stats.Timing.total Timing.this.total
66 13802 1689 - 1694 Select org.locationtech.geomesa.utils.stats.Timing.count Timing.this.count
73 13803 1804 - 1818 Select scala.Long.toDouble Timing.this.count.toDouble
73 13804 1796 - 1818 Apply scala.Long./ Timing.this.total./(Timing.this.count.toDouble)
122 13805 2726 - 2776 TypeApply scala.collection.mutable.Map.empty scala.collection.mutable.Map.empty[String, org.locationtech.geomesa.utils.stats.Timing]
125 13806 2848 - 2908 Apply org.locationtech.geomesa.utils.stats.Timing.occurrence TimingsImpl.this.map.getOrElseUpdate(identifier, new Timing()).occurrence(time)
127 13807 2990 - 3000 Apply org.locationtech.geomesa.utils.stats.Timing.<init> new Timing()
127 13808 2958 - 3006 Select org.locationtech.geomesa.utils.stats.Timing.time TimingsImpl.this.map.getOrElseUpdate(identifier, new Timing()).time
129 13809 3095 - 3105 Apply org.locationtech.geomesa.utils.stats.Timing.<init> new Timing()
129 13810 3063 - 3118 Select org.locationtech.geomesa.utils.stats.Timing.occurrences TimingsImpl.this.map.getOrElseUpdate(identifier, new Timing()).occurrences
131 13811 3170 - 3181 Select scala.collection.MapLike.isEmpty TimingsImpl.this.map.isEmpty
132 13812 3189 - 3205 Literal <nosymbol> "No occurrences"
132 13813 3189 - 3205 Block <nosymbol> "No occurrences"
133 13833 3215 - 3562 Block <nosymbol> { val entries: List[(String, org.locationtech.geomesa.utils.stats.Timing)] = TimingsImpl.this.map.toList.sortBy[String](((x$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$1._1))(math.this.Ordering.String); val total: Long = entries.map[Long, List[Long]](((x$2: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$2._2.occurrences))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral); val percentOccurrences: List[String] = entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")) }))(immutable.this.List.canBuildFrom[String]); percentOccurrences.mkString(scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total), ", ", "") }
134 13814 3253 - 3257 Select scala.Tuple2._1 x$1._1
134 13815 3252 - 3252 Select scala.math.Ordering.String math.this.Ordering.String
134 13816 3235 - 3258 ApplyToImplicitArgs scala.collection.SeqLike.sortBy TimingsImpl.this.map.toList.sortBy[String](((x$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$1._1))(math.this.Ordering.String)
135 13817 3287 - 3303 Select org.locationtech.geomesa.utils.stats.Timing.occurrences x$2._2.occurrences
135 13818 3286 - 3286 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[Long]
135 13819 3305 - 3305 Select scala.math.Numeric.LongIsIntegral math.this.Numeric.LongIsIntegral
135 13820 3275 - 3308 ApplyToImplicitArgs scala.collection.TraversableOnce.sum entries.map[Long, List[Long]](((x$2: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$2._2.occurrences))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral)
136 13827 3350 - 3350 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
136 13828 3338 - 3459 ApplyToImplicitArgs scala.collection.immutable.List.map entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")) }))(immutable.this.List.canBuildFrom[String])
137 13821 3381 - 3382 Literal <nosymbol> ""
137 13822 3384 - 3387 Literal <nosymbol> ": "
137 13823 3452 - 3453 Literal <nosymbol> ""
137 13824 3388 - 3451 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")
137 13825 3379 - 3453 Apply scala.StringContext.s scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%"))
137 13826 3379 - 3453 Block scala.StringContext.s scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%"))
139 13829 3492 - 3547 Apply scala.StringContext.s scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total)
139 13830 3549 - 3553 Literal <nosymbol> ", "
139 13831 3555 - 3557 Literal <nosymbol> ""
139 13832 3464 - 3558 Apply scala.collection.TraversableOnce.mkString percentOccurrences.mkString(scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total), ", ", "")
142 13834 3608 - 3619 Select scala.collection.MapLike.isEmpty TimingsImpl.this.map.isEmpty
143 13835 3627 - 3643 Literal <nosymbol> "No occurrences"
143 13836 3627 - 3643 Block <nosymbol> "No occurrences"
144 13862 3653 - 4055 Block <nosymbol> { val entries: List[(String, org.locationtech.geomesa.utils.stats.Timing)] = TimingsImpl.this.map.toList.sortBy[String](((x$3: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$3._1))(math.this.Ordering.String); val total: Long = entries.map[Long, List[Long]](((x$4: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$4._2.time))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral); val percentTimes: List[String] = entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))) }))(immutable.this.List.canBuildFrom[String]); percentTimes.mkString(scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total), ", ", "") }
145 13837 3691 - 3695 Select scala.Tuple2._1 x$3._1
145 13838 3690 - 3690 Select scala.math.Ordering.String math.this.Ordering.String
145 13839 3673 - 3696 ApplyToImplicitArgs scala.collection.SeqLike.sortBy TimingsImpl.this.map.toList.sortBy[String](((x$3: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$3._1))(math.this.Ordering.String)
146 13840 3725 - 3734 Select org.locationtech.geomesa.utils.stats.Timing.time x$4._2.time
146 13841 3724 - 3724 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[Long]
146 13842 3736 - 3736 Select scala.math.Numeric.LongIsIntegral math.this.Numeric.LongIsIntegral
146 13843 3713 - 3739 ApplyToImplicitArgs scala.collection.TraversableOnce.sum entries.map[Long, List[Long]](((x$4: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$4._2.time))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral)
147 13856 3775 - 3775 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
147 13857 3763 - 3969 ApplyToImplicitArgs scala.collection.immutable.List.map entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))) }))(immutable.this.List.canBuildFrom[String])
148 13844 3806 - 3807 Literal <nosymbol> ""
148 13845 3809 - 3812 Literal <nosymbol> ": "
148 13846 3870 - 3871 Literal <nosymbol> ""
148 13847 3813 - 3869 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")
148 13854 3804 - 3963 Apply java.lang.String.+ scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")))
148 13855 3804 - 3963 Block java.lang.String.+ scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")))
149 13848 3886 - 3888 Literal <nosymbol> " "
149 13849 3908 - 3919 Literal <nosymbol> " times at "
149 13850 3955 - 3963 Literal <nosymbol> " ms avg"
149 13851 3889 - 3907 Select org.locationtech.geomesa.utils.stats.Timing.occurrences timing.occurrences
149 13852 3920 - 3954 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")
149 13853 3884 - 3963 Apply scala.StringContext.s scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))
151 13858 3996 - 4040 Apply scala.StringContext.s scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total)
151 13859 4042 - 4046 Literal <nosymbol> ", "
151 13860 4048 - 4050 Literal <nosymbol> ""
151 13861 3974 - 4051 Apply scala.collection.TraversableOnce.mkString percentTimes.mkString(scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total), ", ", "")
160 13863 4180 - 4230 TypeApply scala.collection.mutable.Map.empty scala.collection.mutable.Map.empty[String, org.locationtech.geomesa.utils.stats.Timing]
163 13864 4366 - 4376 Apply org.locationtech.geomesa.utils.stats.Timing.<init> new Timing()
163 13865 4334 - 4377 Apply scala.collection.mutable.MapLike.getOrElseUpdate ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing())
163 13866 4317 - 4378 Apply java.lang.Object.synchronized ThreadSafeTimingsImpl.this.map.synchronized[org.locationtech.geomesa.utils.stats.Timing](ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing()))
164 13867 4403 - 4426 Apply org.locationtech.geomesa.utils.stats.Timing.occurrence timing.occurrence(time)
164 13868 4383 - 4427 Apply java.lang.Object.synchronized timing.synchronized[Unit](timing.occurrence(time))
168 13869 4534 - 4544 Apply org.locationtech.geomesa.utils.stats.Timing.<init> new Timing()
168 13870 4502 - 4545 Apply scala.collection.mutable.MapLike.getOrElseUpdate ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing())
168 13871 4485 - 4551 Select org.locationtech.geomesa.utils.stats.Timing.time ThreadSafeTimingsImpl.this.map.synchronized[org.locationtech.geomesa.utils.stats.Timing](ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing())).time
171 13872 4661 - 4671 Apply org.locationtech.geomesa.utils.stats.Timing.<init> new Timing()
171 13873 4629 - 4672 Apply scala.collection.mutable.MapLike.getOrElseUpdate ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing())
171 13874 4612 - 4685 Select org.locationtech.geomesa.utils.stats.Timing.occurrences ThreadSafeTimingsImpl.this.map.synchronized[org.locationtech.geomesa.utils.stats.Timing](ThreadSafeTimingsImpl.this.map.getOrElseUpdate(identifier, new Timing())).occurrences
173 13875 4737 - 4748 Select scala.collection.MapLike.isEmpty ThreadSafeTimingsImpl.this.map.isEmpty
174 13876 4756 - 4772 Literal <nosymbol> "No occurrences"
174 13877 4756 - 4772 Block <nosymbol> "No occurrences"
175 13898 4782 - 5147 Block <nosymbol> { val entries: List[(String, org.locationtech.geomesa.utils.stats.Timing)] = ThreadSafeTimingsImpl.this.map.synchronized[List[(String, org.locationtech.geomesa.utils.stats.Timing)]](ThreadSafeTimingsImpl.this.map.toList).sortBy[String](((x$5: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$5._1))(math.this.Ordering.String); val total: Long = entries.map[Long, List[Long]](((x$6: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$6._2.occurrences))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral); val percentOccurrences: List[String] = entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")) }))(immutable.this.List.canBuildFrom[String]); percentOccurrences.mkString(scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total), ", ", "") }
176 13878 4819 - 4829 Select scala.collection.TraversableOnce.toList ThreadSafeTimingsImpl.this.map.toList
176 13879 4838 - 4842 Select scala.Tuple2._1 x$5._1
176 13880 4837 - 4837 Select scala.math.Ordering.String math.this.Ordering.String
176 13881 4802 - 4843 ApplyToImplicitArgs scala.collection.SeqLike.sortBy ThreadSafeTimingsImpl.this.map.synchronized[List[(String, org.locationtech.geomesa.utils.stats.Timing)]](ThreadSafeTimingsImpl.this.map.toList).sortBy[String](((x$5: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$5._1))(math.this.Ordering.String)
177 13882 4872 - 4888 Select org.locationtech.geomesa.utils.stats.Timing.occurrences x$6._2.occurrences
177 13883 4871 - 4871 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[Long]
177 13884 4890 - 4890 Select scala.math.Numeric.LongIsIntegral math.this.Numeric.LongIsIntegral
177 13885 4860 - 4893 ApplyToImplicitArgs scala.collection.TraversableOnce.sum entries.map[Long, List[Long]](((x$6: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$6._2.occurrences))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral)
178 13892 4935 - 4935 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
178 13893 4923 - 5044 ApplyToImplicitArgs scala.collection.immutable.List.map entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")) }))(immutable.this.List.canBuildFrom[String])
179 13886 4966 - 4967 Literal <nosymbol> ""
179 13887 4969 - 4972 Literal <nosymbol> ": "
179 13888 5037 - 5038 Literal <nosymbol> ""
179 13889 4973 - 5036 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%")
179 13890 4964 - 5038 Apply scala.StringContext.s scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%"))
179 13891 4964 - 5038 Block scala.StringContext.s scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.occurrences.*(100)./(total.toDouble)).formatted("%.1f%%"))
181 13894 5077 - 5132 Apply scala.StringContext.s scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total)
181 13895 5134 - 5138 Literal <nosymbol> ", "
181 13896 5140 - 5142 Literal <nosymbol> ""
181 13897 5049 - 5143 Apply scala.collection.TraversableOnce.mkString percentOccurrences.mkString(scala.StringContext.apply("Total occurrences: ", ". Percent of occurrences - ").s(total), ", ", "")
184 13899 5193 - 5204 Select scala.collection.MapLike.isEmpty ThreadSafeTimingsImpl.this.map.isEmpty
185 13900 5212 - 5228 Literal <nosymbol> "No occurrences"
185 13901 5212 - 5228 Block <nosymbol> "No occurrences"
186 13929 5238 - 5679 Block <nosymbol> { val entries: List[(String, org.locationtech.geomesa.utils.stats.Timing)] = ThreadSafeTimingsImpl.this.map.synchronized[List[(String, org.locationtech.geomesa.utils.stats.Timing)]](ThreadSafeTimingsImpl.this.map.toList).sortBy[String](((x$7: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$7._1))(math.this.Ordering.String); val total: Long = entries.map[Long, List[Long]](((x$8: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$8._2.time))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral); val percentTimes: List[String] = entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => timing.synchronized[String](scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")))) }))(immutable.this.List.canBuildFrom[String]); percentTimes.mkString(scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total), ", ", "") }
187 13902 5275 - 5285 Select scala.collection.TraversableOnce.toList ThreadSafeTimingsImpl.this.map.toList
187 13903 5294 - 5298 Select scala.Tuple2._1 x$7._1
187 13904 5293 - 5293 Select scala.math.Ordering.String math.this.Ordering.String
187 13905 5258 - 5299 ApplyToImplicitArgs scala.collection.SeqLike.sortBy ThreadSafeTimingsImpl.this.map.synchronized[List[(String, org.locationtech.geomesa.utils.stats.Timing)]](ThreadSafeTimingsImpl.this.map.toList).sortBy[String](((x$7: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$7._1))(math.this.Ordering.String)
188 13906 5328 - 5337 Select org.locationtech.geomesa.utils.stats.Timing.time x$8._2.time
188 13907 5327 - 5327 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[Long]
188 13908 5339 - 5339 Select scala.math.Numeric.LongIsIntegral math.this.Numeric.LongIsIntegral
188 13909 5316 - 5342 ApplyToImplicitArgs scala.collection.TraversableOnce.sum entries.map[Long, List[Long]](((x$8: (String, org.locationtech.geomesa.utils.stats.Timing)) => x$8._2.time))(immutable.this.List.canBuildFrom[Long]).sum[Long](math.this.Numeric.LongIsIntegral)
189 13923 5378 - 5378 TypeApply scala.collection.immutable.List.canBuildFrom immutable.this.List.canBuildFrom[String]
189 13924 5366 - 5593 ApplyToImplicitArgs scala.collection.immutable.List.map entries.map[String, List[String]](((x0$1: (String, org.locationtech.geomesa.utils.stats.Timing)) => x0$1 match { case (_1: String, _2: org.locationtech.geomesa.utils.stats.Timing)(String, org.locationtech.geomesa.utils.stats.Timing)((id @ _), (timing @ _)) => timing.synchronized[String](scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")))) }))(immutable.this.List.canBuildFrom[String])
190 13910 5429 - 5430 Literal <nosymbol> ""
190 13911 5432 - 5435 Literal <nosymbol> ": "
190 13912 5493 - 5494 Literal <nosymbol> ""
190 13913 5436 - 5492 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")
190 13920 5427 - 5586 Apply java.lang.String.+ scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")))
190 13921 5407 - 5587 Apply java.lang.Object.synchronized timing.synchronized[String](scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))))
190 13922 5407 - 5587 Block java.lang.Object.synchronized timing.synchronized[String](scala.StringContext.apply("", ": ", "").s(id, scala.Predef.StringFormat[Double](timing.time.*(100)./(total.toDouble)).formatted("%.1f%%")).+(scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))))
191 13914 5509 - 5511 Literal <nosymbol> " "
191 13915 5531 - 5542 Literal <nosymbol> " times at "
191 13916 5578 - 5586 Literal <nosymbol> " ms avg"
191 13917 5512 - 5530 Select org.locationtech.geomesa.utils.stats.Timing.occurrences timing.occurrences
191 13918 5543 - 5577 Apply scala.Predef.StringFormat.formatted scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f")
191 13919 5507 - 5586 Apply scala.StringContext.s scala.StringContext.apply(" ", " times at ", " ms avg").s(timing.occurrences, scala.Predef.StringFormat[Double](timing.average()).formatted("%.4f"))
193 13925 5620 - 5664 Apply scala.StringContext.s scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total)
193 13926 5666 - 5670 Literal <nosymbol> ", "
193 13927 5672 - 5674 Literal <nosymbol> ""
193 13928 5598 - 5675 Apply scala.collection.TraversableOnce.mkString percentTimes.mkString(scala.StringContext.apply("Total time: ", " ms. Percent of time - ").s(total), ", ", "")
204 13930 5937 - 5953 Apply java.util.concurrent.atomic.AtomicLong.<init> new java.util.concurrent.atomic.AtomicLong()
207 13931 6027 - 6061 Apply org.locationtech.geomesa.utils.stats.ThreadSafeTimingsImpl.occurrence AutoLoggingTimings.super.occurrence(identifier, time)
208 13932 6070 - 6112 Apply scala.Long.== AutoLoggingTimings.this.count.incrementAndGet().%(AutoLoggingTimings.this.moduloToLog).==(0)
208 13934 6066 - 6066 Literal <nosymbol> ()
208 13935 6066 - 6066 Block <nosymbol> ()
209 13933 6122 - 6150 Typed <nosymbol> (if (AutoLoggingTimings.this.logger.underlying.isDebugEnabled()) AutoLoggingTimings.this.logger.underlying.debug(AutoLoggingTimings.this.averageTimes()) else (): Unit)
216 13936 6268 - 6270 Literal <nosymbol> ()
218 13937 6321 - 6323 Literal <nosymbol> 0L
220 13938 6367 - 6369 Literal <nosymbol> 0L
222 13939 6403 - 6405 Literal <nosymbol> ""
224 13940 6445 - 6447 Literal <nosymbol> ""