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.lambda.stream.stats
10 
11 import org.geotools.api.feature.simple.SimpleFeatureType
12 import org.geotools.api.filter.Filter
13 import org.geotools.util.factory.Hints
14 import org.locationtech.geomesa.curve.TimePeriod.TimePeriod
15 import org.locationtech.geomesa.index.stats.GeoMesaStats.GeoMesaStatWriter
16 import org.locationtech.geomesa.index.stats.{GeoMesaStats, NoopStatWriter}
17 import org.locationtech.geomesa.lambda.stream.TransientStore
18 import org.locationtech.geomesa.utils.collection.SelfClosingIterator
19 import org.locationtech.geomesa.utils.stats._
20 
21 import scala.reflect.ClassTag
22 
23 class TransientStats(store: TransientStore) extends GeoMesaStats {
24 
25   override val writer: GeoMesaStatWriter = NoopStatWriter
26 
27   override def getCount(sft: SimpleFeatureType, filter: Filter, exact: Boolean, queryHints: Hints): Option[Long] =
28     Some(SelfClosingIterator(store.read(Option(filter).filter(_ != Filter.INCLUDE)).iterator()).length)
29 
30   override def getMinMax[T](
31       sft: SimpleFeatureType,
32       attribute: String,
33       filter: Filter,
34       exact: Boolean): Option[MinMax[T]] = getStat[MinMax[T]](sft, Stat.MinMax(attribute), filter, exact = true)
35 
36   override def getEnumeration[T](
37       sft: SimpleFeatureType,
38       attribute: String,
39       filter: Filter,
40       exact: Boolean): Option[EnumerationStat[T]] = {
41     if (!exact) { None } else {
42       getStat[EnumerationStat[T]](sft, Stat.Enumeration(attribute), filter, exact)
43     }
44   }
45 
46   override def getFrequency[T](
47       sft: SimpleFeatureType,
48       attribute: String,
49       precision: Int,
50       filter: Filter,
51       exact: Boolean): Option[Frequency[T]] = {
52     if (!exact) { None } else {
53       getStat[Frequency[T]](sft, Stat.Frequency(attribute, precision), filter, exact)
54     }
55   }
56 
57   override def getTopK[T](
58       sft: SimpleFeatureType,
59       attribute: String,
60       filter: Filter,
61       exact: Boolean): Option[TopK[T]] = {
62     if (!exact) { None } else {
63       getStat[TopK[T]](sft, Stat.TopK(attribute), filter, exact)
64     }
65   }
66 
67   override def getHistogram[T](
68       sft: SimpleFeatureType,
69       attribute: String,
70       bins: Int,
71       min: T,
72       max: T,
73       filter: Filter,
74       exact: Boolean): Option[Histogram[T]] = {
75     if (!exact) { None } else {
76       getStat[Histogram[T]](sft, Stat.Histogram(attribute, bins, min, max)(ClassTag(min.getClass)), filter, exact)
77     }
78   }
79 
80   override def getZ3Histogram(
81       sft: SimpleFeatureType,
82       geom: String,
83       dtg: String,
84       period: TimePeriod,
85       bins: Int,
86       filter: Filter,
87       exact: Boolean): Option[Z3Histogram] = {
88     if (!exact) { None } else {
89       getStat[Z3Histogram](sft, Stat.Z3Histogram(geom, dtg, period, bins), filter, exact)
90     }
91   }
92 
93   override def getStat[T <: Stat](
94       sft: SimpleFeatureType,
95       query: String,
96       filter: Filter,
97       exact: Boolean): Option[T] = {
98     if (!exact) { None } else {
99       val stat = Stat(sft, query).asInstanceOf[T]
100       SelfClosingIterator(store.read(Option(filter).filter(_ != Filter.INCLUDE)).iterator()).foreach(stat.observe)
101       Some(stat)
102     }
103   }
104 
105   override def close(): Unit = {}
106 }
Line Stmt Id Pos Tree Symbol Tests Code
25 97218 1182 - 1196 Select org.locationtech.geomesa.index.stats.NoopStatWriter org.locationtech.geomesa.index.stats.`package`.NoopStatWriter
28 97219 1342 - 1407 Apply scala.Function0.apply TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$1: org.geotools.api.filter.Filter) => x$1.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()
28 97221 1317 - 1416 Apply scala.Some.apply scala.Some.apply[Long](org.locationtech.geomesa.utils.collection.SelfClosingIterator.apply[org.geotools.api.feature.simple.SimpleFeature](TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$1: org.geotools.api.filter.Filter) => x$1.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()).length.toLong)
28 97220 1322 - 1415 Select scala.Int.toLong org.locationtech.geomesa.utils.collection.SelfClosingIterator.apply[org.geotools.api.feature.simple.SimpleFeature](TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$1: org.geotools.api.filter.Filter) => x$1.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()).length.toLong
34 97223 1631 - 1635 Literal <nosymbol> true
34 97222 1591 - 1613 Apply org.locationtech.geomesa.utils.stats.Stat.MinMax org.locationtech.geomesa.utils.stats.Stat.MinMax(attribute)
34 97224 1567 - 1636 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.MinMax[T]](sft, org.locationtech.geomesa.utils.stats.Stat.MinMax(attribute), filter, true)
41 97225 1811 - 1817 Select scala.Boolean.unary_! exact.unary_!
41 97227 1821 - 1825 Block scala.None scala.None
41 97226 1821 - 1825 Select scala.None scala.None
42 97229 1841 - 1917 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.EnumerationStat[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Enumeration(attribute), filter, exact)
42 97228 1874 - 1901 Apply org.locationtech.geomesa.utils.stats.Stat.Enumeration org.locationtech.geomesa.utils.stats.Stat.Enumeration(attribute)
42 97230 1841 - 1917 Block org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.EnumerationStat[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Enumeration(attribute), filter, exact)
52 97231 2116 - 2122 Select scala.Boolean.unary_! exact.unary_!
52 97233 2126 - 2130 Block scala.None scala.None
52 97232 2126 - 2130 Select scala.None scala.None
53 97235 2146 - 2225 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Frequency[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Frequency(attribute, precision), filter, exact)
53 97234 2173 - 2209 Apply org.locationtech.geomesa.utils.stats.Stat.Frequency org.locationtech.geomesa.utils.stats.Stat.Frequency(attribute, precision)
53 97236 2146 - 2225 Block org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Frequency[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Frequency(attribute, precision), filter, exact)
62 97237 2392 - 2398 Select scala.Boolean.unary_! exact.unary_!
62 97239 2402 - 2406 Block scala.None scala.None
62 97238 2402 - 2406 Select scala.None scala.None
63 97241 2422 - 2480 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.TopK[T]](sft, org.locationtech.geomesa.utils.stats.Stat.TopK(attribute), filter, exact)
63 97240 2444 - 2464 Apply org.locationtech.geomesa.utils.stats.Stat.TopK org.locationtech.geomesa.utils.stats.Stat.TopK(attribute)
63 97242 2422 - 2480 Block org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.TopK[T]](sft, org.locationtech.geomesa.utils.stats.Stat.TopK(attribute), filter, exact)
75 97243 2702 - 2708 Select scala.Boolean.unary_! exact.unary_!
75 97245 2712 - 2716 Block scala.None scala.None
75 97244 2712 - 2716 Select scala.None scala.None
76 97247 2801 - 2823 Apply scala.reflect.ClassTag.apply scala.reflect.ClassTag.apply[T](min.getClass())
76 97246 2810 - 2822 Apply scala.Any.getClass min.getClass()
76 97249 2732 - 2840 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Histogram[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Histogram[T](attribute, bins, min, max)(scala.reflect.ClassTag.apply[T](min.getClass())), filter, exact)
76 97248 2759 - 2824 Apply org.locationtech.geomesa.utils.stats.Stat.Histogram org.locationtech.geomesa.utils.stats.Stat.Histogram[T](attribute, bins, min, max)(scala.reflect.ClassTag.apply[T](min.getClass()))
76 97250 2732 - 2840 Block org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Histogram[T]](sft, org.locationtech.geomesa.utils.stats.Stat.Histogram[T](attribute, bins, min, max)(scala.reflect.ClassTag.apply[T](min.getClass())), filter, exact)
88 97251 3072 - 3078 Select scala.Boolean.unary_! exact.unary_!
88 97253 3082 - 3086 Block scala.None scala.None
88 97252 3082 - 3086 Select scala.None scala.None
89 97255 3102 - 3185 Apply org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Z3Histogram](sft, org.locationtech.geomesa.utils.stats.Stat.Z3Histogram(geom, dtg, period, bins), filter, exact)
89 97254 3128 - 3169 Apply org.locationtech.geomesa.utils.stats.Stat.Z3Histogram org.locationtech.geomesa.utils.stats.Stat.Z3Histogram(geom, dtg, period, bins)
89 97256 3102 - 3185 Block org.locationtech.geomesa.lambda.stream.stats.TransientStats.getStat TransientStats.this.getStat[org.locationtech.geomesa.utils.stats.Z3Histogram](sft, org.locationtech.geomesa.utils.stats.Stat.Z3Histogram(geom, dtg, period, bins), filter, exact)
98 97257 3350 - 3356 Select scala.Boolean.unary_! exact.unary_!
98 97259 3360 - 3364 Block scala.None scala.None
98 97258 3360 - 3364 Select scala.None scala.None
98 97265 3372 - 3561 Block <nosymbol> { val stat: T = org.locationtech.geomesa.utils.stats.Stat.apply(sft, query).asInstanceOf[T]; org.locationtech.geomesa.utils.collection.SelfClosingIterator.apply[org.geotools.api.feature.simple.SimpleFeature](TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$2: org.geotools.api.filter.Filter) => x$2.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()).foreach[Unit]({ ((sf: org.geotools.api.feature.simple.SimpleFeature) => stat.observe(sf)) }); scala.Some.apply[T](stat) }
99 97260 3391 - 3423 TypeApply scala.Any.asInstanceOf org.locationtech.geomesa.utils.stats.Stat.apply(sft, query).asInstanceOf[T]
100 97261 3450 - 3515 Apply scala.Function0.apply TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$2: org.geotools.api.filter.Filter) => x$2.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()
100 97263 3430 - 3538 Apply scala.collection.Iterator.foreach org.locationtech.geomesa.utils.collection.SelfClosingIterator.apply[org.geotools.api.feature.simple.SimpleFeature](TransientStats.this.store.read(scala.Option.apply[org.geotools.api.filter.Filter](filter).filter(((x$2: org.geotools.api.filter.Filter) => x$2.!=(org.geotools.api.filter.Filter.INCLUDE))), TransientStats.this.store.read$default$2, TransientStats.this.store.read$default$3, TransientStats.this.store.read$default$4).iterator.apply()).foreach[Unit]({ ((sf: org.geotools.api.feature.simple.SimpleFeature) => stat.observe(sf)) })
100 97262 3525 - 3537 Apply org.locationtech.geomesa.utils.stats.Stat.observe stat.observe(sf)
101 97264 3545 - 3555 Apply scala.Some.apply scala.Some.apply[T](stat)
105 97266 3598 - 3600 Literal <nosymbol> ()