2015-12-10 2 views
0

У меня есть memoized п, где п является memoized два входных ссылок:нужен WeakMap (а, б) -> с

let NewRefCursor = memoized(
    (deref, swap) => refToHash(deref) + refToHash(swap), // memoizer identity fn 
    (deref, swap) => new RefCursor(deref, swap)); // the function we are memoizing 

поведения мне нужно NewRefCursor(a, b) === NewRefCursor(a, b). Когда a или b получает сбор мусора, курсор также должен быть собран в мусор.

refToHash - еще одна memoized функция, которая использует ES6 WeakMap, так что ссылки, видимые, все еще разрешены к GC.

NewRefCursor намного сложнее запоминать, потому что он использует два параметра для определения попадания в кеш, поэтому он несовместим с WeakMap, таким образом предотвратит любую ссылку, видимую из когда-либо GC'ed. Я открыт для любых способов обмана, прикрепляя частные поля к входным объектам, вероятностные структуры данных. Эта утечка должна быть решена. Единственное решение, которое я имею до сих пор, это добавить параметр memoize, который ограничивает размер кеша и настраивает этот параметр для каждого приложения. валовой.

+1

Если вы создаете слабую карту на двух уровнях (храните слабые карты на слайдах), всякий раз, когда объект на первом уровне заштрихован, вы теряете весь второй уровень (когда a gced, вы теряете b). если b gced, у вас все еще будет слабая карта для a, которая будет только там, когда есть еще пара (a, что-то). это решает вашу проблему или я что-то не хватает? –

ответ

2

Если вы создаете слабую карту на двух уровнях (храните слабые карты на слайдах), всякий раз, когда obj на первом уровне заштрихован, вы теряете весь второй уровень (когда a очерчен, вы теряете b). Если b рубит, у вас все еще будет слабая карта для a, которая будет там, только если есть еще пара (a, что-то). Не лучшая реализация, но я думаю, что этого достаточно:

function BiWeakMap() { 
    this._map = new WeakMap(); 
} 

BiWeakMap.prototype.set = function(key1, key2, value) { 

    if (!this._map.has(key1)) { 
     this._map.set(key1, new WeakMap()); 
    } 

    this._map.get(key1).set(key2, value); 

    return this; 

}; 

BiWeakMap.prototype.has = function(key1, key2) { 

    return this._map.has(key1) && this._map.get(key1).has(key2); 

}; 

BiWeakMap.prototype.get = function(key1, key2) { 

    return this._map.get(key1) && this._map.get(key1).get(key2); 

}; 

Эта концепция может быть расширена до n-уровневого решения. Это решает вашу проблему или я что-то упускаю?

0

См. Memoize in https://github.com/Dans-labs/dariah/blob/master/client/src/js/lib/utils.js Он решает проблему общим способом, создавая индекс WeakMap всех аргументов, являющихся объектами. Индекс WeakMap присваивает уникальные целые числа объектам, которые затем могут быть объединены с другими аргументами посредством stringify.

Смежные вопросы