Skip to content

Commit eae5803

Browse files
committed
Generalize the trace rewrite utility
1 parent 49e3e4f commit eae5803

File tree

14 files changed

+266
-110
lines changed

14 files changed

+266
-110
lines changed

config/spotbugs/exclude.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
<Bug pattern="RV_RETURN_VALUE_IGNORED"/>
152152
</Match>
153153
<Match>
154-
<Class name="com.github.benmanes.caffeine.cache.simulator.parser.rewrite.Rewriter"/>
154+
<Class name="com.github.benmanes.caffeine.cache.simulator.parser.Rewriter"/>
155155
<Method name="run"/>
156156
<Bug code="RCN"/>
157157
</Match>

gradle/codeQuality.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ afterEvaluate {
180180
tasks.findAll { it.name.startsWith('spotbugs') }.each {
181181
it.enabled = System.properties.containsKey('spotbugs')
182182
it.group = 'SpotBugs'
183+
it.reports {
184+
html { enabled = true }
185+
}
183186
}
184187
}
185188

gradle/dependencies.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ ext {
4848
javaObjectLayout: '0.10',
4949
javapoet: '1.12.1',
5050
jcache: '1.1.1',
51-
jcommander: '1.78',
5251
jmh: '1.23',
5352
jsr330: '1',
5453
koloboke: '1.0.0',
5554
nullaway: '0.7.9',
5655
ohc: '0.6.1',
56+
picocli: '4.3.2',
5757
slf4j: '1.7.30',
5858
tcache: '2.0.1',
5959
stream: '2.9.8',
@@ -123,14 +123,14 @@ ext {
123123
javaObjectLayout: "org.openjdk.jol:jol-cli:${versions.javaObjectLayout}",
124124
javapoet: "com.squareup:javapoet:${versions.javapoet}",
125125
jcache: "javax.cache:cache-api:${versions.jcache}",
126-
jcommander: "com.beust:jcommander:${versions.jcommander}",
127126
jsr330: "javax.inject:javax.inject:${versions.jsr330}",
128127
koloboke: [
129128
"com.koloboke:koloboke-api-jdk8:${versions.koloboke}",
130129
"com.koloboke:koloboke-impl-jdk8:${versions.koloboke}",
131130
],
132131
nullaway: "com.uber.nullaway:nullaway:${versions.nullaway}",
133132
ohc: "org.caffinitas.ohc:ohc-core-j8:${versions.ohc}",
133+
picocli: "info.picocli:picocli:${versions.picocli}",
134134
slf4jNop: "org.slf4j:slf4j-nop:${versions.slf4j}",
135135
tcache: "com.trivago:triava:${versions.tcache}",
136136
stream: "com.clearspring.analytics:stream:${versions.stream}",

simulator/build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ dependencies {
1616
implementation libraries.stream
1717
implementation libraries.tcache
1818
implementation libraries.cache2k
19+
implementation libraries.picocli
1920
implementation libraries.ehcache3
2021
implementation libraries.fastutil
2122
implementation libraries.slf4jNop
2223
implementation libraries.collision
2324
implementation libraries.fastfilter
2425
implementation libraries.flipTables
25-
implementation libraries.jcommander
2626
implementation libraries.expiringMap
2727
implementation libraries.commonsLang3
2828
implementation libraries.commonsMath3
@@ -80,10 +80,10 @@ run {
8080
}
8181

8282
task rewrite(type: JavaExec) {
83-
main = 'com.github.benmanes.caffeine.cache.simulator.parser.rewrite.Rewriter'
83+
main = 'com.github.benmanes.caffeine.cache.simulator.parser.Rewriter'
8484
classpath = sourceSets.main.runtimeClasspath
8585

86-
def arguments = ['inputFiles', 'outputFile', 'outputFormat']
86+
def arguments = ['inputFormat', 'inputFiles', 'outputFile', 'outputFormat']
8787
for (def argument : arguments) {
8888
if (project.hasProperty(argument)) {
8989
args "--${argument}", project.property(argument)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2019 Ben Manes. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.benmanes.caffeine.cache.simulator.parser;
17+
18+
import java.io.BufferedOutputStream;
19+
import java.io.OutputStream;
20+
import java.util.function.Function;
21+
22+
import com.github.benmanes.caffeine.cache.simulator.parser.adapt_size.AdaptSizeTraceWriter;
23+
import com.github.benmanes.caffeine.cache.simulator.parser.climb.ClimbTraceWriter;
24+
25+
/**
26+
* The trace output format.
27+
*
28+
* @author ben.manes@gmail.com (Ben Manes)
29+
*/
30+
@SuppressWarnings("ImmutableEnumChecker")
31+
public enum OutputFormat {
32+
ADAPT_SIZE(AdaptSizeTraceWriter::new),
33+
CLIMB(ClimbTraceWriter::new);
34+
35+
private final Function<OutputStream, TraceWriter> factory;
36+
37+
OutputFormat(Function<OutputStream, TraceWriter> factory) {
38+
this.factory = factory;
39+
}
40+
41+
public TraceWriter writer(OutputStream output) {
42+
return factory.apply(new BufferedOutputStream(output));
43+
}
44+
}

simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/parser/rewrite/Rewriter.java simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/parser/Rewriter.java

+37-33
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,79 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package com.github.benmanes.caffeine.cache.simulator.parser.rewrite;
16+
package com.github.benmanes.caffeine.cache.simulator.parser;
1717

18-
import java.io.BufferedWriter;
18+
import java.io.BufferedOutputStream;
1919
import java.io.IOException;
20+
import java.io.OutputStream;
21+
import java.io.UncheckedIOException;
2022
import java.nio.file.Files;
2123
import java.nio.file.Path;
2224
import java.util.ArrayList;
2325
import java.util.Iterator;
2426
import java.util.List;
2527
import java.util.stream.Stream;
2628

27-
import com.beust.jcommander.JCommander;
28-
import com.beust.jcommander.Parameter;
29-
import com.github.benmanes.caffeine.cache.simulator.parser.TraceFormat;
3029
import com.github.benmanes.caffeine.cache.simulator.policy.AccessEvent;
3130
import com.google.common.base.Stopwatch;
3231

32+
import picocli.CommandLine;
33+
import picocli.CommandLine.Help;
34+
import picocli.CommandLine.Option;
35+
3336
/**
3437
* A simple utility to rewrite traces for into the format used by other simulators. This lets us
3538
* run multiple simulators in parallel for a quick-and-dirty analysis, rather than port their code
3639
* into Java.
3740
* <p>
3841
* <pre>{@code
39-
* ./gradlew :simulator:rewrite -PinputFiles=? -PoutputFile=? -PoutputFormat=?
42+
* ./gradlew :simulator:rewrite \
43+
* -PinputFormat=? \
44+
* -PinputFiles=? \
45+
* -PoutputFile=? \
46+
* -PoutputFormat=?
4047
* }</pre>
4148
*
4249
* @author ben.manes@gmail.com (Ben Manes)
4350
*/
4451
@SuppressWarnings("PMD.ImmutableField")
45-
public final class Rewriter {
46-
@Parameter(names = "--inputFiles", required = true, description = "The trace input files. To use "
52+
public final class Rewriter implements Runnable {
53+
@Option(names = "--inputFiles", required = true, description = "The trace input files. To use "
4754
+ "a mix of formats, specify the entry as format:path, e.g. lirs:loop.trace.gz")
4855
private List<String> inputFiles = new ArrayList<>();
49-
@Parameter(names = "--inputFormat", description = "The default trace input format")
50-
private TraceFormat inputFormat = TraceFormat.LIRS;
56+
@Option(names = "--inputFormat", required = true, description = "The default trace input format")
57+
private TraceFormat inputFormat;
5158

52-
@Parameter(names = "--outputFile", description = "The trace output file", required = true)
59+
@Option(names = "--outputFile", required = true, description = "The trace output file")
5360
private Path outputFile;
54-
@Parameter(names = "--outputFormat", description = "The trace output format", required = true)
61+
@Option(names = "--outputFormat", required = true, description = "The trace output format")
5562
private OutputFormat outputFormat;
5663

57-
@Parameter(names = "--help", help = true, hidden = true)
58-
private boolean help;
59-
64+
@Override
6065
@SuppressWarnings("PMD.ForLoopCanBeForeach")
61-
public void run() throws IOException {
62-
long count = 0;
66+
public void run() {
67+
int tick = 0;
6368
Stopwatch stopwatch = Stopwatch.createStarted();
64-
try (Stream<AccessEvent> events = inputFormat.readFiles(inputFiles).events();
65-
BufferedWriter writer = Files.newBufferedWriter(outputFile)) {
69+
try (OutputStream output = new BufferedOutputStream(Files.newOutputStream(outputFile));
70+
Stream<AccessEvent> events = inputFormat.readFiles(inputFiles).events();
71+
TraceWriter writer = outputFormat.writer(output)) {
72+
writer.writeHeader();
6673
for (Iterator<AccessEvent> i = events.iterator(); i.hasNext();) {
67-
outputFormat.write(writer, i.next(), count);
68-
count++;
74+
writer.writeEvent(tick, i.next());
75+
tick++;
6976
}
77+
writer.writeFooter();
78+
System.out.printf("Rewrote %,d events in %s%n", tick, stopwatch);
79+
} catch (IOException e) {
80+
throw new UncheckedIOException(e);
7081
}
71-
System.out.printf("Rewrote %,d events in %s%n", count, stopwatch);
7282
}
7383

7484
public static void main(String[] args) throws IOException {
75-
Rewriter rewriter = new Rewriter();
76-
JCommander commander = JCommander.newBuilder()
77-
.programName(Rewriter.class.getSimpleName())
78-
.addObject(rewriter)
79-
.build();
80-
commander.parse(args);
81-
if (rewriter.help) {
82-
commander.usage();
83-
} else {
84-
rewriter.run();
85-
}
85+
new CommandLine(Rewriter.class)
86+
.setColorScheme(Help.defaultColorScheme(Help.Ansi.ON))
87+
.setCommandName(Rewriter.class.getSimpleName())
88+
.setCaseInsensitiveEnumValuesAllowed(true)
89+
.execute(args);
8690
}
8791
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2020 Ben Manes. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.benmanes.caffeine.cache.simulator.parser;
17+
18+
import static java.nio.charset.StandardCharsets.UTF_8;
19+
20+
import java.io.BufferedWriter;
21+
import java.io.IOException;
22+
import java.io.OutputStream;
23+
import java.io.OutputStreamWriter;
24+
25+
/**
26+
* A skeletal implementation that writes to the trace file as textual data.
27+
*
28+
* @author ben.manes@gmail.com (Ben Manes)
29+
*/
30+
public abstract class TextTraceWriter implements TraceWriter {
31+
private final BufferedWriter writer;
32+
33+
public TextTraceWriter(OutputStream output) {
34+
this.writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8));
35+
}
36+
37+
protected BufferedWriter writer() {
38+
return writer;
39+
}
40+
41+
@Override
42+
public void close() throws IOException {
43+
writer.close();
44+
}
45+
}

simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/parser/TraceFormat.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import java.util.function.Function;
2525
import java.util.stream.Stream;
2626

27-
import com.github.benmanes.caffeine.cache.simulator.parser.adapt_size.AdaptSizeReader;
27+
import com.github.benmanes.caffeine.cache.simulator.parser.adapt_size.AdaptSizeTraceReader;
2828
import com.github.benmanes.caffeine.cache.simulator.parser.address.AddressTraceReader;
2929
import com.github.benmanes.caffeine.cache.simulator.parser.address.penalties.AddressPenaltiesTraceReader;
3030
import com.github.benmanes.caffeine.cache.simulator.parser.arc.ArcTraceReader;
@@ -54,7 +54,7 @@
5454
public enum TraceFormat {
5555
ADDRESS(AddressTraceReader::new),
5656
ADDRESS_PENALTIES(AddressPenaltiesTraceReader::new),
57-
ADAPT_SIZE(AdaptSizeReader::new),
57+
ADAPT_SIZE(AdaptSizeTraceReader::new),
5858
ARC(ArcTraceReader::new),
5959
CACHE2K(Cache2kTraceReader::new),
6060
CAMELAB(CamelabTraceReader::new),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2020 Ben Manes. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.benmanes.caffeine.cache.simulator.parser;
17+
18+
import java.io.Closeable;
19+
import java.io.IOException;
20+
21+
import com.github.benmanes.caffeine.cache.simulator.policy.AccessEvent;
22+
23+
/**
24+
* A writer to output to an access trace format.
25+
*
26+
* @author ben.manes@gmail.com (Ben Manes)
27+
*/
28+
public interface TraceWriter extends Closeable {
29+
30+
/** Writes the header for the trace format. */
31+
default void writeHeader() throws IOException {};
32+
33+
/** Writes the event in the trace format. */
34+
void writeEvent(int tick, AccessEvent event) throws IOException;
35+
36+
/** Writes the footer for the trace format. */
37+
default void writeFooter() throws IOException {};
38+
}

simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/parser/adapt_size/AdaptSizeReader.java simulator/src/main/java/com/github/benmanes/caffeine/cache/simulator/parser/adapt_size/AdaptSizeTraceReader.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
*
3333
* @author ben.manes@gmail.com (Ben Manes)
3434
*/
35-
public final class AdaptSizeReader extends TextTraceReader {
35+
public final class AdaptSizeTraceReader extends TextTraceReader {
3636

37-
public AdaptSizeReader(String filePath) {
37+
public AdaptSizeTraceReader(String filePath) {
3838
super(filePath);
3939
}
4040

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2020 Ben Manes. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.github.benmanes.caffeine.cache.simulator.parser.adapt_size;
17+
18+
import java.io.IOException;
19+
import java.io.OutputStream;
20+
21+
import com.github.benmanes.caffeine.cache.simulator.parser.TextTraceWriter;
22+
import com.github.benmanes.caffeine.cache.simulator.policy.AccessEvent;
23+
24+
/**
25+
* A writer for the trace format used by the authors of the AdaptSize simulator.
26+
*
27+
* @author ben.manes@gmail.com (Ben Manes)
28+
*/
29+
public final class AdaptSizeTraceWriter extends TextTraceWriter {
30+
31+
public AdaptSizeTraceWriter(OutputStream output) {
32+
super(output);
33+
}
34+
35+
@Override
36+
public void writeEvent(int tick, AccessEvent event) throws IOException {
37+
writer().write(Long.toString(tick));
38+
writer().write(" ");
39+
writer().write(Long.toString(event.key()));
40+
writer().write(" ");
41+
writer().write(Integer.toString(event.weight()));
42+
writer().newLine();
43+
}
44+
}

0 commit comments

Comments
 (0)