Improving cancelability of compute remote duplicates.
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) {