Skip to content

Commit d12ef3f

Browse files
committed
improve identity overrides segments keys
1 parent b0ad7d7 commit d12ef3f

File tree

1 file changed

+32
-6
lines changed

1 file changed

+32
-6
lines changed

src/main/java/com/flagsmith/mappers/EngineMappers.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ private static Map<String, SegmentContext> mapIdentityOverridesToSegments(
177177
List<FeatureContext> overridesKey = entry.getKey();
178178
List<String> identifiers = entry.getValue();
179179

180-
// Generate unique segment key
181-
String segmentKey = String.valueOf(overridesKey.hashCode());
180+
String segmentKey = generateVirtualSegmentKey(overridesKey);
182181

183182
// Create segment condition for identifier check
184183
SegmentCondition identifierCondition = new SegmentCondition()
@@ -191,17 +190,17 @@ private static Map<String, SegmentContext> mapIdentityOverridesToSegments(
191190
.withType(SegmentRule.Type.ALL)
192191
.withConditions(List.of(identifierCondition));
193192

194-
// Create overrides from FeatureContext objects (much cleaner now!)
193+
// Create overrides from FeatureContext objects
195194
List<FeatureContext> overrides = new ArrayList<>();
196195
for (FeatureContext featureContext : overridesKey) {
197196
// Copy the feature context for the override
198197
FeatureContext override = new FeatureContext(featureContext)
199-
.withKey(""); // Identity overrides are never multivariate, so no need to set key
198+
.withKey(""); // Identity overrides never carry multivariate options
200199
overrides.add(override);
201200
}
202201

203202
SegmentContext segmentContext = new SegmentContext()
204-
.withKey("")
203+
.withKey("") // Identity override segments never use % Split operator
205204
.withName("identity_overrides")
206205
.withRules(List.of(segmentRule))
207206
.withOverrides(overrides);
@@ -339,7 +338,7 @@ private static FeatureContext mapFeatureStateToFeatureContext(JsonNode featureSt
339338
for (JsonNode multivariateValue : sortedMultivariate) {
340339
FeatureValue variant = new FeatureValue()
341340
.withValue(getFeatureStateValue(
342-
multivariateValue.get("multivariate_feature_option"), "value"))
341+
multivariateValue.get("multivariate_feature_option"), "value"))
343342
.withWeight(multivariateValue.get("percentage_allocation").asDouble());
344343
variants.add(variant);
345344
}
@@ -387,4 +386,31 @@ private static SegmentContext mapSegmentToSegmentContext(JsonNode segment) {
387386
.withRules(rules)
388387
.withOverrides(overrides);
389388
}
389+
390+
/**
391+
* Generates a unique segment key based on feature contexts.
392+
* Uses a combination of feature names and values to ensure
393+
* uniqueness.
394+
*
395+
* @param featureContexts list of feature contexts
396+
* @return unique segment key
397+
*/
398+
private static String generateVirtualSegmentKey(
399+
List<FeatureContext> featureContexts) {
400+
StringBuilder keyBuilder = new StringBuilder();
401+
402+
// Add feature information to the key
403+
for (FeatureContext featureContext : featureContexts) {
404+
keyBuilder.append(featureContext.getName())
405+
.append(":")
406+
.append(featureContext.getEnabled())
407+
.append(":")
408+
.append(featureContext.getValue())
409+
.append("|");
410+
}
411+
412+
// Generate a hash of the combined string for a shorter key
413+
// This is safer than using List.hashCode() as we control the string content
414+
return String.valueOf(keyBuilder.toString().hashCode());
415+
}
390416
}

0 commit comments

Comments
 (0)