示例#1
0
        /// <summary>
        /// used by random table generators to select random number of columns and rows. This method will return very low numbers with high probability,
        /// </summary>
        public void NextTableDimentions(int maxRows, int maxColumns, int maxTotalSize, out int randRows, out int randColumns)
        {
            // prefer really low values to ensure table size will not go up way too much too frequently
            const LowValueEnforcementLevel level = LowValueEnforcementLevel.Medium;

            if (NextBit())
            {
                // select rows first, then columns
                randColumns = NextAllocationUnit(1, maxColumns, level);
                randRows    = NextAllocationUnit(1, Math.Min(maxRows, maxTotalSize / randColumns), level);
            }
            else
            {
                randRows    = NextAllocationUnit(1, maxRows, level);
                randColumns = NextAllocationUnit(1, Math.Min(maxColumns, maxTotalSize / randRows), level);
            }
        }
示例#2
0
        /// <summary>
        /// generates size value with low probability of large size values within the given range
        /// </summary>
        /// <param name="lowValuesEnforcementLevel">
        /// lowValuesEnforcementLevel is value between 0 and 31;
        /// 0 means uniform distribution in the min/max range;
        /// 31 means very low chances for high values
        /// </param>
        private int NextAllocationUnit(int minSize, int maxSize, LowValueEnforcementLevel lowValuesLevel)
        {
            if (minSize < 0 || maxSize < 0 || minSize > maxSize)
            {
                throw new ArgumentOutOfRangeException("minSize or maxSize are out of range");
            }

            if (lowValuesLevel < LowValueEnforcementLevel.VeryStrong || lowValuesLevel > LowValueEnforcementLevel.Uniform)
            {
                throw new ArgumentOutOfRangeException("lowValuesLevel");
            }

            if (minSize == maxSize)
            {
                return(minSize); // shortcut for fixed size
            }
            long longRange = (long)maxSize - (long)minSize + 1;

            // create a sample in range [0, 1) (it is never 1)
            double sample = base.NextDouble();

            // decrease chances of large size values based on the how many bits digits are set in the maxValue
            int  bitsPerLevel = (int)lowValuesLevel;
            long maxBitsLeft  = longRange >> bitsPerLevel;

            while (maxBitsLeft > 0)
            {
                sample       *= base.NextDouble();
                maxBitsLeft >>= bitsPerLevel;
            }

            int res = minSize + (int)(sample * longRange);

            Debug.Assert(res >= minSize && res <= maxSize);
            return(res);
        }