correctly clean source-to-outputs storage

This commit is contained in:
Eugene Zhuravlev
2012-05-04 18:47:34 +02:00
parent 5fb349cd83
commit 26933cb1c8
4 changed files with 69 additions and 34 deletions
@@ -234,46 +234,51 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler
}
void onChunkBuildComplete(@NotNull ModuleChunk chunk) throws IOException {
getDataManager().closeSourceToOutputStorages(chunk, isCompilingTests());
getDataManager().flush(true);
final boolean compilingTests = isCompilingTests();
myProjectDescriptor.fsState.clearContextRoundData();
myProjectDescriptor.fsState.clearContextChunk();
if (!myErrorsFound && !myCancelStatus.isCanceled()) {
final boolean compilingTests = isCompilingTests();
final DirtyMarkScope dirtyScope = compilingTests ? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION;
boolean marked = false;
for (Module module : chunk.getModules()) {
if (isMake()) {
// ensure non-incremental flag cleared
myNonIncrementalModules.remove(new Pair<Module, DirtyMarkScope>(module, dirtyScope));
}
if (isProjectRebuild()) {
myProjectDescriptor.fsState.markInitialScanPerformed(module.getName(), compilingTests);
}
final List<RootDescriptor> roots = myProjectDescriptor.rootsIndex.getModuleRoots(module);
for (RootDescriptor descriptor : roots) {
if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) {
marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTimestamps, myCompilationStartStamp);
final BuildDataManager dataManager = getDataManager();
try {
if (!myErrorsFound && !myCancelStatus.isCanceled()) {
final DirtyMarkScope dirtyScope = compilingTests ? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION;
boolean marked = false;
for (Module module : chunk.getModules()) {
if (isMake()) {
// ensure non-incremental flag cleared
myNonIncrementalModules.remove(new Pair<Module, DirtyMarkScope>(module, dirtyScope));
}
if (isProjectRebuild()) {
myProjectDescriptor.fsState.markInitialScanPerformed(module.getName(), compilingTests);
}
final List<RootDescriptor> roots = myProjectDescriptor.rootsIndex.getModuleRoots(module);
for (RootDescriptor descriptor : roots) {
if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) {
marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTimestamps, myCompilationStartStamp);
}
}
}
}
// clean mapping only after everything else is processed
final Map<String, Collection<String>> map = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(this);
if (map != null) {
for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
final SourceToOutputMapping mapping = getDataManager().getSourceToOutputMap(entry.getKey(), isCompilingTests());
for (String path : entry.getValue()) {
mapping.remove(path);
// clean mapping only after everything else is processed
final Map<String, Collection<String>> map = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(this);
if (map != null) {
for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
final SourceToOutputMapping mapping = dataManager.getSourceToOutputMap(entry.getKey(), isCompilingTests());
for (String path : entry.getValue()) {
mapping.remove(path);
}
}
}
}
if (marked) {
processMessage(UptoDateFilesSavedEvent.INSTANCE);
if (marked) {
processMessage(UptoDateFilesSavedEvent.INSTANCE);
}
}
}
finally {
dataManager.closeSourceToOutputStorages(chunk, compilingTests);
dataManager.flush(true);
}
}
public CompileScope getScope() {
@@ -489,7 +489,8 @@ public class IncProjectBuilder {
final Map<String, Collection<String>> perModuleRemovedSources = new HashMap<String, Collection<String>>();
for (Module module : chunk.getModules()) {
final Collection<String> deletedPaths = myProjectDescriptor.fsState.getDeletedPaths(module.getName(), context.isCompilingTests());
final Collection<String> deletedPaths = myProjectDescriptor.fsState.getAndClearDeletedPaths(module.getName(),
context.isCompilingTests());
if (deletedPaths.isEmpty()) {
continue;
}
@@ -525,7 +526,6 @@ public class IncProjectBuilder {
new File(output).delete();
}
}
//sourceToOutputStorage.remove(deletedSource);
// check if deleted source was associated with a form
final SourceToFormMapping sourceToFormMap = context.getDataManager().getSourceToFormMap();
@@ -545,10 +545,20 @@ public class IncProjectBuilder {
allChunkRemovedSources.addAll(currentData);
}
Utils.CHUNK_REMOVED_SOURCES_KEY.set(context, allChunkRemovedSources);
Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.set(context, perModuleRemovedSources);
for (Module module : chunk.getModules()) {
myProjectDescriptor.fsState.clearDeletedPaths(module.getName(), context.isCompilingTests());
final Map<String, Collection<String>> existing = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(context);
if (existing != null) {
for (Map.Entry<String, Collection<String>> entry : existing.entrySet()) {
final Collection<String> paths = perModuleRemovedSources.get(entry.getKey());
if (paths != null) {
paths.addAll(entry.getValue());
}
else {
perModuleRemovedSources.put(entry.getKey(), entry.getValue());
}
}
}
Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.set(context, perModuleRemovedSources);
}
}
catch (IOException e) {
@@ -113,6 +113,14 @@ public class FSState {
}
}
public Collection<String> getAndClearDeletedPaths(final String moduleName, final boolean forTests) {
final FilesDelta delta = myDeltas.get(moduleName);
if (delta != null) {
return delta.getAndClearDeletedPaths(forTests);
}
return Collections.emptyList();
}
@NotNull
protected final FilesDelta getDelta(final String moduleName) {
synchronized (myDeltas) {
@@ -127,6 +127,18 @@ final class FilesDelta {
deleted.clear();
}
public Set<String> getAndClearDeletedPaths(boolean isTest) {
final Set<String> deleted = isTest? myDeletedTests : myDeletedProduction;
synchronized (deleted) {
try {
return new HashSet<String>(deleted);
}
finally {
deleted.clear();
}
}
}
public Map<File, Set<File>> getSourcesToRecompile(boolean forTests) {
return forTests? myTestsToRecompile : mySourcesToRecompile;
}