Hash-consing заключается в сохранении в памяти только одной копии данного объекта; то есть, если два объекта семантически равны (одно и то же содержимое), то они должны быть физически равными (одно и то же местоположение в памяти). Этот метод обычно реализуется путем сохранения глобального набора хэшей и создания новых объектов только в том случае, если они не равны объекту в хэш-наборе.
Дополнительным требованием является то, что объекты в хэш-таблице должны собираться, если на них не ссылаются ничего, кроме хеш-таблицы; в противном случае хеш-таблица должна содержать слабые ссылки.
Проблема, кроме того, осложняется необходимостью иметь постоянное время, таким образом, мелкие, хэширующие и равенства тесты; таким образом, объекты имеют уникальный идентификатор, который увеличивается при добавлении нового объекта в таблицу.
У меня есть рабочая реализация, которая использует System.Collections.Generic.Dictionary<key, node>
, где key
является кортежем, дающим неглубокую сводку node (подходит для теста хэширования и равенства по умолчанию) и node
является объектом. Единственная проблема заключается в том, что Dictionary
сохраняет сильные ссылки на узлы!
Я мог бы использовать Dictionary
to WeakReference
, но это не освободило бы клавиши, указывающие на оборванные ссылки.
Некоторые сторонники используют System.Runtime.CompilerServices.ConditionalWeakTable
, но этот класс, похоже, делает обратное: он освобождает значение при сборке ключа, тогда как мне нужно освободить ключ, когда значение будет собрано.
Можно попробовать использовать System.Runtime.CompilerServices.ConditionalWeakTable<node, node>
, но мне нужны специальные тесты хеширования и равенства... и ConditionalWeakTable
документируется не использовать виртуальный метод GetHashCode()
, вместо этого используя функцию хеширования по умолчанию.
Таким образом, мой вопрос: есть ли какой-то эквивалент Dictionary
, который будет поддерживать слабые ссылки на значения и освобождать ключи при обрыве ссылок?