diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/LintMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/LintMojo.java index 4633924c08..44c88e5084 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/LintMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/LintMojo.java @@ -34,17 +34,15 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.Mapped; import org.cactoos.list.ListOf; -import org.cactoos.number.SumOf; import org.eolang.lints.Defect; import org.eolang.lints.Program; import org.eolang.lints.Severity; import org.eolang.maven.footprint.FpDefault; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.tojos.TojoHash; +import org.eolang.maven.util.Threaded; import org.w3c.dom.Node; import org.xembly.Directives; import org.xembly.Xembler; @@ -97,15 +95,10 @@ void exec() { tojos ) ); - final int passed = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - tojo -> () -> this.lintOne(tojo, counts), - must - ) - ) - ).intValue(); + final int passed = new Threaded<>( + must, + tojo -> this.lintOne(tojo, counts) + ).total(); if (must.isEmpty()) { Logger.info(this, "No XMIR programs out of %d linted", tojos.size()); } else if (tojos.isEmpty()) { diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/OptimizeMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/OptimizeMojo.java index 9222ab4fc6..b901f3684b 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/OptimizeMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/OptimizeMojo.java @@ -33,16 +33,14 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.eolang.maven.footprint.FpDefault; import org.eolang.maven.optimization.OptSpy; import org.eolang.maven.optimization.OptTrain; import org.eolang.maven.optimization.Optimization; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.tojos.TojoHash; +import org.eolang.maven.util.Threaded; import org.eolang.parser.TrParsing; /** @@ -91,18 +89,13 @@ public void exec() { final long start = System.currentTimeMillis(); final Collection tojos = this.scopedTojos().withXmir(); final Optimization optimization = this.optimization(); - final int total = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - tojo -> () -> this.optimized(tojo, optimization), - new Filtered<>( - ForeignTojo::notOptimized, - tojos - ) - ) - ) - ).intValue(); + final int total = new Threaded<>( + new Filtered<>( + ForeignTojo::notOptimized, + tojos + ), + tojo -> this.optimized(tojo, optimization) + ).total(); if (total > 0) { Logger.info( this, diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java index c1580739f1..341cd16a84 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/ParseMojo.java @@ -35,14 +35,12 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.cactoos.Func; -import org.cactoos.experimental.Threads; import org.cactoos.io.InputOf; import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.eolang.maven.footprint.FpDefault; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.tojos.TojoHash; +import org.eolang.maven.util.Threaded; import org.eolang.parser.EoSyntax; import org.xembly.Directives; import org.xembly.Xembler; @@ -89,18 +87,13 @@ public final class ParseMojo extends SafeMojo { @Override public void exec() { final long start = System.currentTimeMillis(); - final int total = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - tojo -> () -> this.parsed(tojo), - new Filtered<>( - ForeignTojo::notParsed, - this.scopedTojos().withSources() - ) - ) - ) - ).intValue(); + final int total = new Threaded<>( + new Filtered<>( + ForeignTojo::notParsed, + this.scopedTojos().withSources() + ), + this::parsed + ).total(); if (0 == total) { if (this.scopedTojos().withSources().isEmpty()) { Logger.info( diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/PhiMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/PhiMojo.java index 8cd137166f..4e46e1c79c 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/PhiMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/PhiMojo.java @@ -40,11 +40,9 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.cactoos.text.TextOf; import org.eolang.maven.footprint.Saved; +import org.eolang.maven.util.Threaded; import org.eolang.maven.util.Walk; import org.eolang.parser.StUnhex; import org.eolang.parser.TrParsing; @@ -111,18 +109,13 @@ public void exec() { final Walk walk = new Walk(this.phiInputDir.toPath()); final int total = walk.size(); final Xsline xsline = new Xsline(this.train()); - final int count = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - xmir -> () -> { - final int position = passed.addAndGet(1); - return this.translate(xmir, xsline, position, total); - }, - walk - ) - ) - ).intValue(); + final int count = new Threaded<>( + walk, + xmir -> { + final int position = passed.addAndGet(1); + return this.translate(xmir, xsline, position, total); + } + ).total(); if (count > 0) { Logger.info( this, "Translated %d XMIR file(s) from %[file]s to %[file]s", diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/PrintMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/PrintMojo.java index dc44d6c33c..2bcccdb2af 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/PrintMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/PrintMojo.java @@ -33,12 +33,10 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.cactoos.text.TextOf; import org.eolang.maven.util.HmBase; import org.eolang.maven.util.Home; +import org.eolang.maven.util.Threaded; import org.eolang.maven.util.Walk; import org.eolang.parser.Xmir; @@ -88,37 +86,32 @@ public final class PrintMojo extends SafeMojo { @Override void exec() throws IOException { final Home home = new HmBase(this.printOutputDir); - final int total = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - source -> () -> { - final Path relative = Paths.get( - this.printSourcesDir.toPath().relativize(source).toString() - .replace(".xmir", ".eo") - ); - final XML xml = new XMLDocument(new TextOf(source).asString()); - final String program; - if (this.printReversed) { - program = new Xmir(xml).toReversed(); - } else { - program = new Xmir(xml).toEO(); - } - home.save(program, relative); - Logger.info( - this, - "Printed: %[file]s (%[size]s) => %[file]s (%[size]s)", - source, - source.toFile().length(), - this.printOutputDir.toPath().resolve(relative), - this.printOutputDir.toPath().resolve(relative).toFile().length() - ); - return 1; - }, - new Walk(this.printSourcesDir.toPath()) - ) - ) - ).intValue(); + final int total = new Threaded<>( + new Walk(this.printSourcesDir.toPath()), + source -> { + final Path relative = Paths.get( + this.printSourcesDir.toPath().relativize(source).toString() + .replace(".xmir", ".eo") + ); + final XML xml = new XMLDocument(new TextOf(source).asString()); + final String program; + if (this.printReversed) { + program = new Xmir(xml).toReversed(); + } else { + program = new Xmir(xml).toEO(); + } + home.save(program, relative); + Logger.info( + this, + "Printed: %[file]s (%[size]s) => %[file]s (%[size]s)", + source, + source.toFile().length(), + this.printOutputDir.toPath().resolve(relative), + this.printOutputDir.toPath().resolve(relative).toFile().length() + ); + return 1; + } + ).total(); if (total == 0) { Logger.info(this, "No XMIR sources found"); } else { diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/ShakeMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/ShakeMojo.java index 427e231067..995a2b8a6a 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/ShakeMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/ShakeMojo.java @@ -31,16 +31,14 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; import org.cactoos.iterable.Filtered; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.eolang.maven.footprint.FpDefault; import org.eolang.maven.optimization.OptSpy; import org.eolang.maven.optimization.OptTrain; import org.eolang.maven.optimization.Optimization; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.tojos.TojoHash; +import org.eolang.maven.util.Threaded; /** * Shake (prepare) XML files after optimizations for translation to java. @@ -83,18 +81,13 @@ void exec() { final long start = System.currentTimeMillis(); final Collection tojos = this.scopedTojos().withOptimized(); final Optimization optimization = this.optimization(); - final int total = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - tojo -> () -> this.shaken(tojo, optimization), - new Filtered<>( - ForeignTojo::notShaken, - tojos - ) - ) - ) - ).intValue(); + final int total = new Threaded<>( + new Filtered<>( + ForeignTojo::notShaken, + tojos + ), + tojo -> this.shaken(tojo, optimization) + ).total(); if (total > 0) { Logger.info( this, diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/TranspileMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/TranspileMojo.java index bb08b9b221..9cc14f45f8 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/TranspileMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/TranspileMojo.java @@ -38,15 +38,12 @@ import java.nio.file.Paths; import java.util.Collection; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.cactoos.experimental.Threads; -import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.cactoos.text.Joined; import org.eolang.maven.footprint.CachePath; import org.eolang.maven.footprint.Footprint; @@ -63,6 +60,7 @@ import org.eolang.maven.tojos.AttributeNotFoundException; import org.eolang.maven.tojos.ForeignTojo; import org.eolang.maven.tojos.TojoHash; +import org.eolang.maven.util.Threaded; /** * Transpile. @@ -164,12 +162,10 @@ public final class TranspileMojo extends SafeMojo { public void exec() { final Collection sources = this.scopedTojos().withOptimized(); final Optimization optimization = this.transpilation(); - final long saved = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>(tojo -> () -> this.transpiled(tojo, optimization), sources) - ) - ).longValue(); + final int saved = new Threaded<>( + sources, + tojo -> this.transpiled(tojo, optimization) + ).total(); Logger.info( this, "Transpiled %d XMIRs, created %d Java files in %[file]s", sources.size(), saved, this.generatedDir @@ -197,7 +193,7 @@ public void exec() { * @return Number of transpiled files. * @throws java.io.IOException If any issues with I/O */ - private long transpiled(final ForeignTojo tojo, final Optimization transpilation) + private int transpiled(final ForeignTojo tojo, final Optimization transpilation) throws IOException { final Path source; try { @@ -246,10 +242,10 @@ private Optimization transpilation() { * @return Amount of generated .java files * @throws IOException If fails to save files */ - private long javaGenerated(final boolean rewrite, final Path target, final String hsh) + private int javaGenerated(final boolean rewrite, final Path target, final String hsh) throws IOException { final Collection nodes = new XMLDocument(target).nodes("//class[java and not(@atom)]"); - final AtomicLong saved = new AtomicLong(0L); + final AtomicInteger saved = new AtomicInteger(0); for (final XML java : nodes) { final Path tgt = new Place(java.xpath("@java-name").get(0)).make( this.generatedDir.toPath(), TranspileMojo.JAVA diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java index eac6095773..655fcd0b4b 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/UnphiMojo.java @@ -38,15 +38,14 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.cactoos.experimental.Threads; import org.cactoos.iterable.IterableEnvelope; import org.cactoos.iterable.Joined; import org.cactoos.iterable.Mapped; -import org.cactoos.number.SumOf; import org.cactoos.set.SetOf; import org.cactoos.text.TextOf; import org.eolang.maven.util.HmBase; import org.eolang.maven.util.Home; +import org.eolang.maven.util.Threaded; import org.eolang.maven.util.Walk; import org.eolang.parser.PhiSyntax; import org.eolang.parser.TrStepped; @@ -112,47 +111,42 @@ public void exec() { final Iterable metas = new UnphiMojo.Metas(this.unphiMetas); final Xsline xsline = new Xsline(this.measured(UnphiMojo.TRANSFORMATIONS)); final long start = System.currentTimeMillis(); - final int count = new SumOf( - new Threads<>( - Runtime.getRuntime().availableProcessors(), - new Mapped<>( - phi -> () -> { - final Path relative = this.unphiInputDir.toPath().relativize(phi); - final Path xmir = Paths.get( - relative.toString().replace( - String.format(".%s", PhiMojo.EXT), - String.format(".%s", AssembleMojo.XMIR) - ) - ); - final XML result = xsline.pass( - new PhiSyntax( - phi.getFileName().toString().replace(".phi", ""), - new TextOf(phi), - metas - ).parsed() - ); - home.save(result.toString(), xmir); - Logger.debug( - this, - "Parsed to xmir: %[file]s -> %[file]s", - phi, this.unphiOutputDir.toPath().resolve(xmir) - ); - final List here = result.xpath("//errors/error/text()"); - if (!here.isEmpty()) { - errors.add( - Logger.format( - "%[file]s:\n\t%s\n", - xmir, - String.join("\n\t", here) - ) - ); - } - return 1; - }, - new Walk(this.unphiInputDir.toPath()) - ) - ) - ).intValue(); + final int count = new Threaded<>( + new Walk(this.unphiInputDir.toPath()), + phi -> { + final Path relative = this.unphiInputDir.toPath().relativize(phi); + final Path xmir = Paths.get( + relative.toString().replace( + String.format(".%s", PhiMojo.EXT), + String.format(".%s", AssembleMojo.XMIR) + ) + ); + final XML result = xsline.pass( + new PhiSyntax( + phi.getFileName().toString().replace(".phi", ""), + new TextOf(phi), + metas + ).parsed() + ); + home.save(result.toString(), xmir); + Logger.debug( + this, + "Parsed to xmir: %[file]s -> %[file]s", + phi, this.unphiOutputDir.toPath().resolve(xmir) + ); + final List here = result.xpath("//errors/error/text()"); + if (!here.isEmpty()) { + errors.add( + Logger.format( + "%[file]s:\n\t%s\n", + xmir, + String.join("\n\t", here) + ) + ); + } + return 1; + } + ).total(); Logger.info( this, "Parsed %d phi files to xmir in %[ms]s", diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/tojos/ForeignTojo.java b/eo-maven-plugin/src/main/java/org/eolang/maven/tojos/ForeignTojo.java index 95014c71b6..d028f4b22e 100644 --- a/eo-maven-plugin/src/main/java/org/eolang/maven/tojos/ForeignTojo.java +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/tojos/ForeignTojo.java @@ -52,6 +52,11 @@ public ForeignTojo(final Tojo original) { this.delegate = original; } + @Override + public String toString() { + return this.delegate.toString(); + } + /** * The id of the tojo. * @return The id of the tojo. diff --git a/eo-maven-plugin/src/main/java/org/eolang/maven/util/Threaded.java b/eo-maven-plugin/src/main/java/org/eolang/maven/util/Threaded.java new file mode 100644 index 0000000000..f3b1388d92 --- /dev/null +++ b/eo-maven-plugin/src/main/java/org/eolang/maven/util/Threaded.java @@ -0,0 +1,93 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2024 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.maven.util; + +import org.cactoos.Func; +import org.cactoos.experimental.Threads; +import org.cactoos.iterable.Mapped; +import org.cactoos.number.SumOf; + +/** + * Processes elements in multiple threads. + * + *

We use this class to process a large number of elements in parallel, + * using all available processors. It is used in most Mojos, where multiple + * files must be processed parallel.

+ * + * @param The type of the element to iterate + * @since 0.1 + */ +public final class Threaded { + + /** + * The sources. + */ + private final Iterable sources; + + /** + * The function. + */ + private final Func scalar; + + /** + * Ctor. + * @param src The sources + * @param fun The function to run + */ + public Threaded(final Iterable src, final Func fun) { + this.sources = src; + this.scalar = fun; + } + + /** + * Exec them all and count. + * @return How many succeeded + */ + @SuppressWarnings("PMD.AvoidCatchingGenericException") + public int total() { + return new SumOf( + new Threads<>( + Runtime.getRuntime().availableProcessors() * 2, + new Mapped<>( + tojo -> () -> { + try { + return this.scalar.apply(tojo); + // @checkstyle IllegalCatchCheck (1 line) + } catch (final Exception ex) { + throw new IllegalStateException( + String.format( + "Failed to process %s (%s)", + tojo, tojo.getClass().getCanonicalName() + ), + ex + ); + } + }, + this.sources + ) + ) + ).intValue(); + } + +}