Skip to content

Commit

Permalink
Merge pull request #2524 from IBM/tbieste-issue-2155
Browse files Browse the repository at this point in the history
Issue #2155 - Use hash to determine if search parameters need update
  • Loading branch information
tbieste authored Jun 30, 2021
2 parents ced088f + cd99fac commit 70738cf
Show file tree
Hide file tree
Showing 21 changed files with 1,566 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ public class ReindexResourceDAO extends ResourceDAOImpl {
private final ParameterDAO parameterDao;

private static final String PICK_SINGLE_LOGICAL_RESOURCE = ""
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid "
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid, lr.parameter_hash "
+ " FROM logical_resources lr "
+ " WHERE lr.logical_resource_id = ? "
+ " AND lr.is_deleted = 'N' "
+ " AND lr.reindex_tstamp < ? "
;

private static final String PICK_SINGLE_RESOURCE = ""
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid "
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid, lr.parameter_hash "
+ " FROM logical_resources lr "
+ " WHERE lr.resource_type_id = ? "
+ " AND lr.logical_id = ? "
Expand All @@ -66,7 +66,7 @@ public class ReindexResourceDAO extends ResourceDAOImpl {
;

private static final String PICK_SINGLE_RESOURCE_TYPE = ""
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid "
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid, lr.parameter_hash "
+ " FROM logical_resources lr "
+ " WHERE lr.resource_type_id = ? "
+ " AND lr.is_deleted = 'N' "
Expand All @@ -75,7 +75,7 @@ public class ReindexResourceDAO extends ResourceDAOImpl {
;

private static final String PICK_ANY_RESOURCE = ""
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid "
+ " SELECT lr.logical_resource_id, lr.resource_type_id, lr.logical_id, lr.reindex_txid, lr.parameter_hash "
+ " FROM logical_resources lr "
+ " WHERE lr.is_deleted = 'N' "
+ " AND lr.reindex_tstamp < ? "
Expand Down Expand Up @@ -152,7 +152,7 @@ protected ResourceIndexRecord getResource(Instant reindexTstamp, Long logicalRes
}
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4));
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4), rs.getString(5));
}
} catch (SQLException x) {
logger.log(Level.SEVERE, select, x);
Expand Down Expand Up @@ -219,7 +219,7 @@ protected ResourceIndexRecord getNextResource(SecureRandom random, Instant reind
}
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4));
result = new ResourceIndexRecord(rs.getLong(1), rs.getInt(2), rs.getString(3), rs.getLong(4), rs.getString(5));
}
} catch (SQLException x) {
logger.log(Level.SEVERE, select, x);
Expand Down Expand Up @@ -327,12 +327,13 @@ public ResourceIndexRecord getResourceToReindex(Instant reindexTstamp, Long logi
/**
* Reindex the resource by deleting existing parameters and replacing them with those passed in.
* @param tablePrefix the table prefix
* @param parameters the extracted parameters
* @param parameters A collection of search parameters to be persisted along with the passed Resource
* @param parameterHashB64 the Base64 encoded SHA-256 hash of parameters
* @param logicalId the logical id
* @param logicalResourceId the logical resource id
* @throws Exception
*/
public void updateParameters(String tablePrefix, List<ExtractedParameterValue> parameters, String logicalId, long logicalResourceId) throws Exception {
public void updateParameters(String tablePrefix, List<ExtractedParameterValue> parameters, String parameterHashB64, String logicalId, long logicalResourceId) throws Exception {

final String METHODNAME = "updateParameters() for " + tablePrefix + "/" + logicalId;
logger.entering(CLASSNAME, METHODNAME);
Expand All @@ -355,6 +356,35 @@ identityCache, getResourceReferenceDAO(), getTransactionData())) {
throw translator.translate(x);
}
}

// Update the parameter hash in the LOGICAL_RESOURCES table
updateParameterHash(connection, logicalResourceId, parameterHashB64);

logger.exiting(CLASSNAME, METHODNAME);
}

/**
* Updates the parameter hash in the LOGICAL_RESOURCES table.
* @param conn the connection
* @param logicalResourceId the logical resource ID
* @param parameterHashB64 the Base64 encoded SHA-256 hash of parameters
* @throws SQLException
*/
protected void updateParameterHash(Connection conn, long logicalResourceId, String parameterHashB64) throws SQLException {
final String SQL = "UPDATE logical_resources SET parameter_hash = ? WHERE logical_resource_id = ?";
try (PreparedStatement stmt = conn.prepareStatement(SQL)) {
// bind parameters
stmt.setString(1, parameterHashB64);
stmt.setLong(2, logicalResourceId);
long dbCallStartTime = System.nanoTime();
stmt.executeUpdate();
double dbCallDuration = (System.nanoTime() - dbCallStartTime) / 1e6;
if (logger.isLoggable(Level.FINEST)) {
logger.finest("Update parameter_hash '" + parameterHashB64 + "' for logicalResourceId '" + logicalResourceId + "' [took " + dbCallDuration + " ms]");
}
} catch (SQLException x) {
logger.log(Level.SEVERE, SQL, x);
throw translator.translate(x);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,15 @@ public class ResourceIndexRecord {
// Deletion flag for the resource. Set when we read the resource
private boolean deleted;

public ResourceIndexRecord(long logicalResourceId, int resourceTypeId, String logicalId, long transactionId) {
// Base64-encoded SHA-256 hash of the search parameters
private String parameterHash;

public ResourceIndexRecord(long logicalResourceId, int resourceTypeId, String logicalId, long transactionId, String parameterHash) {
this.logicalResourceId = logicalResourceId;
this.resourceTypeId = resourceTypeId;
this.logicalId = logicalId;
this.transactionId = transactionId;
this.parameterHash = parameterHash;
}

/**
Expand Down Expand Up @@ -92,4 +96,20 @@ public boolean isDeleted() {
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}

/**
* Gets the Base64-encoded SHA-256 hash of the search parameters.
* @return the Base64-encoded SHA-256 hash
*/
public String getParameterHash() {
return parameterHash;
}

/**
* Gets the Base64-encoded SHA-256 hash of the search parameters.
* @param parameterHash the Base64-encoded SHA-256 hash
*/
public void setParameterHash(String parameterHash) {
this.parameterHash = parameterHash;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ public CompositeParmVal() {
component = new ArrayList<>(2);
}

/**
* We know our type, so we can call the correct method on the visitor
*/
public void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException {
visitor.visit(this);
}

/**
* @return get the list of components in this composite parameter
*/
Expand All @@ -54,4 +47,42 @@ public void addComponent(ExtractedParameterValue... component) {
this.component.add(value);
}
}

/**
* We know our type, so we can call the correct method on the visitor
*/
@Override
public void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException {
visitor.visit(this);
}

@Override
protected int compareToInner(ExtractedParameterValue o) {
CompositeParmVal other = (CompositeParmVal) o;
int retVal;

List<ExtractedParameterValue> thisComponent = this.getComponent();
List<ExtractedParameterValue> otherComponent = other.getComponent();
if (thisComponent != null || otherComponent != null) {
if (thisComponent == null) {
return -1;
} else if (otherComponent == null) {
return 1;
}
Integer thisSize = thisComponent.size();
Integer otherSize = otherComponent.size();
for (int i=0; i<thisSize && i<otherSize; i++) {
retVal = thisComponent.get(i).compareTo(otherComponent.get(i));
if (retVal != 0) {
return retVal;
}
}
retVal = thisSize.compareTo(otherSize);
if (retVal != 0) {
return retVal;
}
}

return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,50 @@ public void setValueDateEnd(Timestamp valueDateEnd) {
/**
* We know our type, so we can call the correct method on the visitor
*/
@Override
public void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException {
visitor.visit(this);
}

@Override
protected int compareToInner(ExtractedParameterValue o) {
DateParmVal other = (DateParmVal) o;
int retVal;

Timestamp thisValueDateStart = this.getValueDateStart();
Timestamp otherValueDateStart = other.getValueDateStart();
if (thisValueDateStart != null || otherValueDateStart != null) {
if (thisValueDateStart == null) {
return -1;
} else if (otherValueDateStart == null) {
return 1;
}
retVal = thisValueDateStart.compareTo(otherValueDateStart);
if (retVal != 0) {
return retVal;
}
}

Timestamp thisValueDateEnd = this.getValueDateEnd();
Timestamp otherValueDateEnd = other.getValueDateEnd();
if (thisValueDateEnd != null || otherValueDateEnd != null) {
if (thisValueDateEnd == null) {
return -1;
} else if (otherValueDateEnd == null) {
return 1;
}
retVal = thisValueDateEnd.compareTo(otherValueDateEnd);
if (retVal != 0) {
return retVal;
}
}

return 0;
}

@Override
public String toString() {
return "DateParmVal [resourceType=" + getResourceType() + ", name=" + getName()
+ ", valueDateStart=" + valueDateStart + ", valueDateEnd=" + valueDateEnd + ", base=" + getBase() + "]";
+ ", valueDateStart=" + valueDateStart + ", valueDateEnd=" + valueDateEnd + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* A search parameter value extracted from a resource and ready to store / index for search
*/
public abstract class ExtractedParameterValue {
public abstract class ExtractedParameterValue implements Comparable<ExtractedParameterValue> {

// The name (code) of this parameter
private String name;
Expand All @@ -22,8 +22,9 @@ public abstract class ExtractedParameterValue {
// The resource type associated with this parameter
private String resourceType;

// The base resource name
private String base;
// URL and version of search parameter
private String url;
private String version;

/**
* Protected constructor
Expand Down Expand Up @@ -52,20 +53,6 @@ public void setResourceType(String resourceType) {
*/
public abstract void accept(ExtractedParameterValueVisitor visitor) throws FHIRPersistenceException;

/**
* @return the base
*/
public String getBase() {
return this.base;
}

/**
* @param base the base to set
*/
public void setBase(String base) {
this.base = base;
}

/**
* @return the wholeSystem
*/
Expand Down Expand Up @@ -93,4 +80,99 @@ public String getName() {
public void setName(String name) {
this.name = name;
}

/**
* @return the url
*/
public String getUrl() {
return url;
}

/**
* @param url the url to set
*/
public void setUrl(String url) {
this.url = url;
}

/**
* @return the version
*/
public String getVersion() {
return version;
}

/**
* @param version the version to set
*/
public void setVersion(String version) {
this.version = version;
}

@Override
public int compareTo(ExtractedParameterValue o) {
int retVal;
String thisName = this.getName();
String otherName = o.getName();
if (thisName != null || otherName != null) {
if (thisName == null) {
return -1;
} else if (otherName == null) {
return 1;
}
retVal = thisName.compareTo(otherName);
if (retVal != 0) {
return retVal;
}
}
String thisUrl = this.getUrl();
String otherUrl = o.getUrl();
if (thisUrl != null || otherUrl != null) {
if (thisUrl == null) {
return -1;
} else if (otherUrl == null) {
return 1;
}
retVal = thisUrl.compareTo(otherUrl);
if (retVal != 0) {
return retVal;
}
}
String thisVersion = this.getVersion();
String otherVersion = o.getVersion();
if (thisVersion != null || otherVersion != null) {
if (thisVersion == null) {
return -1;
} else if (otherVersion == null) {
return 1;
}
retVal = thisVersion.compareTo(otherVersion);
if (retVal != 0) {
return retVal;
}
}
String thisClass = this.getClass().getName();
String otherClass = o.getClass().getName();
if (thisClass != null || otherClass != null) {
if (thisClass == null) {
return -1;
} else if (otherClass == null) {
return 1;
}
retVal = thisClass.compareTo(otherClass);
if (retVal != 0) {
return retVal;
}
}
return compareToInner(o);
}

/**
* Additional extracted parameter value comparisions when the same class.
* @param o an extracted parameter value to compare to
* @return a negative integer, zero, or a positive integer as this extracted parameter value
* is less than, equal to, or greater than the specified extracted parameter value.
*/
protected abstract int compareToInner(ExtractedParameterValue o);

}
Loading

0 comments on commit 70738cf

Please sign in to comment.