From 85d9577ea2cb46d5fefda58956b7660ccb217e1a Mon Sep 17 00:00:00 2001 From: millmanorama Date: Wed, 21 Feb 2018 13:21:02 +0100 Subject: [PATCH] use new getRelationshionshipsCount(a1,a2) method to improve graph loading time --- .../communications/CommunicationsGraph.java | 91 +++++++++++-------- .../communications/VisualizationPanel.java | 16 +++- 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java index f278bc311b..81ec5d7838 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java +++ b/Core/src/org/sleuthkit/autopsy/communications/CommunicationsGraph.java @@ -33,10 +33,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -50,6 +47,7 @@ import org.sleuthkit.datamodel.AccountDeviceInstance; import org.sleuthkit.datamodel.CommunicationsFilter; import org.sleuthkit.datamodel.CommunicationsManager; import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.Relationship; import org.sleuthkit.datamodel.TskCoreException; /** @@ -239,30 +237,29 @@ final class CommunicationsGraph extends mxGraph { size); return newVertex; }); - final mxCellState state = getView().getState(vertex, true); - - getView().updateLabel(state); - getView().updateLabelBounds(state); - getView().updateBoundingBox(state); +// final mxCellState state = getView().getState(vertex, true); +// +// getView().updateLabel(state); +// getView().updateLabelBounds(state); +// getView().updateBoundingBox(state); return vertex; } @SuppressWarnings("unchecked") - private mxCell addEdge(Collection relSources, AccountDeviceInstanceKey account1, AccountDeviceInstanceKey account2) { + private mxCell addOrUpdateEdge(long relSources, AccountDeviceInstanceKey account1, AccountDeviceInstanceKey account2) { mxCell vertex1 = getOrCreateVertex(account1); mxCell vertex2 = getOrCreateVertex(account2); Object[] edgesBetween = getEdgesBetween(vertex1, vertex2); mxCell edge; if (edgesBetween.length == 0) { final String edgeName = vertex1.getId() + " <-> " + vertex2.getId(); - final HashSet hashSet = new HashSet<>(relSources); - edge = (mxCell) insertEdge(getDefaultParent(), edgeName, hashSet, vertex1, vertex2, - "strokeWidth=" + (Math.log(hashSet.size()) + 1)); + edge = (mxCell) insertEdge(getDefaultParent(), edgeName, relSources, vertex1, vertex2, + "strokeWidth=" + (Math.log(relSources) + 1)); } else { edge = (mxCell) edgesBetween[0]; - ((Collection) edge.getValue()).addAll(relSources); - edge.setStyle("strokeWidth=" + (Math.log(((Collection) edge.getValue()).size()) + 1)); +// ((Collection) edge.getValue()).addAll(relSources); + edge.setStyle("strokeWidth=" + (Math.log(relSources) + 1)); } return edge; } @@ -287,54 +284,68 @@ final class CommunicationsGraph extends mxGraph { @Override protected Void doInBackground() throws Exception { progress.start("Loading accounts"); -// progress.switchToDeterminate("Loading accounts", 0,pinnedAccountDevices.size()); int i = 0; try { /** * set to keep track of accounts related to pinned accounts */ - Set relatedAccounts = new HashSet<>(); + Map relatedAccounts = new HashMap<>(); for (AccountDeviceInstanceKey adiKey : pinnedAccountModel.getPinnedAccounts()) { if (isCancelled()) { break; } List relatedAccountDeviceInstances = commsManager.getRelatedAccountDeviceInstances(adiKey.getAccountDeviceInstance(), currentFilter); - relatedAccounts.add(adiKey); + relatedAccounts.put(adiKey.getAccountDeviceInstance().getAccount().getAccountID(), adiKey); getOrCreateVertex(adiKey); //get accounts related to pinned account for (AccountDeviceInstance relatedADI : relatedAccountDeviceInstances) { -// handle.progress(1); long adiRelationshipsCount = commsManager.getRelationshipSourcesCount(relatedADI, currentFilter); final AccountDeviceInstanceKey relatedADIKey = new AccountDeviceInstanceKey(relatedADI, currentFilter, adiRelationshipsCount); - relatedAccounts.add(relatedADIKey); //store related accounts + relatedAccounts.put(relatedADI.getAccount().getAccountID(), relatedADIKey); //store related accounts } progress.progress(++i); } - //for each pair of related accounts add edges if they are related o each other. - // this is O(n^2) in the number of related accounts!!! - List relatedAccountsList = new ArrayList<>(relatedAccounts); - progress.switchToDeterminate("", 0, relatedAccountsList.size()); - for (i = 0; i < relatedAccountsList.size(); i++) { - AccountDeviceInstanceKey adiKey1 = relatedAccountsList.get(i); - for (int j = i; j < relatedAccountsList.size(); j++) { - if (isCancelled()) { - break; - } - AccountDeviceInstanceKey adiKey2 = relatedAccountsList.get(j); - List relationships = commsManager.getRelationshipSources( - adiKey1.getAccountDeviceInstance(), - adiKey2.getAccountDeviceInstance(), - currentFilter); - if (relationships.size() > 0) { - mxCell addEdge = addEdge(relationships, adiKey1, adiKey2); - progress.progress(addEdge.getId()); - } - } - progress.progress(i); + Set accountIDs = relatedAccounts.keySet(); + + Map relationshipCounts = commsManager.getRelationshipCounts(accountIDs, currentFilter); + + int total = relationshipCounts.size(); + int k = 0; + progress.switchToDeterminate("", 0,total); + for (Map.Entry entry : relationshipCounts.entrySet()) { + Long count = entry.getValue(); + Relationship.RelationshipKey relationshipKey = entry.getKey(); + AccountDeviceInstanceKey account1 = relatedAccounts.get(relationshipKey.getAccount1ID()); + AccountDeviceInstanceKey account2 = relatedAccounts.get(relationshipKey.getAccount2ID()); + mxCell addEdge = addOrUpdateEdge(count, account1, account2); + progress.progress(addEdge.getId(),k++); } +// //for each pair of related accounts add edges if they are related o each other. +// // this is O(n^2) in the number of related accounts!!! +// List relatedAccountsList = new ArrayList<>(relatedAccounts); +// progress.switchToDeterminate("", 0, relatedAccountsList.size()); +// +// for (i = 0; i < relatedAccountsList.size(); i++) { +// AccountDeviceInstanceKey adiKey1 = relatedAccountsList.get(i); +// for (int j = i; j < relatedAccountsList.size(); j++) { +// if (isCancelled()) { +// break; +// } +// AccountDeviceInstanceKey adiKey2 = relatedAccountsList.get(j); +// List relationships = commsManager.getRelationshipSources( +// adiKey1.getAccountDeviceInstance(), +// adiKey2.getAccountDeviceInstance(), +// currentFilter); +// if (relationships.size() > 0) { +// mxCell addEdge = addEdge(relationships, adiKey1, adiKey2); +// progress.progress(addEdge.getId()); +// } +// } +// progress.progress(i); +// } } catch (TskCoreException tskCoreException) { logger.log(Level.SEVERE, "Error", tskCoreException); } finally { diff --git a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java index 12b66824e6..889b81cf74 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/VisualizationPanel.java @@ -53,7 +53,7 @@ import java.util.Arrays; import static java.util.Collections.singleton; import java.util.EnumSet; import java.util.HashSet; -import java.util.Set; +import java.util.List; import java.util.concurrent.Future; import java.util.logging.Level; import javax.swing.AbstractAction; @@ -723,11 +723,23 @@ final public class VisualizationPanel extends JPanel implements Lookup.Provider HashSet adis = new HashSet<>(); for (mxICell cell : selectedCells) { if (cell.isEdge()) { - relationshipSources.addAll((Set) cell.getValue()); + mxICell source = (mxICell) graph.getModel().getTerminal(cell, true); + AccountDeviceInstanceKey account1 = (AccountDeviceInstanceKey) source.getValue(); + mxICell target = (mxICell) graph.getModel().getTerminal(cell, false); + AccountDeviceInstanceKey account2 = (AccountDeviceInstanceKey) target.getValue(); + try { + final List relationshipSources1 = commsManager.getRelationshipSources(account1.getAccountDeviceInstance(), + account2.getAccountDeviceInstance(), + currentFilter); + relationshipSources.addAll(relationshipSources1); + } catch (TskCoreException tskCoreException) { + logger.log(Level.SEVERE, " Error getting relationsips....", tskCoreException); + } } else if (cell.isVertex()) { adis.add(((AccountDeviceInstanceKey) cell.getValue()).getAccountDeviceInstance()); } } + rootNode = SelectionNode.createFromAccountsAndRelationships(relationshipSources, adis, currentFilter, commsManager); selectedNodes = new Node[]{rootNode}; }