<commit_before>/*
 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
 */

/*
 * Created by IntelliJ IDEA.
 * User: yole
 * Date: 12.07.2006
 * Time: 14:34:37
 */
package com.intellij.openapi.vcs.changes;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;

import java.util.*;

public class VcsDirtyScopeImpl extends VcsDirtyScope {
  private final Set<FilePath> myDirtyFiles = new THashSet<FilePath>();
  private final Set<FilePath> myDirtyDirectoriesRecursively = new THashSet<FilePath>();
  private final Set<VirtualFile> myAffectedContentRoots = new THashSet<VirtualFile>();
  private final Project myProject;
  private final ProjectLevelVcsManager myVcsManager;
  private final AbstractVcs myVcs;

  public VcsDirtyScopeImpl(final AbstractVcs vcs, final Project project) {
    myProject = project;
    myVcs = vcs;
    myVcsManager = ProjectLevelVcsManager.getInstance(project);
  }

  public Collection<VirtualFile> getAffectedContentRoots() {
    return myAffectedContentRoots;
  }

  public Project getProject() {
    return myProject;
  }

  public AbstractVcs getVcs() {
    return myVcs;
  }

  public synchronized Set<FilePath> getDirtyFiles() {
    final THashSet<FilePath> result = new THashSet<FilePath>(myDirtyFiles);
    for(FilePath filePath: myDirtyFiles) {
      VirtualFile vFile = filePath.getVirtualFile();
      if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
        for(VirtualFile child: vFile.getChildren()) {
          result.add(new FilePathImpl(child));
        }
      }
    }
    return result;
  }

  public Set<FilePath> getDirtyFilesNoExpand() {
    return new THashSet<FilePath>(myDirtyFiles);
  }

  public synchronized Set<FilePath> getRecursivelyDirtyDirectories() {
    return new THashSet<FilePath>(myDirtyDirectoriesRecursively);
  }

  public synchronized void addDirtyDirRecursively(FilePath newcomer) {
    myAffectedContentRoots.add(myVcsManager.getVcsRootFor(newcomer));

    for (Iterator<FilePath> it = myDirtyFiles.iterator(); it.hasNext();) {
      FilePath oldBoy = it.next();
      if (oldBoy.isUnder(newcomer, false)) {
        it.remove();
      }
    }

    for (Iterator<FilePath> it = myDirtyDirectoriesRecursively.iterator(); it.hasNext();) {
      FilePath oldBoy = it.next();
      if (newcomer.isUnder(oldBoy, false)) {
        return;
      }

      if (oldBoy.isUnder(newcomer, false)) {
        it.remove();
      }
    }
    myDirtyDirectoriesRecursively.add(newcomer);
  }

  public synchronized void addDirtyFile(FilePath newcomer) {
    myAffectedContentRoots.add(myVcsManager.getVcsRootFor(newcomer));

    for (FilePath oldBoy : myDirtyDirectoriesRecursively) {
      if (newcomer.isUnder(oldBoy, false)) {
        return;
      }
    }

    if (newcomer.isDirectory()) {
      final List<FilePath> files = new ArrayList<FilePath>(myDirtyFiles);
      for (FilePath oldBoy : files) {
        if (!oldBoy.isDirectory() && oldBoy.getVirtualFileParent() == newcomer.getVirtualFile()) {
          myDirtyFiles.remove(oldBoy);
        }
      }
    }
    else {
      for (FilePath oldBoy : myDirtyFiles) {
        if (oldBoy.isDirectory() && newcomer.getVirtualFileParent() == oldBoy.getVirtualFile()) {
          return;
        }
      }
    }

    myDirtyFiles.add(newcomer);
  }

  public synchronized void iterate(final Processor<FilePath> iterator) {
    if (myProject.isDisposed()) return;

    for (VirtualFile root : myAffectedContentRoots) {
      for (FilePath dir : myDirtyDirectoriesRecursively) {
        final VirtualFile vFile = dir.getVirtualFile();
        if (vFile != null && vFile.isValid()) {
          if (VfsUtil.isAncestor(root, vFile, false)) {
            myVcsManager.iterateVcsRoot(vFile, iterator);
          }
          else if (VfsUtil.isAncestor(vFile, root, false)) {
            myVcsManager.iterateVcsRoot(root, iterator);
          }
        }
      }
    }

    for (FilePath file : myDirtyFiles) {
      iterator.process(file);
      final VirtualFile vFile = file.getVirtualFile();
      if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
        for (VirtualFile child : vFile.getChildren()) {
          iterator.process(new FilePathImpl(child));<commit_msg>fix deadlock caused by lock ordering violation<commit_after>/*
 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
 */

/*
 * Created by IntelliJ IDEA.
 * User: yole
 * Date: 12.07.2006
 * Time: 14:34:37
 */
package com.intellij.openapi.vcs.changes;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;

import java.util.*;

public class VcsDirtyScopeImpl extends VcsDirtyScope {
  private final Set<FilePath> myDirtyFiles = new THashSet<FilePath>();
  private final Set<FilePath> myDirtyDirectoriesRecursively = new THashSet<FilePath>();
  private final Set<VirtualFile> myAffectedContentRoots = new THashSet<VirtualFile>();
  private final Project myProject;
  private final ProjectLevelVcsManager myVcsManager;
  private final AbstractVcs myVcs;

  public VcsDirtyScopeImpl(final AbstractVcs vcs, final Project project) {
    myProject = project;
    myVcs = vcs;
    myVcsManager = ProjectLevelVcsManager.getInstance(project);
  }

  public Collection<VirtualFile> getAffectedContentRoots() {
    return myAffectedContentRoots;
  }

  public Project getProject() {
    return myProject;
  }

  public AbstractVcs getVcs() {
    return myVcs;
  }

  public synchronized Set<FilePath> getDirtyFiles() {
    final THashSet<FilePath> result = new THashSet<FilePath>(myDirtyFiles);
    for(FilePath filePath: myDirtyFiles) {
      VirtualFile vFile = filePath.getVirtualFile();
      if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
        for(VirtualFile child: vFile.getChildren()) {
          result.add(new FilePathImpl(child));
        }
      }
    }
    return result;
  }

  public Set<FilePath> getDirtyFilesNoExpand() {
    return new THashSet<FilePath>(myDirtyFiles);
  }

  public synchronized Set<FilePath> getRecursivelyDirtyDirectories() {
    return new THashSet<FilePath>(myDirtyDirectoriesRecursively);
  }

  public synchronized void addDirtyDirRecursively(final FilePath newcomer) {
    ApplicationManager.getApplication().runReadAction(new Runnable() {
      public void run() {
        synchronized (VcsDirtyScopeImpl.this) {
          myAffectedContentRoots.add(myVcsManager.getVcsRootFor(newcomer));

          for (Iterator<FilePath> it = myDirtyFiles.iterator(); it.hasNext();) {
            FilePath oldBoy = it.next();
            if (oldBoy.isUnder(newcomer, false)) {
              it.remove();
            }
          }

          for (Iterator<FilePath> it = myDirtyDirectoriesRecursively.iterator(); it.hasNext();) {
            FilePath oldBoy = it.next();
            if (newcomer.isUnder(oldBoy, false)) {
              return;
            }

            if (oldBoy.isUnder(newcomer, false)) {
              it.remove();
            }
          }
          myDirtyDirectoriesRecursively.add(newcomer);
        }
      }
    });
  }

  public void addDirtyFile(final FilePath newcomer) {
    ApplicationManager.getApplication().runReadAction(new Runnable() {
      public void run() {
        synchronized (VcsDirtyScopeImpl.this) {
          myAffectedContentRoots.add(myVcsManager.getVcsRootFor(newcomer));

          for (FilePath oldBoy : myDirtyDirectoriesRecursively) {
            if (newcomer.isUnder(oldBoy, false)) {
              return;
            }
          }

          if (newcomer.isDirectory()) {
            final List<FilePath> files = new ArrayList<FilePath>(myDirtyFiles);
            for (FilePath oldBoy : files) {
              if (!oldBoy.isDirectory() && oldBoy.getVirtualFileParent() == newcomer.getVirtualFile()) {
                myDirtyFiles.remove(oldBoy);
              }
            }
          }
          else {
            for (FilePath oldBoy : myDirtyFiles) {
              if (oldBoy.isDirectory() && newcomer.getVirtualFileParent() == oldBoy.getVirtualFile()) {
                return;
              }
            }
          }

          myDirtyFiles.add(newcomer);
        }
      }
    });
  }

  public synchronized void iterate(final Processor<FilePath> iterator) {
    if (myProject.isDisposed()) return;

    for (VirtualFile root : myAffectedContentRoots) {
      for (FilePath dir : myDirtyDirectoriesRecursively) {
        final VirtualFile vFile = dir.getVirtualFile();
        if (vFile != null && vFile.isValid()) {
          if (VfsUtil.isAncestor(root, vFile, false)) {
            myVcsManager.iterateVcsRoot(vFile, iterator);
          }
          else if (VfsUtil.isAncestor(vFile, root, false)) {
            myVcsManager.iterateVcsRoot(root, iterator);
          }
        }
      }
    }

    for (FilePath file : myDirtyFiles) {
      iterator.process(file);
      final VirtualFile vFile = file.getVirtualFile();
      if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
        for (VirtualFile child : vFile.getChildren()) {
          iterator.process(new FilePathImpl(child));
{'fraction_non_alphanumeric': 0.10861723446893788, 'fraction_numerical': 0.004408817635270541, 'mean_word_length': 3.0805396565821748, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4670847', 'n_tokens_mistral': 3191, 'n_tokens_neox': 3060, 'n_words': 588}