git ssb

1+

Matt McKegg / mutant



Commit b715609f8d6393dc7cf2fa7be33b256bffcce3e3

map: add option maxTime for incremental updating (avoid tight loop)

Matt McKegg committed on 7/27/2016, 6:28:13 AM
Parent: 880a92caf2ae2e1a7551e7a500794c09adf5880b

Files changed

map.jschanged
map.jsView
@@ -1,9 +1,9 @@
11 var resolve = require('./resolve')
22
33 module.exports = Map
44
5-function Map (obs, lambda) {
5 +function Map (obs, lambda, opts) {
66 var releases = []
77 var live = false
88 var lazy = false
99 var listeners = []
@@ -14,8 +14,15 @@
1414 var raw = []
1515 var values = []
1616 var watches = []
1717
18 + // incremental update
19 + var queue = []
20 + var maxTime = null
21 + if (opts && opts.maxTime) {
22 + maxTime = opts.maxTime
23 + }
24 +
1825 var result = function MutantMap (listener) {
1926 if (!listener) {
2027 return getValue()
2128 }
@@ -93,26 +100,22 @@
93100 if (items.length !== getLength(obs)) {
94101 changed = true
95102 }
96103
104 + var startedAt = Date.now()
105 +
97106 for (var i = 0, len = getLength(obs); i < len; i++) {
98107 var item = get(obs, i)
108 + var currentItem = items[i]
109 + items[i] = item
99110
100- if (typeof item === 'object') {
101- items[i] = item
102- raw[i] = lambda(item)
103- values[i] = resolve(raw[i])
104- changed = true
105- rebind(i)
106- } else if (item !== items[i]) {
107- items[i] = item
108- if (!lastValues.has(item)) {
109- lastValues.set(item, lambda(item))
111 + if (typeof item === 'object' || item !== currentItem) {
112 + if (maxTime && Date.now() - startedAt > maxTime) {
113 + queueUpdateItem(i)
114 + } else {
115 + updateItem(i)
110116 }
111- raw[i] = lastValues.get(item)
112- values[i] = resolve(raw[i])
113117 changed = true
114- rebind(i)
115118 }
116119 }
117120
118121 if (changed) {
@@ -124,8 +127,42 @@
124127
125128 return changed
126129 }
127130
131 + function queueUpdateItem (i) {
132 + if (!queue.length) {
133 + setImmediate(flushQueue)
134 + }
135 + if (!~queue.indexOf(i)) {
136 + queue.push(i)
137 + }
138 + }
139 +
140 + function flushQueue () {
141 + var startedAt = Date.now()
142 + while (queue.length && (!maxTime || Date.now() - startedAt < maxTime)) {
143 + updateItem(queue.pop())
144 + }
145 + broadcast()
146 + if (queue.length) {
147 + setImmediate(flushQueue)
148 + }
149 + }
150 +
151 + function updateItem (i) {
152 + var item = get(obs, i)
153 + if (typeof item === 'object') {
154 + raw[i] = lambda(item)
155 + } else {
156 + if (!lastValues.has(item)) {
157 + lastValues.set(item, lambda(item))
158 + }
159 + raw[i] = lastValues.get(item)
160 + }
161 + values[i] = resolve(raw[i])
162 + rebind(i)
163 + }
164 +
128165 function rebind (index) {
129166 if (watches[index]) {
130167 watches[index]()
131168 watches[index] = null

Built with git-ssb-web