コード例 #1
0
ファイル: TextKeyedCache.cs プロジェクト: zhxjdwh/roslyn
        private void AddSharedEntry(int hashCode, SharedEntryValue e)
        {
            var arr = _sharedTableInst;
            int idx = SharedIdxFromHash(hashCode);

            // try finding an empty spot in the bucket
            // we use quadratic probing here
            // bucket positions are (n^2 + n)/2 relative to the masked hashcode
            int curIdx = idx;

            for (int i = 1; i < SharedBucketSize + 1; i++)
            {
                if (arr[curIdx].Entry == null)
                {
                    idx = curIdx;
                    goto foundIdx;
                }

                curIdx = (curIdx + i) & SharedSizeMask;
            }

            // or pick a random victim within the bucket range
            // and replace with new entry
            var i1 = NextRandom() & SharedBucketSizeMask;

            idx = (idx + ((i1 * i1 + i1) / 2)) & SharedSizeMask;

foundIdx:
            arr[idx].HashCode = hashCode;
            Volatile.Write(ref arr[idx].Entry, e);
        }
コード例 #2
0
ファイル: TextKeyedCache.cs プロジェクト: zhxjdwh/roslyn
        private SharedEntryValue FindSharedEntry(char[] chars, int start, int len, int hashCode)
        {
            var arr = _sharedTableInst;
            int idx = SharedIdxFromHash(hashCode);

            SharedEntryValue e = null;

            // we use quadratic probing here
            // bucket positions are (n^2 + n)/2 relative to the masked hashcode
            for (int i = 1; i < SharedBucketSize + 1; i++)
            {
                e = arr[idx].Entry;
                int hash = arr[idx].HashCode;

                if (e != null)
                {
                    if (hash == hashCode && StringTable.TextEquals(e.Text, chars, start, len))
                    {
                        break;
                    }

                    // this is not e we are looking for
                    e = null;
                }
                else
                {
                    // once we see unfilled entry, the rest of the bucket will be empty
                    break;
                }

                idx = (idx + i) & SharedSizeMask;
            }

            return(e);
        }
コード例 #3
0
ファイル: TextKeyedCache.cs プロジェクト: zhxjdwh/roslyn
        internal T FindItem(char[] chars, int start, int len, int hashCode)
        {
            // capture array to avoid extra range checks
            var arr = _localTable;
            var idx = LocalIdxFromHash(hashCode);

            var text = arr[idx].Text;

            if (text != null && arr[idx].HashCode == hashCode)
            {
                if (StringTable.TextEquals(text, chars, start, len))
                {
                    return(arr[idx].Item);
                }
            }

            SharedEntryValue e = FindSharedEntry(chars, start, len, hashCode);

            if (e != null)
            {
                // PERF: the following code does element-wise assignment of a struct
                //       because current JIT produces better code compared to
                //       arr[idx] = new LocalEntry(...)
                arr[idx].HashCode = hashCode;
                arr[idx].Text     = e.Text;

                var tk = e.Item;
                arr[idx].Item = tk;

                return(tk);
            }

            return(null);
        }
コード例 #4
0
ファイル: TextKeyedCache.cs プロジェクト: zhxjdwh/roslyn
        internal void AddItem(char[] chars, int start, int len, int hashCode, T item)
        {
            var text = _strings.Add(chars, start, len);

            // add to the shared table first (in case someone looks for same item)
            var e = new SharedEntryValue(text, item);

            AddSharedEntry(hashCode, e);

            // add to the local table too
            var arr = _localTable;
            var idx = LocalIdxFromHash(hashCode);

            arr[idx].HashCode = hashCode;
            arr[idx].Text     = text;
            arr[idx].Item     = item;
        }