validation optimisation

This commit is contained in:
Grahame Grieve 2021-04-12 11:22:43 +10:00
parent faae5a206f
commit a10fdb13e3
3 changed files with 55 additions and 9 deletions

View File

@ -133,7 +133,7 @@ public class TerminologyCache {
json.setOutputStyle(OutputStyle.PRETTY); json.setOutputStyle(OutputStyle.PRETTY);
ValueSet vsc = getVSEssense(vs); ValueSet vsc = getVSEssense(vs);
try { try {
ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : json.composeString(vsc))+(options == null ? "" : ", "+options.toJson())+"}"; ct.request = "{\"code\" : "+json.composeString(code, "code")+", \"valueSet\" :"+(vsc == null ? "null" : extracted(json, vsc))+(options == null ? "" : ", "+options.toJson())+"}";
} catch (IOException e) { } catch (IOException e) {
throw new Error(e); throw new Error(e);
} }
@ -141,6 +141,16 @@ public class TerminologyCache {
return ct; return ct;
} }
public String extracted(JsonParser json, ValueSet vsc) throws IOException {
String s = null;
if (vsc.getExpansion().getContains().size() > 1000 || vsc.getCompose().getIncludeFirstRep().getConcept().size() > 1000) {
s = Integer.toString(vsc.hashCode()); // turn caching off - hack efficiency optimisation
} else {
s = json.composeString(vsc);
}
return s;
}
public CacheToken generateValidationToken(ValidationOptions options, CodeableConcept code, ValueSet vs) { public CacheToken generateValidationToken(ValidationOptions options, CodeableConcept code, ValueSet vs) {
CacheToken ct = new CacheToken(); CacheToken ct = new CacheToken();
for (Coding c : code.getCoding()) { for (Coding c : code.getCoding()) {
@ -151,7 +161,7 @@ public class TerminologyCache {
json.setOutputStyle(OutputStyle.PRETTY); json.setOutputStyle(OutputStyle.PRETTY);
ValueSet vsc = getVSEssense(vs); ValueSet vsc = getVSEssense(vs);
try { try {
ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+json.composeString(vsc)+(options == null ? "" : ", "+options.toJson())+"}"; ct.request = "{\"code\" : "+json.composeString(code, "codeableConcept")+", \"valueSet\" :"+extracted(json, vsc)+(options == null ? "" : ", "+options.toJson())+"}";
} catch (IOException e) { } catch (IOException e) {
throw new Error(e); throw new Error(e);
} }
@ -186,7 +196,7 @@ public class TerminologyCache {
JsonParser json = new JsonParser(); JsonParser json = new JsonParser();
json.setOutputStyle(OutputStyle.PRETTY); json.setOutputStyle(OutputStyle.PRETTY);
try { try {
ct.request = "{\"hierarchical\" : "+(heirarchical ? "true" : "false")+", \"valueSet\" :"+json.composeString(vsc)+"}\r\n"; ct.request = "{\"hierarchical\" : "+(heirarchical ? "true" : "false")+", \"valueSet\" :"+extracted(json, vsc)+"}\r\n";
} catch (IOException e) { } catch (IOException e) {
throw new Error(e); throw new Error(e);
} }

View File

@ -722,7 +722,11 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
return true; return true;
} }
if (fetcher != null) { if (fetcher != null) {
try {
return fetcher.resolveURL(appContext, path, url, type); return fetcher.resolveURL(appContext, path, url, type);
} catch (Exception e) {
return false;
}
} }
return false; return false;
} }

View File

@ -21,8 +21,10 @@ import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
@ -30,6 +32,9 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
private FilesystemPackageCacheManager pcm; private FilesystemPackageCacheManager pcm;
private IWorkerContext context; private IWorkerContext context;
private IPackageInstaller installer; private IPackageInstaller installer;
private Map<String, Boolean> urlList = new HashMap<>();
private Map<String, String> pidList = new HashMap<>();
private Map<String, NpmPackage> pidMap = new HashMap<>();
public StandAloneValidatorFetcher(FilesystemPackageCacheManager pcm, IWorkerContext context, IPackageInstaller installer) { public StandAloneValidatorFetcher(FilesystemPackageCacheManager pcm, IWorkerContext context, IPackageInstaller installer) {
super(); super();
@ -70,15 +75,25 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
return !url.startsWith("http://hl7.org/fhir") && !type.equals("canonical"); return !url.startsWith("http://hl7.org/fhir") && !type.equals("canonical");
} }
// the next operations are expensive. we're going to cache them
if (urlList.containsKey(url)) {
return urlList.get(url);
}
if (base.equals("http://terminology.hl7.org")) { if (base.equals("http://terminology.hl7.org")) {
pid = "hl7.terminology"; pid = "hl7.terminology";
} else if (url.startsWith("http://hl7.org/fhir")) { } else if (url.startsWith("http://hl7.org/fhir")) {
pid = pcm.getPackageId(base); pid = pcm.getPackageId(base);
} else {
if (pidList.containsKey(base)) {
pid = pidList.get(base);
} else { } else {
pid = pcm.findCanonicalInLocalCache(base); pid = pcm.findCanonicalInLocalCache(base);
pidList.put(base, pid);
}
} }
ver = url.contains("|") ? url.substring(url.indexOf("|") + 1) : null; ver = url.contains("|") ? url.substring(url.indexOf("|") + 1) : null;
if (pid == null && Utilities.startsWithInList(url, "http://hl7.org/fhir", "http://terminology.hl7.org")) { if (pid == null && Utilities.startsWithInList(url, "http://hl7.org/fhir", "http://terminology.hl7.org")) {
urlList.put(url, false);
return false; return false;
} }
@ -87,15 +102,32 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
VersionURLInfo vu = VersionUtilities.parseVersionUrl(url); VersionURLInfo vu = VersionUtilities.parseVersionUrl(url);
if (vu != null) { if (vu != null) {
NpmPackage pi = pcm.loadPackage(VersionUtilities.packageForVersion(vu.getVersion()), VersionUtilities.getCurrentVersion(vu.getVersion())); NpmPackage pi = pcm.loadPackage(VersionUtilities.packageForVersion(vu.getVersion()), VersionUtilities.getCurrentVersion(vu.getVersion()));
return pi.hasCanonical(vu.getUrl()); boolean res = pi.hasCanonical(vu.getUrl());
urlList.put(url, res);
return res;
} }
} }
// ok maybe it's a reference to a package we know // ok maybe it's a reference to a package we know
if (pid != null) { if (pid != null) {
if (installer.packageExists(pid, ver)) { if ("sharedhealth.fhir.ca.common".equals(pid)) { // special case - optimise this
return false;
}
NpmPackage pi = null;
if (pidMap.containsKey(pid+"|"+ver)) {
pi = pidMap.get(pid+"|"+ver);
} else if (installer.packageExists(pid, ver)) {
try {
installer.loadPackage(pid, ver); installer.loadPackage(pid, ver);
NpmPackage pi = pcm.loadPackage(pid); pi = pcm.loadPackage(pid);
pidMap.put(pid+"|"+ver, pi);
} catch (Exception e) {
pidMap.put(pid+"|"+ver, null);
}
} else {
pidMap.put(pid+"|"+ver, null);
}
if (pi != null) {
return pi.hasCanonical(url); return pi.hasCanonical(url);
} }
} }