Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
if ((this.entries[i].hashCode == hashcode) && this.comparer.Equals(this.entries[i].key, key))
int bucketNum = (hashcode & 0x7fffffff) % capacity;
hashcode & 0x7fffffff — интересный приём. 0x7fffffff — это значение int.MaxValue.Int32 в положительную. Логически это то же самое, что:hashcode >= 0 ? hashcode : int.MaxValue + hashcode + 1
Ответ на 1 вопрос — ключа и его хэша на самом деле. Я не уверен зачем так сделано, учитывая, что хэш генерится по ключу, но проверка там выглядит так
if ((this.entries[i].hashCode == hashcode) && this.comparer.Equals(this.entries[i].key, key))
При добавлении элемента вычисляется хэшкод его ключа и затем — индекс корзины в которую он будет добавлен по модулю от величины коллекции (именно для этого размер выбирается простым числом, чтобы обеспечить более равномерное распределение и уменьшить число возможных коллизий):Я, наверное, что-то недопонял. Можете пояснить, как деление по модулю простого числа обеспечивает «более равномерное» распределение, чем деление по модулю обычного числа (например, на единицу большего, чем простое)?
buckets, тем меньше вероятность, что мы с этим стокнёмся — ведь простые числа растут, и всё меньше остаётся чисел, которые на них без остатка делятся.x% = capacity / GCD (capacity, hashcode)
capacity = 10
hashcode = 18
GCD = 2
bucketNumber = 18 % 10 = 8
2 % 10 = 12 % 10 = 2 и т.д.
2) Добавилось в коллекцию кучу других элементов так, что словарь увеличился до 29. Так? Значит количество корзин стало 29. (просто создался массив из 29 элементов и 23 элемента скопировалось в 29), так?
Под капотом у Dictionary и ConcurrentDictionary