Performance improvement for artifact sorting.

This commit is contained in:
Jeff Wallace 2013-12-04 11:41:49 -05:00
parent 4a6ac42282
commit 15de072e71

View File

@ -34,7 +34,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -51,6 +50,7 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.EscapeUtil; import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import org.sleuthkit.autopsy.coreutils.StopWatch;
import org.sleuthkit.autopsy.datamodel.Tags; import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus; import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
@ -58,7 +58,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -375,6 +374,8 @@ public class ReportGenerator {
if (tableModules.isEmpty()) { if (tableModules.isEmpty()) {
break; break;
} }
System.out.println("----------- " + type.getDisplayName() + " ------------");
Iterator<TableReportModule> iter = tableModules.iterator(); Iterator<TableReportModule> iter = tableModules.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
TableReportModule module = iter.next(); TableReportModule module = iter.next();
@ -383,6 +384,10 @@ public class ReportGenerator {
} }
} }
for (TableReportModule module : tableModules) {
tableProgress.get(module).updateStatusLabel("Now processing " + type.getDisplayName() + "...");
}
// If the type is keyword hit or hashset hit, use the helper // If the type is keyword hit or hashset hit, use the helper
if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) { if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
writeKeywordHits(tableModules, comment.toString(), tagNamesFilter); writeKeywordHits(tableModules, comment.toString(), tagNamesFilter);
@ -392,7 +397,12 @@ public class ReportGenerator {
continue; continue;
} }
StopWatch stopwatch = new StopWatch();
stopwatch.start();
List<ArtifactData> unsortedArtifacts = getFilteredArtifacts(type, tagNamesFilter); List<ArtifactData> unsortedArtifacts = getFilteredArtifacts(type, tagNamesFilter);
stopwatch.stop();
System.out.println("Number of Artifacts:\t" + unsortedArtifacts.size());
System.out.println("getFilteredArtifacts:\t" + stopwatch.getElapsedTime());
if (unsortedArtifacts.isEmpty()) { if (unsortedArtifacts.isEmpty()) {
// Don't report on this artifact type if there are no results // Don't report on this artifact type if there are no results
@ -401,7 +411,11 @@ public class ReportGenerator {
// The most efficient way to sort all the Artifacts is to add them to a List, and then // The most efficient way to sort all the Artifacts is to add them to a List, and then
// sort that List based off a Comparator. Adding to a TreeMap/Set/List sorts the list // sort that List based off a Comparator. Adding to a TreeMap/Set/List sorts the list
// each time an element is added, which adds unnecessary overhead if we only need it sorted once. // each time an element is added, which adds unnecessary overhead if we only need it sorted once.
stopwatch.reset();
stopwatch.start();
Collections.sort(unsortedArtifacts); Collections.sort(unsortedArtifacts);
stopwatch.stop();
System.out.println("Collections.sort:\t" + stopwatch.getElapsedTime());
// Get the column headers appropriate for the artifact type. // Get the column headers appropriate for the artifact type.
/* @@@ BC: Seems like a better design here woudl be to have a method that /* @@@ BC: Seems like a better design here woudl be to have a method that
@ -416,8 +430,7 @@ public class ReportGenerator {
continue; continue;
} }
for (TableReportModule module : tableModules) { for (TableReportModule module : tableModules) {
tableProgress.get(module).updateStatusLabel("Now processing " + type.getDisplayName() + "...");
// This is a temporary workaround to avoid modifying the TableReportModule interface. // This is a temporary workaround to avoid modifying the TableReportModule interface.
if (module instanceof ReportHTML) { if (module instanceof ReportHTML) {
@ -988,7 +1001,12 @@ public class ReportGenerator {
* @throws TskCoreException * @throws TskCoreException
*/ */
private List<String> getArtifactRow(ArtifactData artifactData, TableReportModule module) throws TskCoreException { private List<String> getArtifactRow(ArtifactData artifactData, TableReportModule module) throws TskCoreException {
Map<Integer, String> attributes = getMappedAttributes(artifactData.getAttributes(), module); Map<Integer, String> attributes;
if (module != null) {
attributes = getMappedAttributes(artifactData.getAttributes(), module);
} else {
attributes = artifactData.getMappedAttributes();
}
BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactData.getArtifact().getArtifactTypeID()); BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifactData.getArtifact().getArtifactTypeID());
@ -1282,6 +1300,7 @@ public class ReportGenerator {
private BlackboardArtifact artifact; private BlackboardArtifact artifact;
private List<BlackboardAttribute> attributes; private List<BlackboardAttribute> attributes;
private HashSet<String> tags; private HashSet<String> tags;
private Map<Integer,String> mappedAttributes;
ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) { ArtifactData(BlackboardArtifact artifact, List<BlackboardAttribute> attrs, HashSet<String> tags) {
this.artifact = artifact; this.artifact = artifact;
@ -1299,7 +1318,7 @@ public class ReportGenerator {
public long getObjectID() { return artifact.getObjectID(); } public long getObjectID() { return artifact.getObjectID(); }
@Override
/** /**
* Compares ArtifactData objects by the first attribute they have in * Compares ArtifactData objects by the first attribute they have in
* common in their List<BlackboardAttribute>. * common in their List<BlackboardAttribute>.
@ -1308,22 +1327,35 @@ public class ReportGenerator {
* compared by their artifact id. Should only be used with attributes * compared by their artifact id. Should only be used with attributes
* of the same type. * of the same type.
*/ */
@Override
public int compareTo(ArtifactData data) { public int compareTo(ArtifactData data) {
// Get all the attributes for each artifact List<String> thisRow = getRow();
int size = ATTRIBUTE_TYPE.values().length; List<String> dataRow = data.getRow();
Map<Integer, String> att1 = getMappedAttributes(this.attributes); for (int i = 0; i < thisRow.size(); i++) {
Map<Integer, String> att2 = getMappedAttributes(data.getAttributes()); int compare = thisRow.get(i).compareTo(dataRow.get(i));
// Compare the attributes one-by-one looking for differences if (compare != 0) {
for(int i=0; i < size; i++) { return compare;
String a1 = att1.get(i);
String a2 = att2.get(i);
if((!a1.equals("") && !a2.equals("")) && a1.compareTo(a2) != 0) {
return a1.compareTo(a2);
} }
} }
// If all attributes are the same, they're most likely duplicates so sort by artifact ID // If all attributes are the same, they're most likely duplicates so sort by artifact ID
return ((Long)this.getArtifactID()).compareTo((Long)data.getArtifactID()); return ((Long)this.getArtifactID()).compareTo((Long)data.getArtifactID());
} }
public Map<Integer,String> getMappedAttributes() {
if (mappedAttributes == null) {
mappedAttributes = ReportGenerator.this.getMappedAttributes(attributes);
}
return mappedAttributes;
}
public List<String> getRow() {
try {
return ReportGenerator.this.getArtifactRow(this, null);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Core exception while generating row data for artifact report.");
return Collections.<String>emptyList();
}
}
} }
} }