private int?VariationIndexForUser(int?variation, Rollout?rollout, string key, string salt) { if (variation.HasValue) { return(variation.Value); } if (rollout.HasValue && rollout.Value.Variations.Count() > 0) { var bucketBy = rollout.Value.BucketBy.GetValueOrDefault(UserAttribute.Key); float bucket = Bucketing.BucketUser(_user, key, bucketBy, salt); float sum = 0F; foreach (WeightedVariation wv in rollout.Value.Variations) { sum += (float)wv.Weight / 100000F; if (bucket < sum) { return(wv.Variation); } } // The user's bucket value was greater than or equal to the end of the last bucket. This could happen due // to a rounding error, or due to the fact that we are scaling to 100000 rather than 99999, or the flag // data could contain buckets that don't actually add up to 100000. Rather than returning an error in // this case (or changing the scaling, which would potentially change the results for *all* users), we // will simply put the user in the last bucket. return(rollout.Value.Variations.Last().Variation); } return(null); }
public void TestBucketUserByFloatAttr() { var user = User.Builder("userKey").Custom("floatAttr", 999.999F).Build(); var bucket = Bucketing.BucketUser(user, "hashKey", UserAttribute.ForName("floatAttr"), "saltyA"); Assert.Equal(0, bucket, 15); }
public void TestBucketUserByIntAttr() { var user = User.Builder("userKey").Custom("intAttr", 33333).Build(); var bucket = Bucketing.BucketUser(user, "hashKey", UserAttribute.ForName("intAttr"), "saltyA"); Assert.Equal(0.54771423, bucket, 7); user = User.Builder("userKey").Custom("stringAttr", "33333").Build(); var bucket2 = Bucketing.BucketUser(user, "hashKey", UserAttribute.ForName("stringAttr"), "saltyA"); Assert.Equal(bucket, bucket2, 15); }
public void TestBucketUserByKey() { var user1 = User.WithKey("userKeyA"); var bucket = Bucketing.BucketUser(user1, "hashKey", UserAttribute.Key, "saltyA"); Assert.Equal(0.42157587, bucket, 6); var user2 = User.WithKey("userKeyB"); bucket = Bucketing.BucketUser(user2, "hashKey", UserAttribute.Key, "saltyA"); Assert.Equal(0.6708485, bucket, 6); var user3 = User.WithKey("userKeyC"); bucket = Bucketing.BucketUser(user3, "hashKey", UserAttribute.Key, "saltyA"); Assert.Equal(0.10343106, bucket, 6); }
private bool MatchSegmentRule(Segment segment, SegmentRule segmentRule) { foreach (var c in segmentRule.Clauses) { if (!MatchClauseNoSegments(c)) { return(false); } } // If the Weight is absent, this rule matches if (!segmentRule.Weight.HasValue) { return(true); } // All of the clauses are met. See if the user buckets in var by = segmentRule.BucketBy.GetValueOrDefault(UserAttribute.Key); double bucket = Bucketing.BucketUser(_user, segment.Key, by, segment.Salt); double weight = (double)segmentRule.Weight / 100000F; return(bucket < weight); }