Пример #1
0
        public void CacheReadReference(string cacheBlock)
        {
            this.refreshCounter++;       //increment the refresh counter
            this.totalCacheReferences++; //Increment the total number of references we've seen in the cache so far

            Int32 blockIndex = -1;

            byte[] hashedByteValue = this.Murmur3HashFunction.ComputeHash(System.Text.Encoding.UTF8.GetBytes(cacheBlock));
            UInt64 hashedValue     = IntHelpers.GetUInt64(hashedByteValue, 8);

            if ((hashedValue & (this.modulusP - 1)) < this.thresholdT)
            {
                this.totalProcessedReferences++;

                GhostCacheElement ghostBlock = null;

                if (this.hashTableLookup.TryGetValue(hashedValue, out ghostBlock))        //O(1)
                {                                                                         //hit, it's in the ghost cache
                    blockIndex = this.distanceTree.IndexOfKey(ghostBlock.refreshCounter); // O(log n)

                    Int32 scaledReuseDistance = (Int32)Math.Round((double)blockIndex / this.samplingRateR);

                    ghostBlock.refreshCounter = this.refreshCounter;                                    //update counter in the block
                    //update the counter at its current depth
                    Debug.Assert(this.reuseAccessHistogram[scaledReuseDistance] + 1 < UInt32.MaxValue); //make sure we don't overflow the counter
                    this.reuseAccessHistogram[scaledReuseDistance] += 1;
                    //Move it to the right place in the stack (new counter value == "0th position")
                    this.distanceTree.RemoveAt(blockIndex);                 //O(log n)
                    this.distanceTree.Add(this.refreshCounter, ghostBlock); //O(log n)
                }
                else
                {
                    this.Evict(); //check if we need to free up space (should rarely have to...)
                    ghostBlock = new GhostCacheElement(refreshCounter, hashedValue);

                    this.distanceTree.Add(refreshCounter, ghostBlock);
                    this.hashTableLookup.Add(hashedValue, ghostBlock);
                    this.coldMisses++; //this is only true (ie: a cold miss) until the ghost cache has to start evicting things
                }
            }
        }
Пример #2
0
            public byte[] ComputeHash(byte[] bb)
            {
                ulong h1 = 0L;
                ulong h2 = 0L;

                h1 = seed;
                ulong length = 0L;

                int   pos       = 0;
                ulong remaining = (ulong)bb.Length;

                // read 128 bits, 16 bytes, 2 longs in eacy cycle
                while (remaining >= READ_SIZE)
                {
                    ulong k1 = IntHelpers.GetUInt64(bb, pos);
                    pos += 8;

                    ulong k2 = IntHelpers.GetUInt64(bb, pos);
                    pos += 8;

                    length    += READ_SIZE;
                    remaining -= READ_SIZE;

                    //Used to be MixBody(k1, k2);
                    k1 *= C1;
                    k1  = IntHelpers.RotateLeft(k1, 31);
                    k1 *= C2;
                    h1 ^= k1; //was h1 ^= MixKey1(k1);

                    h1  = IntHelpers.RotateLeft(h1, 27);
                    h1 += h2;
                    h1  = h1 * 5 + 0x52dce729;

                    k2 *= C2;
                    k2  = IntHelpers.RotateLeft(k2, 33);
                    k2 *= C1;
                    h2 ^= k2; //was h2 ^= MixKey2(k2);

                    h2  = IntHelpers.RotateLeft(h2, 31);
                    h2 += h1;
                    h2  = h2 * 5 + 0x38495ab5;
                }

                // if the input MOD 16 != 0
                if (remaining > 0)
                {
                    //ProcessBytesRemaining(bb, remaining, pos);
                    ulong j1 = 0;
                    ulong j2 = 0;
                    length += remaining;

                    // little endian (x86) processing
                    switch (remaining)
                    {
                    case 15:
                        j2 ^= (ulong)bb[pos + 14] << 48;     // fall through
                        goto case 14;

                    case 14:
                        j2 ^= (ulong)bb[pos + 13] << 40;     // fall through
                        goto case 13;

                    case 13:
                        j2 ^= (ulong)bb[pos + 12] << 32;     // fall through
                        goto case 12;

                    case 12:
                        j2 ^= (ulong)bb[pos + 11] << 24;     // fall through
                        goto case 11;

                    case 11:
                        j2 ^= (ulong)bb[pos + 10] << 16;     // fall through
                        goto case 10;

                    case 10:
                        j2 ^= (ulong)bb[pos + 9] << 8;     // fall through
                        goto case 9;

                    case 9:
                        j2 ^= (ulong)bb[pos + 8];     // fall through
                        goto case 8;

                    case 8:
                        j1 ^= bb.GetUInt64(pos);
                        break;

                    case 7:
                        j1 ^= (ulong)bb[pos + 6] << 48;     // fall through
                        goto case 6;

                    case 6:
                        j1 ^= (ulong)bb[pos + 5] << 40;     // fall through
                        goto case 5;

                    case 5:
                        j1 ^= (ulong)bb[pos + 4] << 32;     // fall through
                        goto case 4;

                    case 4:
                        j1 ^= (ulong)bb[pos + 3] << 24;     // fall through
                        goto case 3;

                    case 3:
                        j1 ^= (ulong)bb[pos + 2] << 16;     // fall through
                        goto case 2;

                    case 2:
                        j1 ^= (ulong)bb[pos + 1] << 8;     // fall through
                        goto case 1;

                    case 1:
                        j1 ^= (ulong)bb[pos];     // fall through
                        break;

                    default:
                        throw new Exception("Something went wrong with remaining bytes calculation.");
                    }

                    j1 *= C1;
                    j1  = IntHelpers.RotateLeft(j1, 31);
                    j1 *= C2;
                    h1 ^= j1;

                    j2 *= C2;
                    j2  = IntHelpers.RotateLeft(j2, 33);
                    j2 *= C1;
                    h2 ^= j2;
                }



                /////////////////////////////////////
                //// BELOW WAS ALL return Hash;
                /////////////////////////////////////

                h1 ^= length;
                h2 ^= length;

                h1 += h2;
                h2 += h1;

                //h1 = Murmur3.MixFinal(h1);
                h1 ^= h1 >> 33;
                h1 *= 0xff51afd7ed558ccdL;
                h1 ^= h1 >> 33;
                h1 *= 0xc4ceb9fe1a85ec53L;
                h1 ^= h1 >> 33;

                //h2 = Murmur3.MixFinal(h2);
                h2 ^= h2 >> 33;
                h2 *= 0xff51afd7ed558ccdL;
                h2 ^= h2 >> 33;
                h2 *= 0xc4ceb9fe1a85ec53L;
                h2 ^= h2 >> 33;

                h1 += h2;
                h2 += h1;

                var hash = new byte[Murmur3.READ_SIZE];

                Array.Copy(BitConverter.GetBytes(h1), 0, hash, 0, 8);
                Array.Copy(BitConverter.GetBytes(h2), 0, hash, 8, 8);

                return(hash);
            }