public static Serializable diff(Object[] a, Object[] b) { List<Object> la = Arrays.asList(a); List<Object> lb = Arrays.asList(b); Serializable diff = diff(la, lb); if (diff instanceof List) { return b; } ListDiff listDiff = (ListDiff) diff; listDiff.isArray = true; return listDiff; }
public static Serializable diff(List<Object> a, List<Object> b) { ListDiff listDiff = new ListDiff(); listDiff.isArray = false; int aSize = a.size(); int bSize = b.size(); // TODO configure zero-length "a" case boolean doRPush = aSize > 0 && aSize < bSize; // we can use a list diff if lists are the same size, // or we have a rpush boolean doDiff = aSize == bSize || doRPush; if (!doDiff) { return (Serializable) b; } int len = Math.min(aSize, bSize); List<Object> diff = new ArrayList<>(len); int nops = 0; int diffs = 0; for (int i = 0; i < len; i++) { Serializable elemDiff = diff(a.get(i), b.get(i)); if (elemDiff == NOP) { nops++; } else if (elemDiff instanceof StateDiff) { diffs++; } // TODO if the individual element diffs are big StateDiffs, // do a full State replacement instead diff.add(elemDiff); } if (nops == len) { // only nops diff = null; } else if (diffs == 0) { // only setting elements or nops // TODO use a higher ratio than 0% of diffs return (Serializable) b; } listDiff.diff = diff; if (doRPush) { List<Object> rpush = new ArrayList<>(bSize - aSize); for (int i = aSize; i < bSize; i++) { rpush.add(b.get(i)); } listDiff.rpush = rpush; } return listDiff; }
private static final ListDiff listDiff(List<Object> diff, List<Object> rpush) { ListDiff listDiff = new ListDiff(); listDiff.diff = diff; listDiff.rpush = rpush; return listDiff; }