Esempio n. 1
0
        private void OptimizeInternal(int size, Trie <T>[] children)
        {
            var smallChildren = new Trie <T> [size];

            Mask = int.MaxValue >> 31 - Bits.CeilLog2(size);
            foreach (var trie in children)
            {
                var key = trie.Key[0] & Mask;
                if (smallChildren[key] != null)
                {
                    if (smallChildren[key] == trie)
                    {
                        break; // different casing, same val, nothing to do
                    }
                    // real collision, double the size and try again
                    OptimizeInternal(size * 2, children);
                    return;
                }
                trie.DebugKey = DebugKey + trie.Key;

                smallChildren[key] = trie;
                trie.Optimize();
            }
            Children = smallChildren;
        }
Esempio n. 2
0
        public PageLocatorCurrent(LowLevelTransactionStub tx, int cacheSize = 8)
        {
            //Debug.Assert(tx != null);
            //Debug.Assert(cacheSize > 0);
            _tx = tx;

            if (tx != null)
            {
                Debug.Fail("");
            }

            cacheSize = Bits.NextPowerOf2(cacheSize);
            if (cacheSize > 1024)
            {
                cacheSize = 1024;
            }

            int shiftRight = Bits.CeilLog2(cacheSize);

            _andMask = (int)(0xFFFFFFFF >> (sizeof(uint) * 8 - shiftRight));

            _tx = tx;

            _allocator.Allocate(cacheSize * sizeof(PageData), out _cacheMemory);
            _cache = (PageData *)_cacheMemory.Ptr;

            for (var i = 0; i < cacheSize; i++)
            {
                _cache[i].PageNumber = Invalid;
            }
        }
Esempio n. 3
0
        public void Renew(LowLevelTransaction tx, int cacheSize)
        {
            Debug.Assert(tx != null);
            Debug.Assert(cacheSize > 0);
            Debug.Assert(cacheSize <= 1024);

            if (!Bits.IsPowerOfTwo(cacheSize))
            {
                cacheSize = Bits.NextPowerOf2(cacheSize);
            }

            int shiftRight = Bits.CeilLog2(cacheSize);

            _andMask = (int)(0xFFFFFFFF >> (sizeof(uint) * 8 - shiftRight));

            _tx = tx;

            tx.Allocator.Allocate(cacheSize * sizeof(PageData), out _cacheMemory);
            _cache = (PageData *)_cacheMemory.Ptr;

            for (var i = 0; i < cacheSize; i++)
            {
                _cache[i].PageNumber = Invalid;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Converts <see cref="IntX" /> digits into real representation (used in FHT).
        /// </summary>
        /// <param name="digitsPtr">Big integer digits.</param>
        /// <param name="length"><paramref name="digitsPtr" /> length.</param>
        /// <param name="newLength">Multiplication result length (must be pow of 2).</param>
        /// <returns>Double array.</returns>
        static public double[] ConvertDigitsToDouble(uint *digitsPtr, uint length, uint newLength)
        {
            // Maybe fix newLength (make it the nearest bigger pow of 2)
            newLength = 1U << Bits.CeilLog2(newLength);

            // For better FHT accuracy we will choose length smaller then dwords.
            // So new length must be modified accordingly
            newLength <<= DoubleDataLengthShift;
            double[] data = ArrayPool <double> .Instance.GetArray(newLength);

            // Run in unsafe context
            fixed(double *slice = data)
            {
                // Amount of units pointed by digitsPtr
                uint unitCount = length << DoubleDataLengthShift;

                // Copy all words from digits into new double[]
                byte *unitDigitsPtr = (byte *)digitsPtr;

                for (uint i = 0; i < unitCount; ++i)
                {
                    slice[i] = unitDigitsPtr[i];
                }

                // Clear remaining double values (this array is from pool and may be dirty)
                DigitHelper.SetBlockDigits(slice + unitCount, newLength - unitCount, 0.0);

                // FHT (as well as FFT) works more accurate with "balanced" data, so let's balance it
                double carry = 0, dataDigit;

                for (uint i = 0; i < unitCount || i < newLength && carry != 0; ++i)
                {
                    dataDigit = slice[i] + carry;
                    if (dataDigit >= DoubleDataBaseDiv2)
                    {
                        dataDigit -= DoubleDataBase;
                        carry      = 1.0;
                    }
                    else
                    {
                        carry = 0;
                    }
                    slice[i] = dataDigit;
                }

                if (carry > 0)
                {
                    slice[0] -= carry;
                }
            }

            return(data);
        }
Esempio n. 5
0
File: Bits.cs Progetto: ikvm/ravendb
        public void Bits_Ceil2Log()
        {
            Assert.Equal(0, Bits.CeilLog2(0));
            Assert.Equal(0, Bits.CeilLog2(1));
            Assert.Equal(1, Bits.CeilLog2(2));
            Assert.Equal(2, Bits.CeilLog2(3));
            Assert.Equal(2, Bits.CeilLog2(4));
            Assert.Equal(16, Bits.CeilLog2(0x0000FF00));
            Assert.Equal(31, Bits.CeilLog2(0x40B79DF0));

            Assert.Equal(0, Bits.CeilLog2((uint)0));
            Assert.Equal(0, Bits.CeilLog2((uint)1));
            Assert.Equal(1, Bits.CeilLog2((uint)2));
            Assert.Equal(2, Bits.CeilLog2((uint)3));
            Assert.Equal(2, Bits.CeilLog2((uint)4));
            Assert.Equal(16, Bits.CeilLog2((uint)0x0000FF00));
            Assert.Equal(32, Bits.CeilLog2((uint)0xFFFF0000));
            Assert.Equal(31, Bits.CeilLog2((uint)0x40B79DF0));
        }
Esempio n. 6
0
 private static int CalculateCompressionAcceleration(int size)
 {
     return(Bits.CeilLog2(size));
 }
Esempio n. 7
0
        /// <summary>
        /// Generates integer opposite to the given one using approximation.
        /// Uses algorithm from Khuth vol. 2 3rd Edition (4.3.3).
        /// </summary>
        /// <param name="digitsPtr">Initial big integer digits.</param>
        /// <param name="length">Initial big integer length.</param>
        /// <param name="maxLength">Precision length.</param>
        /// <param name="bufferPtr">Buffer in which shifted big integer may be stored.</param>
        /// <param name="newLength">Resulting big integer length.</param>
        /// <param name="rightShift">How much resulting big integer is shifted to the left (or: must be shifted to the right).</param>
        /// <returns>Resulting big integer digits.</returns>
        static unsafe public uint[] GetIntegerOpposite(
            uint *digitsPtr,
            uint length,
            uint maxLength,
            uint *bufferPtr,
            out uint newLength,
            out ulong rightShift)
        {
            // Maybe initially shift original digits a bit to the left
            // (it must have MSB on 2nd position in the highest digit)
            int msb = Bits.Msb(digitsPtr[length - 1]);

            rightShift = (ulong)(length - 1) * Constants.DigitBitCount + (ulong)msb + 1U;

            if (msb != 2)
            {
                // Shift to the left (via actually right shift)
                int leftShift = (2 - msb + Constants.DigitBitCount) % Constants.DigitBitCount;
                length = DigitOpHelper.Shr(digitsPtr, length, bufferPtr + 1, Constants.DigitBitCount - leftShift, true) + 1U;
            }
            else
            {
                // Simply use the same digits without any shifting
                bufferPtr = digitsPtr;
            }

            // Calculate possible result length
            int  lengthLog2     = Bits.CeilLog2(maxLength);
            uint newLengthMax   = 1U << (lengthLog2 + 1);
            int  lengthLog2Bits = lengthLog2 + Bits.Msb(Constants.DigitBitCount);

            // Create result digits
            uint[] resultDigits = ArrayPool <uint> .Instance.GetArray(newLengthMax);           //new uint[newLengthMax];

            uint resultLength;

            // Create temporary digits for squared result (twice more size)
            uint[] resultDigitsSqr = ArrayPool <uint> .Instance.GetArray(newLengthMax);           //new uint[newLengthMax];

            uint resultLengthSqr;

            // Create temporary digits for squared result * buffer
            uint[] resultDigitsSqrBuf = new uint[newLengthMax + length];
            uint   resultLengthSqrBuf;

            // We will always use current multiplier
            IMultiplier multiplier = MultiplyManager.GetCurrentMultiplier();

            // Fix some digits
            fixed(uint *resultPtrFixed = resultDigits, resultSqrPtrFixed = resultDigitsSqr, resultSqrBufPtr = resultDigitsSqrBuf)
            {
                uint *resultPtr    = resultPtrFixed;
                uint *resultSqrPtr = resultSqrPtrFixed;

                // Cache two first digits
                uint bufferDigitN1 = bufferPtr[length - 1];
                uint bufferDigitN2 = bufferPtr[length - 2];

                // Prepare result.
                // Initially result = floor(32 / (4*v1 + 2*v2 + v3)) / 4
                // (last division is not floored - here we emulate fixed point)
                resultDigits[0] = 32 / bufferDigitN1;
                resultLength    = 1;

                // Prepare variables
                uint  nextBufferTempStorage = 0;
                int   nextBufferTempShift;
                uint  nextBufferLength = 1U;
                uint *nextBufferPtr    = &nextBufferTempStorage;

                ulong bitsAfterDotResult;
                ulong bitsAfterDotResultSqr;
                ulong bitsAfterDotNextBuffer;
                ulong bitShift;
                uint  shiftOffset;

                uint *tempPtr;

                uint[] tempDigits;

                // Iterate 'till result will be precise enough
                for (int k = 0; k < lengthLog2Bits; ++k)
                {
                    // Get result squared
                    resultLengthSqr = multiplier.Multiply(
                        resultPtr,
                        resultLength,
                        resultPtr,
                        resultLength,
                        resultSqrPtr);

                    // Calculate current result bits after dot
                    bitsAfterDotResult    = (1UL << k) + 1UL;
                    bitsAfterDotResultSqr = bitsAfterDotResult << 1;

                    // Here we will get the next portion of data from bufferPtr
                    if (k < 4)
                    {
                        // For now buffer intermediate has length 1 and we will use this fact
                        nextBufferTempShift   = 1 << (k + 1);
                        nextBufferTempStorage =
                            bufferDigitN1 << nextBufferTempShift |
                                bufferDigitN2 >> (Constants.DigitBitCount - nextBufferTempShift);

                        // Calculate amount of bits after dot (simple formula here)
                        bitsAfterDotNextBuffer = (ulong)nextBufferTempShift + 3UL;
                    }
                    else
                    {
                        // Determine length to get from bufferPtr
                        nextBufferLength = System.Math.Min((1U << (k - 4)) + 1U, length);
                        nextBufferPtr    = bufferPtr + (length - nextBufferLength);

                        // Calculate amount of bits after dot (simple formula here)
                        bitsAfterDotNextBuffer = (ulong)(nextBufferLength - 1U) * Constants.DigitBitCount + 3UL;
                    }

                    // Multiply result ^ 2 and nextBuffer + calculate new amount of bits after dot
                    resultLengthSqrBuf = multiplier.Multiply(
                        resultSqrPtr,
                        resultLengthSqr,
                        nextBufferPtr,
                        nextBufferLength,
                        resultSqrBufPtr);

                    bitsAfterDotNextBuffer += bitsAfterDotResultSqr;

                    // Now calculate 2 * result - resultSqrBufPtr
                    --bitsAfterDotResult;
                    --bitsAfterDotResultSqr;

                    // Shift result on a needed amount of bits to the left
                    bitShift     = bitsAfterDotResultSqr - bitsAfterDotResult;
                    shiftOffset  = (uint)(bitShift / Constants.DigitBitCount);
                    resultLength =
                        shiftOffset + 1U +
                        DigitOpHelper.Shr(
                            resultPtr,
                            resultLength,
                            resultSqrPtr + shiftOffset + 1U,
                            Constants.DigitBitCount - (int)(bitShift % Constants.DigitBitCount),
                            true);

                    // Swap resultPtr and resultSqrPtr pointers
                    tempPtr      = resultPtr;
                    resultPtr    = resultSqrPtr;
                    resultSqrPtr = tempPtr;

                    tempDigits      = resultDigits;
                    resultDigits    = resultDigitsSqr;
                    resultDigitsSqr = tempDigits;

                    DigitHelper.SetBlockDigits(resultPtr, shiftOffset, 0U);

                    bitShift    = bitsAfterDotNextBuffer - bitsAfterDotResultSqr;
                    shiftOffset = (uint)(bitShift / Constants.DigitBitCount);

                    if (shiftOffset < resultLengthSqrBuf)
                    {
                        // Shift resultSqrBufPtr on a needed amount of bits to the right
                        resultLengthSqrBuf = DigitOpHelper.Shr(
                            resultSqrBufPtr + shiftOffset,
                            resultLengthSqrBuf - shiftOffset,
                            resultSqrBufPtr,
                            (int)(bitShift % Constants.DigitBitCount),
                            false);

                        // Now perform actual subtraction
                        resultLength = DigitOpHelper.Sub(
                            resultPtr,
                            resultLength,
                            resultSqrBufPtr,
                            resultLengthSqrBuf,
                            resultPtr);
                    }
                    else
                    {
                        // Actually we can assume resultSqrBufPtr == 0 here and have nothing to do
                    }
                }
            }

            // Return some arrays to pool
            ArrayPool <uint> .Instance.AddArray(resultDigitsSqr);

            rightShift += (1UL << lengthLog2Bits) + 1UL;
            newLength   = resultLength;
            return(resultDigits);
        }
Esempio n. 8
0
 private static int GetPoolIndexForReuse(int size)
 {
     return(Bits.CeilLog2(size) - 1); // x^0 = 1 therefore we start counting at 1 instead.
 }