Dear users, Please note that, from Monday, August 16, 2019, RSA keys shorter than 2048bit will no longer be accepted for security reasons. Please update your keys as needed before this date. If you need assistance with regard to this process, please contact sia@list.lu

Thank you for your understanding.

Commit 060595ad authored by Nico Mack's avatar Nico Mack

Refactoring of API

parent 64c24630
......@@ -42,8 +42,9 @@ public class ClusterManager<P extends Positionable> {
private double radius;
private KdComparator<P> comparator;
private List<P> constituents;
private List<P> clustered;
private List<P> nodes;
private List<P> clusteredNodes;
private boolean clustersFormed;
private KdTree<P> kdTree;
......@@ -66,8 +67,9 @@ public class ClusterManager<P extends Positionable> {
@SuppressWarnings("unchecked")
public ClusterManager(double radius) {
this.radius = radius;
this.constituents = new ArrayList<>();
this.clustered = new ArrayList<>();
this.clustersFormed = false;
this.nodes = new ArrayList<>();
this.clusteredNodes = new ArrayList<>();
this.comparator = (KdComparator<P>) new PositionableComparator();
((PositionableComparator) this.comparator).setReferenceState(ScreenCoordinates.class);
}
......@@ -84,44 +86,50 @@ public class ClusterManager<P extends Positionable> {
// Iterate over all candidates.
for (P candidate : candidates) {
// Check whether candidate is indeed clusterable and has not already been
// coalesced into a cluster.
// Check whether candidate is indeed clusterable.
if ((candidate instanceof Clusterable) && !coalesced.contains(candidate)) {
if ((candidate instanceof Clusterable) && ((Clusterable) candidate).isClusterable()) {
// Try to find items within a specific radius.
// Next check whether node has not already been coalesced into a cluster.
List<P> coalescing = kdTree.findNearest(candidate, radius);
if (!coalesced.contains(candidate)) {
// If there were items within that zone, than the candidate will be
// a cluster, representing the matching items.
// Try to find items within a specific radius.
boolean isClustered = (!coalescing.isEmpty());
List<P> coalescing = kdTree.findNearest(candidate, radius);
// However, since we don't rebuild the kdTree for performance reasons
// on each iteration, the tree will always hold to the totality of
// available items. We thus have to remove previously coalesced items
// in order to find out whether we're in the presence of a new cluster
// or not.
// If there were items within that zone, than the candidate will be
// a cluster, representing the matching items.
coalescing.removeAll(coalesced);
clusterDetected |= (!coalescing.isEmpty());
boolean isClustered = (!coalescing.isEmpty());
// Add remaining coalescing items to list of already coalesced items
// and make sure none of them remains in the retained list.
// However, since we don't rebuild the kdTree for performance reasons
// on each iteration, the tree will always hold to the totality of
// available items. We thus have to remove previously coalesced items
// in order to find out whether we're in the presence of a new cluster
// or not.
if (isClustered) {
coalesced.addAll(coalescing);
retained.removeAll(coalescing);
}
coalescing.removeAll(coalesced);
clusterDetected |= (!coalescing.isEmpty());
// Add remaining coalescing items to list of already coalesced items
// and make sure none of them remains in the retained list.
// Last but not least, set the candidates' clustered flag and add
// it to the list of retained items.
if (isClustered) {
coalesced.addAll(coalescing);
retained.removeAll(coalescing);
}
((Clusterable) candidate).setClustered(isClustered);
if (!retained.contains(candidate)) {
retained.add(candidate);
// Last but not least, set the candidates' clustered flag and add
// it to the list of retained items.
((Clusterable) candidate).setClustered(isClustered);
if (!retained.contains(candidate)) {
retained.add(candidate);
}
}
} else {
retained.add(candidate);
}
}
return clusterDetected;
......@@ -133,34 +141,51 @@ public class ClusterManager<P extends Positionable> {
// ***************************************************************************
// ---------------------------------------------------------------------------
/**
*
* Clears internal state of this instance. Previously added constituents are no longer known to this
* instance.
*/
// ---------------------------------------------------------------------------
public void clear() {
this.kdTree = null;
this.constituents.clear();
this.nodes.clear();
}
// ---------------------------------------------------------------------------
/**
* @param constituent
* sets the list of nodes this cluster manager is aware off. Previously added or set nodes will be
* discarded.
*
* @param newNodes
*/
// ---------------------------------------------------------------------------
public void addConstituent(P constituent) {
if (!this.constituents.contains(constituent)) {
this.constituents.add(constituent);
public void setNodes(List<P> newNodes) {
this.nodes.clear();
this.nodes.addAll(newNodes);
}
// ---------------------------------------------------------------------------
/**
* Adds the specified node to the list of nodes this instance is aware of.
*
* @param node
*/
// ---------------------------------------------------------------------------
public void addNode(P node) {
if (!this.nodes.contains(node)) {
this.nodes.add(node);
}
}
// ---------------------------------------------------------------------------
public void setup() {
if (!this.constituents.isEmpty()) {
kdTree = new KdTree<>(this.constituents, 2, this.comparator);
if (!this.nodes.isEmpty()) {
kdTree = new KdTree<>(this.nodes, 2, this.comparator);
} else {
LOGGER.info("No clusterable items available! Clustering is disabled!");
LOGGER.info("No clusterable items available! Clustering is disabled!"); //$NON-NLS-1$
}
}
......@@ -175,36 +200,41 @@ public class ClusterManager<P extends Positionable> {
if (kdTree == null)
return;
this.clustersFormed = false;
List<P> retained = new ArrayList<>();
List<P> coalesced = new ArrayList<>();
List<P> candidates = new ArrayList<>(this.constituents);
List<P> candidates = new ArrayList<>(this.nodes);
boolean clusterDetected;
int iterations = 0;
do {
clusterDetected = this.cluster(candidates, retained, coalesced);
clustersFormed |= clusterDetected;
candidates.clear();
candidates.addAll(retained);
iterations++;
} while (clusterDetected);
synchronized (clustered) {
clustered.clear();
clustered.addAll(retained);
LOGGER.info("Clustering completed in {} iteration(s)! {} Marker(s) remaining!", iterations, clustered.size()); //$NON-NLS-1$
synchronized (clusteredNodes) {
clusteredNodes.clear();
clusteredNodes.addAll(retained);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Clustering completed in {} iteration(s)! {} Marker(s) remaining!", iterations, clusteredNodes.size()); //$NON-NLS-1$
}
}
}
// ---------------------------------------------------------------------------
public boolean hasClusters() {
return !this.clustered.isEmpty();
public boolean haveClustersFormed() {
return this.clustersFormed;
}
// ---------------------------------------------------------------------------
public synchronized List<P> getClusters() {
return new ArrayList<>(this.clustered);
public synchronized List<P> getClusteredNodes() {
return new ArrayList<>(this.clusteredNodes);
}
// ---------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment