Performance improvements

Signed-off-by: Taylor Smock <tsmock@meta.com>
pull/50/head
Taylor Smock 2024-10-31 13:55:36 -06:00
rodzic 87274baa62
commit 551e26ef8e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 3D4E7B422350E843
5 zmienionych plików z 47 dodań i 44 usunięć

Wyświetl plik

@ -10,10 +10,7 @@ import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Utils; import org.openstreetmap.josm.tools.Utils;
import jakarta.json.Json; import jakarta.json.Json;
import jakarta.json.JsonObject; import jakarta.json.stream.JsonParser;
import jakarta.json.JsonReader;
import jakarta.json.JsonStructure;
import jakarta.json.JsonValue;
import jakarta.json.stream.JsonParsingException; import jakarta.json.stream.JsonParsingException;
/** /**
@ -44,12 +41,12 @@ public abstract class CommonSourceReader<T> implements AutoCloseable {
this.cachedFile = new CachedFile(this.source); this.cachedFile = new CachedFile(this.source);
} }
this.cachedFile.setFastFail(this.fastFail); this.cachedFile.setFastFail(this.fastFail);
try (JsonReader reader = Json.createReader(cachedFile.setMaxAge(CachedFile.DAYS) try (JsonParser reader = Json.createParser(cachedFile.setMaxAge(CachedFile.DAYS)
.setCachingStrategy(CachedFile.CachingStrategy.IfModifiedSince).getContentReader())) { .setCachingStrategy(CachedFile.CachingStrategy.IfModifiedSince).getContentReader())) {
JsonStructure struct = reader.read(); while (reader.hasNext()) {
if (JsonValue.ValueType.OBJECT == struct.getValueType()) { if (reader.hasNext() && reader.next() == JsonParser.Event.START_OBJECT) {
final var jsonObject = struct.asJsonObject(); return Optional.ofNullable(this.parseJson(reader));
return Optional.ofNullable(this.parseJson(jsonObject)); }
} }
} catch (JsonParsingException jsonParsingException) { } catch (JsonParsingException jsonParsingException) {
Logging.error(jsonParsingException); Logging.error(jsonParsingException);
@ -60,10 +57,10 @@ public abstract class CommonSourceReader<T> implements AutoCloseable {
/** /**
* Parses MapWithAI entry sources * Parses MapWithAI entry sources
* *
* @param jsonObject The json of the data sources * @param parser The json of the data sources. This will be in the {@link JsonParser.Event#START_OBJECT} state.
* @return The parsed entries * @return The parsed entries
*/ */
public abstract T parseJson(JsonObject jsonObject); public abstract T parseJson(JsonParser parser);
/** /**
* Sets whether opening HTTP connections should fail fast, i.e., whether a * Sets whether opening HTTP connections should fail fast, i.e., whether a

Wyświetl plik

@ -10,9 +10,9 @@ import java.util.stream.Collectors;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory; import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
import org.openstreetmap.josm.tools.Pair; import org.openstreetmap.josm.tools.Pair;
import jakarta.json.JsonObject;
import jakarta.json.JsonString; import jakarta.json.JsonString;
import jakarta.json.JsonValue; import jakarta.json.JsonValue;
import jakarta.json.stream.JsonParser;
/** /**
* Read conflation entries from JSON * Read conflation entries from JSON
@ -44,12 +44,12 @@ public class ConflationSourceReader extends CommonSourceReader<Map<MapWithAICate
/** /**
* Parses MapWithAI entry sources * Parses MapWithAI entry sources
* *
* @param jsonObject The json of the data sources * @param parser The json of the data sources
* @return The parsed entries * @return The parsed entries
*/ */
@Override @Override
public Map<MapWithAICategory, List<String>> parseJson(JsonObject jsonObject) { public Map<MapWithAICategory, List<String>> parseJson(JsonParser parser) {
return jsonObject.entrySet().stream().flatMap(i -> parse(i).stream()) return parser.getObjectStream().flatMap(i -> parse(i).stream())
.collect(Collectors.groupingBy(p -> p.a, Collectors.mapping(p -> p.b, Collectors.toList()))); .collect(Collectors.groupingBy(p -> p.a, Collectors.mapping(p -> p.b, Collectors.toList())));
} }

Wyświetl plik

@ -164,7 +164,7 @@ public class ESRISourceReader {
newInfo.setName(feature.getString("title", feature.getString("name"))); newInfo.setName(feature.getString("title", feature.getString("name")));
final var extent = feature.getJsonArray("extent").getValuesAs(JsonArray.class).stream() final var extent = feature.getJsonArray("extent").getValuesAs(JsonArray.class).stream()
.flatMap(array -> array.getValuesAs(JsonNumber.class).stream()).map(JsonNumber::doubleValue) .flatMap(array -> array.getValuesAs(JsonNumber.class).stream()).map(JsonNumber::doubleValue)
.map(Object::toString).toArray(String[]::new); .map(d -> Double.toString(d)).toArray(String[]::new);
final var imageryBounds = new ImageryBounds(String.join(",", extent[1], extent[0], extent[3], extent[2]), ","); final var imageryBounds = new ImageryBounds(String.join(",", extent[1], extent[0], extent[3], extent[2]), ",");
newInfo.setBounds(imageryBounds); newInfo.setBounds(imageryBounds);
newInfo.setSourceType(MapWithAIType.ESRI_FEATURE_SERVER); newInfo.setSourceType(MapWithAIType.ESRI_FEATURE_SERVER);

Wyświetl plik

@ -17,9 +17,9 @@ import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIType; import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIType;
import org.openstreetmap.josm.tools.Territories; import org.openstreetmap.josm.tools.Territories;
import jakarta.json.JsonObject;
import jakarta.json.JsonString; import jakarta.json.JsonString;
import jakarta.json.JsonValue; import jakarta.json.JsonValue;
import jakarta.json.stream.JsonParser;
/** /**
* Reader to parse the list of available MapWithAI servers from an JSON * Reader to parse the list of available MapWithAI servers from an JSON
@ -54,12 +54,12 @@ public class MapWithAISourceReader extends CommonSourceReader<List<MapWithAIInfo
/** /**
* Parses MapWithAI entry sources * Parses MapWithAI entry sources
* *
* @param jsonObject The json of the data sources * @param parser The json of the data sources
* @return The parsed entries * @return The parsed entries
*/ */
@Override @Override
public List<MapWithAIInfo> parseJson(JsonObject jsonObject) { public List<MapWithAIInfo> parseJson(JsonParser parser) {
return jsonObject.entrySet().stream().map(MapWithAISourceReader::parse).collect(Collectors.toList()); return parser.getObjectStream().map(MapWithAISourceReader::parse).collect(Collectors.toList());
} }
private static MapWithAIInfo parse(Map.Entry<String, JsonValue> entry) { private static MapWithAIInfo parse(Map.Entry<String, JsonValue> entry) {

Wyświetl plik

@ -9,6 +9,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.imagery.ImageryInfo; import org.openstreetmap.josm.data.imagery.ImageryInfo;
@ -23,6 +25,7 @@ import jakarta.json.JsonArray;
import jakarta.json.JsonObject; import jakarta.json.JsonObject;
import jakarta.json.JsonString; import jakarta.json.JsonString;
import jakarta.json.JsonValue; import jakarta.json.JsonValue;
import jakarta.json.stream.JsonParser;
/** /**
* Read data from overture sources * Read data from overture sources
@ -36,33 +39,36 @@ public class OvertureSourceReader extends CommonSourceReader<List<MapWithAIInfo>
} }
@Override @Override
public List<MapWithAIInfo> parseJson(JsonObject jsonObject) { public List<MapWithAIInfo> parseJson(JsonParser jsonParser) {
final var jsonObject = jsonParser.getObject();
if (jsonObject.containsKey("releases")) { if (jsonObject.containsKey("releases")) {
return parseRoot(jsonObject);
}
return Collections.emptyList();
}
private List<MapWithAIInfo> parseRoot(JsonObject jsonObject) {
final var info = new ArrayList<MapWithAIInfo>(6 * 4); final var info = new ArrayList<MapWithAIInfo>(6 * 4);
final var releases = jsonObject.get("releases"); final var releases = jsonObject.get("releases");
final var baseUri = URI.create(this.source.getUrl()).resolve("./"); // safe since we created an URI from the source to get to this point final var baseUri = URI.create(this.source.getUrl()).resolve("./"); // safe since we created an URI from the source to get to this point
if (releases instanceof JsonArray rArray) { if (releases instanceof JsonArray rArray) {
for (JsonValue value : rArray) { rArray.parallelStream().flatMap(value -> parseReleases(baseUri, value)).filter(Objects::nonNull)
if (value instanceof JsonObject release && release.containsKey("release_id") .forEachOrdered(info::add);
&& release.containsKey("files")) {
final var id = release.get("release_id");
final var files = release.get("files");
if (id instanceof JsonString sId && files instanceof JsonArray fArray) {
final String releaseId = sId.getString();
for (JsonValue file : fArray) {
final var newInfo = parseFile(baseUri, releaseId, file);
if (newInfo != null) {
info.add(newInfo);
}
}
}
}
}
} }
info.trimToSize(); info.trimToSize();
return info; return info;
} }
return Collections.emptyList();
private Stream<MapWithAIInfo> parseReleases(URI baseUri, JsonValue value) {
if (value instanceof JsonObject release && release.containsKey("release_id") && release.containsKey("files")) {
final var id = release.get("release_id");
final var files = release.get("files");
if (id instanceof JsonString sId && files instanceof JsonArray fArray) {
final String releaseId = sId.getString();
return fArray.parallelStream().map(file -> parseFile(baseUri, releaseId, file));
}
}
return Stream.empty();
} }
/** /**