Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

since data filter

  • Loading branch information...
commit 9ba1c2166669eb46e1ea727ba1660aed36d05160 1 parent 517de9f
@elizarov authored
View
28 src/org/vsegda/util/DataRequest.java
@@ -6,9 +6,7 @@
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.ServletRequest;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import java.util.*;
/**
* @author Roman Elizarov
@@ -18,6 +16,7 @@
private int first;
private int last = 1000; // last 1000 items by default
private double filter = 5; // 5 sigmas by default
+ private TimeInstant since;
public DataRequest(ServletRequest req) {
RequestUtil.populate(this, req);
@@ -44,12 +43,21 @@ public DataRequest(ServletRequest req) {
} else {
for (long id : this.id) {
Query query = pm.newQuery(DataItem.class);
- query.setFilter("streamId == id");
- query.declareParameters("int id");
+ String queryFilter = "streamId == id";
+ String queryParams = "int id";
+ Map<String, Object> queryArgs = new HashMap<String, Object>();
+ queryArgs.put("id", id);
+ if (since != null) {
+ queryFilter += " && timeMillis >= since";
+ queryParams += ", long since";
+ queryArgs.put("since", since.time());
+ }
+ query.setFilter(queryFilter);
+ query.declareParameters(queryParams);
query.setOrdering("timeMillis desc");
query.setRange(first, first + last);
int s0 = items.size();
- items.addAll((Collection<DataItem>)query.execute(id));
+ items.addAll((Collection<DataItem>)query.executeWithMap(queryArgs));
filter(items.subList(s0, items.size()));
}
}
@@ -129,4 +137,12 @@ public double getFilter() {
public void setFilter(double filter) {
this.filter = filter;
}
+
+ public TimeInstant getSince() {
+ return since;
+ }
+
+ public void setSince(TimeInstant since) {
+ this.since = since;
+ }
}
View
2  src/org/vsegda/util/RequestUtil.java
@@ -11,6 +11,8 @@
public class RequestUtil {
static {
ConvertUtils.register(new IdList.Cnv(), IdList.class);
+ ConvertUtils.register(new TimeInstant.Cnv(), TimeInstant.class);
+ ConvertUtils.register(new TimePeriod.Cnv(), TimePeriod.class);
}
public static void populate(Object obj, ServletRequest req) {
View
52 src/org/vsegda/util/TimeInstant.java
@@ -0,0 +1,52 @@
+package org.vsegda.util;
+
+import org.apache.commons.beanutils.Converter;
+
+import java.sql.Time;
+
+/**
+ * @author Roman Elizarov
+ */
+public class TimeInstant {
+ private final long time;
+
+ private TimeInstant(long time) {
+ this.time = time;
+ }
+
+ public static TimeInstant valueOf(long time) {
+ return new TimeInstant(time);
+ }
+
+ public static TimeInstant valueOf(String s) {
+ long now = System.currentTimeMillis();
+ long time;
+ if (s.startsWith("+") || s.startsWith("-")) {
+ time = now + TimePeriod.valueOf(s).period();
+ }
+ else
+ time = TimeUtil.parseTime(s, now);
+ return valueOf(time);
+ }
+
+ public long time() {
+ return time;
+ }
+
+ @Override
+ public String toString() {
+ return TimeUtil.formatDateTime(time);
+ }
+
+ public static class Cnv implements Converter {
+ public Object convert(Class clazz, Object o) {
+ if (o == null)
+ return null;
+ String s = o.toString();
+ if (s == null)
+ return null;
+ return valueOf(s);
+ }
+ }
+
+}
View
108 src/org/vsegda/util/TimePeriod.java
@@ -0,0 +1,108 @@
+package org.vsegda.util;
+
+import org.apache.commons.beanutils.Converter;
+
+/**
+ * @author Roman Elizarov
+ */
+public class TimePeriod {
+ private final long period;
+
+ public static TimePeriod valueOf(long period) {
+ return new TimePeriod(period);
+ }
+
+ public static TimePeriod valueOf(long n, TimePeriodUnit unit) {
+ return new TimePeriod(n * unit.period());
+ }
+
+ public static TimePeriod valueOf(String s) {
+ long period = 0;
+ long mul = 1;
+ int i = 0;
+ if (s.startsWith("+"))
+ i++;
+ else if (s.startsWith("-")) {
+ i++;
+ mul = -1;
+ }
+ TimePeriodUnit[] units = TimePeriodUnit.values();
+ int k = units.length - 1;
+ while (i < s.length()) {
+ int j = i;
+ while (j < s.length() && numChar(s.charAt(j)))
+ j++;
+ double part = Double.parseDouble(s.substring(i, j));
+ if (j >= s.length()) {
+ period += part;
+ break;
+ }
+ while (k >= 0 && s.charAt(j) != units[k].code())
+ k--;
+ if (k < 0)
+ throw new IllegalArgumentException("Invalid time period code: " + s.charAt(j));
+ period += part * units[k].period();
+ k--;
+ i = j + 1;
+ }
+ return valueOf(mul * period);
+ }
+
+ private static boolean numChar(char c) {
+ return c >= '0' && c <= '9' || c == '.';
+ }
+
+ private TimePeriod(long period) {
+ this.period = period;
+ }
+
+ public long period() {
+ return period;
+ }
+
+ public String format(int limit) {
+ StringBuilder sb = new StringBuilder();
+ long r = period;
+ if (r < 0) {
+ sb.append('-');
+ r = -r;
+ }
+ TimePeriodUnit[] units = TimePeriodUnit.values();
+ int cnt = 0;
+ for (int i = units.length; --i >= 0;) {
+ TimePeriodUnit unit = units[i];
+ if (cnt > 0 || r >= unit.period()) {
+ cnt++;
+ sb.append(r / unit.period());
+ r %= unit.period();
+ if (unit == TimePeriodUnit.SECOND && r > 0 && cnt < limit)
+ sb.append('.')
+ .append(r / 100)
+ .append((r / 10) % 10)
+ .append(r % 10);
+ sb.append(unit.code());
+ if (cnt >= limit)
+ break;
+ }
+ }
+ if (cnt == 0)
+ sb.append(r);
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ return format(Integer.MAX_VALUE);
+ }
+
+ public static class Cnv implements Converter {
+ public Object convert(Class clazz, Object o) {
+ if (o == null)
+ return null;
+ String s = o.toString();
+ if (s == null)
+ return null;
+ return valueOf(s);
+ }
+ }
+}
View
33 src/org/vsegda/util/TimePeriodUnit.java
@@ -0,0 +1,33 @@
+package org.vsegda.util;
+
+/**
+ * @author Roman Elizarov
+ */
+public enum TimePeriodUnit {
+ SECOND('s', 1000),
+ MINUTE('m', SECOND.period * 60),
+ HOUR('h', MINUTE.period * 60),
+ DAY('d', HOUR.period * 24),
+ WEEK('w', DAY.period * 7);
+
+ private final char code;
+ private final long period;
+
+ TimePeriodUnit(char code, long period) {
+ this.code = code;
+ this.period = period;
+ }
+
+ public char code() {
+ return code;
+ }
+
+ public long period() {
+ return period;
+ }
+
+ @Override
+ public String toString() {
+ return "1" + code;
+ }
+}
View
2  src/org/vsegda/util/TimeUtil.java
@@ -26,7 +26,7 @@ public static String formatDateTime(long timeMillis) {
return getDateTimeFormat().format(new Date(timeMillis));
}
- public static String formatDateTimeDifference(long timeMillis, long now) {
+ public static String formatDateTimeDifference(long timeMillis, long now) {
StringBuilder sb = new StringBuilder();
long diff = now - timeMillis;
if (diff < 0) {
View
38 src/org/vsegda/util/test/TimePeriodTest.java
@@ -0,0 +1,38 @@
+package org.vsegda.util.test;
+
+import junit.framework.TestCase;
+import org.vsegda.util.TimePeriod;
+
+/**
+ * @author Roman Elizarov
+ */
+public class TimePeriodTest extends TestCase {
+ public void testParse() {
+ assertEquals(0, TimePeriod.valueOf("0").period());
+ assertEquals(1, TimePeriod.valueOf("1").period());
+ assertEquals(1, TimePeriod.valueOf("+1").period());
+ assertEquals(-1, TimePeriod.valueOf("-1").period());
+ assertEquals(1000, TimePeriod.valueOf("1s").period());
+ assertEquals(1500, TimePeriod.valueOf("1.5s").period());
+ assertEquals(60000, TimePeriod.valueOf("1m").period());
+ assertEquals(3600000, TimePeriod.valueOf("1h").period());
+ assertEquals(24 * 3600000, TimePeriod.valueOf("1d").period());
+ assertEquals(12 * 3600000, TimePeriod.valueOf(".5d").period());
+ assertEquals(7 * 24 * 3600000, TimePeriod.valueOf("1w").period());
+ assertEquals(7 * 24 * 3600000 + 15000, TimePeriod.valueOf("1w15s").period());
+ assertEquals(-7 * 24 * 3600000 - 20 * 60000, TimePeriod.valueOf("-1w20m").period());
+ }
+
+ public void testString() {
+ assertEquals("0", TimePeriod.valueOf(0).toString());
+ assertEquals("1", TimePeriod.valueOf(1).toString());
+ assertEquals("-1", TimePeriod.valueOf(-1).toString());
+ assertEquals("1s", TimePeriod.valueOf(1000).toString());
+ assertEquals("1.234s", TimePeriod.valueOf(1234).toString());
+ assertEquals("1m0s", TimePeriod.valueOf(60000).toString());
+ assertEquals("1h0m0s", TimePeriod.valueOf(60 * 60000).toString());
+ assertEquals("1d0h0m0s", TimePeriod.valueOf(24 * 60 * 60000).toString());
+ assertEquals("1w0d0h0m0s", TimePeriod.valueOf(7 * 24 * 60 * 60000).toString());
+ assertEquals("1w0d0h30m0s", TimePeriod.valueOf(7 * 24 * 60 * 60000 + 30 * 60000).toString());
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.