Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getIdentifiable optimization #16

Merged
merged 10 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions network-store-integration-test/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@
<artifactId>powsybl-ucte-converter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.powsybl</groupId>
<artifactId>powsybl-ieee-cdf-converter</artifactId>
<scope>test</scope>
</dependency>

<!-- Added so that the aggregated jacoco report takes it into account -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.powsybl.entsoe.util.EntsoeArea;
import com.powsybl.entsoe.util.EntsoeAreaImpl;
import com.powsybl.entsoe.util.EntsoeGeographicalCode;
import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.*;
import com.powsybl.iidm.network.test.*;
Expand Down Expand Up @@ -4071,4 +4072,62 @@ public void testFixNpeGetIdentifiable() {
assertEquals(2, twt2.getRatioTapChanger().getHighTapPosition());
}
}

@Test
public void testGetIdentifiablePerf() {
List<String> lineIds;
try (NetworkStoreService service = createNetworkStoreService(randomServerPort)) {
Network network = IeeeCdfNetworkFactory.create14(service.getNetworkFactory());
lineIds = network.getLineStream().map(Identifiable::getId).toList();
service.flush(network);
}

RestClientMetrics metrics = new RestClientMetrics();
assertEquals(0, metrics.oneGetterCallCount);
assertEquals(0, metrics.allGetterCallCount);
try (NetworkStoreService service = createNetworkStoreService(metrics, randomServerPort)) {
Map<UUID, String> networkIds = service.getNetworkIds();
UUID networkUuid = networkIds.keySet().stream().findFirst().orElseThrow();
Network network = service.getNetwork(networkUuid);
for (String id : lineIds.stream().limit(3).toList()) {
network.getIdentifiable(id);
}
assertEquals(4, metrics.oneGetterCallCount); // network + 3 lines
assertEquals(0, metrics.allGetterCallCount);

// we are under the threshold, we don't have downloaded the IDs of all existing identifiables
// and so on accessing a non-existing identifiable without having download the full collection
// need to access the server
network.getIdentifiable("FOO");
assertEquals(5, metrics.oneGetterCallCount);
assertEquals(0, metrics.allGetterCallCount);
}

metrics = new RestClientMetrics();
assertEquals(0, metrics.oneGetterCallCount);
assertEquals(0, metrics.allGetterCallCount);
try (NetworkStoreService service = createNetworkStoreService(metrics, randomServerPort)) {
Map<UUID, String> networkIds = service.getNetworkIds();
UUID networkUuid = networkIds.keySet().stream().findFirst().orElseThrow();
Network network = service.getNetwork(networkUuid);

for (String id : lineIds.stream().limit(16).toList()) { // only the last one is not get
network.getIdentifiable(id);
}
assertEquals(17, metrics.oneGetterCallCount); // one network + 16 lines
assertEquals(0, metrics.allGetterCallCount);

// no more server access because we have downloaded the IDs of all existing identifiables and we know
// that FOO does not exist in the network
network.getIdentifiable("FOO");
assertEquals(17, metrics.oneGetterCallCount);
assertEquals(0, metrics.allGetterCallCount);

network.getIdentifiable("L13-14-1"); // the last one
// it is part of the network and thanks to all IDs download we know that we need to request it from the
// server
assertEquals(18, metrics.oneGetterCallCount);
assertEquals(0, metrics.allGetterCallCount);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1423,4 +1423,15 @@ public ResponseEntity<TopLevelDocument<IdentifiableAttributes>> getIdentifiable(
@Parameter(description = "Identifiable ID", required = true) @PathVariable("id") String id) {
return get(() -> repository.getIdentifiable(networkId, variantNum, id));
}

@GetMapping(value = "/{networkUuid}/{variantNum}/identifiables-ids", produces = APPLICATION_JSON_VALUE)
@Operation(summary = "Get all identifiables IDs")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully get the all identifiables IDs"),
@ApiResponse(responseCode = "404", description = "The network has not been found")
})
public List<String> getIdentifiablesIds(@Parameter(description = "Network ID", required = true) @PathVariable("networkUuid") UUID networkUuid,
@Parameter(description = "Variant number", required = true) @PathVariable("variantNum") int variantNum) {
return repository.getIdentifiablesIds(networkUuid, variantNum);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,32 @@ public Optional<Resource<NetworkAttributes>> getNetwork(UUID uuid, int variantNu
}
}

public List<String> getIdentifiablesIds(UUID networkUuid, int variantNum) {
Stopwatch stopwatch = Stopwatch.createStarted();

List<String> ids = new ArrayList<>();
try (var connection = dataSource.getConnection()) {
for (String table : ELEMENT_TABLES) {
try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildGetIdsQuery(table))) {
preparedStmt.setObject(1, networkUuid);
preparedStmt.setObject(2, variantNum);
try (ResultSet resultSet = preparedStmt.executeQuery()) {
while (resultSet.next()) {
ids.add(resultSet.getString(1));
}
}
}
}
} catch (SQLException e) {
throw new UncheckedSqlException(e);
}

stopwatch.stop();
LOGGER.info("Get identifiables IDs done in {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));

return ids;
}

@FunctionalInterface
interface SqlExecutor {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -614,4 +614,11 @@ public static String buildDeleteTapChangerStepVariantEquipmentINQuery(int number
EQUIPMENT_ID_COLUMN + " in (" +
"?, ".repeat(numberOfValues - 1) + "?)";
}

public static String buildGetIdsQuery(String table) {
return "select " + ID_COLUMN +
" from " + table + " where " +
NETWORK_UUID_COLUMN + " = ? and " +
VARIANT_NUM_COLUMN + " = ?";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -781,4 +781,25 @@ public void insertTapChangerStepsInThreeWindingsTranformerTest() {
assertNull(res3WTransformerB.getAttributes().getLeg(3).getRatioTapChangerAttributes());
assertEquals(1, res3WTransformerB.getAttributes().getLeg(3).getPhaseTapChangerAttributes().getSteps().size());
}

@Test
public void test() {
Resource<LineAttributes> line1 = Resource.lineBuilder()
.id("line1")
.attributes(LineAttributes.builder()
.voltageLevelId1("vl1")
.voltageLevelId2("vl2")
.build())
.build();
Resource<LoadAttributes> load1 = Resource.loadBuilder()
.id("load1")
.attributes(LoadAttributes.builder()
.voltageLevelId("vl1")
.build())
.build();
networkStoreRepository.createLines(NETWORK_UUID, List.of(line1));
networkStoreRepository.createLoads(NETWORK_UUID, List.of(load1));
List<String> identifiablesIds = networkStoreRepository.getIdentifiablesIds(NETWORK_UUID, Resource.INITIAL_VARIANT_NUM);
assertEquals(List.of("load1", "line1"), identifiablesIds);
}
}
Loading