use special enum for DateBucket units
Preparation step for having custom intervals.
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
package org.lucares.pdb.datastore.internal;
|
package org.lucares.pdb.datastore.internal;
|
||||||
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
@@ -8,11 +7,12 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.lucares.pdb.api.DateTimeRange;
|
import org.lucares.pdb.api.DateTimeRange;
|
||||||
|
import org.lucares.utils.DateBucketUnit;
|
||||||
import org.lucares.utils.LongToDateBucket;
|
import org.lucares.utils.LongToDateBucket;
|
||||||
|
|
||||||
public class DateIndexExtension {
|
public class DateIndexExtension {
|
||||||
|
|
||||||
private static final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", ChronoUnit.MONTHS);
|
private static final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", DateBucketUnit.MONTH);
|
||||||
|
|
||||||
static Set<String> toDateIndexPrefix(final DateTimeRange dateRange) {
|
static Set<String> toDateIndexPrefix(final DateTimeRange dateRange) {
|
||||||
return longToDateBucket.toDateIndexPrefix(dateRange.getStart(), dateRange.getEnd());
|
return longToDateBucket.toDateIndexPrefix(dateRange.getStart(), dateRange.getEnd());
|
||||||
@@ -31,7 +31,7 @@ public class DateIndexExtension {
|
|||||||
*/
|
*/
|
||||||
static List<ParititionId> toPartitionIds(final DateTimeRange dateRange) {
|
static List<ParititionId> toPartitionIds(final DateTimeRange dateRange) {
|
||||||
final List<String> partitionIds = longToDateBucket.toPartitionIds(dateRange.getStart(), dateRange.getEnd(),
|
final List<String> partitionIds = longToDateBucket.toPartitionIds(dateRange.getStart(), dateRange.getEnd(),
|
||||||
ChronoUnit.MONTHS);
|
DateBucketUnit.MONTH);
|
||||||
|
|
||||||
final List<ParititionId> result = new ArrayList<>();
|
final List<ParititionId> result = new ArrayList<>();
|
||||||
for (final String partitionId : partitionIds) {
|
for (final String partitionId : partitionIds) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.lucares.pdb.plot.api;
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -10,38 +9,6 @@ import org.lucares.pdb.api.DateTimeRange;
|
|||||||
import org.lucares.utils.LongToDateBucket;
|
import org.lucares.utils.LongToDateBucket;
|
||||||
|
|
||||||
public class Interval {
|
public class Interval {
|
||||||
public enum IntervalTimeUnit {
|
|
||||||
MINUTE, HOUR, DAY, WEEK, MONTH, YEAR;
|
|
||||||
|
|
||||||
public static boolean isValid(final String value) {
|
|
||||||
for (final IntervalTimeUnit e : values()) {
|
|
||||||
if (e.name().equals(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChronoUnit toChronoUnit() {
|
|
||||||
switch (this) {
|
|
||||||
case MINUTE:
|
|
||||||
return ChronoUnit.MINUTES;
|
|
||||||
case HOUR:
|
|
||||||
return ChronoUnit.HOURS;
|
|
||||||
case DAY:
|
|
||||||
return ChronoUnit.DAYS;
|
|
||||||
case WEEK:
|
|
||||||
return ChronoUnit.WEEKS;
|
|
||||||
case MONTH:
|
|
||||||
return ChronoUnit.MONTHS;
|
|
||||||
case YEAR:
|
|
||||||
return ChronoUnit.YEARS;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("Unexpected value: " + this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final IntervalTimeUnit intervalTimeUnit;
|
private final IntervalTimeUnit intervalTimeUnit;
|
||||||
|
|
||||||
private final int value;
|
private final int value;
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.lucares.pdb.plot.api;
|
||||||
|
|
||||||
|
import org.lucares.utils.DateBucketUnit;
|
||||||
|
|
||||||
|
public enum IntervalTimeUnit {
|
||||||
|
MINUTE, HOUR, DAY, WEEK, MONTH, YEAR;
|
||||||
|
|
||||||
|
public static boolean isValid(final String value) {
|
||||||
|
for (final IntervalTimeUnit e : values()) {
|
||||||
|
if (e.name().equals(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateBucketUnit toChronoUnit() {
|
||||||
|
switch (this) {
|
||||||
|
case MINUTE:
|
||||||
|
return DateBucketUnit.MINUTE;
|
||||||
|
case HOUR:
|
||||||
|
return DateBucketUnit.HOUR;
|
||||||
|
case DAY:
|
||||||
|
return DateBucketUnit.DAY;
|
||||||
|
case WEEK:
|
||||||
|
return DateBucketUnit.WEEK;
|
||||||
|
case MONTH:
|
||||||
|
return DateBucketUnit.MONTH;
|
||||||
|
case YEAR:
|
||||||
|
return DateBucketUnit.YEAR;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unexpected value: " + this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import java.time.temporal.TemporalAdjuster;
|
|||||||
|
|
||||||
public class BeginningOfNextInterval implements TemporalAdjuster {
|
public class BeginningOfNextInterval implements TemporalAdjuster {
|
||||||
|
|
||||||
private final ChronoUnit unit;
|
private final DateBucketUnit unit;
|
||||||
|
|
||||||
public BeginningOfNextInterval(final ChronoUnit unit) {
|
public BeginningOfNextInterval(final DateBucketUnit unit) {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,27 +19,27 @@ public class BeginningOfNextInterval implements TemporalAdjuster {
|
|||||||
result = result.with(startOfInterval);
|
result = result.with(startOfInterval);
|
||||||
|
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case MINUTES: {
|
case MINUTE: {
|
||||||
result = result.plus(1, ChronoUnit.MINUTES);
|
result = result.plus(1, ChronoUnit.MINUTES);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HOURS: {
|
case HOUR: {
|
||||||
result = result.plus(1, ChronoUnit.HOURS);
|
result = result.plus(1, ChronoUnit.HOURS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DAYS: {
|
case DAY: {
|
||||||
result = result.plus(1, ChronoUnit.DAYS);
|
result = result.plus(1, ChronoUnit.DAYS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WEEKS: {
|
case WEEK: {
|
||||||
result = result.plus(1, ChronoUnit.WEEKS);
|
result = result.plus(1, ChronoUnit.WEEKS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MONTHS: {
|
case MONTH: {
|
||||||
result = result.plus(1, ChronoUnit.MONTHS);
|
result = result.plus(1, ChronoUnit.MONTHS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case YEARS: {
|
case YEAR: {
|
||||||
result = result.plus(1, ChronoUnit.YEARS);
|
result = result.plus(1, ChronoUnit.YEARS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.lucares.utils;
|
||||||
|
|
||||||
|
public enum DateBucketUnit {
|
||||||
|
MINUTE, HOUR, DAY, WEEK, MONTH, YEAR;
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ import java.time.temporal.TemporalAdjuster;
|
|||||||
|
|
||||||
public class EndOfInterval implements TemporalAdjuster {
|
public class EndOfInterval implements TemporalAdjuster {
|
||||||
|
|
||||||
private final ChronoUnit unit;
|
private final DateBucketUnit unit;
|
||||||
|
|
||||||
public EndOfInterval(final ChronoUnit unit) {
|
public EndOfInterval(final DateBucketUnit unit) {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.time.Instant;
|
|||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@@ -55,14 +54,14 @@ public class LongToDateBucket {
|
|||||||
*/
|
*/
|
||||||
private final DateTimeFormatter datePattern;
|
private final DateTimeFormatter datePattern;
|
||||||
|
|
||||||
ChronoUnit chronoUnit;
|
DateBucketUnit chronoUnit;
|
||||||
|
|
||||||
// visible for test
|
// visible for test
|
||||||
final ConcurrentNavigableMap<Long, DatePrefixAndRange> datePrefixCache = new ConcurrentSkipListMap<>();
|
final ConcurrentNavigableMap<Long, DatePrefixAndRange> datePrefixCache = new ConcurrentSkipListMap<>();
|
||||||
|
|
||||||
private final AtomicReference<DatePrefixAndRange> lastAccessed = new AtomicReference<>(null);
|
private final AtomicReference<DatePrefixAndRange> lastAccessed = new AtomicReference<>(null);
|
||||||
|
|
||||||
public LongToDateBucket(final String dateFormatPattern, final ChronoUnit chronoUnit) {
|
public LongToDateBucket(final String dateFormatPattern, final DateBucketUnit chronoUnit) {
|
||||||
this.chronoUnit = chronoUnit;
|
this.chronoUnit = chronoUnit;
|
||||||
this.datePattern = DateTimeFormatter.ofPattern(dateFormatPattern);
|
this.datePattern = DateTimeFormatter.ofPattern(dateFormatPattern);
|
||||||
}
|
}
|
||||||
@@ -118,7 +117,7 @@ public class LongToDateBucket {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<String> toPartitionIds(final OffsetDateTime start, final OffsetDateTime end,
|
public List<String> toPartitionIds(final OffsetDateTime start, final OffsetDateTime end,
|
||||||
final ChronoUnit chronoUnit) {
|
final DateBucketUnit chronoUnit) {
|
||||||
final List<String> result = new ArrayList<>();
|
final List<String> result = new ArrayList<>();
|
||||||
|
|
||||||
OffsetDateTime current = start;
|
OffsetDateTime current = start;
|
||||||
|
|||||||
@@ -1,62 +1,50 @@
|
|||||||
package org.lucares.utils;
|
package org.lucares.utils;
|
||||||
|
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.time.temporal.Temporal;
|
import java.time.temporal.Temporal;
|
||||||
import java.time.temporal.TemporalAdjuster;
|
import java.time.temporal.TemporalAdjuster;
|
||||||
|
|
||||||
public class StartOfInterval implements TemporalAdjuster {
|
public class StartOfInterval implements TemporalAdjuster {
|
||||||
|
|
||||||
private final ChronoUnit unit;
|
private final DateBucketUnit unit;
|
||||||
|
|
||||||
public StartOfInterval(final ChronoUnit unit) {
|
public StartOfInterval(final DateBucketUnit unit) {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Temporal adjustInto(final Temporal temporal) {
|
public Temporal adjustInto(final Temporal temporal) {
|
||||||
Temporal result = temporal;
|
Temporal result = temporal;
|
||||||
for (final ChronoUnit chronoUnit : ChronoUnit.values()) {
|
result = result.with(ChronoField.NANO_OF_SECOND, 0);
|
||||||
if (chronoUnit.compareTo(unit) >= 0) {
|
result = result.with(ChronoField.MICRO_OF_SECOND, 0);
|
||||||
|
result = result.with(ChronoField.MILLI_OF_SECOND, 0);
|
||||||
|
result = result.with(ChronoField.SECOND_OF_MINUTE, 0);
|
||||||
|
|
||||||
|
for (final DateBucketUnit dateBucketUnit : DateBucketUnit.values()) {
|
||||||
|
if (dateBucketUnit.compareTo(unit) >= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (chronoUnit) {
|
switch (dateBucketUnit) {
|
||||||
case NANOS: {
|
case MINUTE: {
|
||||||
result = result.with(ChronoField.NANO_OF_SECOND, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MICROS: {
|
|
||||||
result = result.with(ChronoField.MICRO_OF_SECOND, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MILLIS: {
|
|
||||||
result = result.with(ChronoField.MILLI_OF_SECOND, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SECONDS: {
|
|
||||||
result = result.with(ChronoField.SECOND_OF_MINUTE, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MINUTES: {
|
|
||||||
result = result.with(ChronoField.MINUTE_OF_HOUR, 0);
|
result = result.with(ChronoField.MINUTE_OF_HOUR, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HOURS: {
|
case HOUR: {
|
||||||
result = result.with(ChronoField.HOUR_OF_DAY, 0);
|
result = result.with(ChronoField.HOUR_OF_DAY, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DAYS: {
|
case DAY: {
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case WEEKS: {
|
case WEEK: {
|
||||||
result = result.with(ChronoField.DAY_OF_WEEK, 1);
|
result = result.with(ChronoField.DAY_OF_WEEK, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MONTHS: {
|
case MONTH: {
|
||||||
result = result.with(ChronoField.DAY_OF_MONTH, 1);
|
result = result.with(ChronoField.DAY_OF_MONTH, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case YEARS: {
|
case YEAR: {
|
||||||
result = result.with(ChronoField.MONTH_OF_YEAR, 1);
|
result = result.with(ChronoField.MONTH_OF_YEAR, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -65,15 +53,14 @@ public class StartOfInterval implements TemporalAdjuster {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MONTHS: {
|
case MONTH: {
|
||||||
result = result.with(ChronoField.MONTH_OF_YEAR, 1);
|
result = result.with(ChronoField.MONTH_OF_YEAR, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HALF_DAYS:
|
case WEEK:
|
||||||
case WEEKS:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unexpected value: " + chronoUnit);
|
throw new IllegalArgumentException("Unexpected value: " + dateBucketUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.lucares.utils;
|
|||||||
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.DoubleSummaryStatistics;
|
import java.util.DoubleSummaryStatistics;
|
||||||
@@ -49,7 +48,7 @@ public class LongToDateBucketTest {
|
|||||||
@MethodSource("provider")
|
@MethodSource("provider")
|
||||||
public void test(final OffsetDateTime start, final OffsetDateTime end, final Set<String> expected) {
|
public void test(final OffsetDateTime start, final OffsetDateTime end, final Set<String> expected) {
|
||||||
|
|
||||||
final Set<String> actual = new LongToDateBucket("yyyyMM", ChronoUnit.MONTHS).toDateIndexPrefix(start, end);
|
final Set<String> actual = new LongToDateBucket("yyyyMM", DateBucketUnit.MONTH).toDateIndexPrefix(start, end);
|
||||||
|
|
||||||
Assertions.assertEquals(expected, actual);
|
Assertions.assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
@@ -60,18 +59,18 @@ public class LongToDateBucketTest {
|
|||||||
final OffsetDateTime min_201801 = OffsetDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
final OffsetDateTime min_201801 = OffsetDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
||||||
final OffsetDateTime min_201802 = OffsetDateTime.of(2018, 2, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
final OffsetDateTime min_201802 = OffsetDateTime.of(2018, 2, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
||||||
|
|
||||||
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", ChronoUnit.MONTHS);
|
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", DateBucketUnit.MONTH);
|
||||||
|
|
||||||
final List<String> dateIndexPrefixesWithEmptyCache = longToDateBucket.toPartitionIds(mid_201712, min_201802,
|
final List<String> dateIndexPrefixesWithEmptyCache = longToDateBucket.toPartitionIds(mid_201712, min_201802,
|
||||||
ChronoUnit.MONTHS);
|
DateBucketUnit.MONTH);
|
||||||
Assertions.assertEquals(Arrays.asList("201712", "201801", "201802"), dateIndexPrefixesWithEmptyCache);
|
Assertions.assertEquals(Arrays.asList("201712", "201801", "201802"), dateIndexPrefixesWithEmptyCache);
|
||||||
|
|
||||||
final List<String> dateIndexPrefixesWithFilledCache = longToDateBucket.toPartitionIds(mid_201712, min_201801,
|
final List<String> dateIndexPrefixesWithFilledCache = longToDateBucket.toPartitionIds(mid_201712, min_201801,
|
||||||
ChronoUnit.MONTHS);
|
DateBucketUnit.MONTH);
|
||||||
Assertions.assertEquals(Arrays.asList("201712", "201801"), dateIndexPrefixesWithFilledCache);
|
Assertions.assertEquals(Arrays.asList("201712", "201801"), dateIndexPrefixesWithFilledCache);
|
||||||
|
|
||||||
final List<String> dateIndexPrefixesOneMonth = longToDateBucket.toPartitionIds(mid_201712, mid_201712,
|
final List<String> dateIndexPrefixesOneMonth = longToDateBucket.toPartitionIds(mid_201712, mid_201712,
|
||||||
ChronoUnit.MONTHS);
|
DateBucketUnit.MONTH);
|
||||||
Assertions.assertEquals(Arrays.asList("201712"), dateIndexPrefixesOneMonth);
|
Assertions.assertEquals(Arrays.asList("201712"), dateIndexPrefixesOneMonth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +83,7 @@ public class LongToDateBucketTest {
|
|||||||
final long exp_201801 = OffsetDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli();
|
final long exp_201801 = OffsetDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli();
|
||||||
final long exp_201802 = OffsetDateTime.of(2018, 2, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli();
|
final long exp_201802 = OffsetDateTime.of(2018, 2, 1, 0, 0, 0, 0, ZoneOffset.UTC).toInstant().toEpochMilli();
|
||||||
|
|
||||||
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", ChronoUnit.MONTHS);
|
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", DateBucketUnit.MONTH);
|
||||||
|
|
||||||
final List<Long> dateIndexEpochMillis = longToDateBucket.toDateIndexEpochMillis(mid_201712, min_201802);
|
final List<Long> dateIndexEpochMillis = longToDateBucket.toDateIndexEpochMillis(mid_201712, min_201802);
|
||||||
Assertions.assertEquals(Arrays.asList(exp_201712, exp_201801, exp_201802), dateIndexEpochMillis);
|
Assertions.assertEquals(Arrays.asList(exp_201712, exp_201801, exp_201802), dateIndexEpochMillis);
|
||||||
@@ -102,7 +101,7 @@ public class LongToDateBucketTest {
|
|||||||
final int warmup = 20 * factor;
|
final int warmup = 20 * factor;
|
||||||
final int rounds = warmup + 20;
|
final int rounds = warmup + 20;
|
||||||
|
|
||||||
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", ChronoUnit.MONTHS);
|
final LongToDateBucket longToDateBucket = new LongToDateBucket("yyyyMM", DateBucketUnit.MONTH);
|
||||||
|
|
||||||
// fill the cache
|
// fill the cache
|
||||||
for (long i = min; i < max; i += 3600 * 24 * 28) {
|
for (long i = min; i < max; i += 3600 * 24 * 28) {
|
||||||
|
|||||||
Reference in New Issue
Block a user