diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDAFIntegral.java b/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDAFIntegral.java index 2bb938d5f327c..c293e929cd00b 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDAFIntegral.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDAFIntegral.java @@ -37,11 +37,8 @@ public class UDAFIntegral implements UDTF { private static final String TIME_UNIT_KEY = "unit"; - private static final String TIME_UNIT_MS = "1S"; private static final String TIME_UNIT_S = "1s"; - private static final String TIME_UNIT_M = "1m"; - private static final String TIME_UNIT_H = "1H"; - private static final String TIME_UNIT_D = "1d"; + long unitTime; long lastTime = -1; @@ -53,41 +50,19 @@ public void validate(UDFParameterValidator validator) throws Exception { validator .validateInputSeriesNumber(1) .validate( - unit -> - TIME_UNIT_D.equals(unit) - || TIME_UNIT_H.equals(unit) - || TIME_UNIT_M.equals(unit) - || TIME_UNIT_S.equals(unit) - || TIME_UNIT_MS.equals(unit), - "Unknown time unit input", - validator.getParameters().getStringOrDefault(TIME_UNIT_KEY, TIME_UNIT_S)); + x -> (long) x > 0, + "Unknown time unit input.", + Util.parseTime( + validator.getParameters().getStringOrDefault(TIME_UNIT_KEY, TIME_UNIT_S), + validator.getParameters())); } @Override public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception { configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.DOUBLE); - switch (parameters.getStringOrDefault(TIME_UNIT_KEY, TIME_UNIT_S)) { - case TIME_UNIT_MS: - unitTime = 1L; - break; - case TIME_UNIT_S: - unitTime = 1000L; - break; - case TIME_UNIT_M: - unitTime = 60000L; - break; - case TIME_UNIT_H: - unitTime = 3600000L; - break; - case TIME_UNIT_D: - unitTime = 3600000L * 24L; - break; - default: - throw new UDFException( - "Unknown time unit input: " - + parameters.getStringOrDefault(TIME_UNIT_KEY, TIME_UNIT_S)); - } + unitTime = + Util.parseTime(parameters.getStringOrDefault(TIME_UNIT_KEY, TIME_UNIT_S), parameters); } @Override diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDTFResample.java b/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDTFResample.java index 91cbf24ae2c30..15d2828c04f35 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDTFResample.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dprofile/UDTFResample.java @@ -34,19 +34,19 @@ /** This function does upsample or downsample of input series. */ public class UDTFResample implements UDTF { - private static final String START_PARAM = "start"; private Resampler resampler; @Override public void validate(UDFParameterValidator validator) throws Exception { + validator .validateInputSeriesNumber(1) .validateInputSeriesDataType(0, Type.DOUBLE, Type.FLOAT, Type.INT32, Type.INT64) .validate( x -> (long) x > 0, "gap should be a time period whose unit is ms, s, m, h, d.", - Util.parseTime(validator.getParameters().getString("every"))) + Util.parseTime(validator.getParameters().getString("every"), validator.getParameters())) .validate( x -> "min".equals(x) @@ -80,7 +80,7 @@ public void validate(UDFParameterValidator validator) throws Exception { public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception { configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.DOUBLE); - long newPeriod = Util.parseTime(parameters.getString("every")); + long newPeriod = Util.parseTime(parameters.getString("every"), parameters); String aggregator = parameters.getStringOrDefault("aggr", "mean").toLowerCase(); String interpolator = parameters.getStringOrDefault("interp", "nan").toLowerCase(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFCompleteness.java b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFCompleteness.java index e5241062d6cf4..8b349240386f9 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFCompleteness.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFCompleteness.java @@ -36,6 +36,7 @@ /** This function calculates completeness of input series. */ public class UDTFCompleteness implements UDTF { + private boolean downtime; @Override @@ -44,7 +45,7 @@ public void beforeStart(UDFParameters udfp, UDTFConfigurations udtfc) throws Exc long window = Integer.MAX_VALUE; if (udfp.hasAttribute("window")) { String s = udfp.getString("window"); - window = Util.parseTime(s); + window = Util.parseTime(s, udfp); if (window > 0) { isTime = true; } else { diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFConsistency.java b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFConsistency.java index 52f2787646899..3178d33343cb2 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFConsistency.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFConsistency.java @@ -44,7 +44,7 @@ public void beforeStart(UDFParameters udfp, UDTFConfigurations udtfc) throws Exc long window = Integer.MAX_VALUE; if (udfp.hasAttribute("window")) { String s = udfp.getString("window"); - window = Util.parseTime(s); + window = Util.parseTime(s, udfp); if (window > 0) { isTime = true; } else { diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFTimeliness.java b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFTimeliness.java index 8ac93e1bf5436..7a5fc98e18290 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFTimeliness.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFTimeliness.java @@ -37,13 +37,14 @@ /** This function calculates timeliness of input series. */ public class UDTFTimeliness implements UDTF { + @Override public void beforeStart(UDFParameters udfp, UDTFConfigurations udtfc) throws Exception { boolean isTime = false; long window = Integer.MAX_VALUE; if (udfp.hasAttribute("window")) { String s = udfp.getString("window"); - window = Util.parseTime(s); + window = Util.parseTime(s, udfp); if (window > 0) { isTime = true; } else { diff --git a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFValidity.java b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFValidity.java index 7e7028d382fa7..e3b0de6065bc8 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFValidity.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/dquality/UDTFValidity.java @@ -37,13 +37,14 @@ /** This function calculates validity of input series. */ public class UDTFValidity implements UDTF { + @Override public void beforeStart(UDFParameters udfp, UDTFConfigurations udtfc) throws Exception { boolean isTime = false; long window = Integer.MAX_VALUE; if (udfp.hasAttribute("window")) { String s = udfp.getString("window"); - window = Util.parseTime(s); + window = Util.parseTime(s, udfp); if (window > 0) { isTime = true; } else { diff --git a/library-udf/src/main/java/org/apache/iotdb/library/drepair/UDTFTimestampRepair.java b/library-udf/src/main/java/org/apache/iotdb/library/drepair/UDTFTimestampRepair.java index 9554cff6d18c9..c9ec136dcf925 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/drepair/UDTFTimestampRepair.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/drepair/UDTFTimestampRepair.java @@ -33,18 +33,26 @@ /** This function is used for timestamp repair. */ public class UDTFTimestampRepair implements UDTF { String intervalMethod; - int interval; - int intervalMode; + long interval; + long intervalMode; @Override public void validate(UDFParameterValidator validator) throws Exception { validator .validateInputSeriesNumber(1) - .validateInputSeriesDataType(0, Type.DOUBLE, Type.FLOAT, Type.INT32, Type.INT64) - .validate( - x -> (Integer) x >= 0, - "Interval should be a positive integer.", - validator.getParameters().getIntOrDefault("interval", 0)); + .validateInputSeriesDataType(0, Type.DOUBLE, Type.FLOAT, Type.INT32, Type.INT64); + String intervalString = validator.getParameters().getStringOrDefault("interval", null); + if (intervalString != null) { + try { + long parsedInterval = Util.parseTime(intervalString, validator.getParameters()); + validator.validate( + x -> parsedInterval > 0, + "Invalid time unit input. Supported units are ns, us, ms, s, m, h, d."); + } catch (Exception e) { + throw new UDFException( + "Invalid time format for interval."); + } + } } @Override @@ -54,15 +62,20 @@ public void beforeStart(UDFParameters parameters, UDTFConfigurations configurati .setAccessStrategy(new SlidingSizeWindowAccessStrategy(Integer.MAX_VALUE)) .setOutputDataType(parameters.getDataType(0)); intervalMethod = parameters.getStringOrDefault("method", "Median"); - interval = parameters.getIntOrDefault("interval", 0); + String intervalString = parameters.getStringOrDefault("interval", null); + if (intervalString != null) { + interval = Util.parseTime(intervalString, parameters); + } else { + interval = 0; + } if (interval > 0) { intervalMode = interval; } else if ("Median".equalsIgnoreCase(intervalMethod)) { - intervalMode = -1; + intervalMode = -1L; } else if ("Mode".equalsIgnoreCase(intervalMethod)) { - intervalMode = -2; + intervalMode = -2L; } else if ("Cluster".equalsIgnoreCase(intervalMethod)) { - intervalMode = -3; + intervalMode = -3L; } else { throw new UDFException("Illegal method."); } diff --git a/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampInterval.java b/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampInterval.java index 57feae842299b..f596a3552db2c 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampInterval.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampInterval.java @@ -44,19 +44,15 @@ public TimestampInterval(long[] time, double[] original) { // get standard interval // -1 median -2 mode -3 cluster - public long getInterval(int mode) { - switch (mode) { - case -1: - this.deltaT = getIntervalByMedian(); - break; - case -2: - this.deltaT = getIntervalByMode(); - break; - case -3: - this.deltaT = getIntervalByCluster(); - break; - default: - this.deltaT = mode; + public long getInterval(long mode) { + if (mode == -1L) { + this.deltaT = getIntervalByMedian(); + } else if (mode == -2L) { + this.deltaT = getIntervalByMode(); + } else if (mode == -3L) { + this.deltaT = getIntervalByCluster(); + } else { + this.deltaT = mode; } return this.deltaT; } diff --git a/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampRepair.java b/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampRepair.java index d1a856e56a9e4..4b98256436bef 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampRepair.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/drepair/util/TimestampRepair.java @@ -35,7 +35,7 @@ public class TimestampRepair { protected long deltaT; protected long start0; - public TimestampRepair(RowIterator dataIterator, int intervalMode, int startPointMode) + public TimestampRepair(RowIterator dataIterator, long intervalMode, int startPointMode) throws Exception { ArrayList timeList = new ArrayList<>(); ArrayList originList = new ArrayList<>(); diff --git a/library-udf/src/main/java/org/apache/iotdb/library/frequency/UDTFIFFT.java b/library-udf/src/main/java/org/apache/iotdb/library/frequency/UDTFIFFT.java index 38a655f7b2cf5..6e5f52d7e6f1a 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/frequency/UDTFIFFT.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/frequency/UDTFIFFT.java @@ -42,6 +42,7 @@ public class UDTFIFFT implements UDTF { private final DoubleArrayList real = new DoubleArrayList(); private final DoubleArrayList imag = new DoubleArrayList(); private final IntArrayList time = new IntArrayList(); + private long start; private long interval; @@ -53,7 +54,9 @@ public void validate(UDFParameterValidator validator) throws Exception { .validate( x -> (long) x > 0, "interval should be a time period whose unit is ms, s, m, h, d.", - Util.parseTime(validator.getParameters().getStringOrDefault("interval", "1s"))); + Util.parseTime( + validator.getParameters().getStringOrDefault("interval", "1s"), + validator.getParameters())); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (validator.getParameters().hasAttribute(START_PARAM)) { validator.validate( @@ -67,7 +70,7 @@ public void validate(UDFParameterValidator validator) throws Exception { public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception { configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.DOUBLE); - this.interval = Util.parseTime(parameters.getStringOrDefault("interval", "1s")); + this.interval = Util.parseTime(parameters.getStringOrDefault("interval", "1s"), parameters); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); this.start = 0; if (parameters.hasAttribute(START_PARAM)) { diff --git a/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveSequences.java b/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveSequences.java index c58111fa0ada5..a13caa6324319 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveSequences.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveSequences.java @@ -41,14 +41,15 @@ public void validate(UDFParameterValidator validator) throws Exception { validator.validate( x -> (long) x > 0, "gap should be a time period whose unit is ms, s, m, h.", - Util.parseTime(validator.getParameters().getStringOrDefault("gap", "1ms"))); + Util.parseTime( + validator.getParameters().getStringOrDefault("gap", "1ms"), validator.getParameters())); } @Override public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception { configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.INT32); - long gap = Util.parseTime(parameters.getStringOrDefault("gap", "0ms")); + long gap = Util.parseTime(parameters.getStringOrDefault("gap", "0ms"), parameters); consUtil = new ConsecutiveUtil(-gap, -gap, gap); } diff --git a/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveWindows.java b/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveWindows.java index e7abedef87e9a..d7dbe4148b3a8 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveWindows.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/series/UDTFConsecutiveWindows.java @@ -44,19 +44,22 @@ public void validate(UDFParameterValidator validator) throws Exception { .validate( x -> (long) x > 0, "gap should be a time period whose unit is ms, s, m, h.", - Util.parseTime(validator.getParameters().getStringOrDefault("gap", "1ms"))) + Util.parseTime( + validator.getParameters().getStringOrDefault("gap", "1ms"), + validator.getParameters())) .validate( x -> (long) x > 0, "length should be a time period whose unit is ms, s, m, h.", - Util.parseTime(validator.getParameters().getString("length"))); + Util.parseTime( + validator.getParameters().getString("length"), validator.getParameters())); } @Override public void beforeStart(UDFParameters parameters, UDTFConfigurations configurations) throws Exception { configurations.setAccessStrategy(new RowByRowAccessStrategy()).setOutputDataType(Type.INT32); - long gap = Util.parseTime(parameters.getStringOrDefault("gap", "0ms")); - len = Util.parseTime(parameters.getString("length")); + long gap = Util.parseTime(parameters.getStringOrDefault("gap", "0ms"), parameters); + len = Util.parseTime(parameters.getString("length"), parameters); int count = gap == 0 ? 0 : (int) (len / gap + 1); consUtil = new ConsecutiveUtil(-gap, -gap, gap); consUtil.setCount(count); diff --git a/library-udf/src/main/java/org/apache/iotdb/library/util/Util.java b/library-udf/src/main/java/org/apache/iotdb/library/util/Util.java index 5c65c4314ce9c..e30cc7d45c314 100644 --- a/library-udf/src/main/java/org/apache/iotdb/library/util/Util.java +++ b/library-udf/src/main/java/org/apache/iotdb/library/util/Util.java @@ -21,6 +21,7 @@ import org.apache.iotdb.udf.api.access.Row; import org.apache.iotdb.udf.api.collector.PointCollector; +import org.apache.iotdb.udf.api.customizer.parameter.UDFParameters; import org.apache.iotdb.udf.api.type.Type; import org.apache.commons.math3.stat.descriptive.rank.Median; @@ -32,6 +33,9 @@ /** This class offers functions of getting and putting values from iotdb interface. */ public class Util { + private static final String TIMESTAMP_PRECISION = "timestampPrecision"; + public static final String MS_PRECISION = "ms"; + private Util() { throw new IllegalStateException("Utility class"); } @@ -300,26 +304,80 @@ public static long mode(long[] values) { * @param s input string * @return timestamp */ - public static long parseTime(String s) { + public static long parseTime(String s, UDFParameters parameters) { long unit = 0; + String timestampPrecision = + parameters.getSystemStringOrDefault(TIMESTAMP_PRECISION, MS_PRECISION); s = s.toLowerCase(); s = s.replace(" ", ""); - if (s.endsWith("ms")) { - unit = 1; - s = s.substring(0, s.length() - 2); - } else if (s.endsWith("s")) { - unit = 1000; - s = s.substring(0, s.length() - 1); - } else if (s.endsWith("m")) { - unit = 60 * 1000L; - s = s.substring(0, s.length() - 1); - } else if (s.endsWith("h")) { - unit = 60 * 60 * 1000L; - s = s.substring(0, s.length() - 1); - } else if (s.endsWith("d")) { - unit = 24 * 60 * 60 * 1000L; - s = s.substring(0, s.length() - 1); + if (timestampPrecision.equals("ms")) { + if (s.endsWith("ns") || s.endsWith("us")) { + throw new IllegalArgumentException( + "The provided time precision is higher than the system's time precision (ms). Please check your input."); + } else if (s.endsWith("ms")) { + unit = 1; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("s")) { + unit = 1000; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("m")) { + unit = 60 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("h")) { + unit = 60 * 60 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("d")) { + unit = 24 * 60 * 60 * 1000L; + s = s.substring(0, s.length() - 1); + } + } else if (timestampPrecision.equals("us")) { + if (s.endsWith("ns")) { + throw new IllegalArgumentException( + "The provided time precision is higher than the system's time precision (us). Please check your input."); + } else if (s.endsWith("us")) { + unit = 1; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("ms")) { + unit = 1000; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("s")) { + unit = 1000 * 1000; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("m")) { + unit = 60 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("h")) { + unit = 60 * 60 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("d")) { + unit = 24 * 60 * 60 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } + } else if (timestampPrecision.equals("ns")) { + if (s.endsWith("ns")) { + unit = 1; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("us")) { + unit = 1000; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("ms")) { + unit = 1000 * 1000; + s = s.substring(0, s.length() - 2); + } else if (s.endsWith("s")) { + unit = 1000 * 1000 * 1000; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("m")) { + unit = 60 * 1000 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("h")) { + unit = 60 * 60 * 1000 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } else if (s.endsWith("d")) { + unit = 24 * 60 * 60 * 1000 * 1000 * 1000L; + s = s.substring(0, s.length() - 1); + } } + double v = Double.parseDouble(s); return (long) (unit * v); }