wip on faster unsharing

dbus-notify
Zlatin Balevsky 2022-08-15 15:28:56 +01:00
parent bad697a8a2
commit 6ff25d32f5
No known key found for this signature in database
GPG Key ID: A72832072D525E41
5 changed files with 137 additions and 63 deletions

View File

@ -6,4 +6,8 @@ import com.muwire.core.SharedFile
class FileUnsharedEvent extends Event { class FileUnsharedEvent extends Event {
SharedFile[] unsharedFiles SharedFile[] unsharedFiles
boolean deleted boolean deleted
/**
* true if the files are implicitly removed as part of unsharing a folder.
*/
boolean implicit
} }

View File

@ -580,49 +580,75 @@ class MainFrameController {
} }
void unshareSelectedFile() { void unshareSelectedFile() {
def sfs = view.selectedSharedFiles() /*
* A selection may include files, folders or both.
*/
Set<File> folders = view.selectedFolders() Set<File> folders = view.selectedFolders()
if (sfs == null && folders.isEmpty()) List<SharedFile> leafFiles = view.selectedIndividualSharedFiles()
if (leafFiles == null)
leafFiles = Collections.emptyList()
if (folders.isEmpty() && leafFiles.isEmpty())
return return
if (sfs == null)
sfs = Collections.emptyList()
List<SharedFile> toUnshare = new ArrayList<>() List<SharedFile> implicitUnshared = new ArrayList<>()
sfs.each { SharedFile sf -> for (File folder : folders) {
List<SharedFile> contained = model.sharedTree.getFilesInFolder(folder)
if (view.settings.collectionWarning) { for (SharedFile sf : contained) {
Set<InfoHash> collectionsInfoHashes = core.collectionManager.collectionsForFile(sf.rootInfoHash) if (collectionMembershipCheck(sf))
if (!collectionsInfoHashes.isEmpty()) { implicitUnshared.add sf
String[] affected = collectionsInfoHashes.collect({core.collectionManager.getByInfoHash(it)}).collect{it.name}.toArray(new String[0]) else
return
boolean [] answer = new boolean[1]
def props = [:]
props.collections = affected
props.answer = answer
props.fileName = sf.file.getName()
props.settings = view.settings
props.home = core.home
def mvc = mvcGroup.createMVCGroup("collection-warning", props)
mvc.destroy()
if (!answer[0]) {
File f = sf.getFile()
while(true) {
File parent = f.getParentFile()
if (parent == null)
break
folders.remove(parent)
f = parent
}
return
}
}
} }
toUnshare.add(sf)
} }
if (!folders.isEmpty())
List<SharedFile> explicitUnshared = new ArrayList<>()
for (SharedFile sf : leafFiles) {
if (collectionMembershipCheck(sf))
explicitUnshared << sf
else
return
}
if (!folders.isEmpty()) {
for (File folder : folders) {
model.sharedTree.removeFromTree(folder)
model.allFilesSharedTree.removeFromTree(folder)
}
core.eventBus.publish(new DirectoryUnsharedEvent(directories: folders.toArray(new File[0]), deleted: false)) core.eventBus.publish(new DirectoryUnsharedEvent(directories: folders.toArray(new File[0]), deleted: false))
if (!toUnshare.isEmpty()) core.eventBus.publish(new FileUnsharedEvent(
core.eventBus.publish(new FileUnsharedEvent(unsharedFiles : toUnshare.toArray(new SharedFile[0]))) unsharedFiles: implicitUnshared.toArray(new SharedFile[0]),
deleted: false,
implicit: true
))
}
if (!explicitUnshared.isEmpty())
core.eventBus.publish(new FileUnsharedEvent(unsharedFiles : explicitUnshared.toArray(new SharedFile[0])))
}
/**
* @param sharedFile that may be in a collection
* @return true if the file should be unshared
*/
private boolean collectionMembershipCheck(SharedFile sf) {
if (!view.settings.collectionWarning)
return true
Set<InfoHash> collectionsInfoHashes = core.collectionManager.collectionsForFile(sf.rootInfoHash)
if (!collectionsInfoHashes.isEmpty()) {
String[] affected = collectionsInfoHashes.collect({core.collectionManager.getByInfoHash(it)}).collect{it.name}.toArray(new String[0])
boolean [] answer = new boolean[1]
def props = [:]
props.collections = affected
props.answer = answer
props.fileName = sf.file.getName()
props.settings = view.settings
props.home = core.home
def mvc = mvcGroup.createMVCGroup("collection-warning", props)
mvc.destroy()
return answer[0]
}
return true
} }
@ControllerAction @ControllerAction

View File

@ -621,21 +621,19 @@ class MainFrameModel {
loadedFiles = allSharedFiles.size() loadedFiles = allSharedFiles.size()
for (SharedFile sharedFile : e.unsharedFiles) { for (SharedFile sharedFile : e.unsharedFiles) {
removeUnsharedFromTree(sharedFile, e.deleted) if (fileToNode.remove(sharedFile) == null)
continue
if (e.implicit)
continue
allFilesSharedTree.removeFromTree(sharedFile, e.deleted)
sharedTree.removeFromTree(sharedFile, e.deleted)
} }
view.refreshSharedFiles() view.refreshSharedFiles()
} }
} }
private void removeUnsharedFromTree(SharedFile sharedFile, boolean deleted) {
SortedTreeNode dmtn = fileToNode.remove(sharedFile)
if (dmtn == null)
return
allFilesSharedTree.removeFromTree(sharedFile, deleted)
sharedTree.removeFromTree(sharedFile, deleted)
}
void onUploadEvent(UploadEvent e) { void onUploadEvent(UploadEvent e) {
runInsideUIAsync { runInsideUIAsync {
int index = -1 int index = -1

View File

@ -1534,6 +1534,23 @@ class MainFrameView {
} }
} }
List<SharedFile> selectedIndividualSharedFiles() {
if (!model.treeVisible)
return selectedSharedFiles()
else {
List<SharedFile> rv = new ArrayList<>()
def sharedFilesTree = builder.getVariable("shared-files-tree")
TreePath[] selectedPaths = sharedFilesTree.getSelectionPaths()
for (TreePath path : selectedPaths) {
DefaultMutableTreeNode dmtn = (DefaultMutableTreeNode) path.getLastPathComponent()
Object obj = dmtn.getUserObject()
if (obj instanceof SharedFile)
rv << obj
}
return rv
}
}
/** /**
* @return if a single file is selected, return it. * @return if a single file is selected, return it.
*/ */

View File

@ -14,7 +14,7 @@ class LibraryTreeModel extends DefaultTreeModel {
} }
TreeNode addToTree(SharedFile sharedFile) { TreeNode addToTree(SharedFile sharedFile) {
List<File> parents = getParents(sharedFile) List<File> parents = getParents(sharedFile.getFile())
LibraryTreeNode node = root LibraryTreeNode node = root
for (File path : parents) { for (File path : parents) {
def key = new InterimTreeNode(path) def key = new InterimTreeNode(path)
@ -32,21 +32,33 @@ class LibraryTreeModel extends DefaultTreeModel {
leaf leaf
} }
void removeFromTree(SharedFile sharedFile, boolean deleted) { void removeFromTree(File folder) {
List<File> parents = getParents(sharedFile) def node = findParentNode(folder, false)
LibraryTreeNode node = root def key = new InterimTreeNode(folder)
def child = node.getByKey(key)
for (File path : parents) { while(true) {
def key = new InterimTreeNode(path) def parent = child.getParent()
def child = node.getByKey(key) child.removeFromParent()
if (child == null) { if (parent.getChildCount() == 0 && parent != root)
if (deleted) child = parent
return else
throw new IllegalStateException() break
}
node = child
} }
}
List<SharedFile> getFilesInFolder(File folder) {
def node = findParentNode(folder, false)
def key = new InterimTreeNode(folder)
def child = node.getByKey(key)
List<SharedFile> rv = []
TreeUtil.getLeafs(child, rv)
rv
}
void removeFromTree(SharedFile sharedFile, boolean deleted) {
def node = findParentNode(sharedFile.getFile(), deleted)
def leaf = node.getByKey(sharedFile) def leaf = node.getByKey(sharedFile)
while(true) { while(true) {
def parent = leaf.getParent() def parent = leaf.getParent()
leaf.removeFromParent() leaf.removeFromParent()
@ -57,9 +69,26 @@ class LibraryTreeModel extends DefaultTreeModel {
} }
} }
private List<File> getParents(SharedFile sharedFile) { private LibraryTreeNode findParentNode(File file, boolean deleted) {
List<File> parents = getParents(file)
LibraryTreeNode node = root
for (File path : parents) {
def key = new InterimTreeNode(path)
def child = node.getByKey(key)
if (child == null) {
if (deleted)
return null
throw new IllegalStateException()
}
node = child
}
node
}
private static List<File> getParents(File sharedFile) {
List<File> parents = new ArrayList<>() List<File> parents = new ArrayList<>()
File tmp = sharedFile.file.getParentFile() File tmp = sharedFile.getParentFile()
while(tmp.getParent() != null) { while(tmp.getParent() != null) {
parents << tmp parents << tmp
tmp = tmp.getParentFile() tmp = tmp.getParentFile()