[rrd4j] Improve performance (#8929)
* [rrd4j] Improve performance * Cache item to improve performance * Also return DecimalType for QuantityType values Related to #8928 Reintroduces #8809 Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
parent
b82d5f8063
commit
603ceedff9
|
@ -18,7 +18,6 @@ import java.time.Instant;
|
|||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -154,7 +153,7 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
sample.setValue(DATASOURCE_STATE, lastValue);
|
||||
sample.update();
|
||||
logger.debug("Stored '{}' with state '{}' in rrd4j database (again)", name,
|
||||
mapToState(lastValue, item.getName()));
|
||||
mapToState(lastValue, item));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -199,7 +198,8 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
logger.debug("Stored '{}' with state '{}' in rrd4j database", name, value);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (e.getMessage().contains("at least one second step is required")) {
|
||||
String message = e.getMessage();
|
||||
if (message != null && message.contains("at least one second step is required")) {
|
||||
// we try to store the value one second later
|
||||
ScheduledFuture<?> job = scheduledJobs.get(name);
|
||||
if (job != null) {
|
||||
|
@ -230,9 +230,20 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
@Override
|
||||
public Iterable<HistoricItem> query(FilterCriteria filter) {
|
||||
String itemName = filter.getItemName();
|
||||
|
||||
RrdDb db = getDB(itemName);
|
||||
if (db != null) {
|
||||
ConsolFun consolidationFunction = getConsolidationFunction(db);
|
||||
if (db == null) {
|
||||
logger.debug("Could not find item '{}' in rrd4j database", itemName);
|
||||
return List.of();
|
||||
}
|
||||
|
||||
Item item = null;
|
||||
try {
|
||||
item = itemRegistry.getItem(itemName);
|
||||
} catch (ItemNotFoundException e) {
|
||||
logger.debug("Could not find item '{}' in registry", itemName);
|
||||
}
|
||||
|
||||
long start = 0L;
|
||||
long end = filter.getEndDate() == null ? System.currentTimeMillis() / 1000
|
||||
: filter.getEndDate().toInstant().getEpochSecond();
|
||||
|
@ -251,13 +262,12 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
// we are asked only for the most recent value!
|
||||
double lastValue = db.getLastDatasourceValue(DATASOURCE_STATE);
|
||||
if (!Double.isNaN(lastValue)) {
|
||||
HistoricItem rrd4jItem = new RRD4jItem(itemName, mapToState(lastValue, itemName),
|
||||
ZonedDateTime.ofInstant(
|
||||
Instant.ofEpochMilli(db.getLastArchiveUpdateTime() * 1000),
|
||||
HistoricItem rrd4jItem = new RRD4jItem(itemName, mapToState(lastValue, item),
|
||||
ZonedDateTime.ofInstant(Instant.ofEpochMilli(db.getLastArchiveUpdateTime() * 1000),
|
||||
ZoneId.systemDefault()));
|
||||
return Collections.singletonList(rrd4jItem);
|
||||
return List.of(rrd4jItem);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
return List.of();
|
||||
}
|
||||
} else {
|
||||
start = end;
|
||||
|
@ -269,15 +279,16 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
} else {
|
||||
start = filter.getBeginDate().toInstant().getEpochSecond();
|
||||
}
|
||||
FetchRequest request = db.createFetchRequest(consolidationFunction, start, end, 1);
|
||||
|
||||
FetchRequest request = db.createFetchRequest(getConsolidationFunction(db), start, end, 1);
|
||||
FetchData result = request.fetchData();
|
||||
|
||||
List<HistoricItem> items = new ArrayList<>();
|
||||
FetchData result = request.fetchData();
|
||||
long ts = result.getFirstTimestamp();
|
||||
long step = result.getRowCount() > 1 ? result.getStep() : 0;
|
||||
for (double value : result.getValues(DATASOURCE_STATE)) {
|
||||
if (!Double.isNaN(value) && (((ts >= start) && (ts <= end)) || (start == end))) {
|
||||
RRD4jItem rrd4jItem = new RRD4jItem(itemName, mapToState(value, itemName),
|
||||
RRD4jItem rrd4jItem = new RRD4jItem(itemName, mapToState(value, item),
|
||||
ZonedDateTime.ofInstant(Instant.ofEpochMilli(ts * 1000), ZoneId.systemDefault()));
|
||||
items.add(rrd4jItem);
|
||||
}
|
||||
|
@ -286,17 +297,16 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
return items;
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not query rrd4j database for item '{}': {}", itemName, e.getMessage());
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<PersistenceItemInfo> getItemInfo() {
|
||||
return Collections.emptySet();
|
||||
return Set.of();
|
||||
}
|
||||
|
||||
protected @Nullable synchronized RrdDb getDB(String alias) {
|
||||
protected synchronized @Nullable RrdDb getDB(String alias) {
|
||||
RrdDb db = null;
|
||||
File file = new File(DB_FOLDER + File.separator + alias + ".rrd");
|
||||
try {
|
||||
|
@ -383,10 +393,7 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private State mapToState(double value, String itemName) {
|
||||
try {
|
||||
Item item = itemRegistry.getItem(itemName);
|
||||
private State mapToState(double value, @Nullable Item item) {
|
||||
if (item instanceof SwitchItem && !(item instanceof DimmerItem)) {
|
||||
return value == 0.0d ? OnOffType.OFF : OnOffType.ON;
|
||||
} else if (item instanceof ContactItem) {
|
||||
|
@ -394,18 +401,9 @@ public class RRD4jPersistenceService implements QueryablePersistenceService {
|
|||
} else if (item instanceof DimmerItem || item instanceof RollershutterItem) {
|
||||
// make sure Items that need PercentTypes instead of DecimalTypes do receive the right information
|
||||
return new PercentType((int) Math.round(value * 100));
|
||||
} else if (item instanceof NumberItem) {
|
||||
Unit<? extends Quantity<?>> unit = ((NumberItem) item).getUnit();
|
||||
if (unit != null) {
|
||||
return new QuantityType(value, unit);
|
||||
} else {
|
||||
return new DecimalType(value);
|
||||
}
|
||||
}
|
||||
} catch (ItemNotFoundException e) {
|
||||
logger.debug("Could not find item '{}' in registry", itemName);
|
||||
}
|
||||
// just return a DecimalType as a fallback
|
||||
// return a DecimalType as a fallback and for QuantityType values to prevent performance issues
|
||||
// see: https://github.com/openhab/openhab-addons/issues/8928
|
||||
return new DecimalType(value);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue