Skip to content

Commit dcb6a8d

Browse files
authored
[PostGIS] Optimize queries and indexes (opensensorhub#216)
* Improve DataStreams queries and indexes * Improve DataStreams queries and indexes * Fix some queries and index * Fix FOI full text searches * Use GIN for JSONB into feature tables * Fix obs selection filter by using POSTGIS bounded time * Dot not truncated some postgis time to allow querying in millis * Add Offset support for paging * Add DESCending temporal order support * Add more precision on phenomenonTime and resultTime of obs table * Update time precision to millis * Multiple Fixes * Update osh-core to 2.0.1
1 parent 8849820 commit dcb6a8d

29 files changed

Lines changed: 409 additions & 514 deletions

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ allprojects {
99
group = 'org.sensorhub'
1010
}
1111

12-
ext.oshCoreVersion = '2.0-beta2'
12+
ext.oshCoreVersion = '2.0.1'
1313
//apply from: gradle.oshCoreDir + '/common.gradle'
1414
version = oshCoreVersion
1515
description = 'OSH Add-ons'

persistence/sensorhub-datastore-postgis/src/main/java/org/sensorhub/impl/datastore/postgis/builder/IteratorResultSet.java

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,59 +29,61 @@
2929
public class IteratorResultSet<T> implements Iterator<T> {
3030
private static final Logger logger = LoggerFactory.getLogger(IteratorResultSet.class);
3131

32-
private long limit = Long.MAX_VALUE;
33-
32+
private long limit = 10_000;
3433
private long offset = 0;
35-
34+
private long maxElements = 0;
35+
private long totalFetchedElements = 0;
3636
private String query;
37-
3837
private ConnectionManager connectionManager;
39-
4038
private final Function<ResultSet, T> parsingFn;
41-
4239
private ConcurrentLinkedQueue<T> records = new ConcurrentLinkedQueue<>();
43-
4440
private boolean ended = false;
45-
4641
private final Function<T, Boolean> predicateValidator;
47-
private final boolean useInternalLimit;
42+
private static final long MAX_FAILED = 5;
43+
private long currentFailed = 0;
44+
45+
private boolean disableLimit = false;
4846

4947
public IteratorResultSet(String query,
5048
ConnectionManager connectionManager,
5149
long limit,
5250
Function<ResultSet, T> parsingFn,
5351
Function<T, Boolean> predicateValidator
5452
) {
55-
this.query = query;
56-
this.limit = limit;
53+
QueryCleaner queryCleaner = new QueryCleaner(query);
54+
this.query = queryCleaner.removeNoLimit().removeSqlLimit().build();
55+
this.disableLimit = queryCleaner.isDisableLimit();
56+
this.limit = Math.min(limit,this.limit);
57+
this.maxElements = limit;
5758
this.parsingFn = parsingFn;
5859
this.connectionManager = connectionManager;
5960
this.predicateValidator = predicateValidator;
60-
this.useInternalLimit = !query.contains("LIMIT");
61+
}
62+
63+
private boolean checkFailed() {
64+
return (currentFailed <= MAX_FAILED);
6165
}
6266

6367
@Override
6468
public boolean hasNext() {
69+
if(!checkFailed()) {
70+
logger.error("Max Failed reached, skipping..");
71+
return false;
72+
}
6573
if(!records.isEmpty()) {
6674
return true;
6775
}
6876
if (ended) {
6977
return false;
7078
}
71-
while(records.isEmpty() && !ended) {
79+
while(records.isEmpty() && !ended && checkFailed()) {
7280
this.makeRequest();
7381
}
7482
return !records.isEmpty();
7583
}
7684

7785
private String getQuery() {
78-
if(useInternalLimit) {
79-
return query + " LIMIT " + limit + " OFFSET " + offset;
80-
} else {
81-
// limit set by the filter itself
82-
return query + " OFFSET " + offset;
83-
}
84-
86+
return (!this.disableLimit) ? query + " LIMIT " + limit + " OFFSET " + offset : query;
8587
}
8688

8789
@Override
@@ -91,9 +93,10 @@ public T next() {
9193

9294
private void makeRequest() {
9395
long countRes = 0;
96+
String nextQuery="";
9497
try (Connection connection = connectionManager.getConnection()) {
9598
try(Statement statement = connection.createStatement()) {
96-
String nextQuery = getQuery();
99+
nextQuery = getQuery();
97100
if(logger.isDebugEnabled()) {
98101
logger.debug(nextQuery);
99102
}
@@ -108,11 +111,44 @@ private void makeRequest() {
108111
offset += limit;
109112
}
110113
}
111-
if(countRes == 0 || countRes < limit) {
114+
totalFetchedElements += countRes;
115+
if(countRes == 0 || countRes < limit || totalFetchedElements >= maxElements) {
112116
ended = true;
113117
}
114118
} catch (SQLException e) {
115-
throw new RuntimeException(e);
119+
logger.error("Cannot Execute the request {}, currentFailed={}",query,currentFailed);
120+
currentFailed++;
121+
}
122+
}
123+
124+
public static class QueryCleaner {
125+
private String value;
126+
private boolean disableLimit = false;
127+
public QueryCleaner(String value) {
128+
this.value = value;
129+
}
130+
131+
public QueryCleaner removeNoLimit() {
132+
if (this.value != null && this.value.contains("DISABLE_LIMIT")) {
133+
this.disableLimit = true;
134+
this.value = this.value.replace("DISABLE_LIMIT", "");
135+
}
136+
return this;
137+
}
138+
139+
public QueryCleaner removeSqlLimit() {
140+
if (this.value != null) {
141+
this.value = this.value.replaceAll("(?i)\\s+LIMIT\\s+\\d+(\\s+OFFSET\\s+\\d+)?", "");
142+
}
143+
return this;
144+
}
145+
146+
public String build() {
147+
return this.value;
148+
}
149+
150+
public boolean isDisableLimit() {
151+
return disableLimit;
116152
}
117153
}
118154
}

persistence/sensorhub-datastore-postgis/src/main/java/org/sensorhub/impl/datastore/postgis/builder/ObsIteratorResultSet.java

Lines changed: 0 additions & 233 deletions
This file was deleted.

0 commit comments

Comments
 (0)