mirror of https://github.com/zlatinb/muwire
more efficient updating of group-by-sender view. GitHub issue #129
parent
a41ccb190c
commit
d7880a866c
|
@ -129,12 +129,11 @@ class SearchTabModel {
|
||||||
hashBucket[event.infohash] = bucket
|
hashBucket[event.infohash] = bucket
|
||||||
}
|
}
|
||||||
|
|
||||||
def senderBucket = sendersBucket.get(event.sender)
|
SenderBucket senderBucket = sendersBucket.get(event.sender)
|
||||||
if (senderBucket == null) {
|
if (senderBucket == null) {
|
||||||
senderBucket = []
|
senderBucket = new SenderBucket(event.sender, senders.size())
|
||||||
sendersBucket[event.sender] = senderBucket
|
sendersBucket[event.sender] = senderBucket
|
||||||
senders.clear()
|
senders << senderBucket
|
||||||
senders.addAll(sendersBucket.keySet())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set sourceBucket = sourcesBucket.get(event.infohash)
|
Set sourceBucket = sourcesBucket.get(event.infohash)
|
||||||
|
@ -145,7 +144,7 @@ class SearchTabModel {
|
||||||
sourceBucket.addAll(event.sources)
|
sourceBucket.addAll(event.sources)
|
||||||
|
|
||||||
bucket.add event
|
bucket.add event
|
||||||
senderBucket << event
|
senderBucket.results << event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +159,8 @@ class SearchTabModel {
|
||||||
allResults2.addAll(hashBucket.keySet())
|
allResults2.addAll(hashBucket.keySet())
|
||||||
allResults2.stream().filter({ InfoHash ih -> filter(ih) }).forEach({ results2.add it })
|
allResults2.stream().filter({ InfoHash ih -> filter(ih) }).forEach({ results2.add it })
|
||||||
}
|
}
|
||||||
view.refreshResults()
|
view.addPendingResults()
|
||||||
|
view.updateResultsTable2()
|
||||||
dirty = false
|
dirty = false
|
||||||
}
|
}
|
||||||
} else if (!copy.isEmpty())
|
} else if (!copy.isEmpty())
|
||||||
|
@ -245,6 +245,26 @@ class SearchTabModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class SenderBucket {
|
||||||
|
final Persona sender
|
||||||
|
private final int rowIdx
|
||||||
|
final List<UIResultEvent> results = []
|
||||||
|
private int lastUpdatedIdx
|
||||||
|
|
||||||
|
SenderBucket(Persona sender, int rowIdx) {
|
||||||
|
this.sender = sender
|
||||||
|
this.rowIdx = rowIdx
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UIResultEvent> getPendingResults() {
|
||||||
|
if (lastUpdatedIdx == results.size())
|
||||||
|
return Collections.emptyList()
|
||||||
|
def rv = results.subList(lastUpdatedIdx, results.size())
|
||||||
|
lastUpdatedIdx = results.size()
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class Filterer extends SwingWorker<Void, InfoHash> {
|
private class Filterer extends SwingWorker<Void, InfoHash> {
|
||||||
private volatile boolean cancelled
|
private volatile boolean cancelled
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.muwire.gui
|
package com.muwire.gui
|
||||||
|
|
||||||
import com.muwire.core.SharedFile
|
import com.muwire.core.SharedFile
|
||||||
|
import com.muwire.gui.SearchTabModel.SenderBucket
|
||||||
import griffon.core.artifact.GriffonView
|
import griffon.core.artifact.GriffonView
|
||||||
import net.i2p.data.Destination
|
import net.i2p.data.Destination
|
||||||
|
|
||||||
|
@ -11,6 +12,7 @@ import javax.swing.JTabbedPane
|
||||||
import javax.swing.JTextField
|
import javax.swing.JTextField
|
||||||
import javax.swing.KeyStroke
|
import javax.swing.KeyStroke
|
||||||
import javax.swing.RowSorter
|
import javax.swing.RowSorter
|
||||||
|
import javax.swing.table.DefaultTableModel
|
||||||
import javax.swing.tree.TreePath
|
import javax.swing.tree.TreePath
|
||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
import java.awt.event.ActionEvent
|
import java.awt.event.ActionEvent
|
||||||
|
@ -93,15 +95,15 @@ class SearchTabView {
|
||||||
scrollPane (constraints : BorderLayout.CENTER) {
|
scrollPane (constraints : BorderLayout.CENTER) {
|
||||||
sendersTable = table(id : "senders-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
|
sendersTable = table(id : "senders-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
|
||||||
tableModel(list : model.senders) {
|
tableModel(list : model.senders) {
|
||||||
closureColumn(header : trans("SENDER"), preferredWidth : 500, type: String, read : {row -> row.getHumanReadableName()})
|
closureColumn(header : trans("SENDER"), preferredWidth : 500, type: String, read : { SenderBucket row -> row.sender.getHumanReadableName()})
|
||||||
closureColumn(header : trans("RESULTS"), preferredWidth : 20, type: Integer, read : {row -> model.sendersBucket[row].size()})
|
closureColumn(header : trans("RESULTS"), preferredWidth : 20, type: Integer, read : {SenderBucket row -> row.results.size()})
|
||||||
closureColumn(header : trans("BROWSE"), preferredWidth : 20, type: Boolean, read : {row -> model.sendersBucket[row].first().browse})
|
closureColumn(header : trans("BROWSE"), preferredWidth : 20, type: Boolean, read : {SenderBucket row -> row.results[0].browse})
|
||||||
closureColumn(header : trans("COLLECTIONS"), preferredWidth : 20, type: Boolean, read : {row -> model.sendersBucket[row].first().browseCollections})
|
closureColumn(header : trans("COLLECTIONS"), preferredWidth : 20, type: Boolean, read : {SenderBucket row -> row.results[0].browseCollections})
|
||||||
closureColumn(header : trans("FEED"), preferredWidth : 20, type : Boolean, read : {row -> model.sendersBucket[row].first().feed})
|
closureColumn(header : trans("FEED"), preferredWidth : 20, type : Boolean, read : {SenderBucket row -> row.results[0].feed})
|
||||||
closureColumn(header : trans("MESSAGES"), preferredWidth : 20, type : Boolean, read : {row -> model.sendersBucket[row].first().messages})
|
closureColumn(header : trans("MESSAGES"), preferredWidth : 20, type : Boolean, read : {SenderBucket row -> row.results[0].messages})
|
||||||
closureColumn(header : trans("CHAT"), preferredWidth : 20, type : Boolean, read : {row -> model.sendersBucket[row].first().chat})
|
closureColumn(header : trans("CHAT"), preferredWidth : 20, type : Boolean, read : {SenderBucket row -> row.results[0].chat})
|
||||||
closureColumn(header : trans("TRUST_NOUN"), preferredWidth : 50, type: String, read : { row ->
|
closureColumn(header : trans("TRUST_NOUN"), preferredWidth : 50, type: String, read : { SenderBucket row ->
|
||||||
trans(model.core.trustService.getLevel(row.destination).name())
|
trans(model.core.trustService.getLevel(row.sender.destination).name())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,21 +411,22 @@ class SearchTabView {
|
||||||
model.messageActionEnabled = false
|
model.messageActionEnabled = false
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
Persona sender = model.senders[row]
|
SenderBucket bucket = model.senders[row]
|
||||||
model.browseActionEnabled = model.sendersBucket[sender].first().browse
|
Persona sender = bucket.sender
|
||||||
model.browseCollectionsActionEnabled = model.sendersBucket[sender].first().browseCollections
|
model.browseActionEnabled = bucket.results[0].browse
|
||||||
model.chatActionEnabled = model.sendersBucket[sender].first().chat
|
model.browseCollectionsActionEnabled = bucket.results[0].browseCollections
|
||||||
model.messageActionEnabled = model.sendersBucket[sender].first().messages
|
model.chatActionEnabled = bucket.results[0].chat
|
||||||
model.subscribeActionEnabled = model.sendersBucket[sender].first().feed &&
|
model.messageActionEnabled = bucket.results[0].messages
|
||||||
|
model.subscribeActionEnabled = bucket.results[0].feed &&
|
||||||
model.core.feedManager.getFeed(sender) == null
|
model.core.feedManager.getFeed(sender) == null
|
||||||
model.trustButtonsEnabled = true
|
model.trustButtonsEnabled = true
|
||||||
|
|
||||||
model.results.clear()
|
model.results.clear()
|
||||||
model.results.addAll(model.sendersBucket[sender])
|
model.results.addAll(bucket.results)
|
||||||
resultsTable.model.fireTableDataChanged()
|
resultsTable.model.fireTableDataChanged()
|
||||||
|
|
||||||
model.root.removeAllChildren()
|
model.root.removeAllChildren()
|
||||||
for(UIResultEvent event : model.sendersBucket[sender])
|
for(UIResultEvent event : bucket.results)
|
||||||
model.treeModel.addToTree(event)
|
model.treeModel.addToTree(event)
|
||||||
model.treeModel.nodeStructureChanged(model.root)
|
model.treeModel.nodeStructureChanged(model.root)
|
||||||
TreeUtil.expand(resultTree)
|
TreeUtil.expand(resultTree)
|
||||||
|
@ -676,7 +679,7 @@ class SearchTabView {
|
||||||
if (model.groupedByFile)
|
if (model.groupedByFile)
|
||||||
return model.senders2[row]?.sender
|
return model.senders2[row]?.sender
|
||||||
else
|
else
|
||||||
return model.senders[row]
|
return model.senders[row]?.sender
|
||||||
}
|
}
|
||||||
|
|
||||||
def showSenderGrouping = {
|
def showSenderGrouping = {
|
||||||
|
@ -708,6 +711,58 @@ class SearchTabView {
|
||||||
return sequentialDownloadCheckbox.model.isSelected()
|
return sequentialDownloadCheckbox.model.isSelected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addPendingResults() {
|
||||||
|
JTable table = builder.getVariable("senders-table")
|
||||||
|
int selectedRow = table.getSelectedRow()
|
||||||
|
|
||||||
|
int newRowsStart = -1
|
||||||
|
int newRowsEnd = -1
|
||||||
|
for (int row = 0; row < model.senders.size(); row++) {
|
||||||
|
SenderBucket sb = model.senders[row]
|
||||||
|
List<UIResultEvent> pending = sb.getPendingResults()
|
||||||
|
if (pending.isEmpty())
|
||||||
|
continue
|
||||||
|
if (pending.size() == sb.results.size()) {
|
||||||
|
if (newRowsStart == -1)
|
||||||
|
newRowsStart = row
|
||||||
|
newRowsEnd = row
|
||||||
|
} else {
|
||||||
|
table.model.fireTableRowsUpdated(row, row)
|
||||||
|
}
|
||||||
|
if (row == selectedRow)
|
||||||
|
displayPendingResults(pending)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newRowsStart >= 0 && newRowsEnd >= 0) {
|
||||||
|
table.model.fireTableRowsInserted(newRowsStart, newRowsEnd)
|
||||||
|
} else {
|
||||||
|
boolean shouldSort = false
|
||||||
|
for (RowSorter.SortKey key : table.rowSorter.getSortKeys()) {
|
||||||
|
if (key.column == 1) {
|
||||||
|
shouldSort = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSort) {
|
||||||
|
table.model.fireTableDataChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayPendingResults(List<UIResultEvent> pending) {
|
||||||
|
int rowCount = model.results.size()
|
||||||
|
model.results.addAll(pending)
|
||||||
|
resultsTable.model.fireTableRowsInserted(rowCount - 1, model.results.size() - 1)
|
||||||
|
if (!resultsTable.rowSorter.getSortKeys().isEmpty())
|
||||||
|
resultsTable.model.fireTableDataChanged()
|
||||||
|
|
||||||
|
for (UIResultEvent event : pending)
|
||||||
|
model.treeModel.addToTree(event)
|
||||||
|
model.treeModel.nodeStructureChanged(model.root)
|
||||||
|
// TODO: decide whether to expand
|
||||||
|
}
|
||||||
|
|
||||||
void refreshResults() {
|
void refreshResults() {
|
||||||
JTable table = builder.getVariable("senders-table")
|
JTable table = builder.getVariable("senders-table")
|
||||||
int selectedRow = table.getSelectedRow()
|
int selectedRow = table.getSelectedRow()
|
||||||
|
@ -719,8 +774,11 @@ class SearchTabView {
|
||||||
table.selectionModel.setSelectionInterval(selectedRow, selectedRow)
|
table.selectionModel.setSelectionInterval(selectedRow, selectedRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateResultsTable2()
|
||||||
|
}
|
||||||
|
|
||||||
table = builder.getVariable("results-table2")
|
void updateResultsTable2() {
|
||||||
|
JTable table = builder.getVariable("results-table2")
|
||||||
int [] selectedRows = table.getSelectedRows()
|
int [] selectedRows = table.getSelectedRows()
|
||||||
for (int i = 0; i < selectedRows.length; i++)
|
for (int i = 0; i < selectedRows.length; i++)
|
||||||
selectedRows[i] = table.rowSorter.convertRowIndexToModel(selectedRows[i])
|
selectedRows[i] = table.rowSorter.convertRowIndexToModel(selectedRows[i])
|
||||||
|
@ -742,9 +800,7 @@ class SearchTabView {
|
||||||
// there should be exactly 1 entry if at all.
|
// there should be exactly 1 entry if at all.
|
||||||
if (!model.sendersBucket.containsKey(persona))
|
if (!model.sendersBucket.containsKey(persona))
|
||||||
return
|
return
|
||||||
int index = model.senders.indexOf(persona)
|
int index = model.sendersBucket[persona].rowIdx
|
||||||
if (index < 0)
|
|
||||||
return // should not happen!
|
|
||||||
|
|
||||||
// 2. it exists in the senders table, update the row
|
// 2. it exists in the senders table, update the row
|
||||||
JTable table = builder.getVariable("senders-table")
|
JTable table = builder.getVariable("senders-table")
|
||||||
|
|
Loading…
Reference in New Issue