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
This commit is contained in:
angryziber 2007-07-09 19:07:15 +00:00
parent 7e2d427cac
commit 2df546a888
5 changed files with 75 additions and 37 deletions

View File

@ -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<ScanningResult> {
// selected fetchers are cached here, because the may be changed in the registry already
private List<Fetcher> selectedFetchers;
/** TODO: use a Map instead of List here and remove all index-based access */
private List<ScanningResult> resultList = new ArrayList<ScanningResult>(1024);
private List<ScanningResult> resultList = new ArrayList<ScanningResult>(RESULT_LIST_INITIAL_SIZE);
private Map<InetAddress, Integer> resultIndexes = new HashMap<InetAddress, Integer>(RESULT_LIST_INITIAL_SIZE);
private ResultsComparator resultsComparator = new ResultsComparator();
public ScanningResultList(FetcherRegistry fetcherRegistry) {
@ -53,8 +56,12 @@ public class ScanningResultList implements Iterable<ScanningResult> {
* @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<ScanningResult> {
public synchronized void clear() {
// clear the results
resultList.clear();
resultIndexes.clear();
// reload currently selected fetchers
selectedFetchers = new ArrayList<Fetcher>(fetcherRegistry.getSelectedFetchers());
}
@ -117,13 +125,17 @@ public class ScanningResultList implements Iterable<ScanningResult> {
*/
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<ScanningResult> newList = new ArrayList<ScanningResult>(RESULT_LIST_INITIAL_SIZE);
Map<InetAddress, Integer> newMap = new HashMap<InetAddress, Integer>(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<ScanningResult> {
public synchronized void sort(int columnIndex) {
resultsComparator.index = columnIndex;
Collections.sort(resultList, resultsComparator);
// now rebuild indexes
resultIndexes = new HashMap<InetAddress, Integer>(RESULT_LIST_INITIAL_SIZE);
for (int i = 0; i < resultList.size(); i++) {
resultIndexes.put(resultList.get(i).getAddress(), i);
}
}
/**

View File

@ -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<Object> values = scanningResult.getValues();

View File

@ -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 {

View File

@ -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

View File

@ -33,7 +33,8 @@ import org.junit.Test;
*/
public class ScanningResultListTest {
private List<Fetcher> fetchers = new ArrayList<Fetcher>(Arrays.asList(new Fetcher[] {new DummyFetcher("fetcher.ip"), new DummyFetcher("fetcher.ping"), new DummyFetcher("fetcher.hostname"), new DummyFetcher("fetcher.ping.ttl")}));
private List<Fetcher> fetchers = new ArrayList<Fetcher>(
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<ScanningResult> 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<ScanningResult> 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<ScanningResult> 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<Fetcher> fetchers = scanningResults.getFetchers();
int index = scanningResults.add(InetAddress.getByName("172.28.43.55"));