Improving cancelability of compute remote duplicates.
authorJan Lahoda <jlahoda@netbeans.org>
Thu, 12 Jul 2012 23:03:36 +0200
changeset 829dfca790003e9
parent 828 2b0a8532d08e
child 830 23546c35c5a2
Improving cancelability of compute remote duplicates.
duplicates/ide/impl/manifest.mf
duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/hints/FindDuplicates.java
duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java
duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java
     1.1 --- a/duplicates/ide/impl/manifest.mf	Wed Jul 11 07:13:46 2012 +0200
     1.2 +++ b/duplicates/ide/impl/manifest.mf	Thu Jul 12 23:03:36 2012 +0200
     1.3 @@ -1,5 +1,5 @@
     1.4  Manifest-Version: 1.0
     1.5  OpenIDE-Module: org.netbeans.modules.jackpot30.duplicates.impl
     1.6  OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/jackpot30/duplicates/impl/Bundle.properties
     1.7 -OpenIDE-Module-Specification-Version: 1.1
     1.8 +OpenIDE-Module-Specification-Version: 1.2
     1.9  
     2.1 --- a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/hints/FindDuplicates.java	Wed Jul 11 07:13:46 2012 +0200
     2.2 +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/hints/FindDuplicates.java	Thu Jul 12 23:03:36 2012 +0200
     2.3 @@ -98,7 +98,7 @@
     2.4          List<ErrorDescription> result = new LinkedList<ErrorDescription>();
     2.5  
     2.6          Map<String, long[]> encoded = ComputeDuplicates.encodeGeneralized(info);
     2.7 -        Iterator<? extends DuplicateDescription> duplicates = RemoteDuplicatesIndex.findDuplicates(encoded, info.getFileObject()).iterator();
     2.8 +        Iterator<? extends DuplicateDescription> duplicates = RemoteDuplicatesIndex.findDuplicates(encoded, info.getFileObject(), cancel).iterator();
     2.9  
    2.10          for (DuplicateDescription dd : NbCollections.iterable(duplicates)) {
    2.11              long[] spans = encoded.get(dd.hash);
     3.1 --- a/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java	Wed Jul 11 07:13:46 2012 +0200
     3.2 +++ b/duplicates/ide/impl/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndex.java	Thu Jul 12 23:03:36 2012 +0200
     3.3 @@ -66,6 +66,7 @@
     3.4  import java.util.Map.Entry;
     3.5  import java.util.Set;
     3.6  import java.util.TreeMap;
     3.7 +import java.util.concurrent.atomic.AtomicBoolean;
     3.8  import java.util.logging.Level;
     3.9  import java.util.logging.Logger;
    3.10  import org.apache.lucene.document.Document;
    3.11 @@ -105,11 +106,11 @@
    3.12      private static final Logger LOG = Logger.getLogger(RemoteDuplicatesIndex.class.getName());
    3.13      private static final Logger TIMER = Logger.getLogger("TIMER");
    3.14  
    3.15 -    public static List<DuplicateDescription> findDuplicates(Map<String, long[]> hashes, FileObject currentFile) throws IOException, URISyntaxException {
    3.16 -        return translate(hashes, findHashOccurrences(hashes.keySet(), currentFile), currentFile);
    3.17 +    public static List<DuplicateDescription> findDuplicates(Map<String, long[]> hashes, FileObject currentFile, AtomicBoolean cancel) throws IOException, URISyntaxException {
    3.18 +        return translate(hashes, findHashOccurrences(hashes.keySet(), currentFile, cancel), currentFile);
    3.19      }
    3.20  
    3.21 -    private static Map<String, Map<RemoteIndex, Collection<String>>> findHashOccurrences(Collection<? extends String> hashes, FileObject currentFile) throws IOException, URISyntaxException {
    3.22 +    private static Map<String, Map<RemoteIndex, Collection<String>>> findHashOccurrences(Collection<? extends String> hashes, FileObject currentFile, AtomicBoolean cancel) throws IOException, URISyntaxException {
    3.23          Map<URI, Collection<RemoteIndex>> indices = new LinkedHashMap<URI, Collection<RemoteIndex>>();
    3.24  
    3.25          for (RemoteIndex ri : RemoteIndex.loadIndices()) {
    3.26 @@ -132,18 +133,20 @@
    3.27          long remoteTime = 0;
    3.28  
    3.29          for (RemoteIndex ri : RemoteIndex.loadIndices()) {
    3.30 +            if (cancel.get()) return Collections.emptyMap();
    3.31 +            
    3.32              Set<String> toProcess = new LinkedHashSet<String>(hashes);
    3.33              Map<String, Map<String, Collection<? extends String>>> indexResult = new LinkedHashMap<String, Map<String, Collection<? extends String>>>();
    3.34  
    3.35              long locS = System.currentTimeMillis();
    3.36 -            indexResult.putAll(findHashOccurrencesInLocalCache(ri, toProcess));
    3.37 +            indexResult.putAll(findHashOccurrencesInLocalCache(ri, toProcess, cancel));
    3.38              localTime += System.currentTimeMillis() - locS;
    3.39  
    3.40              toProcess.removeAll(indexResult.keySet());
    3.41  
    3.42              if (!toProcess.isEmpty()) {
    3.43                  long remS = System.currentTimeMillis();
    3.44 -                Map<String, Map<String, Collection<? extends String>>> remoteResults = findHashOccurrencesRemote(ri.remote.toURI(), toProcess);
    3.45 +                Map<String, Map<String, Collection<? extends String>>> remoteResults = findHashOccurrencesRemote(ri.remote.toURI(), toProcess, cancel);
    3.46                  remoteTime += System.currentTimeMillis() - remS;
    3.47  
    3.48                  Map<String, Map<String, Collection<? extends String>>> toSave = new LinkedHashMap<String, Map<String, Collection<? extends String>>>(remoteResults);
    3.49 @@ -154,6 +157,8 @@
    3.50                      }
    3.51                  }
    3.52  
    3.53 +                if (cancel.get()) return Collections.emptyMap();
    3.54 +                
    3.55                  saveToLocalCache(ri, toSave);
    3.56  
    3.57                  indexResult.putAll(remoteResults);
    3.58 @@ -167,6 +172,8 @@
    3.59                  }
    3.60  
    3.61                  for (Entry<String, Collection<? extends String>> insideHash : e.getValue().entrySet()) {
    3.62 +                    if (cancel.get()) return Collections.emptyMap();
    3.63 +
    3.64                      Collection<String> dupes = hashResult.get(ri);
    3.65  
    3.66                      if (dupes == null) {
    3.67 @@ -183,13 +190,13 @@
    3.68          return result;
    3.69      }
    3.70  
    3.71 -    private static Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesRemote(URI remoteIndex, Iterable<? extends String> hashes) {
    3.72 +    private static Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesRemote(URI remoteIndex, Iterable<? extends String> hashes, AtomicBoolean cancel) {
    3.73          try {
    3.74              String indexURL = remoteIndex.toASCIIString();
    3.75              URI u = new URI(indexURL + "/duplicates/findDuplicates?hashes=" + WebUtilities.escapeForQuery(Pojson.save(hashes)));
    3.76 -            String hashesMap = WebUtilities.requestStringResponse(u);
    3.77 +            String hashesMap = WebUtilities.requestStringResponse(u, cancel);
    3.78  
    3.79 -            if (hashesMap == null) {
    3.80 +            if (hashesMap == null || cancel.get()) {
    3.81                  //some kind of error while getting the duplicates (cannot access remote server)?
    3.82                  //ignore:
    3.83                  return Collections.emptyMap();
    3.84 @@ -211,7 +218,7 @@
    3.85      private static final long VERSION_CHECK_PERIOD = 60 * 60 * 1000;
    3.86      private static final Map<Entry<URI, String>, Long> lastVersionCheck = new HashMap<Entry<URI, String>, Long>();
    3.87      
    3.88 -    private static synchronized Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesInLocalCache(RemoteIndex ri, Iterable<? extends String> hashes) throws IOException, URISyntaxException {
    3.89 +    private static synchronized Map<String, Map<String, Collection<? extends String>>> findHashOccurrencesInLocalCache(RemoteIndex ri, Iterable<? extends String> hashes, AtomicBoolean cancel) throws IOException, URISyntaxException {
    3.90          URI uri = ri.remote.toURI();
    3.91          SimpleEntry<URI, String> versionCheckKey = new SimpleEntry<URI, String>(uri, ri.remoteSegment);
    3.92          Long lastCheck = lastVersionCheck.get(versionCheckKey);
    3.93 @@ -222,8 +229,10 @@
    3.94              FileObject remoteVersionFO = FileUtil.toFileObject(remoteVersion);
    3.95              String previousVersion = remoteVersionFO != null ? remoteVersionFO.asText("UTF-8") : null;
    3.96              URI infoURI = new URI(ri.remote.toExternalForm() + "/info?path=" + WebUtilities.escapeForQuery(ri.remoteSegment));
    3.97 -            String infoContent = WebUtilities.requestStringResponse(infoURI);
    3.98 +            String infoContent = WebUtilities.requestStringResponse(infoURI, cancel);
    3.99  
   3.100 +            if (cancel.get()) return Collections.emptyMap();
   3.101 +            
   3.102              if (infoContent != null) {
   3.103                  Object buildId = Pojson.load(LinkedHashMap.class, infoContent).get("BUILD_ID");
   3.104  
   3.105 @@ -251,7 +260,7 @@
   3.106  
   3.107          IndexReader reader = readerCache.get(uri);
   3.108  
   3.109 -        if (reader == null) {
   3.110 +        if (reader == null && !cancel.get()) {
   3.111              File dir = new File(findLocalCacheDir(ri), "index");
   3.112  
   3.113              if (dir.listFiles() != null && dir.listFiles().length > 0) {
   3.114 @@ -259,13 +268,15 @@
   3.115              }
   3.116          }
   3.117  
   3.118 -        if (reader == null) {
   3.119 +        if (reader == null || cancel.get()) {
   3.120              return Collections.emptyMap();
   3.121          }
   3.122  
   3.123          Map<String, Map<String, Collection<String>>> result = new LinkedHashMap<String, Map<String, Collection<String>>>();
   3.124  
   3.125 -        for (Entry<String, Collection<? extends String>> e : containsHash(reader, hashes).entrySet()) {
   3.126 +        for (Entry<String, Collection<? extends String>> e : containsHash(reader, hashes, cancel).entrySet()) {
   3.127 +            if (cancel.get()) return Collections.emptyMap();
   3.128 +
   3.129              Map<String, Collection<String>> forHash = result.get(e.getKey());
   3.130  
   3.131              if (forHash == null) {
   3.132 @@ -414,10 +425,12 @@
   3.133          return false;
   3.134      }
   3.135  
   3.136 -    public static Map<String, Collection<? extends String>> containsHash(IndexReader reader, Iterable<? extends String> hashes) throws IOException {
   3.137 +    private static Map<String, Collection<? extends String>> containsHash(IndexReader reader, Iterable<? extends String> hashes, AtomicBoolean cancel) throws IOException {
   3.138          Map<String, Collection<? extends String>> result = new LinkedHashMap<String, Collection<? extends String>>();
   3.139  
   3.140          for (String hash : hashes) {
   3.141 +            if (cancel.get()) return Collections.emptyMap();
   3.142 +
   3.143              Collection<String> found = new LinkedList<String>();
   3.144              Query query = new TermQuery(new Term("hash", hash));
   3.145              Searcher s = new IndexSearcher(reader);
   3.146 @@ -429,6 +442,8 @@
   3.147              boolean wasFound = false;
   3.148  
   3.149              for (int docNum = matchingDocuments.nextSetBit(0); docNum >= 0; docNum = matchingDocuments.nextSetBit(docNum + 1)) {
   3.150 +                if (cancel.get()) return Collections.emptyMap();
   3.151 +
   3.152                  final Document doc = reader.document(docNum);
   3.153  
   3.154                  found.addAll(Arrays.asList(doc.getValues("path")));
     4.1 --- a/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java	Wed Jul 11 07:13:46 2012 +0200
     4.2 +++ b/duplicates/ide/impl/test/unit/src/org/netbeans/modules/jackpot30/impl/duplicates/indexing/RemoteDuplicatesIndexTest.java	Thu Jul 12 23:03:36 2012 +0200
     4.3 @@ -48,6 +48,7 @@
     4.4  import java.util.HashMap;
     4.5  import java.util.List;
     4.6  import java.util.Map;
     4.7 +import java.util.concurrent.atomic.AtomicBoolean;
     4.8  import org.netbeans.api.java.source.TestUtilities;
     4.9  import static org.junit.Assert.*;
    4.10  import org.netbeans.api.java.source.SourceUtilsTestUtil;
    4.11 @@ -108,7 +109,7 @@
    4.12          hashes.put("01", new long[] {8, 9});
    4.13          hashes.put("02", new long[] {3, 4});
    4.14          
    4.15 -        List<DuplicateDescription> duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source);
    4.16 +        List<DuplicateDescription> duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source, new AtomicBoolean());
    4.17          List<String> duplicatesReal = new ArrayList<String>();
    4.18  
    4.19          for (DuplicateDescription dd : duplicates) {
    4.20 @@ -120,7 +121,7 @@
    4.21          assertEquals(Arrays.asList("T2", "T1", "T4", "T3"), duplicatesReal);
    4.22  
    4.23          //check local cache:
    4.24 -        duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source);
    4.25 +        duplicates = RemoteDuplicatesIndex.findDuplicates(hashes, source, new AtomicBoolean());
    4.26          duplicatesReal = new ArrayList<String>();
    4.27  
    4.28          for (DuplicateDescription dd : duplicates) {