-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathRuleBasedSegmentMatcher.java
More file actions
99 lines (81 loc) · 3.38 KB
/
RuleBasedSegmentMatcher.java
File metadata and controls
99 lines (81 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package io.split.engine.matchers;
import io.split.client.dtos.ExcludedSegments;
import io.split.engine.evaluator.EvaluationContext;
import io.split.engine.experiments.ParsedCondition;
import io.split.engine.experiments.ParsedRuleBasedSegment;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A matcher that checks if the key is part of a user defined segment. This class
* assumes that the logic for refreshing what keys are part of a segment is delegated
* to SegmentFetcher.
*
* @author adil
*/
public class RuleBasedSegmentMatcher implements Matcher {
private final String standardType = "standard";
private final String ruleBasedType = "rule-based";
private final String _segmentName;
public RuleBasedSegmentMatcher(String segmentName) {
_segmentName = checkNotNull(segmentName);
}
@Override
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
if (!(matchValue instanceof String)) {
return false;
}
ParsedRuleBasedSegment parsedRuleBasedSegment = evaluationContext.getRuleBasedSegmentCache().get(_segmentName);
if (parsedRuleBasedSegment == null) {
return false;
}
if (parsedRuleBasedSegment.excludedKeys().contains(matchValue)) {
return false;
}
for (ExcludedSegments segment: parsedRuleBasedSegment.excludedSegments()) {
if (segment.type.equals(standardType) && evaluationContext.getSegmentCache().isInSegment(segment.name, (String) matchValue)) {
return false;
}
if (segment.type.equals(ruleBasedType)) {
List<ParsedCondition> conditions = evaluationContext.getRuleBasedSegmentCache().get(segment.name).parsedConditions();
if (matchConditions(conditions, matchValue, bucketingKey, attributes, evaluationContext)) {
return true;
}
}
}
return matchConditions(parsedRuleBasedSegment.parsedConditions(), matchValue, bucketingKey, attributes, evaluationContext);
}
private boolean matchConditions(List<ParsedCondition> conditions, Object matchValue, String bucketingKey,
Map<String, Object> attributes, EvaluationContext evaluationContext) {
for (ParsedCondition parsedCondition : conditions) {
if (parsedCondition.matcher().match((String) matchValue, bucketingKey, attributes, evaluationContext)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + _segmentName.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (!(obj instanceof RuleBasedSegmentMatcher)) return false;
RuleBasedSegmentMatcher other = (RuleBasedSegmentMatcher) obj;
return _segmentName.equals(other._segmentName);
}
@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("in segment ");
bldr.append(_segmentName);
return bldr.toString();
}
public String getSegmentName() {
return _segmentName;
}
}