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.fs.storage.common.partitions
10 
11 import org.geotools.api.feature.simple.{SimpleFeature, SimpleFeatureType}
12 import org.geotools.api.filter.Filter
13 import org.locationtech.geomesa.filter.FilterHelper
14 import org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter
15 import org.locationtech.geomesa.fs.storage.api.{NamedOptions, PartitionScheme, PartitionSchemeFactory}
16 import org.locationtech.geomesa.utils.date.DateUtils.toInstant
17 import org.locationtech.geomesa.utils.text.DateParsing
18 
19 import java.time.format.{DateTimeFormatter, DateTimeFormatterBuilder}
20 import java.time.temporal.{ChronoField, ChronoUnit, TemporalAdjusters, WeekFields}
21 import java.time.{ZoneOffset, ZonedDateTime}
22 import java.util.Date
23 import scala.annotation.tailrec
24 import scala.collection.mutable.ListBuffer
25 import scala.util.control.NonFatal
26 
27 case class DateTimeScheme(
28     formatter: DateTimeFormatter,
29     pattern: String,
30     stepUnit: ChronoUnit,
31     step: Int,
32     dtg: String,
33     dtgIndex: Int
34   ) extends PartitionScheme {
35 
36   import FilterHelper.ff
37   import org.locationtech.geomesa.filter.{andOption, isTemporalFilter, partitionSubFilters}
38 
39   import ChronoUnit._
40 
41   // note: `truncatedTo` is only valid up to DAYS, other units require additional steps
42   private val truncate: ZonedDateTime => ZonedDateTime = stepUnit match {
43     case NANOS | MICROS | MILLIS | SECONDS | MINUTES | HOURS | DAYS =>
44       dt => dt.truncatedTo(stepUnit)
45 
46     case MONTHS =>
47       val adjuster = TemporalAdjusters.firstDayOfMonth()
48       dt => dt.`with`(adjuster).truncatedTo(DAYS)
49 
50     case YEARS =>
51       val adjuster = TemporalAdjusters.firstDayOfYear()
52       dt => dt.`with`(adjuster).truncatedTo(DAYS)
53 
54     case _ =>
55       dt => DateParsing.parse(formatter.format(dt), formatter) // fall back to format and re-parse
56   }
57 
58   // TODO This may not be the best way to calculate max depth...
59   // especially if we are going to use other separators
60   override val depth: Int = pattern.count(_ == '/') + 1
61 
62   override def getPartitionName(feature: SimpleFeature): String =
63     formatter.format(toInstant(feature.getAttribute(dtgIndex).asInstanceOf[Date]).atZone(ZoneOffset.UTC))
64 
65   override def getSimplifiedFilters(filter: Filter, partition: Option[String]): Option[Seq[SimplifiedFilter]] = {
66     getCoveringPartitions(filter).map { case (covered, intersecting) =>
67       val result = Seq.newBuilder[SimplifiedFilter]
68 
69       if (covered.nonEmpty) {
70         // remove the temporal filter that we've already accounted for in our covered partitions
71         val coveredFilter = andOption(partitionSubFilters(filter, isTemporalFilter(_, dtg))._2)
72         result += SimplifiedFilter(coveredFilter.getOrElse(Filter.INCLUDE), covered, partial = false)
73       }
74       if (intersecting.nonEmpty) {
75         result += SimplifiedFilter(filter, intersecting.distinct, partial = false)
76       }
77 
78       partition match {
79         case None => result.result
80         case Some(p) =>
81           val matched = result.result.find(_.partitions.contains(p))
82           matched.map(_.copy(partitions = Seq(p))).toSeq
83       }
84     }
85   }
86 
87   override def getIntersectingPartitions(filter: Filter): Option[Seq[String]] =
88     getCoveringPartitions(filter).map { case (covered, intersecting) => covered ++ intersecting }
89 
90   override def getCoveringFilter(partition: String): Filter = {
91     val zdt = DateParsing.parse(partition, formatter)
92     val start = DateParsing.format(zdt)
93     val end = DateParsing.format(zdt.plus(1, stepUnit))
94     ff.and(ff.greaterOrEqual(ff.property(dtg), ff.literal(start)), ff.less(ff.property(dtg), ff.literal(end)))
95   }
96 
97   private def getCoveringPartitions(filter: Filter): Option[(Seq[String], Seq[String])] = {
98     val bounds = FilterHelper.extractIntervals(filter, dtg, handleExclusiveBounds = false)
99     if (bounds.disjoint) {
100       Some((Seq.empty, Seq.empty))
101     } else if (bounds.isEmpty || !bounds.forall(_.isBoundedBothSides)) {
102       None
103     } else {
104       // there should be no duplicates in covered partitions, as our bounds will not overlap,
105       // but there may be multiple partial intersects with a given partition
106       val covered = ListBuffer.empty[String]
107       val intersecting = ListBuffer.empty[String]
108 
109       bounds.values.foreach { bound =>
110         // note: we verified both sides are bounded above
111         val lower = bound.lower.value.get
112         val upper = bound.upper.value.get
113         val start = truncate(lower)
114         // `stepUnit.between` claims to be upper endpoint exclusive, but doesn't seem to be...
115         // if exclusive end, subtract one milli so we don't search the whole next partition if it's on the endpoint
116         // note: we only support millisecond resolution
117         val end = truncate(if (bound.upper.inclusive) { upper } else { upper.minus(1, MILLIS) })
118         val steps = stepUnit.between(start, end).toInt
119 
120         // do our endpoints match the partition boundary, or do we need to apply a filter to the first/last partition?
121         val coveringFirst = bound.lower.inclusive && lower == start
122         val coveringLast =
123           (bound.upper.exclusive && upper == end.plus(1, stepUnit)) ||
124               (bound.upper.inclusive && !upper.isBefore(end.plus(1, stepUnit).minus(1, MILLIS)))
125 
126         if (steps == 0) {
127           if (coveringFirst && coveringLast) {
128             covered += formatter.format(start)
129           } else {
130             intersecting += formatter.format(start)
131           }
132         } else {
133           // add the first partition
134           if (coveringFirst) {
135             covered += formatter.format(start)
136           } else {
137             intersecting += formatter.format(start)
138           }
139 
140           @tailrec
141           def addSteps(step: Int, current: ZonedDateTime): Unit = {
142             if (step == steps) {
143               // last partition
144               if (coveringLast) {
145                 covered += formatter.format(current)
146               } else {
147                 intersecting += formatter.format(current)
148               }
149             } else {
150               covered += formatter.format(current)
151               addSteps(step + 1, current.plus(1, stepUnit))
152             }
153           }
154 
155           addSteps(1, start.plus(1, stepUnit))
156         }
157       }
158 
159       Some((covered.toSeq, intersecting.toSeq))
160     }
161   }
162 }
163 
164 object DateTimeScheme {
165 
166   val Name = "datetime"
167 
168   def apply(format: String, stepUnit: ChronoUnit, step: Int, dtg: String, dtgIndex: Int): DateTimeScheme =
169     DateTimeScheme(DateTimeFormatter.ofPattern(format), format, stepUnit, step, dtg, dtgIndex)
170 
171   @deprecated("Pattern is not correct when using this constructor")
172   def apply(formatter: DateTimeFormatter, stepUnit: ChronoUnit, step: Int, dtg: String, dtgIndex: Int): DateTimeScheme =
173     DateTimeScheme(formatter, formatter.toString, stepUnit, step, dtg, dtgIndex)
174 
175   object Config {
176     val DateTimeFormatOpt: String = "datetime-format"
177     val StepUnitOpt      : String = "step-unit"
178     val StepOpt          : String = "step"
179     val DtgAttribute     : String = "dtg-attribute"
180   }
181 
182   object Formats {
183 
184     def apply(name: String): Option[Format] = all.find(_.name.equalsIgnoreCase(name))
185 
186     case class Format private[Formats](name: String, formatter: DateTimeFormatter, pattern: String, unit: ChronoUnit)
187 
188     private[Formats] object Format {
189       def apply(name: String, format: String, unit: ChronoUnit): Format =
190         Format(name, DateTimeFormatter.ofPattern(format), format, unit)
191     }
192 
193     val Minute       : Format = Format("minute",        "yyyy/MM/dd/HH/mm", ChronoUnit.MINUTES)
194     val Hourly       : Format = Format("hourly",        "yyyy/MM/dd/HH",    ChronoUnit.HOURS  )
195     val Daily        : Format = Format("daily",         "yyyy/MM/dd",       ChronoUnit.DAYS   )
196     val Monthly      : Format = Format("monthly",       "yyyy/MM",          ChronoUnit.MONTHS )
197     val JulianMinute : Format = Format("julian-minute", "yyyy/DDD/HH/mm",   ChronoUnit.MINUTES)
198     val JulianHourly : Format = Format("julian-hourly", "yyyy/DDD/HH",      ChronoUnit.HOURS  )
199     val JulianDaily  : Format = Format("julian-daily",  "yyyy/DDD",         ChronoUnit.DAYS   )
200 
201     // java.time doesn't seem to have a way to parse back out a year/week format...
202     // to get around that we have to define the default day of week in the formatter
203     val Weekly: Format = {
204       val formatter =
205         new DateTimeFormatterBuilder()
206           .appendValue(WeekFields.ISO.weekBasedYear(), 4)
207           .appendLiteral("/W")
208           .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2)
209           .parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
210           .toFormatter()
211       Format("weekly", formatter, "YYYY/'W'ww", ChronoUnit.WEEKS)
212     }
213 
214     private val all = Seq(Minute, Hourly, Daily, Weekly, Monthly, JulianMinute, JulianHourly, JulianDaily)
215   }
216 
217   class DateTimePartitionSchemeFactory extends PartitionSchemeFactory {
218     override def load(sft: SimpleFeatureType, config: NamedOptions): Option[PartitionScheme] = {
219       import org.locationtech.geomesa.utils.geotools.RichSimpleFeatureType.RichSimpleFeatureType
220 
221       lazy val step = config.options.get(Config.StepOpt).map(_.toInt).getOrElse(1)
222       lazy val dtg = config.options.get(Config.DtgAttribute).orElse(sft.getDtgField).getOrElse {
223         throw new IllegalArgumentException(s"DateTime scheme requires valid attribute '${Config.DtgAttribute}'")
224       }
225       lazy val dtgIndex = Some(sft.indexOf(dtg)).filter(_ != -1).getOrElse {
226         throw new IllegalArgumentException(s"Attribute '$dtg' does not exist in feature type ${sft.getTypeName}")
227       }
228 
229       if (config.name == Name) {
230         val unit = config.options.get(Config.StepUnitOpt).map(c => ChronoUnit.valueOf(c.toUpperCase)).getOrElse {
231           throw new IllegalArgumentException(s"DateTime scheme requires valid unit '${Config.StepUnitOpt}'")
232         }
233         val format = config.options.getOrElse(Config.DateTimeFormatOpt,
234           throw new IllegalArgumentException(s"DateTime scheme requires valid format '${Config.DateTimeFormatOpt}'"))
235         require(!format.endsWith("/"), "Format cannot end with a slash")
236         val formatter = try { DateTimeFormatter.ofPattern(format) } catch {
237           case NonFatal(e) => throw new IllegalArgumentException(s"Invalid date format '$format':", e)
238         }
239         Some(DateTimeScheme(formatter, format, unit, step, dtg, dtgIndex))
240       } else {
241         Formats(config.name).map(f => DateTimeScheme(f.formatter, f.pattern, f.unit, step, dtg, dtgIndex))
242       }
243     }
244   }
245 }
Line Stmt Id Pos Tree Symbol Tests Code
42 3377 1800 - 1808 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
44 3378 1915 - 1923 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
44 3379 1900 - 1924 Apply java.time.ZonedDateTime.truncatedTo dt.truncatedTo(DateTimeScheme.this.stepUnit)
44 3380 1894 - 1924 Function org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.$anonfun ((dt: java.time.ZonedDateTime) => dt.truncatedTo(DateTimeScheme.this.stepUnit))
46 3383 1942 - 2051 Block <nosymbol> { val adjuster: java.time.temporal.TemporalAdjuster = java.time.temporal.TemporalAdjusters.firstDayOfMonth(); ((dt: java.time.ZonedDateTime) => dt.`with`(adjuster).truncatedTo(DAYS)) }
47 3381 1966 - 2001 Apply java.time.temporal.TemporalAdjusters.firstDayOfMonth java.time.temporal.TemporalAdjusters.firstDayOfMonth()
48 3382 2014 - 2051 Apply java.time.ZonedDateTime.truncatedTo dt.`with`(adjuster).truncatedTo(DAYS)
50 3386 2068 - 2176 Block <nosymbol> { val adjuster: java.time.temporal.TemporalAdjuster = java.time.temporal.TemporalAdjusters.firstDayOfYear(); ((dt: java.time.ZonedDateTime) => dt.`with`(adjuster).truncatedTo(DAYS)) }
51 3384 2092 - 2126 Apply java.time.temporal.TemporalAdjusters.firstDayOfYear java.time.temporal.TemporalAdjusters.firstDayOfYear()
52 3385 2139 - 2176 Apply java.time.ZonedDateTime.truncatedTo dt.`with`(adjuster).truncatedTo(DAYS)
55 3387 2222 - 2242 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(dt)
55 3388 2244 - 2253 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.formatter DateTimeScheme.this.formatter
55 3389 2204 - 2254 Apply org.locationtech.geomesa.utils.text.DateParsing.parse org.locationtech.geomesa.utils.text.DateParsing.parse(DateTimeScheme.this.formatter.format(dt), DateTimeScheme.this.formatter)
55 3390 2198 - 2254 Function org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.$anonfun ((dt: java.time.ZonedDateTime) => org.locationtech.geomesa.utils.text.DateParsing.parse(DateTimeScheme.this.formatter.format(dt), DateTimeScheme.this.formatter))
60 3391 2445 - 2472 Apply scala.Int.+ scala.Predef.augmentString(DateTimeScheme.this.pattern).count(((x$1: Char) => x$1.==('/'))).+(1)
63 3392 2592 - 2600 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.dtgIndex DateTimeScheme.this.dtgIndex
63 3393 2571 - 2620 TypeApply scala.Any.asInstanceOf feature.getAttribute(DateTimeScheme.this.dtgIndex).asInstanceOf[java.util.Date]
63 3394 2629 - 2643 Select java.time.ZoneOffset.UTC java.time.ZoneOffset.UTC
63 3395 2561 - 2644 Apply java.time.Instant.atZone org.locationtech.geomesa.utils.date.DateUtils.toInstant(feature.getAttribute(DateTimeScheme.this.dtgIndex).asInstanceOf[java.util.Date]).atZone(java.time.ZoneOffset.UTC)
63 3396 2544 - 2645 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(org.locationtech.geomesa.utils.date.DateUtils.toInstant(feature.getAttribute(DateTimeScheme.this.dtgIndex).asInstanceOf[java.util.Date]).atZone(java.time.ZoneOffset.UTC))
66 3429 2830 - 3562 Block <nosymbol> { val result: scala.collection.mutable.Builder[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter,Seq[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]] = scala.collection.Seq.newBuilder[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]; if (covered.nonEmpty) { val coveredFilter: Option[org.geotools.api.filter.Filter] = { <artifact> val x$1: Seq[org.geotools.api.filter.Filter] @scala.reflect.internal.annotations.uncheckedBounds = org.locationtech.geomesa.filter.`package`.partitionSubFilters(filter, ((x$2: org.geotools.api.filter.Filter) => org.locationtech.geomesa.filter.`package`.isTemporalFilter(x$2, DateTimeScheme.this.dtg)))._2; <artifact> val x$2: org.geotools.api.filter.FilterFactory = org.locationtech.geomesa.filter.`package`.andOption$default$2(x$1); org.locationtech.geomesa.filter.`package`.andOption(x$1)(x$2) }; result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE), covered, false)) } else (); if (intersecting.nonEmpty) result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(filter, intersecting.distinct, false)) else (); partition match { case scala.None => result.result() case (value: String)Some[String]((p @ _)) => { val matched: Option[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter] = result.result().find(((x$3: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => x$3.partitions.contains[String](p))); scala.this.Option.option2Iterable[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](matched.map[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](((x$4: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => { <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = scala.collection.Seq.apply[String](p); <artifact> val x$4: org.geotools.api.filter.Filter = x$4.copy$default$1; <artifact> val x$5: Boolean = x$4.copy$default$3; x$4.copy(x$4, x$3, x$5) }))).toSeq } } }
66 3430 2765 - 3568 Apply scala.Option.map DateTimeScheme.this.getCoveringPartitions(filter).map[Seq[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]](((x0$1: (Seq[String], Seq[String])) => x0$1 match { case (_1: Seq[String], _2: Seq[String])(Seq[String], Seq[String])((covered @ _), (intersecting @ _)) => { val result: scala.collection.mutable.Builder[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter,Seq[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]] = scala.collection.Seq.newBuilder[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]; if (covered.nonEmpty) { val coveredFilter: Option[org.geotools.api.filter.Filter] = { <artifact> val x$1: Seq[org.geotools.api.filter.Filter] @scala.reflect.internal.annotations.uncheckedBounds = org.locationtech.geomesa.filter.`package`.partitionSubFilters(filter, ((x$2: org.geotools.api.filter.Filter) => org.locationtech.geomesa.filter.`package`.isTemporalFilter(x$2, DateTimeScheme.this.dtg)))._2; <artifact> val x$2: org.geotools.api.filter.FilterFactory = org.locationtech.geomesa.filter.`package`.andOption$default$2(x$1); org.locationtech.geomesa.filter.`package`.andOption(x$1)(x$2) }; result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE), covered, false)) } else (); if (intersecting.nonEmpty) result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(filter, intersecting.distinct, false)) else (); partition match { case scala.None => result.result() case (value: String)Some[String]((p @ _)) => { val matched: Option[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter] = result.result().find(((x$3: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => x$3.partitions.contains[String](p))); scala.this.Option.option2Iterable[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](matched.map[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](((x$4: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => { <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = scala.collection.Seq.apply[String](p); <artifact> val x$4: org.geotools.api.filter.Filter = x$4.copy$default$1; <artifact> val x$5: Boolean = x$4.copy$default$3; x$4.copy(x$4, x$3, x$5) }))).toSeq } } } }))
67 3397 2852 - 2884 TypeApply scala.collection.Seq.newBuilder scala.collection.Seq.newBuilder[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter]
69 3398 2896 - 2912 Select scala.collection.TraversableOnce.nonEmpty covered.nonEmpty
69 3409 2914 - 3218 Block <nosymbol> { val coveredFilter: Option[org.geotools.api.filter.Filter] = { <artifact> val x$1: Seq[org.geotools.api.filter.Filter] @scala.reflect.internal.annotations.uncheckedBounds = org.locationtech.geomesa.filter.`package`.partitionSubFilters(filter, ((x$2: org.geotools.api.filter.Filter) => org.locationtech.geomesa.filter.`package`.isTemporalFilter(x$2, DateTimeScheme.this.dtg)))._2; <artifact> val x$2: org.geotools.api.filter.FilterFactory = org.locationtech.geomesa.filter.`package`.andOption$default$2(x$1); org.locationtech.geomesa.filter.`package`.andOption(x$1)(x$2) }; result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE), covered, false)) }
69 3410 2892 - 2892 Literal <nosymbol> ()
69 3411 2892 - 2892 Block <nosymbol> ()
71 3399 3099 - 3102 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.dtg DateTimeScheme.this.dtg
71 3400 3079 - 3103 Apply org.locationtech.geomesa.filter.isTemporalFilter org.locationtech.geomesa.filter.`package`.isTemporalFilter(x$2, DateTimeScheme.this.dtg)
71 3401 3051 - 3107 Select scala.Tuple2._2 org.locationtech.geomesa.filter.`package`.partitionSubFilters(filter, ((x$2: org.geotools.api.filter.Filter) => org.locationtech.geomesa.filter.`package`.isTemporalFilter(x$2, DateTimeScheme.this.dtg)))._2
71 3402 3050 - 3050 Apply org.locationtech.geomesa.filter.andOption$default$2 org.locationtech.geomesa.filter.`package`.andOption$default$2(x$1)
71 3403 3041 - 3108 ApplyToImplicitArgs org.locationtech.geomesa.filter.andOption org.locationtech.geomesa.filter.`package`.andOption(x$1)(x$2)
72 3404 3168 - 3182 Select org.geotools.api.filter.Filter.INCLUDE org.geotools.api.filter.Filter.INCLUDE
72 3405 3144 - 3183 Apply scala.Option.getOrElse coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE)
72 3406 3204 - 3209 Literal <nosymbol> false
72 3407 3127 - 3210 Apply org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE), covered, false)
72 3408 3117 - 3210 Apply scala.collection.mutable.Builder.+= result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(coveredFilter.getOrElse[org.geotools.api.filter.Filter](org.geotools.api.filter.Filter.INCLUDE), covered, false))
74 3412 3229 - 3250 Select scala.collection.TraversableOnce.nonEmpty intersecting.nonEmpty
74 3418 3225 - 3225 Literal <nosymbol> ()
74 3419 3225 - 3225 Block <nosymbol> ()
75 3413 3297 - 3318 Select scala.collection.SeqLike.distinct intersecting.distinct
75 3414 3330 - 3335 Literal <nosymbol> false
75 3415 3272 - 3336 Apply org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(filter, intersecting.distinct, false)
75 3416 3262 - 3336 Apply scala.collection.mutable.Builder.+= result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(filter, intersecting.distinct, false))
75 3417 3262 - 3336 Block scala.collection.mutable.Builder.+= result.+=(org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.apply(filter, intersecting.distinct, false))
79 3420 3391 - 3404 Apply scala.collection.mutable.Builder.result result.result()
79 3421 3391 - 3404 Block scala.collection.mutable.Builder.result result.result()
80 3428 3426 - 3554 Block <nosymbol> { val matched: Option[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter] = result.result().find(((x$3: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => x$3.partitions.contains[String](p))); scala.this.Option.option2Iterable[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](matched.map[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](((x$4: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => { <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = scala.collection.Seq.apply[String](p); <artifact> val x$4: org.geotools.api.filter.Filter = x$4.copy$default$1; <artifact> val x$5: Boolean = x$4.copy$default$3; x$4.copy(x$4, x$3, x$5) }))).toSeq }
81 3422 3472 - 3496 Apply scala.collection.SeqLike.contains x$3.partitions.contains[String](p)
81 3423 3453 - 3497 Apply scala.collection.IterableLike.find result.result().find(((x$3: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => x$3.partitions.contains[String](p)))
82 3424 3540 - 3546 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[String](p)
82 3425 3520 - 3547 Apply org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter.copy x$4.copy(x$4, x$3, x$5)
82 3426 3508 - 3548 Apply scala.Option.map matched.map[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](((x$4: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => { <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = scala.collection.Seq.apply[String](p); <artifact> val x$4: org.geotools.api.filter.Filter = x$4.copy$default$1; <artifact> val x$5: Boolean = x$4.copy$default$3; x$4.copy(x$4, x$3, x$5) }))
82 3427 3508 - 3554 Select scala.collection.TraversableOnce.toSeq scala.this.Option.option2Iterable[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](matched.map[org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter](((x$4: org.locationtech.geomesa.fs.storage.api.PartitionScheme.SimplifiedFilter) => { <artifact> val x$3: Seq[String] @scala.reflect.internal.annotations.uncheckedBounds = scala.collection.Seq.apply[String](p); <artifact> val x$4: org.geotools.api.filter.Filter = x$4.copy$default$1; <artifact> val x$5: Boolean = x$4.copy$default$3; x$4.copy(x$4, x$3, x$5) }))).toSeq
88 3431 3734 - 3734 TypeApply scala.collection.Seq.canBuildFrom collection.this.Seq.canBuildFrom[String]
88 3432 3726 - 3749 ApplyToImplicitArgs scala.collection.TraversableLike.++ covered.++[String, Seq[String]](intersecting)(collection.this.Seq.canBuildFrom[String])
88 3433 3726 - 3749 Block scala.collection.TraversableLike.++ covered.++[String, Seq[String]](intersecting)(collection.this.Seq.canBuildFrom[String])
88 3434 3658 - 3751 Apply scala.Option.map DateTimeScheme.this.getCoveringPartitions(filter).map[Seq[String]](((x0$1: (Seq[String], Seq[String])) => x0$1 match { case (_1: Seq[String], _2: Seq[String])(Seq[String], Seq[String])((covered @ _), (intersecting @ _)) => covered.++[String, Seq[String]](intersecting)(collection.this.Seq.canBuildFrom[String]) }))
91 3435 3860 - 3869 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.formatter DateTimeScheme.this.formatter
91 3436 3831 - 3870 Apply org.locationtech.geomesa.utils.text.DateParsing.parse org.locationtech.geomesa.utils.text.DateParsing.parse(partition, DateTimeScheme.this.formatter)
92 3437 3887 - 3910 Apply org.locationtech.geomesa.utils.text.DateParsing.format org.locationtech.geomesa.utils.text.DateParsing.format(zdt, org.locationtech.geomesa.utils.text.DateParsing.format$default$2)
93 3438 3953 - 3954 Literal <nosymbol> 1L
93 3439 3956 - 3964 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
93 3440 3944 - 3965 Apply java.time.ZonedDateTime.plus zdt.plus(1L, DateTimeScheme.this.stepUnit)
93 3441 3925 - 3966 Apply org.locationtech.geomesa.utils.text.DateParsing.format org.locationtech.geomesa.utils.text.DateParsing.format(zdt.plus(1L, DateTimeScheme.this.stepUnit), org.locationtech.geomesa.utils.text.DateParsing.format$default$2)
94 3442 4008 - 4011 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.dtg DateTimeScheme.this.dtg
94 3443 3996 - 4012 Apply org.geotools.api.filter.FilterFactory.property org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg)
94 3444 4014 - 4031 Apply org.geotools.api.filter.FilterFactory.literal org.locationtech.geomesa.filter.FilterHelper.ff.literal(start)
94 3445 3978 - 4032 Apply org.geotools.api.filter.FilterFactory.greaterOrEqual org.locationtech.geomesa.filter.FilterHelper.ff.greaterOrEqual(org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg), org.locationtech.geomesa.filter.FilterHelper.ff.literal(start))
94 3446 4054 - 4057 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.dtg DateTimeScheme.this.dtg
94 3447 4042 - 4058 Apply org.geotools.api.filter.FilterFactory.property org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg)
94 3448 4060 - 4075 Apply org.geotools.api.filter.FilterFactory.literal org.locationtech.geomesa.filter.FilterHelper.ff.literal(end)
94 3449 4034 - 4076 Apply org.geotools.api.filter.FilterFactory.less org.locationtech.geomesa.filter.FilterHelper.ff.less(org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg), org.locationtech.geomesa.filter.FilterHelper.ff.literal(end))
94 3450 3971 - 4077 Apply org.geotools.api.filter.FilterFactory.and org.locationtech.geomesa.filter.FilterHelper.ff.and(org.locationtech.geomesa.filter.FilterHelper.ff.greaterOrEqual(org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg), org.locationtech.geomesa.filter.FilterHelper.ff.literal(start)), org.locationtech.geomesa.filter.FilterHelper.ff.less(org.locationtech.geomesa.filter.FilterHelper.ff.property(DateTimeScheme.this.dtg), org.locationtech.geomesa.filter.FilterHelper.ff.literal(end)))
98 3451 4230 - 4233 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.dtg DateTimeScheme.this.dtg
98 3452 4259 - 4264 Literal <nosymbol> false
98 3453 4192 - 4265 Apply org.locationtech.geomesa.filter.FilterHelper.extractIntervals org.locationtech.geomesa.filter.FilterHelper.extractIntervals(x$1, x$2, x$4, x$3)
99 3454 4274 - 4289 Select org.locationtech.geomesa.filter.FilterValues.disjoint bounds.disjoint
100 3455 4305 - 4314 TypeApply scala.collection.generic.GenericCompanion.empty scala.collection.Seq.empty[Nothing]
100 3456 4316 - 4325 TypeApply scala.collection.generic.GenericCompanion.empty scala.collection.Seq.empty[Nothing]
100 3457 4304 - 4326 Apply scala.Tuple2.apply scala.Tuple2.apply[Seq[Nothing], Seq[Nothing]](scala.collection.Seq.empty[Nothing], scala.collection.Seq.empty[Nothing])
100 3458 4299 - 4327 Apply scala.Some.apply scala.Some.apply[(Seq[Nothing], Seq[Nothing])](scala.Tuple2.apply[Seq[Nothing], Seq[Nothing]](scala.collection.Seq.empty[Nothing], scala.collection.Seq.empty[Nothing]))
100 3459 4299 - 4327 Block scala.Some.apply scala.Some.apply[(Seq[Nothing], Seq[Nothing])](scala.Tuple2.apply[Seq[Nothing], Seq[Nothing]](scala.collection.Seq.empty[Nothing], scala.collection.Seq.empty[Nothing]))
101 3460 4376 - 4396 Select org.locationtech.geomesa.filter.Bounds.isBoundedBothSides x$5.isBoundedBothSides
101 3461 4361 - 4397 Select scala.Boolean.unary_! bounds.forall(((x$5: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => x$5.isBoundedBothSides)).unary_!
101 3462 4343 - 4397 Apply scala.Boolean.|| bounds.isEmpty.||(bounds.forall(((x$5: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => x$5.isBoundedBothSides)).unary_!)
101 3531 4339 - 6745 If <nosymbol> if (bounds.isEmpty.||(bounds.forall(((x$5: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => x$5.isBoundedBothSides)).unary_!)) scala.None else { val covered: scala.collection.mutable.ListBuffer[String] = scala.collection.mutable.ListBuffer.empty[String]; val intersecting: scala.collection.mutable.ListBuffer[String] = scala.collection.mutable.ListBuffer.empty[String]; bounds.values.foreach[Any](((bound: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => { val lower: java.time.ZonedDateTime = bound.lower.value.get; val upper: java.time.ZonedDateTime = bound.upper.value.get; val start: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(lower); val end: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(if (bound.upper.inclusive) upper else upper.minus(1L, MILLIS)); val steps: Int = DateTimeScheme.this.stepUnit.between(start, end).toInt; val coveringFirst: Boolean = bound.lower.inclusive.&&(lower.==(start)); val coveringLast: Boolean = bound.upper.exclusive.&&(upper.==(end.plus(1L, DateTimeScheme.this.stepUnit))).||(bound.upper.inclusive.&&(upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!)); if (steps.==(0)) if (coveringFirst.&&(coveringLast)) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)) else { if (coveringFirst) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)); @scala.annotation.tailrec def addSteps(step: Int, current: java.time.ZonedDateTime): Unit = if (step.==(steps)) if (coveringLast) { covered.+=(DateTimeScheme.this.formatter.format(current)); () } else { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () } else { covered.+=(DateTimeScheme.this.formatter.format(current)); addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit)) }; addSteps(1, start.plus(1L, DateTimeScheme.this.stepUnit)) } })); scala.Some.apply[(Seq[String], Seq[String])](scala.Tuple2.apply[Seq[String], Seq[String]](covered.toSeq, intersecting.toSeq)) }
102 3463 4407 - 4411 Select scala.None scala.None
102 3464 4407 - 4411 Block scala.None scala.None
103 3530 4423 - 6745 Block <nosymbol> { val covered: scala.collection.mutable.ListBuffer[String] = scala.collection.mutable.ListBuffer.empty[String]; val intersecting: scala.collection.mutable.ListBuffer[String] = scala.collection.mutable.ListBuffer.empty[String]; bounds.values.foreach[Any](((bound: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => { val lower: java.time.ZonedDateTime = bound.lower.value.get; val upper: java.time.ZonedDateTime = bound.upper.value.get; val start: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(lower); val end: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(if (bound.upper.inclusive) upper else upper.minus(1L, MILLIS)); val steps: Int = DateTimeScheme.this.stepUnit.between(start, end).toInt; val coveringFirst: Boolean = bound.lower.inclusive.&&(lower.==(start)); val coveringLast: Boolean = bound.upper.exclusive.&&(upper.==(end.plus(1L, DateTimeScheme.this.stepUnit))).||(bound.upper.inclusive.&&(upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!)); if (steps.==(0)) if (coveringFirst.&&(coveringLast)) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)) else { if (coveringFirst) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)); @scala.annotation.tailrec def addSteps(step: Int, current: java.time.ZonedDateTime): Unit = if (step.==(steps)) if (coveringLast) { covered.+=(DateTimeScheme.this.formatter.format(current)); () } else { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () } else { covered.+=(DateTimeScheme.this.formatter.format(current)); addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit)) }; addSteps(1, start.plus(1L, DateTimeScheme.this.stepUnit)) } })); scala.Some.apply[(Seq[String], Seq[String])](scala.Tuple2.apply[Seq[String], Seq[String]](covered.toSeq, intersecting.toSeq)) }
106 3465 4616 - 4640 TypeApply scala.collection.generic.GenericCompanion.empty scala.collection.mutable.ListBuffer.empty[String]
107 3466 4666 - 4690 TypeApply scala.collection.generic.GenericCompanion.empty scala.collection.mutable.ListBuffer.empty[String]
109 3525 4698 - 6690 Apply scala.collection.IterableLike.foreach bounds.values.foreach[Any](((bound: org.locationtech.geomesa.filter.Bounds[java.time.ZonedDateTime]) => { val lower: java.time.ZonedDateTime = bound.lower.value.get; val upper: java.time.ZonedDateTime = bound.upper.value.get; val start: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(lower); val end: java.time.ZonedDateTime = DateTimeScheme.this.truncate.apply(if (bound.upper.inclusive) upper else upper.minus(1L, MILLIS)); val steps: Int = DateTimeScheme.this.stepUnit.between(start, end).toInt; val coveringFirst: Boolean = bound.lower.inclusive.&&(lower.==(start)); val coveringLast: Boolean = bound.upper.exclusive.&&(upper.==(end.plus(1L, DateTimeScheme.this.stepUnit))).||(bound.upper.inclusive.&&(upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!)); if (steps.==(0)) if (coveringFirst.&&(coveringLast)) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)) else { if (coveringFirst) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)); @scala.annotation.tailrec def addSteps(step: Int, current: java.time.ZonedDateTime): Unit = if (step.==(steps)) if (coveringLast) { covered.+=(DateTimeScheme.this.formatter.format(current)); () } else { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () } else { covered.+=(DateTimeScheme.this.formatter.format(current)); addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit)) }; addSteps(1, start.plus(1L, DateTimeScheme.this.stepUnit)) } }))
111 3467 4809 - 4830 Select scala.Option.get bound.lower.value.get
112 3468 4851 - 4872 Select scala.Option.get bound.upper.value.get
113 3469 4893 - 4908 Apply scala.Function1.apply DateTimeScheme.this.truncate.apply(lower)
117 3470 5207 - 5228 Select org.locationtech.geomesa.filter.Bounds.Bound.inclusive bound.upper.inclusive
117 3471 5232 - 5237 Ident org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.upper upper
117 3472 5247 - 5269 Apply java.time.ZonedDateTime.minus upper.minus(1L, MILLIS)
117 3473 5247 - 5269 Block java.time.ZonedDateTime.minus upper.minus(1L, MILLIS)
117 3474 5194 - 5272 Apply scala.Function1.apply DateTimeScheme.this.truncate.apply(if (bound.upper.inclusive) upper else upper.minus(1L, MILLIS))
118 3475 5293 - 5327 Select scala.Long.toInt DateTimeScheme.this.stepUnit.between(start, end).toInt
121 3476 5501 - 5515 Apply java.lang.Object.== lower.==(start)
121 3477 5476 - 5515 Apply scala.Boolean.&& bound.lower.inclusive.&&(lower.==(start))
123 3478 5597 - 5598 Literal <nosymbol> 1L
123 3479 5600 - 5608 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
123 3480 5588 - 5609 Apply java.time.ZonedDateTime.plus end.plus(1L, DateTimeScheme.this.stepUnit)
123 3481 5579 - 5609 Apply java.lang.Object.== upper.==(end.plus(1L, DateTimeScheme.this.stepUnit))
123 3485 5553 - 5710 Apply scala.Boolean.|| bound.upper.exclusive.&&(upper.==(end.plus(1L, DateTimeScheme.this.stepUnit))).||(bound.upper.inclusive.&&(upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!))
124 3482 5670 - 5708 Apply java.time.ZonedDateTime.minus end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)
124 3483 5654 - 5709 Select scala.Boolean.unary_! upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!
124 3484 5629 - 5709 Apply scala.Boolean.&& bound.upper.inclusive.&&(upper.isBefore(end.plus(1L, DateTimeScheme.this.stepUnit).minus(1L, MILLIS)).unary_!)
126 3486 5724 - 5734 Apply scala.Int.== steps.==(0)
127 3487 5752 - 5781 Apply scala.Boolean.&& coveringFirst.&&(coveringLast)
127 3494 5748 - 5914 If <nosymbol> if (coveringFirst.&&(coveringLast)) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start))
128 3488 5808 - 5831 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(start)
128 3489 5797 - 5831 Apply scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(start))
128 3490 5797 - 5831 Block scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(start))
130 3491 5879 - 5902 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(start)
130 3492 5863 - 5902 Apply scala.collection.mutable.ListBuffer.+= intersecting.+=(DateTimeScheme.this.formatter.format(start))
130 3493 5863 - 5902 Block scala.collection.mutable.ListBuffer.+= intersecting.+=(DateTimeScheme.this.formatter.format(start))
132 3524 5930 - 6682 Block <nosymbol> { if (coveringFirst) covered.+=(DateTimeScheme.this.formatter.format(start)) else intersecting.+=(DateTimeScheme.this.formatter.format(start)); @scala.annotation.tailrec def addSteps(step: Int, current: java.time.ZonedDateTime): Unit = if (step.==(steps)) if (coveringLast) { covered.+=(DateTimeScheme.this.formatter.format(current)); () } else { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () } else { covered.+=(DateTimeScheme.this.formatter.format(current)); addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit)) }; addSteps(1, start.plus(1L, DateTimeScheme.this.stepUnit)) }
135 3495 6023 - 6046 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(start)
135 3496 6012 - 6046 Apply scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(start))
135 3497 6012 - 6046 Block scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(start))
137 3498 6094 - 6117 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(start)
137 3499 6078 - 6117 Apply scala.collection.mutable.ListBuffer.+= intersecting.+=(DateTimeScheme.this.formatter.format(start))
137 3500 6078 - 6117 Block scala.collection.mutable.ListBuffer.+= intersecting.+=(DateTimeScheme.this.formatter.format(start))
142 3501 6234 - 6247 Apply scala.Int.== step.==(steps)
144 3510 6297 - 6466 If <nosymbol> if (coveringLast) { covered.+=(DateTimeScheme.this.formatter.format(current)); () } else { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () }
145 3502 6344 - 6369 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(current)
145 3503 6333 - 6369 Apply scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(current))
145 3504 6341 - 6341 Literal <nosymbol> ()
145 3505 6333 - 6369 Block <nosymbol> { covered.+=(DateTimeScheme.this.formatter.format(current)); () }
147 3506 6425 - 6450 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(current)
147 3507 6409 - 6450 Apply scala.collection.mutable.ListBuffer.+= intersecting.+=(DateTimeScheme.this.formatter.format(current))
147 3508 6422 - 6422 Literal <nosymbol> ()
147 3509 6409 - 6450 Block <nosymbol> { intersecting.+=(DateTimeScheme.this.formatter.format(current)); () }
149 3518 6486 - 6612 Block <nosymbol> { covered.+=(DateTimeScheme.this.formatter.format(current)); addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit)) }
150 3511 6513 - 6538 Apply java.time.format.DateTimeFormatter.format DateTimeScheme.this.formatter.format(current)
150 3512 6502 - 6538 Apply scala.collection.mutable.ListBuffer.+= covered.+=(DateTimeScheme.this.formatter.format(current))
151 3513 6562 - 6570 Apply scala.Int.+ step.+(1)
151 3514 6585 - 6586 Literal <nosymbol> 1L
151 3515 6588 - 6596 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
151 3516 6572 - 6597 Apply java.time.ZonedDateTime.plus current.plus(1L, DateTimeScheme.this.stepUnit)
151 3517 6553 - 6598 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.addSteps addSteps(step.+(1), current.plus(1L, DateTimeScheme.this.stepUnit))
155 3519 6645 - 6646 Literal <nosymbol> 1
155 3520 6659 - 6660 Literal <nosymbol> 1L
155 3521 6662 - 6670 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.stepUnit DateTimeScheme.this.stepUnit
155 3522 6648 - 6671 Apply java.time.ZonedDateTime.plus start.plus(1L, DateTimeScheme.this.stepUnit)
155 3523 6636 - 6672 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.addSteps addSteps(1, start.plus(1L, DateTimeScheme.this.stepUnit))
159 3526 6704 - 6717 Select scala.collection.mutable.ListBuffer.toSeq covered.toSeq
159 3527 6719 - 6737 Select scala.collection.mutable.ListBuffer.toSeq intersecting.toSeq
159 3528 6703 - 6738 Apply scala.Tuple2.apply scala.Tuple2.apply[Seq[String], Seq[String]](covered.toSeq, intersecting.toSeq)
159 3529 6698 - 6739 Apply scala.Some.apply scala.Some.apply[(Seq[String], Seq[String])](scala.Tuple2.apply[Seq[String], Seq[String]](covered.toSeq, intersecting.toSeq))
166 3532 6791 - 6801 Literal <nosymbol> "datetime"
169 3533 6929 - 6964 Apply java.time.format.DateTimeFormatter.ofPattern java.time.format.DateTimeFormatter.ofPattern(format)
169 3534 6914 - 7004 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.apply DateTimeScheme.apply(java.time.format.DateTimeFormatter.ofPattern(format), format, stepUnit, step, dtg, dtgIndex)
173 3535 7225 - 7243 Apply java.time.format.DateTimeFormatter.toString formatter.toString()
173 3536 7199 - 7275 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.apply DateTimeScheme.apply(formatter, formatter.toString(), stepUnit, step, dtg, dtgIndex)
176 3537 7331 - 7348 Literal <nosymbol> "datetime-format"
177 3538 7385 - 7396 Literal <nosymbol> "step-unit"
178 3539 7433 - 7439 Literal <nosymbol> "step"
179 3540 7476 - 7491 Literal <nosymbol> "dtg-attribute"
184 3541 7572 - 7601 Apply java.lang.String.equalsIgnoreCase x$6.name.equalsIgnoreCase(name)
184 3542 7563 - 7602 Apply scala.collection.IterableLike.find Formats.this.all.find(((x$6: org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format) => x$6.name.equalsIgnoreCase(name)))
190 3543 7855 - 7890 Apply java.time.format.DateTimeFormatter.ofPattern java.time.format.DateTimeFormatter.ofPattern(format)
190 3544 7842 - 7905 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply(name, java.time.format.DateTimeFormatter.ofPattern(format), format, unit)
193 3545 7945 - 8008 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("minute", "yyyy/MM/dd/HH/mm", MINUTES)
194 3546 8041 - 8104 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("hourly", "yyyy/MM/dd/HH", HOURS)
195 3547 8137 - 8200 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("daily", "yyyy/MM/dd", DAYS)
196 3548 8233 - 8296 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("monthly", "yyyy/MM", MONTHS)
197 3549 8329 - 8392 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("julian-minute", "yyyy/DDD/HH/mm", MINUTES)
198 3550 8425 - 8488 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("julian-hourly", "yyyy/DDD/HH", HOURS)
199 3551 8521 - 8584 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("julian-daily", "yyyy/DDD", DAYS)
210 3552 8812 - 9075 Apply java.time.format.DateTimeFormatterBuilder.toFormatter new java.time.format.DateTimeFormatterBuilder().appendValue(java.time.temporal.WeekFields.ISO.weekBasedYear(), 4).appendLiteral("/W").appendValue(java.time.temporal.WeekFields.ISO.weekOfWeekBasedYear(), 2).parseDefaulting(DAY_OF_WEEK, 1L).toFormatter()
211 3553 9082 - 9141 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.apply Formats.this.Format.apply("weekly", formatter, "YYYY/\'W\'ww", WEEKS)
214 3554 9175 - 9181 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Minute Formats.this.Minute
214 3555 9183 - 9189 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Hourly Formats.this.Hourly
214 3556 9191 - 9196 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Daily Formats.this.Daily
214 3557 9198 - 9204 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Weekly Formats.this.Weekly
214 3558 9206 - 9213 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Monthly Formats.this.Monthly
214 3559 9215 - 9227 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.JulianMinute Formats.this.JulianMinute
214 3560 9229 - 9241 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.JulianHourly Formats.this.JulianHourly
214 3561 9243 - 9254 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.JulianDaily Formats.this.JulianDaily
214 3562 9171 - 9255 Apply scala.collection.generic.GenericCompanion.apply scala.collection.Seq.apply[org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format](Formats.this.Minute, Formats.this.Hourly, Formats.this.Daily, Formats.this.Weekly, Formats.this.Monthly, Formats.this.JulianMinute, Formats.this.JulianHourly, Formats.this.JulianDaily)
229 3563 10054 - 10058 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Name DateTimeScheme.this.Name
229 3564 10039 - 10058 Apply java.lang.Object.== config.name.==(DateTimeScheme.this.Name)
229 3583 10060 - 10829 Block <nosymbol> { val unit: java.time.temporal.ChronoUnit = config.options.get(DateTimeScheme.this.Config.StepUnitOpt).map[java.time.temporal.ChronoUnit](((c: String) => java.time.temporal.ChronoUnit.valueOf(c.toUpperCase()))).getOrElse[java.time.temporal.ChronoUnit](throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid unit \'", "\'").s(DateTimeScheme.this.Config.StepUnitOpt))); val format: String = config.options.getOrElse[String](DateTimeScheme.this.Config.DateTimeFormatOpt, throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid format \'", "\'").s(DateTimeScheme.this.Config.DateTimeFormatOpt))); scala.Predef.require(format.endsWith("/").unary_!, "Format cannot end with a slash"); val formatter: java.time.format.DateTimeFormatter = try { java.time.format.DateTimeFormatter.ofPattern(format) } catch { case scala.util.control.NonFatal.unapply(<unapply-selector>) <unapply> ((e @ _)) => throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("Invalid date format \'", "\':").s(format), e) }; scala.Some.apply[org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme](DateTimeScheme.apply(formatter, format, unit, step, dtg, dtgIndex)) }
230 3565 10100 - 10118 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Config.StepUnitOpt DateTimeScheme.this.Config.StepUnitOpt
230 3566 10148 - 10161 Apply java.lang.String.toUpperCase c.toUpperCase()
230 3567 10129 - 10162 Apply java.time.temporal.ChronoUnit.valueOf java.time.temporal.ChronoUnit.valueOf(c.toUpperCase())
230 3569 10081 - 10294 Apply scala.Option.getOrElse config.options.get(DateTimeScheme.this.Config.StepUnitOpt).map[java.time.temporal.ChronoUnit](((c: String) => java.time.temporal.ChronoUnit.valueOf(c.toUpperCase()))).getOrElse[java.time.temporal.ChronoUnit](throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid unit \'", "\'").s(DateTimeScheme.this.Config.StepUnitOpt)))
231 3568 10186 - 10284 Throw <nosymbol> throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid unit \'", "\'").s(DateTimeScheme.this.Config.StepUnitOpt))
233 3570 10341 - 10365 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Config.DateTimeFormatOpt DateTimeScheme.this.Config.DateTimeFormatOpt
233 3572 10316 - 10484 Apply scala.collection.MapLike.getOrElse config.options.getOrElse[String](DateTimeScheme.this.Config.DateTimeFormatOpt, throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid format \'", "\'").s(DateTimeScheme.this.Config.DateTimeFormatOpt)))
234 3571 10377 - 10483 Throw <nosymbol> throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("DateTime scheme requires valid format \'", "\'").s(DateTimeScheme.this.Config.DateTimeFormatOpt))
235 3573 10518 - 10521 Literal <nosymbol> "/"
235 3574 10501 - 10522 Select scala.Boolean.unary_! format.endsWith("/").unary_!
235 3575 10524 - 10556 Literal <nosymbol> "Format cannot end with a slash"
235 3576 10493 - 10557 Apply scala.Predef.require scala.Predef.require(format.endsWith("/").unary_!, "Format cannot end with a slash")
236 3577 10588 - 10623 Apply java.time.format.DateTimeFormatter.ofPattern java.time.format.DateTimeFormatter.ofPattern(format)
236 3578 10588 - 10623 Block java.time.format.DateTimeFormatter.ofPattern java.time.format.DateTimeFormatter.ofPattern(format)
237 3579 10664 - 10736 Throw <nosymbol> throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("Invalid date format \'", "\':").s(format), e)
237 3580 10664 - 10736 Block <nosymbol> throw new scala.`package`.IllegalArgumentException(scala.StringContext.apply("Invalid date format \'", "\':").s(format), e)
239 3581 10760 - 10820 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.apply DateTimeScheme.apply(formatter, format, unit, step, dtg, dtgIndex)
239 3582 10755 - 10821 Apply scala.Some.apply scala.Some.apply[org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme](DateTimeScheme.apply(formatter, format, unit, step, dtg, dtgIndex))
241 3584 10853 - 10864 Select org.locationtech.geomesa.fs.storage.api.NamedOptions.name config.name
241 3585 10890 - 10901 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.formatter f.formatter
241 3586 10903 - 10912 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.pattern f.pattern
241 3587 10914 - 10920 Select org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format.unit f.unit
241 3588 10875 - 10942 Apply org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.apply DateTimeScheme.apply(f.formatter, f.pattern, f.unit, step, dtg, dtgIndex)
241 3589 10845 - 10943 Apply scala.Option.map DateTimeScheme.this.Formats.apply(config.name).map[org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme](((f: org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format) => DateTimeScheme.apply(f.formatter, f.pattern, f.unit, step, dtg, dtgIndex)))
241 3590 10845 - 10943 Block scala.Option.map DateTimeScheme.this.Formats.apply(config.name).map[org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme](((f: org.locationtech.geomesa.fs.storage.common.partitions.DateTimeScheme.Formats.Format) => DateTimeScheme.apply(f.formatter, f.pattern, f.unit, step, dtg, dtgIndex)))