Skip to content

Commit 79dd1f8

Browse files
committed
new diff
1 parent 9ce807a commit 79dd1f8

1 file changed

Lines changed: 54 additions & 31 deletions

File tree

src/reconcile.ts

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -172,61 +172,84 @@ const side = (effects?: HookEffect[]) => {
172172
effects.length = 0
173173
}
174174

175-
const diff = function (a: Fiber[], b: Fiber[]) {
176-
var actions: Action[] = [],
177-
aMap: Record<string, number | undefined> = {},
178-
bMap: Record<string, number | undefined> = {},
179-
key = (v: Fiber) => v.key,
180-
i: number,
181-
j: number
182-
for (i = 0; i < a.length; i++) {
183-
aMap[key(a[i])] = i
175+
const diff = (aCh, bCh) => {
176+
let aHead = 0,
177+
bHead = 0,
178+
aTail = aCh.length - 1,
179+
bTail = bCh.length - 1,
180+
aMap = null,
181+
bMap = null,
182+
key = (v) => v.key,
183+
temp = [],
184+
actions = []
185+
186+
while (aHead <= aTail && bHead <= bTail) {
187+
if (key(aCh[aTail]) !== key(bCh[bTail])) break
188+
clone(aCh[aTail], bCh[bTail])
189+
temp.push({ op: TAG.UPDATE })
190+
aTail--
191+
bTail--
184192
}
185-
for (i = 0; i < b.length; i++) {
186-
bMap[key(b[i])] = i
193+
194+
while (aHead <= aTail && bHead <= bTail) {
195+
if (key(aCh[aHead]) !== key(bCh[bHead])) break
196+
clone(aCh[aHead], bCh[bHead])
197+
actions.push({ op: TAG.UPDATE })
198+
aHead++
199+
bHead++
187200
}
188-
for (i = j = 0; i !== a.length || j !== b.length;) {
189-
var aElm = a[i],
190-
bElm = b[j]
201+
if (!aMap) {
202+
aMap = {}
203+
for (let i = aHead; i <= aTail; i++) {
204+
aMap[key(aCh[i])] = i
205+
}
206+
}
207+
if (!bMap) {
208+
bMap = {}
209+
for (let i = bHead; i <= bTail; i++) {
210+
bMap[key(bCh[i])] = i
211+
}
212+
}
213+
while (aHead !== aTail + 1 || bHead !== bTail + 1) {
214+
var aElm = aCh[aHead],
215+
bElm = bCh[bHead]
191216
if (aElm === null) {
192-
i++
193-
} else if (b.length <= j) {
217+
aHead++
218+
} else if (bTail + 1 <= bHead) {
194219
removeElement(aElm)
195-
i++
196-
} else if (a.length <= i) {
220+
aHead++
221+
} else if (aTail + 1 <= aHead) {
197222
actions.push({ op: TAG.INSERT, cur: bElm, ref: aElm })
198-
j++
223+
bHead++
199224
} else if (key(aElm) === key(bElm)) {
200-
201225
if (aElm.type === bElm.type) {
202226
clone(aElm, bElm)
203227
actions.push({ op: TAG.UPDATE })
204228
} else { // replace
205229
actions.push({ op: TAG.REPLACE, cur: bElm, ref: aElm })
206230
}
207-
208-
i++
209-
j++
231+
aHead++
232+
bHead++
210233
} else {
211234
var foundB = bMap[key(aElm)]
212235
var foundA = aMap[key(bElm)]
213236
if (foundB === undefined) {
214-
removeElement(a[i])
215-
i++
237+
removeElement(aElm)
238+
aHead++
216239
} else if (foundA === undefined) {
217240
actions.push({ op: TAG.INSERT, cur: bElm, ref: aElm })
218-
j++
241+
bHead++
219242
} else {
220-
clone(a[foundA], bElm)
221-
actions.push({ op: TAG.MOVE, cur: a[foundA], ref: aElm })
222-
a[foundA] = null
223-
j++
243+
clone(aCh[foundA], bElm)
244+
actions.push({ op: TAG.MOVE, cur: aCh[foundA], ref: aElm })
245+
aCh[foundA] = null
246+
bHead++
224247
}
225248
}
226249
}
250+
actions.concat(temp)
227251
return actions
228252
}
229-
230253
export const getCurrentFiber = () => currentFiber || null
231254
export const isFn = (x: unknown): x is Function => typeof x === 'function'
232255
export const isStr = (s: unknown): s is number | string =>

0 commit comments

Comments
 (0)