Last active
December 15, 2015 02:28
-
-
Save teramako/5187008 to your computer and use it in GitHub Desktop.
WeakReference な Set オブジェクトを無理やり作ってみた。Firefox のSystem権限(Components.utils.getWeakReferenceを使用)が必要だけど。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(global) { | |
function mixin (aTarget, aSource) { | |
for (var key of Object.getOwnPropertyNames(aSource)) { | |
var desc = Object.getOwnPropertyDescriptor(aSource, key); | |
desc.enumerable = false; | |
Object.defineProperty(aTarget, key, desc); | |
} | |
return aTarget; | |
} | |
/** | |
* @class | |
* @param {Object[]} items | |
*/ | |
function WeakSet (...items) { | |
mixin(this, { w: new WeakMap, s: new Set, }); | |
for (var item of items) { | |
if (Object(item) === Object(item)) | |
this.add(item); | |
} | |
} | |
mixin(WeakSet.prototype, { | |
/** | |
* @param {Object} item | |
*/ | |
add: function (item) { | |
if (this.has(item) | |
return; | |
// 弱参照なオブジェクトを得る | |
var value = Cu.getWeakReference(item); | |
// 追加するオブジェクトをキーとしてWeakMapに格納 | |
this.w.set(item, value); | |
// イテレート可能にするために、弱参照オブジェクトを格納 | |
this.s.add(value); | |
}, | |
/** | |
* @param {Object} item | |
* @return {Boolean} | |
*/ | |
has: function (item) { return this.w.has(item); }, | |
/** | |
* @param {Object} item | |
*/ | |
delete: function (item) { | |
if (this.w.has(item)) { | |
this.s.delete(this.w.get(item)); | |
this.w.delete(item); | |
} | |
}, | |
/** | |
* delete all items | |
*/ | |
clear:function () { | |
this.s.clear(); | |
this.w.clear(); | |
}, | |
/** | |
* @type {Number} items count | |
* @getter | |
* GC されている可能性があるので、一旦全て舐めてからカウントする | |
*/ | |
get size() { | |
var i = 0, v; | |
for (v of this.s) { | |
if (v.get()) | |
++i; | |
else | |
this.s.delete(v); | |
} | |
return i; | |
}, | |
/** | |
* @return {Generator} | |
* GC 済みのものは削除する | |
*/ | |
iterator: function() { | |
var v, item; | |
for (v of this.s) { | |
item = v.get(); | |
if (item) | |
yield item; | |
else | |
this.s.delete(v); | |
} | |
}, | |
}); | |
global.WeakSet = WeakSet; | |
}(this)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment