Skip to content

Commit

Permalink
SONAR-6068 Improve performance of FileSystem query operation
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed Feb 10, 2015
1 parent db911e4 commit 9fb2ca6
Show file tree
Hide file tree
Showing 51 changed files with 860 additions and 224 deletions.
Expand Up @@ -20,32 +20,39 @@
package org.sonar.plugins.cpd; package org.sonar.plugins.cpd;


import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings; import org.sonar.api.config.Settings;
import org.sonar.api.resources.Java; import org.sonar.api.resources.Java;
import org.sonar.batch.duplication.BlockCache; import org.sonar.batch.duplication.BlockCache;
import org.sonar.plugins.cpd.index.IndexFactory; import org.sonar.plugins.cpd.index.IndexFactory;


import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;


public class CpdSensorTest { public class CpdSensorTest {


@Rule
public TemporaryFolder temp = new TemporaryFolder();

JavaCpdEngine sonarEngine; JavaCpdEngine sonarEngine;
DefaultCpdEngine sonarBridgeEngine; DefaultCpdEngine sonarBridgeEngine;
CpdSensor sensor; CpdSensor sensor;
Settings settings; Settings settings;


@Before @Before
public void setUp() { public void setUp() throws IOException {
IndexFactory indexFactory = mock(IndexFactory.class); IndexFactory indexFactory = mock(IndexFactory.class);
sonarEngine = new JavaCpdEngine(indexFactory, null, null); sonarEngine = new JavaCpdEngine(indexFactory, null, null);
sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class)); sonarBridgeEngine = new DefaultCpdEngine(indexFactory, new CpdMappings(), null, null, mock(BlockCache.class));
settings = new Settings(new PropertyDefinitions(CpdPlugin.class)); settings = new Settings(new PropertyDefinitions(CpdPlugin.class));


DefaultFileSystem fs = new DefaultFileSystem(); DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs); sensor = new CpdSensor(sonarEngine, sonarBridgeEngine, settings, fs);
} }


Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.sonar.xoo.rule.CreateIssueByInternalKeySensor; import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor;
import org.sonar.xoo.rule.OneIssuePerLineSensor; import org.sonar.xoo.rule.OneIssuePerLineSensor;
import org.sonar.xoo.rule.RandomAccessSensor;
import org.sonar.xoo.rule.XooFakeExporter; import org.sonar.xoo.rule.XooFakeExporter;
import org.sonar.xoo.rule.XooFakeImporter; import org.sonar.xoo.rule.XooFakeImporter;
import org.sonar.xoo.rule.XooFakeImporterWithMessages; import org.sonar.xoo.rule.XooFakeImporterWithMessages;
Expand Down Expand Up @@ -74,6 +75,7 @@ public List getExtensions() {
CoveragePerTestSensor.class, CoveragePerTestSensor.class,
DependencySensor.class, DependencySensor.class,
ChecksSensor.class, ChecksSensor.class,
RandomAccessSensor.class,


OneIssuePerLineSensor.class, OneIssuePerLineSensor.class,
OneIssueOnDirPerFileSensor.class, OneIssueOnDirPerFileSensor.class,
Expand Down
@@ -0,0 +1,73 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.xoo.rule;

import org.apache.commons.io.FileUtils;
import org.sonar.api.batch.fs.FilePredicates;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
import org.sonar.api.rule.RuleKey;
import org.sonar.xoo.Xoo;

import java.io.File;
import java.io.IOException;

public class RandomAccessSensor implements Sensor {

private static final String SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS = "sonar.xoo.randomAccessIssue.paths";
public static final String RULE_KEY = "RandomAccessIssue";

@Override
public void describe(SensorDescriptor descriptor) {
descriptor
.name("One Issue Per File with Random Access")
.onlyOnLanguages(Xoo.KEY)
.createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY)
.requireProperty(SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS);
}

@Override
public void execute(SensorContext context) {
File f = new File(context.settings().getString(SONAR_XOO_RANDOM_ACCESS_ISSUE_PATHS));
FileSystem fs = context.fileSystem();
FilePredicates p = fs.predicates();
try {
for (String path : FileUtils.readLines(f)) {
createIssues(fs.inputFile(p.and(p.hasPath(path), p.hasType(Type.MAIN), p.hasLanguage(Xoo.KEY))), context);
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

private void createIssues(InputFile file, SensorContext context) {
RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY);
context.newIssue()
.ruleKey(ruleKey)
.onFile(file)
.atLine(1)
.message("This issue is generated on each file")
.save();
}
}
Expand Up @@ -27,6 +27,6 @@ public class XooPluginTest {


@Test @Test
public void provide_extensions() { public void provide_extensions() {
assertThat(new XooPlugin().getExtensions()).hasSize(19); assertThat(new XooPlugin().getExtensions()).hasSize(20);
} }
} }
Expand Up @@ -57,7 +57,7 @@ public class CoveragePerTestSensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new CoveragePerTestSensor(); sensor = new CoveragePerTestSensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
} }


Expand Down
Expand Up @@ -56,7 +56,7 @@ public class DependencySensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new DependencySensor(); sensor = new DependencySensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
} }


Expand Down
Expand Up @@ -65,7 +65,7 @@ public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
metricFinder = mock(MetricFinder.class); metricFinder = mock(MetricFinder.class);
sensor = new MeasureSensor(metricFinder); sensor = new MeasureSensor(metricFinder);
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
storage = mock(SensorStorage.class); storage = mock(SensorStorage.class);
when(context.newMeasure()).then(new Answer<DefaultMeasure>() { when(context.newMeasure()).then(new Answer<DefaultMeasure>() {
Expand Down
Expand Up @@ -52,7 +52,7 @@ public class SymbolReferencesSensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new SymbolReferencesSensor(); sensor = new SymbolReferencesSensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
} }


Expand Down
Expand Up @@ -52,7 +52,7 @@ public class SyntaxHighlightingSensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new SyntaxHighlightingSensor(); sensor = new SyntaxHighlightingSensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
} }


Expand Down
Expand Up @@ -56,7 +56,7 @@ public class TestCaseSensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new TestCaseSensor(); sensor = new TestCaseSensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
} }


Expand Down
Expand Up @@ -57,7 +57,7 @@ public class XooTokenizerSensorTest {
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
sensor = new XooTokenizerSensor(); sensor = new XooTokenizerSensor();
fileSystem = new DefaultFileSystem(); fileSystem = new DefaultFileSystem(baseDir);
when(context.fileSystem()).thenReturn(fileSystem); when(context.fileSystem()).thenReturn(fileSystem);
settings = new Settings(); settings = new Settings();
when(context.settings()).thenReturn(settings); when(context.settings()).thenReturn(settings);
Expand Down
Expand Up @@ -19,7 +19,9 @@
*/ */
package org.sonar.xoo.rule; package org.sonar.xoo.rule;


import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
Expand All @@ -34,6 +36,8 @@
import org.sonar.api.config.Settings; import org.sonar.api.config.Settings;
import org.sonar.xoo.Xoo; import org.sonar.xoo.Xoo;


import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
Expand All @@ -42,6 +46,9 @@


public class OneIssuePerLineSensorTest { public class OneIssuePerLineSensorTest {


@Rule
public TemporaryFolder temp = new TemporaryFolder();

private OneIssuePerLineSensor sensor = new OneIssuePerLineSensor(); private OneIssuePerLineSensor sensor = new OneIssuePerLineSensor();


@Test @Test
Expand All @@ -52,8 +59,8 @@ public void testDescriptor() {
} }


@Test @Test
public void testRule() { public void testRule() throws IOException {
DefaultFileSystem fs = new DefaultFileSystem(); DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10);
fs.add(inputFile); fs.add(inputFile);


Expand All @@ -76,8 +83,8 @@ public Issue answer(InvocationOnMock invocation) throws Throwable {
} }


@Test @Test
public void testForceSeverity() { public void testForceSeverity() throws IOException {
DefaultFileSystem fs = new DefaultFileSystem(); DefaultFileSystem fs = new DefaultFileSystem(temp.newFolder());
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10); DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10);
fs.add(inputFile); fs.add(inputFile);


Expand Down
Expand Up @@ -57,7 +57,7 @@ public class XooBlameCommandTest {
@Before @Before
public void prepare() throws IOException { public void prepare() throws IOException {
baseDir = temp.newFolder(); baseDir = temp.newFolder();
fs = new DefaultFileSystem(); fs = new DefaultFileSystem(baseDir);
input = mock(BlameInput.class); input = mock(BlameInput.class);
when(input.fileSystem()).thenReturn(fs); when(input.fileSystem()).thenReturn(fs);
} }
Expand Down
18 changes: 18 additions & 0 deletions sonar-batch/pom.xml
Expand Up @@ -9,6 +9,10 @@


<artifactId>sonar-batch</artifactId> <artifactId>sonar-batch</artifactId>
<name>SonarQube :: Batch</name> <name>SonarQube :: Batch</name>

<properties>
<enableBenchmarkAssertions>false</enableBenchmarkAssertions>
</properties>


<dependencies> <dependencies>
<dependency> <dependency>
Expand Down Expand Up @@ -197,4 +201,18 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>

<profiles>
<profile>
<id>runBenchmarks</id>
<activation>
<property>
<name>runBenchmarks</name>
</property>
</activation>
<properties>
<enableBenchmarkAssertions>true</enableBenchmarkAssertions>
</properties>
</profile>
</profiles>
</project> </project>
Expand Up @@ -36,7 +36,6 @@
import org.sonar.api.batch.maven.MavenUtils; import org.sonar.api.batch.maven.MavenUtils;
import org.sonar.api.task.TaskExtension; import org.sonar.api.task.TaskExtension;
import org.sonar.api.utils.MessageException; import org.sonar.api.utils.MessageException;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.java.api.JavaUtils; import org.sonar.java.api.JavaUtils;


import javax.annotation.Nullable; import javax.annotation.Nullable;
Expand Down Expand Up @@ -219,15 +218,6 @@ private static File getBuildDir(MavenProject pom) {
return resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); return resolvePath(pom.getBuild().getDirectory(), pom.getBasedir());
} }


public void synchronizeFileSystem(MavenProject pom, DefaultModuleFileSystem into) {
into.resetDirs(
pom.getBasedir(),
getBuildDir(pom),
mainDirs(pom),
testDirs(pom),
Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir())));
}

static File resolvePath(@Nullable String path, File basedir) { static File resolvePath(@Nullable String path, File basedir) {
if (path != null) { if (path != null) {
File file = new File(StringUtils.trim(path)); File file = new File(StringUtils.trim(path));
Expand Down
Expand Up @@ -20,7 +20,7 @@
package org.sonar.batch.scan.filesystem; package org.sonar.batch.scan.filesystem;


import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.AbstractFilePredicate;
import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;


Expand All @@ -34,7 +34,7 @@ private AdditionalFilePredicates() {
// only static inner classes // only static inner classes
} }


static class KeyPredicate implements FilePredicate { static class KeyPredicate extends AbstractFilePredicate {
private final String key; private final String key;


KeyPredicate(String key) { KeyPredicate(String key) {
Expand All @@ -47,7 +47,7 @@ public boolean apply(InputFile f) {
} }
} }


static class DeprecatedKeyPredicate implements FilePredicate { static class DeprecatedKeyPredicate extends AbstractFilePredicate {
private final String key; private final String key;


DeprecatedKeyPredicate(String key) { DeprecatedKeyPredicate(String key) {
Expand All @@ -60,7 +60,7 @@ public boolean apply(InputFile f) {
} }
} }


static class SourceRelativePathPredicate implements FilePredicate { static class SourceRelativePathPredicate extends AbstractFilePredicate {
private final String path; private final String path;


SourceRelativePathPredicate(String s) { SourceRelativePathPredicate(String s) {
Expand All @@ -73,7 +73,7 @@ public boolean apply(InputFile f) {
} }
} }


static class SourceDirPredicate implements FilePredicate { static class SourceDirPredicate extends AbstractFilePredicate {
private final String path; private final String path;


SourceDirPredicate(String s) { SourceDirPredicate(String s) {
Expand Down

0 comments on commit 9fb2ca6

Please sign in to comment.