diff --git a/core/src/main/groovy/com/muwire/core/collections/CollectionManager.groovy b/core/src/main/groovy/com/muwire/core/collections/CollectionManager.groovy index ac62f0a7..9856b406 100644 --- a/core/src/main/groovy/com/muwire/core/collections/CollectionManager.groovy +++ b/core/src/main/groovy/com/muwire/core/collections/CollectionManager.groovy @@ -31,6 +31,8 @@ class CollectionManager { private final Map rootToCollection = new HashMap<>() /** infohash of a collection item to every collection it is part of */ private final Map> fileRootToCollections = new HashMap<>() + /** FileCollection object to it's corresponding infohash */ + private final Map collectionToHash = new HashMap<>() private final ExecutorService diskIO = Executors.newSingleThreadExecutor({ r -> new Thread(r, "collections-io") @@ -56,10 +58,12 @@ class CollectionManager { rootToCollection.get(ih) } - synchronized int collectionsForFile(InfoHash ih) { - int rv = 0 - if (fileRootToCollections.containsKey(ih)) - rv = fileRootToCollections.get(ih).size() + synchronized Set collectionsForFile(InfoHash ih) { + def rv = Collections.emptySet() + if (fileRootToCollections.containsKey(ih)) { + rv = new HashSet<>() + fileRootToCollections.get(ih).collect(rv, { collectionToHash.get(it) }) + } rv } @@ -131,6 +135,7 @@ class CollectionManager { private synchronized void addToIndex(InfoHash infoHash, FileCollection collection) { rootToCollection.put(infoHash, collection) + collectionToHash.put(collection, infoHash) collection.files.each { Set set = fileRootToCollections.get(it.infoHash) if (set == null) { @@ -167,6 +172,7 @@ class CollectionManager { private synchronized void removeFromIndex(InfoHash infoHash, FileCollection collection) { rootToCollection.remove(infoHash) + collectionToHash.remove(collection) collection.files.each { Set set = fileRootToCollections.get(it.infoHash) if (set == null) diff --git a/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy b/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy index b6c9f179..38fb49b6 100644 --- a/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy +++ b/core/src/main/groovy/com/muwire/core/connection/ConnectionAcceptor.groovy @@ -402,7 +402,7 @@ class ConnectionAcceptor { it.hit(browser, System.currentTimeMillis(), "Browse Host"); InfoHash ih = new InfoHash(it.getRoot()) int certificates = certificateManager.getByInfoHash(ih).size() - int collections = collectionManager.collectionsForFile(ih) + Set collections = collectionManager.collectionsForFile(ih) def obj = ResultsSender.sharedFileToObj(it, false, certificates, collections) def json = jsonOutput.toJson(obj) dos.writeShort((short)json.length()) diff --git a/core/src/main/groovy/com/muwire/core/search/ResultsParser.groovy b/core/src/main/groovy/com/muwire/core/search/ResultsParser.groovy index ad1768ec..8b0d7db7 100644 --- a/core/src/main/groovy/com/muwire/core/search/ResultsParser.groovy +++ b/core/src/main/groovy/com/muwire/core/search/ResultsParser.groovy @@ -2,10 +2,9 @@ package com.muwire.core.search import java.util.stream.Collectors -import javax.naming.directory.InvalidSearchControlsException - import com.muwire.core.InfoHash import com.muwire.core.Persona +import com.muwire.core.collections.FileCollection import com.muwire.core.files.FileHasher import com.muwire.core.util.DataUtil @@ -57,7 +56,7 @@ class ResultsParser { } InfoHash parsedIH = InfoHash.fromHashList(hashList) if (parsedIH.getRoot() != infoHash) - throw new InvalidSearchControlsException("infohash root doesn't match") + throw new InvalidSearchResultException("infohash root doesn't match") return new UIResultEvent( sender : p, name : name, @@ -106,9 +105,12 @@ class ResultsParser { if (json.certificates != null) certificates = json.certificates - int collections = 0 - if (json.collections != null) + Set collections = Collections.emptySet() + if (json.collections != null) { + collections = new HashSet<>() + json.collections.collect(collections, { new InfoHash(Base64.decode(it)) }) collections = json.collections + } log.fine("Received result from ${p.getHumanReadableName()} name \"$name\" infoHash:\"${json.infohash}\"") diff --git a/core/src/main/groovy/com/muwire/core/search/ResultsSender.groovy b/core/src/main/groovy/com/muwire/core/search/ResultsSender.groovy index 38dd4692..5524ea66 100644 --- a/core/src/main/groovy/com/muwire/core/search/ResultsSender.groovy +++ b/core/src/main/groovy/com/muwire/core/search/ResultsSender.groovy @@ -82,6 +82,7 @@ class ResultsSender { } InfoHash ih = new InfoHash(it.getRoot()) int certificates = certificateManager.getByInfoHash(ih).size() + Set collections = collectionManager.collectionsForFile(ih) def uiResultEvent = new UIResultEvent( sender : me, name : it.getFile().getName(), size : length, @@ -94,7 +95,7 @@ class ResultsSender { certificates : certificates, chat : chatServer.isRunning() && settings.advertiseChat, feed : settings.fileFeed && settings.advertiseFeed, - collections : collectionManager.collectionsForFile(ih) + collections : collections ) uiResultEvents << uiResultEvent } @@ -127,7 +128,7 @@ class ResultsSender { results.each { InfoHash ih = new InfoHash(it.getRoot()) int certificates = certificateManager.getByInfoHash(ih).size() - int collections = collectionManager.collectionsForFile(ih) + Set collections = collectionManager.collectionsForFile(ih) def obj = sharedFileToObj(it, settings.browseFiles, certificates, collections) def json = jsonOutput.toJson(obj) os.writeShort((short)json.length()) @@ -154,7 +155,7 @@ class ResultsSender { results.each { InfoHash ih = new InfoHash(it.getRoot()) int certificates = certificateManager.getByInfoHash(ih).size() - int collections = collectionManager.collectionsForFile(ih) + Set collections = collectionManager.collectionsForFile(ih) def obj = sharedFileToObj(it, settings.browseFiles, certificates, collections) def json = jsonOutput.toJson(obj) dos.writeShort((short)json.length()) @@ -173,7 +174,7 @@ class ResultsSender { } } - public static def sharedFileToObj(SharedFile sf, boolean browseFiles, int certificates, int collections) { + public static def sharedFileToObj(SharedFile sf, boolean browseFiles, int certificates, Set collections) { byte [] name = sf.getFile().getName().getBytes(StandardCharsets.UTF_8) def baos = new ByteArrayOutputStream() def daos = new DataOutputStream(baos) @@ -197,7 +198,7 @@ class ResultsSender { obj.browse = browseFiles obj.certificates = certificates - obj.collections = collections + obj.collections = collections.collect { Base64.encode(it.getRoot()) } obj } } diff --git a/core/src/main/groovy/com/muwire/core/search/UIResultEvent.groovy b/core/src/main/groovy/com/muwire/core/search/UIResultEvent.groovy index acde0e27..23f4801a 100644 --- a/core/src/main/groovy/com/muwire/core/search/UIResultEvent.groovy +++ b/core/src/main/groovy/com/muwire/core/search/UIResultEvent.groovy @@ -19,7 +19,7 @@ class UIResultEvent extends Event { int certificates boolean chat boolean feed - int collections + Set collections @Override public String toString() {