From 491da9ff3ada142a8299b75fcb83428909f9c3f5 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Sun, 10 Oct 2021 19:15:41 +0100 Subject: [PATCH] Correct count of direct sources. GitHub issue #79 --- .../com/muwire/gui/SearchTabController.groovy | 2 +- .../com/muwire/gui/SearchTabModel.groovy | 91 ++++++++++++++++++- .../views/com/muwire/gui/SearchTabView.groovy | 49 +++------- 3 files changed, 100 insertions(+), 42 deletions(-) diff --git a/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy b/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy index f1c616a8..6a416b76 100644 --- a/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy +++ b/gui/griffon-app/controllers/com/muwire/gui/SearchTabController.groovy @@ -47,7 +47,7 @@ class SearchTabController { if (target.parent != null) parent = new File(downloadsFolder, target.parent.toString()) - def resultsBucket = model.hashBucket[target.resultEvent.infohash] + def resultsBucket = model.hashBucket[target.resultEvent.infohash].getResults() def sources = model.sourcesBucket[target.resultEvent.infohash] core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources, diff --git a/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy b/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy index edfa0f66..6bd8f4e3 100644 --- a/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/SearchTabModel.groovy @@ -1,5 +1,7 @@ package com.muwire.gui +import com.muwire.core.InfoHash + import javax.annotation.Nonnull import javax.inject.Inject import javax.swing.JTable @@ -39,7 +41,7 @@ class SearchTabModel { String uuid def senders = [] def results = [] - def hashBucket = [:] + def hashBucket = new HashMap() def sourcesBucket = [:] def sendersBucket = new LinkedHashMap<>() @@ -70,10 +72,10 @@ class SearchTabModel { runInsideUIAsync { def bucket = hashBucket.get(e.infohash) if (bucket == null) { - bucket = [] + bucket = new HashBucket() hashBucket[e.infohash] = bucket } - bucket << e + bucket.add(e) def senderBucket = sendersBucket.get(e.sender) if (senderBucket == null) { @@ -109,7 +111,7 @@ class SearchTabModel { return def bucket = hashBucket.get(it.infohash) if (bucket == null) { - bucket = [] + bucket = new HashBucket() hashBucket[it.infohash] = bucket } @@ -128,7 +130,7 @@ class SearchTabModel { } sourceBucket.addAll(it.sources) - bucket << it + bucket.add it senderBucket << it } @@ -144,4 +146,83 @@ class SearchTabModel { table.selectionModel.setSelectionInterval(selectedRow, selectedRow) } } + + private static class HashBucket { + private final Set events = new HashSet<>() + private final Set senders = new HashSet<>() + private String cachedName + private long cachedSize + private void add(UIResultEvent event) { + events.add(event) + senders.add(event.sender) + } + + Set getResults() { + events + } + + Set getSenders() { + senders + } + + String getName() { + if (cachedName == null) { + cachedName = events.first().name + } + cachedName + } + + long getSize() { + if (cachedSize == 0) { + cachedSize = events.first().size + } + cachedSize + } + + int sourceCount() { + senders.size() + } + + int commentCount() { + int count = 0 + for (UIResultEvent event : events) { + if (event.comment != null) + count++ + } + count + } + + int certificateCount() { + int count = 0 + for (UIResultEvent event : events) + count += event.certificates + count + } + + int chatCount() { + int count = 0 + for (UIResultEvent event : events) { + if (event.chat) + count++ + } + count + } + + int feedCount() { + int count = 0 + for (UIResultEvent event : events) { + if (event.feed) + count++ + } + count + } + + int collectionsCount() { + int count = 0 + for (UIResultEvent event : events) { + count += event.collections.size() + } + count + } + } } \ No newline at end of file diff --git a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy index 85a49273..5fed31e5 100644 --- a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy @@ -119,7 +119,7 @@ class SearchTabView { tableModel(list: model.results) { closureColumn(header: trans("NAME"), preferredWidth: 350, type: String, read: { row -> HTMLSanitizer.sanitize(row.name) }) closureColumn(header: trans("SIZE"), preferredWidth: 20, type: Long, read: { row -> row.size }) - closureColumn(header: trans("DIRECT_SOURCES"), preferredWidth: 50, type: Integer, read: { row -> model.hashBucket[row.infohash].size() }) + closureColumn(header: trans("DIRECT_SOURCES"), preferredWidth: 50, type: Integer, read: { row -> model.hashBucket[row.infohash].sourceCount() }) closureColumn(header: trans("POSSIBLE_SOURCES"), preferredWidth: 50, type: Integer, read: { row -> model.sourcesBucket[row.infohash].size() }) closureColumn(header: trans("COMMENTS"), preferredWidth: 20, type: Boolean, read: { row -> row.comment != null }) closureColumn(header: trans("CERTIFICATES"), preferredWidth: 20, type: Integer, read: { row -> row.certificates }) @@ -163,54 +163,31 @@ class SearchTabView { resultsTable2 = table(id : "results-table2", autoCreateRowSorter : true, rowHeight : rowHeight) { tableModel(list : model.results2) { closureColumn(header : trans("NAME"), preferredWidth : 350, type : String, read : { - HTMLSanitizer.sanitize(model.hashBucket[it].first().name) + HTMLSanitizer.sanitize(model.hashBucket[it].getName()) }) closureColumn(header : trans("SIZE"), preferredWidth : 20, type : Long, read : { - model.hashBucket[it].first().size + model.hashBucket[it].getSize() }) closureColumn(header : trans("DIRECT_SOURCES"), preferredWidth : 20, type : Integer, read : { - model.hashBucket[it].size() + model.hashBucket[it].sourceCount() }) closureColumn(header : trans("POSSIBLE_SOURCES"), preferredWidth : 20, type : Integer , read : { model.sourcesBucket[it].size() }) closureColumn(header : trans("COMMENTS"), preferredWidth : 20, type : Integer, read : { - int count = 0 - model.hashBucket[it].each { - if (it.comment != null) - count++ - } - count + model.hashBucket[it].commentCount() }) closureColumn(header : trans("CERTIFICATES"), preferredWidth : 20, type : Integer, read : { - int count = 0 - model.hashBucket[it].each { - count += it.certificates - } - count + model.hashBucket[it].certificateCount() }) closureColumn(header : trans("FEEDS"), preferredWidth : 20, type : Integer, read : { - int count = 0 - model.hashBucket[it].each { - if (it.feed) - count++ - } - count + model.hashBucket[it].feedCount() }) closureColumn(header : trans("CHAT_HOSTS"), preferredWidth : 20, type : Integer, read : { - int count = 0 - model.hashBucket[it].each { - if (it.chat) - count++ - } - count + model.hashBucket[it].chatCount() }) closureColumn(header : trans("COLLECTIONS"), preferredWidth : 20, type : Integer, read : { - int count = 0 - model.hashBucket[it].each { UIResultEvent row -> - count += row.collections.size() - } - count + model.hashBucket[it].collectionsCount() }) } } @@ -476,7 +453,7 @@ class SearchTabView { return } model.downloadActionEnabled = true - def results = model.hashBucket[e.infohash] + def results = model.hashBucket[e.infohash].getResults() model.senders2.clear() model.senders2.addAll(results) int selectedRow = sendersTable2.getSelectedRow() @@ -604,15 +581,15 @@ class SearchTabView { Persona sender = selectedSender() if (sender == null) // really shouldn't happen - return model.hashBucket[infohash].first() + return model.hashBucket[infohash].getResults().first() - for (UIResultEvent candidate : model.hashBucket[infohash]) { + for (UIResultEvent candidate : model.hashBucket[infohash].getResults()) { if (candidate.sender == sender) return candidate } // also shouldn't happen - return model.hashBucket[infohash].first() + return model.hashBucket[infohash].getResults().first() } else { int[] selectedRows = resultsTable.getSelectedRows() if (selectedRows.length != 1)