ResourceIndexedSearchParamString: equals() and hashCode(): Add normalized String and use same fields for both calls. (#4148)

* Fix hashCode() to reflect equals() contract in ResourceIndexedSearchParamString.  Write ResourceIndexedSearchParamStringTest with new tests for normalized hashCode.

* Add un-hashed normalized value to ResourceIndexedSearchParamString equals() and hashCode() with comments about potential performance implications.

* Add changelog.  Remove TODOs.

* Inline hashCode.

* Fix comment and issue number and rename changelog.
This commit is contained in:
Luke deGruchy 2022-10-19 14:13:21 -04:00 committed by GitHub
parent 5a31ce0386
commit 0798ab35db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 0 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 4147
jira: SMILE-4256
title: "Previously when updating a phonetic search parameter, any existing resource will not have its search parameter String updated upon reindex if the normalized String is the same letter as under the old algorithm (ex JN to JAN). Searching on the new normalized String was failing to return results. This has been corrected."

View File

@ -171,6 +171,7 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
b.append(getHashIdentity(), obj.getHashIdentity()); b.append(getHashIdentity(), obj.getHashIdentity());
b.append(getHashExact(), obj.getHashExact()); b.append(getHashExact(), obj.getHashExact());
b.append(getHashNormalizedPrefix(), obj.getHashNormalizedPrefix()); b.append(getHashNormalizedPrefix(), obj.getHashNormalizedPrefix());
b.append(getValueNormalized(), obj.getValueNormalized());
return b.isEquals(); return b.isEquals();
} }
@ -239,6 +240,10 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP
b.append(getResourceType()); b.append(getResourceType());
b.append(getParamName()); b.append(getParamName());
b.append(getValueExact()); b.append(getValueExact());
b.append(getHashIdentity());
b.append(getHashExact());
b.append(getHashNormalizedPrefix());
b.append(getValueNormalized());
return b.toHashCode(); return b.toHashCode();
} }

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.model.entity;
import ca.uhn.fhir.jpa.model.config.PartitionSettings; import ca.uhn.fhir.jpa.model.config.PartitionSettings;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals;
@ -33,6 +34,40 @@ public class ResourceIndexedSearchParamStringTest {
assertEquals(7045214018927566109L, token.getHashExact().longValue()); assertEquals(7045214018927566109L, token.getHashExact().longValue());
} }
@Test
public void testHashFunctionsPrefixOnly_John_JN_vs_JAN() {
final ResourceIndexedSearchParamString token1 = new ResourceIndexedSearchParamString(new PartitionSettings(), new ModelConfig(), "Patient", "query-1-param", "JN", "John");
token1.setResource(new ResourceTable().setResourceType("Patient"));
token1.calculateHashes();
final ResourceIndexedSearchParamString token2 = new ResourceIndexedSearchParamString(new PartitionSettings(), new ModelConfig(), "Patient", "query-1-param", "JAN", "John");
token2.setResource(new ResourceTable().setResourceType("Patient"));
token2.calculateHashes();
assertAll(
// We only hash on the first letter for performance reasons
() -> assertEquals(token1.getHashNormalizedPrefix(), token2.getHashNormalizedPrefix()),
() -> assertEquals(token1.getHashExact(), token2.getHashExact()),
() -> assertNotEquals(token1.hashCode(), token2.hashCode())
);
}
@Test
public void testHashFunctionsPrefixOnly_Doe_T_vs_D() {
final ResourceIndexedSearchParamString token1 = new ResourceIndexedSearchParamString(new PartitionSettings(), new ModelConfig(), "Patient", "query-1-param", "T", "Doe");
token1.setResource(new ResourceTable().setResourceType("Patient"));
token1.calculateHashes();
final ResourceIndexedSearchParamString token2 = new ResourceIndexedSearchParamString(new PartitionSettings(), new ModelConfig(), "Patient", "query-1-param", "D", "Doe");
token2.setResource(new ResourceTable().setResourceType("Patient"));
token2.calculateHashes();
assertAll(
() -> assertNotEquals(token1.getHashNormalizedPrefix(), token2.getHashNormalizedPrefix()),
() -> assertEquals(token1.getHashExact(), token2.getHashExact()),
() -> assertNotEquals(token1.hashCode(), token2.hashCode())
);
}
@Test @Test
public void testEquals() { public void testEquals() {