Skip to content

Commit 03d38ca

Browse files
author
Esben Sparre Andreasen
committed
JS: simplify cache interaction
1 parent 6dbe827 commit 03d38ca

File tree

5 files changed

+56
-65
lines changed

5 files changed

+56
-65
lines changed

javascript/extractor/src/com/semmle/js/extractor/ExtractionMetrics.java

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
package com.semmle.js.extractor;
22

3-
import com.semmle.util.exception.Exceptions;
4-
import com.semmle.util.files.FileUtil;
53
import com.semmle.util.trap.TrapWriter;
64
import com.semmle.util.trap.TrapWriter.Label;
7-
import com.semmle.util.trap.pathtransformers.PathTransformer;
8-
import java.io.BufferedWriter;
95
import java.io.File;
10-
import java.io.FileOutputStream;
11-
import java.io.OutputStreamWriter;
126
import java.lang.management.ManagementFactory;
137
import java.lang.management.ThreadMXBean;
14-
import java.nio.charset.Charset;
158
import java.util.Stack;
16-
import java.util.zip.GZIPOutputStream;
179

1810
/** Metrics for the (single-threaded) extraction of a single file. */
1911
public class ExtractionMetrics {
@@ -79,55 +71,39 @@ public enum ExtractionPhase {
7971
private boolean timingsFailed;
8072

8173
/**
82-
* Appends these metrics to a trap file. Note that this makes the resulting trap file content
74+
* Writes the data metrics to a trap file. Note that this makes the resulting trap file content
8375
* non-deterministic.
8476
*/
85-
public void appendToTrapFile(File trapFileToAppendTo) {
86-
if (trapFileToAppendTo == null) {
87-
return;
88-
}
77+
public void writeDataToTrap(TrapWriter trapwriter) {
78+
trapwriter.addTuple(
79+
"extraction_data",
80+
fileLabel,
81+
cacheFile != null ? cacheFile.getAbsolutePath() : "",
82+
canReuseCacheFile,
83+
length);
84+
}
8985

90-
BufferedWriter out = null;
91-
FileOutputStream fos = null;
92-
GZIPOutputStream gzip = null;
93-
TrapWriter trapwriter = null;
94-
try {
95-
fos = new FileOutputStream(trapFileToAppendTo, true);
96-
gzip = new GZIPOutputStream(fos);
97-
out = new BufferedWriter(new OutputStreamWriter(gzip, Charset.forName("UTF-8")));
98-
99-
trapwriter = new TrapWriter(out, PathTransformer.std());
100-
trapwriter.addTuple(
101-
"extraction_data",
102-
fileLabel,
103-
cacheFile != null ? cacheFile.getAbsolutePath() : "",
104-
canReuseCacheFile,
105-
length);
106-
107-
if (!stack.isEmpty()) {
108-
failTimings(
109-
String.format(
110-
"Could not properly record extraction times for %s. (stack = %s)%n",
111-
fileLabel, stack.toString()));
112-
}
113-
if (!timingsFailed) {
114-
for (int i = 0; i < ExtractionPhase.values().length; i++) {
115-
trapwriter.addTuple("extraction_time", fileLabel, i, 0, (float) cpuTimes[i]);
116-
trapwriter.addTuple("extraction_time", fileLabel, i, 1, (float) wallclockTimes[i]);
117-
}
86+
/**
87+
* Writes the timing metrics to a trap file. Note that this makes the resulting trap file content
88+
* non-deterministic.
89+
*/
90+
public void writeTimingsToTrap(TrapWriter trapwriter) {
91+
if (!stack.isEmpty()) {
92+
failTimings(
93+
String.format(
94+
"Could not properly record extraction times for %s. (stack = %s)%n",
95+
fileLabel, stack.toString()));
96+
}
97+
if (!timingsFailed) {
98+
for (int i = 0; i < ExtractionPhase.values().length; i++) {
99+
trapwriter.addTuple("extraction_time", fileLabel, i, 0, (float) cpuTimes[i]);
100+
trapwriter.addTuple("extraction_time", fileLabel, i, 1, (float) wallclockTimes[i]);
118101
}
119-
FileUtil.close(trapwriter);
120-
} catch (Exception e) {
121-
FileUtil.close(fos);
122-
FileUtil.close(gzip);
123-
FileUtil.close(out);
124-
FileUtil.close(trapwriter);
125-
Exceptions.ignore(e, "Ignoring exception for extraction metrics writing");
126102
}
127103
}
128104

129105
private void failTimings(String msg) {
130-
System.err.printf(msg);
106+
System.err.println(msg);
131107
System.err.flush();
132108
this.timingsFailed = true;
133109
}

javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -450,14 +450,12 @@ private Integer extractContents(
450450

451451
metrics.setCacheFile(cacheFile);
452452
metrics.setCanReuseCacheFile(canReuseCacheFile);
453-
453+
metrics.writeDataToTrap(trapwriter);
454454
if (canUseCacheFile) {
455455
FileUtil.close(trapwriter);
456456

457457
if (canReuseCacheFile) {
458458
FileUtil.append(cacheFile, resultFile);
459-
metrics.stopPhase(ExtractionPhase.FileExtractor_extractContents);
460-
metrics.appendToTrapFile(resultFile);
461459
return null;
462460
}
463461

@@ -481,14 +479,14 @@ private Integer extractContents(
481479
int linesOfCode = loc.getLinesOfCode(), linesOfComments = loc.getLinesOfComments();
482480
trapwriter.addTuple("numlines", fileLabel, numLines, linesOfCode, linesOfComments);
483481
trapwriter.addTuple("filetype", fileLabel, fileType.toString());
482+
metrics.stopPhase(ExtractionPhase.FileExtractor_extractContents);
483+
metrics.writeTimingsToTrap(trapwriter);
484484
successful = true;
485485
return linesOfCode;
486486
} finally {
487487
if (!successful && trapwriter instanceof CachingTrapWriter)
488488
((CachingTrapWriter) trapwriter).discard();
489489
FileUtil.close(trapwriter);
490-
metrics.stopPhase(ExtractionPhase.FileExtractor_extractContents);
491-
metrics.appendToTrapFile(resultFile);
492490
}
493491
}
494492

javascript/extractor/src/com/semmle/js/extractor/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class Main {
3737
* A version identifier that should be updated every time the extractor changes in such a way that
3838
* it may produce different tuples for the same file under the same {@link ExtractorConfig}.
3939
*/
40-
public static final String EXTRACTOR_VERSION = "2019-09-03";
40+
public static final String EXTRACTOR_VERSION = "2019-09-04";
4141

4242
public static final Pattern NEWLINE = Pattern.compile("\n");
4343

javascript/extractor/src/com/semmle/js/extractor/test/TrapTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ public void close() {
166166
String expected = new WholeIO().strictreadText(trap);
167167
expectedVsActual.add(Pair.make(expected, actual));
168168
}
169+
170+
@Override
171+
public void addTuple(String tableName, Object... values) {
172+
if ("extraction_data".equals(tableName)
173+
|| "extraction_time".equals(tableName)) {
174+
// ignore non-deterministic tables
175+
return;
176+
}
177+
super.addTuple(tableName, values);
178+
}
169179
};
170180
}
171181

javascript/ql/src/semmle/javascript/meta/ExtractionMetrics.qll

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ module ExtractionMetrics {
1010
* A file with extraction metrics.
1111
*/
1212
class FileWithExtractionMetrics extends File {
13-
14-
FileWithExtractionMetrics() { extraction_data(this, _, _, _) and extraction_time(this, _, _, _)}
13+
FileWithExtractionMetrics() {
14+
extraction_data(this, _, _, _) and extraction_time(this, _, _, _)
15+
}
1516

1617
/**
1718
* Gets the CPU time in nanoseconds it took to extract this file.
@@ -49,13 +50,18 @@ module ExtractionMetrics {
4950
int getLength() { extraction_data(this, _, _, result) }
5051

5152
private float getTime(PhaseName phaseName, int timerKind) {
52-
// note that we use strictsum to make it clear if data is missing because it comes from an upgraded database.
53-
strictsum(int phaseId, float r |
54-
phaseName = getExtractionPhaseName(phaseId) and
55-
extraction_time(this, phaseId, timerKind, r)
53+
exists(float time |
54+
// note that we use strictsum to make it clear if data is missing because it comes from an upgraded database.
55+
strictsum(int phaseId, float r |
56+
phaseName = getExtractionPhaseName(phaseId) and
57+
extraction_time(this, phaseId, timerKind, r)
58+
|
59+
r
60+
) = time
5661
|
57-
r
58-
) = result
62+
// assume the cache-lookup was for free
63+
if isFromCache() then result = 0 else result = time
64+
)
5965
}
6066
}
6167

@@ -84,7 +90,6 @@ module ExtractionMetrics {
8490
"TypeScriptParser_talkToParserWrapper" = result and 8 = phaseId
8591
}
8692

87-
8893
/**
8994
* The name of a phase of the extraction.
9095
*/
@@ -105,7 +110,9 @@ module ExtractionMetrics {
105110
/**
106111
* Gets the total wallclock time spent on extraction.
107112
*/
108-
float getWallclockTime() { result = strictsum(any(FileWithExtractionMetrics f).getWallclockTime()) }
113+
float getWallclockTime() {
114+
result = strictsum(any(FileWithExtractionMetrics f).getWallclockTime())
115+
}
109116

110117
/**
111118
* Gets the total CPU time spent in phase `phaseName` of the extraction.

0 commit comments

Comments
 (0)