sclass JE_CompressEachElementIndividually extends AbstractCompressor_AnyType> { settable IF0, El>> elementCompressionStrategy; new L, El>> searches; settable IF1 makeLiteral; // required new BitSet compressedElementsBitSet; // TODO: akas for variables selfType onCompressionFail(IF1 f) { makeLiteral = f; this; } settable bool debug; // internal new L renderedElements; IJavaExpr renderedCode; new BitSet dirtyElements; int size() { ret l(inputData()); } int nNotLiteral() { ret countPred(searches, search -> search.has()); } scaffolded IJavaExpr getRenderedElement(int i) { if (contains(dirtyElements, i) || _get(renderedElements, i) == null) { remove(dirtyElements, i); //print("Rendering element " + (i+1) + "/" + size()); var e = renderElement(i); listSet(renderedElements, i, e); //print(" => " + e); } ret renderedElements.get(i); } IJavaExpr renderElement(int i) { var search = _get(searches, i); IJavaExpr comp = search?!; if (comp != null) { synchronized(compressedElementsBitSet) { compressedElementsBitSet.set(i); } ret comp; } // no "good" compression found, return literal IJavaExpr java = makeLiteral.get(_get(inputData(), i)); metaSet(java, gaveUp := this); ret java; } bool dirty() { ret nempty(dirtyElements) || l(renderedElements) < size(); } public void flush { if (!dirty()) ret; submit(code()); } L codeForElements() { ret countIteratorToList getRenderedElement(size()); } // get current best compressed representation IJavaExpr code() { if (dirty() || renderedCode == null) { L els = codeForElements(); int iNull = indexOf(els, null); if (iNull >= 0) fail("Null element: " + iNull + "/" + l(els)); renderedCode = javaExpr( functionCall_list ll(els), -> mapQuickEval_javaExpr(els)); } ret renderedCode; } // start compressors public void step0 { if (elementCompressionStrategy == null) ret; probabilisticForEach(scheduler(), 1.0, 0.5, indexAsSideValue(inputData()), ivf1WithToString("Compress element", data -> { int i = data.sideValue(); var subSearch = new CompressionSearch_AnyType, El>(assertNotNull(+childRegime()), data!, 1 /* TODO */); subSearch.onNewBest(-> set(dirtyElements, i)); listSet(searches, i, subSearch); subSearch.addStrategy(elementCompressionStrategy!); })); } S stats() { ret renderVars(+nNotLiteral() + " of " + size()); } // might as well work (reuse compression regime for children) swappable CompressionRegime_AnyType> childRegime() { ret (CompressionRegime_AnyType) regime(); } bool isElementCompressed(int i) { synchronized(compressedElementsBitSet) { ret compressedElementsBitSet.get(i); } } }