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);
            }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
            }