MCPcopy
hub / github.com/riot/riot / udomdiff

Function udomdiff

riot+compiler.js:23837–23959  ·  view source on GitHub ↗
(a, b, get, before)

Source from the content-addressed store, hash-verified

23835 * @returns {Node[]} The same list of future children.
23836 */
23837 const udomdiff = (a, b, get, before) => {
23838 const bLength = b.length;
23839 let aEnd = a.length;
23840 let bEnd = bLength;
23841 let aStart = 0;
23842 let bStart = 0;
23843 let map = null;
23844 while (aStart < aEnd || bStart < bEnd) {
23845 // append head, tail, or nodes in between: fast path
23846 if (aEnd === aStart) {
23847 // we could be in a situation where the rest of nodes that
23848 // need to be added are not at the end, and in such case
23849 // the node to `insertBefore`, if the index is more than 0
23850 // must be retrieved, otherwise it's gonna be the first item.
23851 const node =
23852 bEnd < bLength
23853 ? bStart
23854 ? get(b[bStart - 1], -0).nextSibling
23855 : get(b[bEnd - bStart], 0)
23856 : before;
23857 while (bStart < bEnd) insertBefore(get(b[bStart++], 1), node);
23858 }
23859 // remove head or tail: fast path
23860 else if (bEnd === bStart) {
23861 while (aStart < aEnd) {
23862 // remove the node only if it's unknown or not live
23863 if (!map || !map.has(a[aStart])) removeChild(get(a[aStart], -1));
23864 aStart++;
23865 }
23866 }
23867 // same node: fast path
23868 else if (a[aStart] === b[bStart]) {
23869 aStart++;
23870 bStart++;
23871 }
23872 // same tail: fast path
23873 else if (a[aEnd - 1] === b[bEnd - 1]) {
23874 aEnd--;
23875 bEnd--;
23876 }
23877 // The once here single last swap "fast path" has been removed in v1.1.0
23878 // https://github.com/WebReflection/udomdiff/blob/single-final-swap/esm/index.js#L69-L85
23879 // reverse swap: also fast path
23880 else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
23881 // this is a "shrink" operation that could happen in these cases:
23882 // [1, 2, 3, 4, 5]
23883 // [1, 4, 3, 2, 5]
23884 // or asymmetric too
23885 // [1, 2, 3, 4, 5]
23886 // [1, 2, 3, 5, 6, 4]
23887 const node = get(a[--aEnd], -1).nextSibling;
23888 moveBefore(get(b[bStart++], 1), get(a[aStart++], -1).nextSibling);
23889 moveBefore(get(b[--bEnd], 1), node);
23890 // mark the future index as identical (yeah, it's dirty, but cheap 👍)
23891 // The main reason to do this, is that when a[aEnd] will be reached,
23892 // the loop will likely be on the fast path, as identical to b[bEnd].
23893 // In the best case scenario, the next loop will skip the tail,
23894 // but in the worst one, this node will be considered as already

Callers 1

updateFunction · 0.70

Calls 4

getFunction · 0.70
insertBeforeFunction · 0.70
removeChildFunction · 0.70
replaceChildFunction · 0.70

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…