Commit 86fcb07200ede42437c85bee77d45436aa8b7775
make set use a prototype to optimise memory
whoops this should have been in the last releaseMatt McKegg committed on 10/6/2016, 4:35:25 AM
Parent: 60e32a22ee42aa95282b16ffa1ccbb3c7a37523f
Files changed
set.js | changed |
set.js | ||
---|---|---|
@@ -2,101 +2,115 @@ | ||
2 | 2 | |
3 | 3 | module.exports = Set |
4 | 4 | |
5 | 5 | function Set (defaultValues) { |
6 | - var object = [] | |
7 | - var sources = [] | |
8 | - var releases = [] | |
6 | + var instance = new ProtoSet(defaultValues) | |
7 | + var observable = instance.MutantSet.bind(instance) | |
8 | + observable.add = instance.add.bind(instance) | |
9 | + observable.clear = instance.clear.bind(instance) | |
10 | + observable.delete = instance.delete.bind(instance) | |
11 | + observable.has = instance.has.bind(instance) | |
12 | + observable.set = instance.set.bind(instance) | |
13 | + observable.get = instance.get.bind(instance) | |
14 | + observable.getLength = instance.getLength.bind(instance) | |
15 | + return observable | |
16 | +} | |
9 | 17 | |
10 | - var binder = LazyWatcher(update, listen, unlisten) | |
11 | - binder.value = object | |
18 | +// optimise memory usage | |
19 | +function ProtoSet (defaultValues) { | |
20 | + var self = this | |
21 | + self.object = [] | |
22 | + self.sources = [] | |
23 | + self.releases = [] | |
24 | + self.binder = LazyWatcher.call(self, self._update, self._listen, self._unlisten) | |
25 | + self.binder.value = this.object | |
12 | 26 | |
13 | 27 | if (defaultValues && defaultValues.length) { |
14 | 28 | defaultValues.forEach(function (valueOrObs) { |
15 | - if (!~sources.indexOf(valueOrObs)) { | |
16 | - sources.push(valueOrObs) | |
29 | + if (!~self.sources.indexOf(valueOrObs)) { | |
30 | + self.sources.push(valueOrObs) | |
17 | 31 | } |
18 | 32 | }) |
19 | - update() | |
33 | + this.update() | |
20 | 34 | } |
35 | +} | |
21 | 36 | |
22 | - var observable = function MutantSet (listener) { | |
23 | - if (!listener) { | |
24 | - return binder.getValue() | |
25 | - } | |
26 | - return binder.addListener(listener) | |
37 | +ProtoSet.prototype.MutantSet = function (listener) { | |
38 | + if (!listener) { | |
39 | + return this.binder.getValue() | |
27 | 40 | } |
41 | + return this.binder.addListener(listener) | |
42 | +} | |
28 | 43 | |
29 | - observable.add = function (valueOrObs) { | |
30 | - if (!~sources.indexOf(valueOrObs)) { | |
31 | - sources.push(valueOrObs) | |
32 | - if (binder.live) { | |
33 | - releases[sources.length - 1] = bind(valueOrObs) | |
34 | - } | |
35 | - binder.onUpdate() | |
44 | +ProtoSet.prototype.add = function (valueOrObs) { | |
45 | + if (!~this.sources.indexOf(valueOrObs)) { | |
46 | + this.sources.push(valueOrObs) | |
47 | + if (this.binder.live) { | |
48 | + this.releases[this.sources.length - 1] = this._bind(valueOrObs) | |
36 | 49 | } |
50 | + this.binder.onUpdate() | |
37 | 51 | } |
52 | +} | |
38 | 53 | |
39 | - observable.clear = function () { | |
40 | - releases.forEach(tryInvoke) | |
41 | - sources.length = 0 | |
42 | - releases.length = 0 | |
43 | - binder.onUpdate() | |
44 | - } | |
54 | +ProtoSet.prototype.clear = function () { | |
55 | + this.releases.forEach(tryInvoke) | |
56 | + this.sources.length = 0 | |
57 | + this.releases.length = 0 | |
58 | + this.binder.onUpdate() | |
59 | +} | |
45 | 60 | |
46 | - observable.delete = function (valueOrObs) { | |
47 | - var index = sources.indexOf(valueOrObs) | |
48 | - if (~index) { | |
49 | - sources.splice(index, 1) | |
50 | - releases.splice(index, 1).forEach(tryInvoke) | |
51 | - binder.onUpdate() | |
52 | - } | |
61 | +ProtoSet.prototype.delete = function (valueOrObs) { | |
62 | + var index = this.sources.indexOf(valueOrObs) | |
63 | + if (~index) { | |
64 | + this.sources.splice(index, 1) | |
65 | + this.releases.splice(index, 1).forEach(tryInvoke) | |
66 | + this.binder.onUpdate() | |
53 | 67 | } |
68 | +} | |
54 | 69 | |
55 | - observable.has = function (valueOrObs) { | |
56 | - return !!~object.indexOf(valueOrObs) | |
57 | - } | |
70 | +ProtoSet.prototype.has = function (valueOrObs) { | |
71 | + return !!~this.object.indexOf(valueOrObs) | |
72 | +} | |
58 | 73 | |
59 | - observable.set = function (values) { | |
60 | - sources.length = 0 | |
61 | - values.forEach(function (value) { | |
62 | - sources.push(value) | |
63 | - }) | |
64 | - binder.onUpdate() | |
65 | - } | |
74 | +ProtoSet.prototype.set = function (values) { | |
75 | + var self = this | |
76 | + self.sources.length = 0 | |
77 | + values.forEach(function (value) { | |
78 | + self.sources.push(value) | |
79 | + }) | |
80 | + self.binder.onUpdate() | |
81 | +} | |
66 | 82 | |
67 | - observable.get = function (index) { | |
68 | - return sources[index] | |
69 | - } | |
83 | +ProtoSet.prototype.get = function (index) { | |
84 | + return this.sources[index] | |
85 | +} | |
70 | 86 | |
71 | - observable.getLength = function () { | |
72 | - return sources.length | |
73 | - } | |
87 | +ProtoSet.prototype.getLength = function () { | |
88 | + return this.sources.length | |
89 | +} | |
74 | 90 | |
75 | - return observable | |
91 | +ProtoSet.prototype._bind = function (valueOrObs) { | |
92 | + return typeof valueOrObs === 'function' ? valueOrObs(this.binder.onUpdate) : null | |
93 | +} | |
76 | 94 | |
77 | - function bind (valueOrObs) { | |
78 | - return typeof valueOrObs === 'function' ? valueOrObs(binder.onUpdate) : null | |
79 | - } | |
95 | +ProtoSet.prototype._listen = function () { | |
96 | + var self = this | |
97 | + self.sources.forEach(function (obs, i) { | |
98 | + self.releases[i] = self._bind(obs) | |
99 | + }) | |
100 | +} | |
80 | 101 | |
81 | - function listen () { | |
82 | - sources.forEach(function (obs, i) { | |
83 | - releases[i] = bind(obs) | |
84 | - }) | |
85 | - } | |
102 | +ProtoSet.prototype._unlisten = function () { | |
103 | + this.releases.forEach(tryInvoke) | |
104 | + this.releases.length = 0 | |
105 | +} | |
86 | 106 | |
87 | - function unlisten () { | |
88 | - releases.forEach(tryInvoke) | |
89 | - releases.length = 0 | |
90 | - } | |
91 | - | |
92 | - function update () { | |
93 | - var currentValues = object.map(get) | |
94 | - var newValues = sources.map(resolve) | |
95 | - currentValues.filter(notIncluded, newValues).forEach(removeFrom, object) | |
96 | - newValues.filter(notIncluded, currentValues).forEach(addTo, object) | |
97 | - return true | |
98 | - } | |
107 | +ProtoSet.prototype._update = function () { | |
108 | + var currentValues = this.object.map(get) | |
109 | + var newValues = this.sources.map(resolve) | |
110 | + currentValues.filter(notIncluded, newValues).forEach(removeFrom, this.object) | |
111 | + newValues.filter(notIncluded, currentValues).forEach(addTo, this.object) | |
112 | + return true | |
99 | 113 | } |
100 | 114 | |
101 | 115 | function get (value) { |
102 | 116 | return value |
Built with git-ssb-web