Skip to content

Commit b592514

Browse files
perf: skip unmodifiableMap wrapper when hookHints is empty (#1953)
* perf: skip unmodifiableMap wrapper when hookHints is empty Signed-off-by: Tobias Ibounig <tobias.ibounig@dynatrace.com> * ensure hookHints non null via builder, added test Signed-off-by: Tobias Ibounig <tobias.ibounig@dynatrace.com> * test null does not throw exception Signed-off-by: Tobias Ibounig <tobias.ibounig@dynatrace.com> * spotless Signed-off-by: Tobias Ibounig <tobias.ibounig@dynatrace.com> --------- Signed-off-by: Tobias Ibounig <tobias.ibounig@dynatrace.com> Co-authored-by: Todd Baert <todd.baert@dynatrace.com>
1 parent 50da905 commit b592514

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

src/main/java/dev/openfeature/sdk/FlagEvaluationOptions.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.openfeature.sdk;
22

3+
import java.util.Collections;
34
import java.util.HashMap;
45
import java.util.List;
56
import java.util.Map;
@@ -19,4 +20,13 @@ public class FlagEvaluationOptions {
1920

2021
@Builder.Default
2122
Map<String, Object> hookHints = new HashMap<>();
23+
24+
public static class FlagEvaluationOptionsBuilder {
25+
/** Sets hook hints, normalizing null to an empty map. */
26+
public FlagEvaluationOptionsBuilder hookHints(Map<String, Object> hookHints) {
27+
this.hookHints$value = hookHints != null ? hookHints : Collections.emptyMap();
28+
this.hookHints$set = true;
29+
return this;
30+
}
31+
}
2232
}

src/main/java/dev/openfeature/sdk/OpenFeatureClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ private <T> FlagEvaluationDetails<T> evaluateFlag(
172172
flagOptions = options;
173173
}
174174

175-
hookSupportData.hints = Collections.unmodifiableMap(flagOptions.getHookHints());
175+
var hookHints = flagOptions.getHookHints();
176+
hookSupportData.hints = hookHints.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(hookHints);
176177
var context = new LayeredEvaluationContext(
177178
openfeatureApi.getEvaluationContext(),
178179
openfeatureApi.getTransactionContext(),

src/test/java/dev/openfeature/sdk/HookSpecTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,27 @@ void missing_hook_hints() {
510510
assertTrue(feo.getHookHints().isEmpty());
511511
}
512512

513+
@Test
514+
void null_hook_hints_does_not_throw() {
515+
Hook hook = mockBooleanHook();
516+
FeatureProvider provider = mock(FeatureProvider.class);
517+
when(provider.getBooleanEvaluation(any(), any(), any()))
518+
.thenReturn(ProviderEvaluation.<Boolean>builder().value(true).build());
519+
520+
api.setProviderAndWait(provider);
521+
Client client = api.getClient();
522+
523+
assertThatCode(() -> client.getBooleanValue(
524+
"key",
525+
false,
526+
new ImmutableContext(),
527+
FlagEvaluationOptions.builder()
528+
.hook(hook)
529+
.hookHints(null)
530+
.build()))
531+
.doesNotThrowAnyException();
532+
}
533+
513534
@Test
514535
void flag_eval_hook_order() {
515536
Hook hook = mockBooleanHook();

0 commit comments

Comments
 (0)