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); }
internal string Add(StringBuilder chars) { var hashCode = Hash.GetFNVHashCode(chars); // 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) { var result = arr[idx].Text; if (StringTable.TextEquals(result, chars)) { return(result); } } string shared = FindSharedEntry(chars, hashCode); if (shared != null) { // PERF: the following code does element-wise assignment of a struct // because current JIT produces better code compared to // arr[idx] = new Entry(...) arr[idx].HashCode = hashCode; arr[idx].Text = shared; return(shared); } return(AddItem(chars, hashCode)); }
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); }