From 2df546a888b7d1ded2d20074ab7c839313d7c993 Mon Sep 17 00:00:00 2001 From: angryziber Date: Mon, 9 Jul 2007 19:07:15 +0000 Subject: [PATCH] ScanningResultList now has an internal map for indexing of addresses. Rescanning now works properly. git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@141 375186e5-ef17-0410-b0b6-91563547dcda --- .../azib/ipscan/core/ScanningResultList.java | 29 +++++++++--- src/net/azib/ipscan/gui/ResultTable.java | 7 +-- .../ipscan/gui/actions/CommandsActions.java | 29 ++++++------ .../gui/actions/StartStopScanningAction.java | 1 + .../ipscan/core/ScanningResultListTest.java | 46 +++++++++++++------ 5 files changed, 75 insertions(+), 37 deletions(-) diff --git a/src/net/azib/ipscan/core/ScanningResultList.java b/src/net/azib/ipscan/core/ScanningResultList.java index 08793b82..d69c36d1 100755 --- a/src/net/azib/ipscan/core/ScanningResultList.java +++ b/src/net/azib/ipscan/core/ScanningResultList.java @@ -10,8 +10,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import net.azib.ipscan.config.Labels; import net.azib.ipscan.fetchers.Fetcher; @@ -30,8 +32,9 @@ public class ScanningResultList implements Iterable { // selected fetchers are cached here, because the may be changed in the registry already private List selectedFetchers; - /** TODO: use a Map instead of List here and remove all index-based access */ - private List resultList = new ArrayList(1024); + private List resultList = new ArrayList(RESULT_LIST_INITIAL_SIZE); + private Map resultIndexes = new HashMap(RESULT_LIST_INITIAL_SIZE); + private ResultsComparator resultsComparator = new ResultsComparator(); public ScanningResultList(FetcherRegistry fetcherRegistry) { @@ -53,8 +56,12 @@ public class ScanningResultList implements Iterable { * @return the index of the added address, can be used in calls to other methods */ public synchronized int add(InetAddress address) { - int index = resultList.size(); - resultList.add(new ScanningResult(address, fetcherRegistry.getSelectedFetchers().size())); + Integer index = resultIndexes.get(address); + if (index == null) { + index = resultList.size(); + resultList.add(new ScanningResult(address, fetcherRegistry.getSelectedFetchers().size())); + resultIndexes.put(address, index); + } return index; } @@ -89,6 +96,7 @@ public class ScanningResultList implements Iterable { public synchronized void clear() { // clear the results resultList.clear(); + resultIndexes.clear(); // reload currently selected fetchers selectedFetchers = new ArrayList(fetcherRegistry.getSelectedFetchers()); } @@ -117,13 +125,17 @@ public class ScanningResultList implements Iterable { */ public synchronized void remove(int[] indices) { // this rebuild is faster then a number of calls to remove() - // however, a further speedup can be obtained by using a Set instead of binarySearch() + // however, a further speedup may be obtained by using a Set instead of binarySearch() List newList = new ArrayList(RESULT_LIST_INITIAL_SIZE); + Map newMap = new HashMap(RESULT_LIST_INITIAL_SIZE); for (int i = 0; i < resultList.size(); i++) { - if (Arrays.binarySearch(indices, i) < 0) + if (Arrays.binarySearch(indices, i) < 0) { newList.add(resultList.get(i)); + newMap.put(resultList.get(i).getAddress(), newList.size()-1); + } } resultList = newList; + resultIndexes = newMap; } /** @@ -134,6 +146,11 @@ public class ScanningResultList implements Iterable { public synchronized void sort(int columnIndex) { resultsComparator.index = columnIndex; Collections.sort(resultList, resultsComparator); + // now rebuild indexes + resultIndexes = new HashMap(RESULT_LIST_INITIAL_SIZE); + for (int i = 0; i < resultList.size(); i++) { + resultIndexes.put(resultList.get(i).getAddress(), i); + } } /** diff --git a/src/net/azib/ipscan/gui/ResultTable.java b/src/net/azib/ipscan/gui/ResultTable.java index 5ead4800..9001a355 100755 --- a/src/net/azib/ipscan/gui/ResultTable.java +++ b/src/net/azib/ipscan/gui/ResultTable.java @@ -116,9 +116,10 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener final int index = scanningResults.add(address); getDisplay().syncExec(new Runnable() { public void run() { - setItemCount(index+1); + if (index >= getItemCount()) + setItemCount(index+1); } - }); + }); return index; } @@ -209,7 +210,7 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener public void handleEvent(Event event) { TableItem item = (TableItem)event.item; - int tableIndex = ResultTable.this.indexOf(item); + int tableIndex = indexOf(item); ScanningResult scanningResult = scanningResults.getResult(tableIndex); List values = scanningResult.getValues(); diff --git a/src/net/azib/ipscan/gui/actions/CommandsActions.java b/src/net/azib/ipscan/gui/actions/CommandsActions.java index 7b47cf4d..2cac8745 100755 --- a/src/net/azib/ipscan/gui/actions/CommandsActions.java +++ b/src/net/azib/ipscan/gui/actions/CommandsActions.java @@ -30,12 +30,25 @@ import org.eclipse.swt.widgets.MenuItem; /** * Commands and Context menu Actions. * All these operate on the items, selected in the results list. - * TODO: check for selection everywhere * * @author anton */ public class CommandsActions { + /** + * Checks that there is at least one item selected in the results list. + * @param mainWindow + */ + static void checkSelection(ResultTable resultTable) { + if (resultTable.getItemCount() <= 0) { + throw new UserErrorException("commands.noResults"); + } + else + if (resultTable.getSelectionIndex() < 0) { + throw new UserErrorException("commands.noSelection"); + } + } + public static class Details implements Listener { private ResultTable resultTable; @@ -112,20 +125,6 @@ public class CommandsActions { clipboard.dispose(); } } - - /** - * Checks that there is at least one item selected in the results list. - * @param mainWindow - */ - static void checkSelection(ResultTable resultTable) { - if (resultTable.getItemCount() <= 0) { - throw new UserErrorException("commands.noResults"); - } - else - if (resultTable.getSelectionIndex() < 0) { - throw new UserErrorException("commands.noSelection"); - } - } public static class ShowOpenersMenu implements Listener { diff --git a/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java b/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java index 6f356db1..5b0a2830 100755 --- a/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java +++ b/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java @@ -113,6 +113,7 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr if (statusBar.isDisposed()) return; + // TODO: separate GUI and non-GUI stuff switch (state) { case IDLE: // reset state text diff --git a/test/net/azib/ipscan/core/ScanningResultListTest.java b/test/net/azib/ipscan/core/ScanningResultListTest.java index 422fc686..6f4e1c81 100755 --- a/test/net/azib/ipscan/core/ScanningResultListTest.java +++ b/test/net/azib/ipscan/core/ScanningResultListTest.java @@ -33,7 +33,8 @@ import org.junit.Test; */ public class ScanningResultListTest { - private List fetchers = new ArrayList(Arrays.asList(new Fetcher[] {new DummyFetcher("fetcher.ip"), new DummyFetcher("fetcher.ping"), new DummyFetcher("fetcher.hostname"), new DummyFetcher("fetcher.ping.ttl")})); + private List fetchers = new ArrayList( + Arrays.asList(new DummyFetcher("fetcher.ip"), new DummyFetcher("fetcher.ping"), new DummyFetcher("fetcher.hostname"), new DummyFetcher("fetcher.ping.ttl"))); private FetcherRegistry fetcherRegistry; private ScanningResultList scanningResults; @@ -56,21 +57,29 @@ public class ScanningResultListTest { @Test public void testAdd() throws Exception { int index = scanningResults.add(InetAddress.getByName("10.0.0.5")); + assertEquals(0, index); assertEquals("10.0.0.5", scanningResults.getResult(index).getAddress().getHostAddress()); assertEquals("10.0.0.5", scanningResults.getResult(index).getValues().get(0)); + + index = scanningResults.add(InetAddress.getByName("10.0.0.17")); + assertEquals(1, index); + assertEquals("10.0.0.17", scanningResults.getResult(index).getAddress().getHostAddress()); + + index = scanningResults.add(InetAddress.getByName("10.0.0.5")); + assertEquals("same index should be returned because the element already exists", 0, index); } @Test public void testIterator() throws Exception { assertFalse(scanningResults.iterator().hasNext()); scanningResults.add(InetAddress.getLocalHost()); - Iterator i = scanningResults.iterator(); + Iterator i = scanningResults.iterator(); assertTrue(i.hasNext()); - assertTrue(i.next() instanceof ScanningResult); + assertEquals(InetAddress.getLocalHost(), i.next().getAddress()); assertFalse(i.hasNext()); } - @Test @SuppressWarnings("unchecked") + @Test public void testClear() throws Exception { fetcherRegistry.getSelectedFetchers().clear(); fetcherRegistry.getSelectedFetchers().add(new DummyFetcher("hello")); @@ -95,12 +104,18 @@ public class ScanningResultListTest { scanningResults.add(InetAddress.getByName("127.9.9.4")); scanningResults.remove(new int[] {i2,i3}); - Iterator i = scanningResults.iterator(); + Iterator i = scanningResults.iterator(); assertTrue(i.hasNext()); - assertEquals(InetAddress.getByName("127.9.9.1"), ((ScanningResult)i.next()).getAddress()); + assertEquals(InetAddress.getByName("127.9.9.1"), i.next().getAddress()); assertTrue(i.hasNext()); - assertEquals(InetAddress.getByName("127.9.9.4"), ((ScanningResult)i.next()).getAddress()); + assertEquals(InetAddress.getByName("127.9.9.4"), i.next().getAddress()); assertFalse(i.hasNext()); + + // now check that there are no forgotten indexes + assertEquals(0, scanningResults.add(InetAddress.getByName("127.9.9.1"))); + assertEquals(1, scanningResults.add(InetAddress.getByName("127.9.9.4"))); + assertEquals(2, scanningResults.add(InetAddress.getByName("127.9.9.3"))); + assertEquals(3, scanningResults.add(InetAddress.getByName("127.9.9.2"))); } @Test @@ -116,15 +131,20 @@ public class ScanningResultListTest { scanningResults.sort(1); - Iterator i = scanningResults.iterator(); - assertEquals(InetAddress.getByName("127.9.9.2"), ((ScanningResult)i.next()).getAddress()); - assertEquals(InetAddress.getByName("127.9.9.4"), ((ScanningResult)i.next()).getAddress()); - assertEquals(InetAddress.getByName("127.9.9.1"), ((ScanningResult)i.next()).getAddress()); - assertEquals(InetAddress.getByName("127.9.9.3"), ((ScanningResult)i.next()).getAddress()); + Iterator i = scanningResults.iterator(); + assertEquals(InetAddress.getByName("127.9.9.2"), i.next().getAddress()); + assertEquals(InetAddress.getByName("127.9.9.4"), i.next().getAddress()); + assertEquals(InetAddress.getByName("127.9.9.1"), i.next().getAddress()); + assertEquals(InetAddress.getByName("127.9.9.3"), i.next().getAddress()); assertFalse(i.hasNext()); + + // now check that internal indexes are not broken + assertEquals(2, scanningResults.add(InetAddress.getByName("127.9.9.1"))); + assertEquals(0, scanningResults.add(InetAddress.getByName("127.9.9.2"))); + assertEquals(4, scanningResults.add(InetAddress.getByName("127.9.9.10"))); } - @Test @SuppressWarnings("unchecked") + @Test public void testGetResultsAsString() throws Exception { List fetchers = scanningResults.getFetchers(); int index = scanningResults.add(InetAddress.getByName("172.28.43.55"));