Skip to content

Commit 8760332

Browse files
authored
[CSAPI] Add "descendingOrder" parameter to TemporalFilter and CSAPI (#326)
1 parent 482891d commit 8760332

12 files changed

Lines changed: 125 additions & 55 deletions

File tree

sensorhub-core/src/main/java/org/sensorhub/api/datastore/TemporalFilter.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ public class TemporalFilter extends RangeFilter<Instant>
3939
protected boolean timeRangeBeginsNow; // now = current time at the time of query evaluation
4040
protected boolean timeRangeEndsNow; // now = current time at the time of query evaluation
4141
protected boolean latestTime; // latest available time (can be in future)
42+
protected boolean descendingOrder;
4243

43-
44+
protected TemporalFilter()
45+
{
46+
this.range = Range.open(Instant.MIN, Instant.MAX);
47+
}
48+
49+
4450
public boolean isCurrentTime()
4551
{
4652
return timeRangeBeginsNow && timeRangeEndsNow;
@@ -78,7 +84,13 @@ public boolean isSingleValue()
7884

7985
return isCurrentTime() || isLatestTime() || super.isSingleValue();
8086
}
81-
87+
88+
89+
public boolean isDescendingOrder()
90+
{
91+
return descendingOrder;
92+
}
93+
8294

8395
@Override
8496
public Range<Instant> getRange()
@@ -208,6 +220,9 @@ else if (otherFilter.isLatestTime() && isAllTimes())
208220
else if (otherFilter.isAllTimes() && isLatestTime())
209221
return builder.withLatestTime();
210222

223+
var descendingOrder = this.descendingOrder || otherFilter.descendingOrder;
224+
builder.descendingOrder(descendingOrder);
225+
211226
// otherwise compute time extent intersection
212227
var thisTe = asTimeExtent();
213228
var otherTe = otherFilter.asTimeExtent();
@@ -289,6 +304,7 @@ protected B copyFrom(F base)
289304
instance.timeRangeBeginsNow = base.timeRangeBeginsNow;
290305
instance.timeRangeEndsNow = base.timeRangeEndsNow;
291306
instance.latestTime = base.latestTime;
307+
instance.descendingOrder = base.descendingOrder;
292308
return (B)this;
293309
}
294310

@@ -378,5 +394,16 @@ else if (!te.hasEnd())
378394
else
379395
return withRange(te.begin(), te.end());
380396
}
397+
398+
/**
399+
* Specify descending or ascending (default) chronological order.
400+
* @param descending order
401+
* @return This builder for chaining
402+
*/
403+
public B descendingOrder(boolean descending)
404+
{
405+
instance.descendingOrder = descending;
406+
return (B)this;
407+
}
381408
}
382409
}

sensorhub-core/src/main/java/org/sensorhub/impl/database/registry/FederatedCommandStatusStore.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
package org.sensorhub.impl.database.registry;
1616

1717
import java.util.ArrayList;
18+
import java.util.Comparator;
1819
import java.util.Map;
1920
import java.util.Set;
2021
import java.util.stream.Stream;
2122
import java.util.stream.StreamSupport;
23+
2224
import org.sensorhub.api.command.ICommandStatus;
2325
import org.sensorhub.api.common.BigId;
2426
import org.sensorhub.api.datastore.command.CommandFilter;
@@ -170,10 +172,13 @@ public Stream<Entry<BigId, ICommandStatus>> selectEntries(CommandStatusFilter fi
170172

171173
if (cmdStreams.isEmpty())
172174
return Stream.empty();
175+
176+
Comparator<Entry<BigId, ICommandStatus>> comparator = Comparator.comparing(e -> e.getValue().getReportTime());
177+
if (filter.getReportTime() != null && filter.getReportTime().isDescendingOrder())
178+
comparator = comparator.reversed();
173179

174180
// stream and merge commands from all selected command streams and time periods
175-
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandStatus>>(cmdStreams,
176-
(e1, e2) -> e1.getValue().getReportTime().compareTo(e2.getValue().getReportTime()));
181+
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandStatus>>(cmdStreams, comparator);
177182

178183
// stream output of merge sort iterator + apply limit
179184
return StreamSupport.stream(mergeSortIt, false)

sensorhub-core/src/main/java/org/sensorhub/impl/database/registry/FederatedCommandStore.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
package org.sensorhub.impl.database.registry;
1616

17-
import java.util.ArrayList;
18-
import java.util.Map;
19-
import java.util.Set;
20-
import java.util.TreeMap;
17+
import java.util.*;
2118
import java.util.stream.Stream;
2219
import java.util.stream.StreamSupport;
2320
import org.sensorhub.api.command.ICommandData;
@@ -204,10 +201,13 @@ public Stream<Entry<BigId, ICommandData>> selectEntries(CommandFilter filter, Se
204201

205202
if (cmdStreams.isEmpty())
206203
return Stream.empty();
207-
204+
205+
Comparator<Entry<BigId, ICommandData>> comparator = Comparator.comparing(e -> e.getValue().getIssueTime());
206+
if (filter.getIssueTime() != null && filter.getIssueTime().isDescendingOrder())
207+
comparator = comparator.reversed();
208+
208209
// stream and merge commands from all selected command streams and time periods
209-
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandData>>(cmdStreams,
210-
(e1, e2) -> e1.getValue().getIssueTime().compareTo(e2.getValue().getIssueTime()));
210+
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandData>>(cmdStreams, comparator);
211211

212212
// stream output of merge sort iterator + apply limit
213213
return StreamSupport.stream(mergeSortIt, false)

sensorhub-core/src/main/java/org/sensorhub/impl/database/registry/FederatedObsStore.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414

1515
package org.sensorhub.impl.database.registry;
1616

17-
import java.util.ArrayList;
18-
import java.util.Map;
19-
import java.util.Set;
20-
import java.util.TreeMap;
17+
import java.util.*;
2118
import java.util.stream.Stream;
2219
import java.util.stream.StreamSupport;
20+
2321
import org.sensorhub.api.common.BigId;
2422
import org.sensorhub.api.data.IObsData;
2523
import org.sensorhub.api.datastore.feature.FoiFilter;
@@ -228,10 +226,13 @@ public Stream<Entry<BigId, IObsData>> selectEntries(ObsFilter filter, Set<ObsFie
228226

229227
if (obsStreams.isEmpty())
230228
return Stream.empty();
229+
230+
Comparator<Entry<BigId, IObsData>> comparator = Comparator.comparing(e -> e.getValue().getPhenomenonTime());
231+
if (filter.getPhenomenonTime() != null && filter.getPhenomenonTime().isDescendingOrder())
232+
comparator = comparator.reversed();
231233

232234
// stream and merge obs from all selected datastreams and time periods
233-
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, IObsData>>(obsStreams,
234-
(e1, e2) -> e1.getValue().getPhenomenonTime().compareTo(e2.getValue().getPhenomenonTime()));
235+
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, IObsData>>(obsStreams, comparator);
235236

236237
// stream output of merge sort iterator + apply limit
237238
return StreamSupport.stream(mergeSortIt, false)

sensorhub-datastore-h2/src/main/java/org/h2/mvstore/RangeCursor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public RangeCursor(MVMap<K, V> map, K from)
4848

4949
public RangeCursor(MVMap<K, V> map, K from, K to)
5050
{
51+
// TODO: Update to use reverse-order cursor in newer H2 version
5152
super(map.cursor(from));
5253
this.map = map;
5354
this.to = to;

sensorhub-datastore-h2/src/main/java/org/sensorhub/impl/datastore/h2/MVCommandStoreImpl.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@
2020
import java.nio.ByteBuffer;
2121
import java.time.Duration;
2222
import java.time.Instant;
23-
import java.util.AbstractSet;
24-
import java.util.ArrayList;
25-
import java.util.Collection;
26-
import java.util.Iterator;
27-
import java.util.Objects;
28-
import java.util.Set;
23+
import java.util.*;
2924
import java.util.stream.Stream;
3025
import java.util.stream.StreamSupport;
3126
import org.h2.mvstore.MVBTreeMap;
@@ -300,10 +295,12 @@ public Stream<Entry<BigId, ICommandData>> selectEntries(CommandFilter filter, Se
300295
return getPostFilteredResultStream(cmdStream, filter);
301296
}));
302297

303-
298+
Comparator<Entry<BigId, ICommandData>> comparator = Comparator.comparing(e -> e.getValue().getIssueTime());
299+
if (filter.getIssueTime() != null && filter.getIssueTime().isDescendingOrder())
300+
comparator = comparator.reversed();
301+
304302
// stream and merge commands from all selected command streams and time periods
305-
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandData>>(cmdStreams,
306-
(e1, e2) -> e1.getValue().getIssueTime().compareTo(e2.getValue().getIssueTime()));
303+
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, ICommandData>>(cmdStreams, comparator);
307304

308305
// stream output of merge sort iterator + apply limit
309306
return StreamSupport.stream(mergeSortIt, false)

sensorhub-datastore-h2/src/main/java/org/sensorhub/impl/datastore/h2/MVObsStoreImpl.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@
2020
import java.nio.ByteBuffer;
2121
import java.time.Duration;
2222
import java.time.Instant;
23-
import java.util.AbstractSet;
24-
import java.util.ArrayList;
25-
import java.util.Collection;
26-
import java.util.Iterator;
27-
import java.util.Objects;
28-
import java.util.Set;
23+
import java.util.*;
2924
import java.util.concurrent.atomic.AtomicInteger;
3025
import java.util.concurrent.atomic.AtomicReference;
3126
import java.util.stream.Collectors;
@@ -463,10 +458,13 @@ public Stream<Entry<BigId, IObsData>> selectEntries(ObsFilter filter, Set<ObsFie
463458
return Stream.empty();
464459

465460
// TODO group by result time when series with different result times are selected
461+
462+
Comparator<Entry<BigId, IObsData>> comparator = Comparator.comparing(e -> e.getValue().getPhenomenonTime());
463+
if (filter.getPhenomenonTime() != null && filter.getPhenomenonTime().isDescendingOrder())
464+
comparator = comparator.reversed();
466465

467466
// stream and merge obs from all selected datastreams and time periods
468-
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, IObsData>>(obsStreams,
469-
(e1, e2) -> e1.getValue().getPhenomenonTime().compareTo(e2.getValue().getPhenomenonTime()));
467+
var mergeSortIt = new MergeSortSpliterator<Entry<BigId, IObsData>>(obsStreams, comparator);
470468

471469
// stream output of merge sort iterator + apply limit
472470
return StreamSupport.stream(mergeSortIt, false)

sensorhub-service-consys/src/main/java/org/sensorhub/impl/service/consys/BaseHandler.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -275,31 +275,37 @@ protected IdCollection parseResourceIdsOrUids(String paramName, final Map<String
275275

276276

277277
protected TemporalFilter parseTimeStampArg(String paramName, final Map<String, String[]> queryParams) throws InvalidRequestException
278+
{
279+
var builder = parseTimeStampArgToBuilder(paramName, queryParams);
280+
if (builder == null)
281+
return null;
282+
return builder.build();
283+
}
284+
285+
286+
protected TemporalFilter.Builder parseTimeStampArgToBuilder(String paramName, final Map<String, String[]> queryParams) throws InvalidRequestException
278287
{
279288
var timeVal = getSingleParam(paramName, queryParams);
280289
if (timeVal == null)
281290
return null;
282-
291+
283292
try
284293
{
285294
if (timeVal.equals("latest"))
286295
{
287296
return new TemporalFilter.Builder()
288-
.withLatestTime()
289-
.build();
297+
.withLatestTime();
290298
}
291299
else if (timeVal.startsWith("latest/"))
292300
{
293301
return new TemporalFilter.Builder()
294-
.withLatestTime()
295-
.withRangeBeginningNow(Instant.MAX)
296-
.build();
302+
.withLatestTime()
303+
.withRangeBeginningNow(Instant.MAX);
297304
}
298305
else
299306
{
300307
return new TemporalFilter.Builder()
301-
.fromTimeExtent(TimeExtent.parse(timeVal))
302-
.build();
308+
.fromTimeExtent(TimeExtent.parse(timeVal));
303309
}
304310
}
305311
catch (Exception e)
@@ -452,6 +458,11 @@ protected Collection<ResourceLink> getPagingLinks(final RequestContext ctx, long
452458

453459
return links;
454460
}
455-
461+
462+
463+
public boolean parseDescendingOrderArg(Map<String, String[]> queryParams) throws InvalidRequestException {
464+
var param = getSingleParam("order", queryParams);
465+
return param != null && !param.isBlank() && ("desc".equals(param) || "descending".equals(param));
466+
}
456467

457468
}

sensorhub-service-consys/src/main/java/org/sensorhub/impl/service/consys/obs/ObsHandler.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.sensorhub.api.database.IObsSystemDatabase;
3535
import org.sensorhub.api.datastore.DataStoreException;
3636
import org.sensorhub.api.datastore.SpatialFilter;
37+
import org.sensorhub.api.datastore.TemporalFilter;
3738
import org.sensorhub.api.datastore.obs.DataStreamKey;
3839
import org.sensorhub.api.datastore.obs.IObsStore;
3940
import org.sensorhub.api.datastore.obs.ObsFilter;
@@ -477,12 +478,21 @@ protected ObsFilter getFilter(ResourceRef parent, Map<String, String[]> queryPar
477478
// filter on parent if needed
478479
if (parent.internalID != null)
479480
builder.withDataStreams(parent.internalID);
480-
481+
482+
var phenomenonTimeFilterBuilder = new TemporalFilter.Builder();
483+
481484
// phenomenonTime param
482-
var phenomenonTime = parseTimeStampArg("phenomenonTime", queryParams);
485+
var phenomenonTime = parseTimeStampArgToBuilder("phenomenonTime", queryParams);
483486
if (phenomenonTime != null)
484-
builder.withPhenomenonTime(phenomenonTime);
485-
487+
phenomenonTimeFilterBuilder = phenomenonTime;
488+
489+
// chronological order, attached to phenomenonTime filter
490+
boolean isDescendingOrder = parseDescendingOrderArg(queryParams);
491+
phenomenonTimeFilterBuilder.descendingOrder(isDescendingOrder);
492+
493+
if (phenomenonTime != null || isDescendingOrder)
494+
builder.withPhenomenonTime(phenomenonTimeFilterBuilder.build());
495+
486496
// resultTime param
487497
var resultTime = parseTimeStampArg("resultTime", queryParams);
488498
if (resultTime != null)

sensorhub-service-consys/src/main/java/org/sensorhub/impl/service/consys/resource/BaseResourceHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ protected void list(final RequestContext ctx) throws IOException
265265
// stream and serialize all resources to servlet output
266266
var binding = getBinding(ctx, false);
267267
binding.startCollection();
268-
268+
269269
// fetch from DB and temporarily handle paging here
270270
try (var results = postProcessResultList(dataStore.selectEntries(filter), filter))
271271
{

0 commit comments

Comments
 (0)