sclass JE_CompressEachElementIndividually extends AbstractCompressor_AnyType> { settable IF0> elementCompressionStrategy; new L> searches; settable IF1 makeLiteral; // required settable bool debug; // internal new LS renderedElements; new FunctionCall renderedCode; new BitSet dirtyElements; int size() { ret l(inputData()); } int nNotLiteral() { ret countPred(searches, search -> search.has()); } scaffolded S getRenderedElement(int i) { if (contains(dirtyElements, i) || empty(_get(renderedElements, i))) { remove(dirtyElements, i); //print("Rendering element " + (i+1) + "/" + size()); var e = renderElement(i); listSet(renderedElements, i, e); //print(" => " + e); } ret renderedElements.get(i); } S renderElement(int i) { var search = _get(searches, i); S comp = search?!; ret comp != null ? comp : makeLiteral.get(_get(inputData(), i)); } bool dirty() { ret nempty(dirtyElements) || l(renderedElements) < size(); } public void flush { if (!dirty()) ret; S code = code(); submit(code, renderedCode); } // get current best compressed representation S code() { if (dirty() || empty(renderedCode)) renderedCode = functionCall ll( countIteratorToObjectArray getRenderedElement(size())); ret str(renderedCode); } // start compressors run { if (elementCompressionStrategy == null) ret; probabilisticForEach(scheduler(), 1.0, 0.5, indexAsSideValue(inputData()), data -> { int i = data.sideValue(); var subSearch = new CompressionSearch_AnyType(assertNotNull(+regime()), data!); subSearch.onNewBest(-> set(dirtyElements, i)); listSet(searches, i, subSearch); subSearch.addStrategy(elementCompressionStrategy!); ret subSearch; }); } }