!7 cprint CompressorSpike { switchable S snippetID = #1020763; LinkedHashMap versions; start-thread { print("Snippet ID: " + snippetID); dm_onFieldChange snippetID(r { setField(versions := null); dm_reload() }); if (versions == null) { versions = mapToLinkedHashMap(textChangesOfSnippet(snippetID), sv -> pair(str(sv.versionID), sv.previousValue)); versions.put("latest", loadSnippet(snippetID)); versions = mapValuesToLinkedHashMap toLinesAndBack(versions); // canonicalize line breaks change(); } print("Have " + nVersions(versions) + " with a total of " + nLines(totalLineCount(values(versions)))); new Compressor().run(); } abstract sclass Chunk { abstract S text(L chunks); } srecord CPair(int i1, int i2) > Chunk { S text(L chunks) { ret linesLL(chunks.get(i1).text(chunks), chunks.get(i2).text(chunks)); } } srecord CPrim(S s) > Chunk { S text(L chunks) { ret s; } } class Compressor { Map textIDToLines = mapValuesToLinkedHashMap lines(versions); LS allUniqueLines; new L chunks; Map lineIndex; new Map linePairIndex; run { allUniqueLines = uniquify(concatLists(values(textIDToLines))); for (S line : allUniqueLines) chunks.add(new CPrim(line)); lineIndex = listIndex(collect s(chunks)); for (S id, LS lines : textIDToLines) { new L encoded; encoded = map(lines, line -> lineIndex.get(line)); print(id + ": " + joinWithSpace(encoded)); assertEquals(lines(lines), decode(encoded)); } } S decode(L encoded) { ret lines(lambdaMap chunkText(encoded)); } S chunkText(int idx) { ret chunks.get(idx).text(chunks); } } }