From d05ff87b1b781690016a38a8d97f6cd0c9b7810d Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Fri, 16 Sep 2011 11:14:28 -0400
Subject: [PATCH] CHECKPOINT: Several fixes, but class implementation seems to
be complete on the graph side. Time to start cleaning up the rest of the
graph package.
---
.../dann/graph/AbstractAdjacencyGraph.java | 61 ++---
.../syncleus/dann/graph/AbstractCloud.java | 74 +++++-
.../AbstractContextMutableAdjacencyGraph.java | 173 +++++++++++++
.../com/syncleus/dann/graph/AbstractEdge.java | 6 +-
.../graph/AbstractMutableAdjacencyGraph.java | 232 ++++++++++--------
.../syncleus/dann/graph/AdjacencyMapping.java | 6 +-
.../java/com/syncleus/dann/graph/Cloud.java | 19 +-
.../dann/graph/HashAdjacencyMapping.java | 229 ++++++++++++++---
.../dann/graph/MutableAdjacencyGraph.java | 80 +++++-
.../com/syncleus/dann/graph/MutableGraph.java | 10 +-
.../event/context/ContextCloudElement.java | 9 +-
.../event/context/ContextEdgeElement.java | 7 +-
.../graph/event/context/ContextGraphEdge.java | 7 +-
.../event/context/ContextGraphElement.java | 8 +-
.../graph/event/context/ContextGraphNode.java | 7 +-
15 files changed, 720 insertions(+), 208 deletions(-)
create mode 100644 src/main/java/com/syncleus/dann/graph/AbstractContextMutableAdjacencyGraph.java
diff --git a/src/main/java/com/syncleus/dann/graph/AbstractAdjacencyGraph.java b/src/main/java/com/syncleus/dann/graph/AbstractAdjacencyGraph.java
index 2a9dc2f3..0835c179 100644
--- a/src/main/java/com/syncleus/dann/graph/AbstractAdjacencyGraph.java
+++ b/src/main/java/com/syncleus/dann/graph/AbstractAdjacencyGraph.java
@@ -37,9 +37,9 @@ import java.util.*;
public abstract class AbstractAdjacencyGraph<
N,
E extends Cloud<N,? extends Cloud.Endpoint<? extends N>>,
- NEP extends Graph.NodeEndpoint<N, E>,
- EEP extends Graph.EdgeEndpoint<N, E>
- > extends AbstractCloud<Object,Graph.Endpoint<?, N,E>> implements Graph<N, E, NEP, EEP>
+ NE extends Graph.NodeEndpoint<N, E>,
+ EE extends Graph.EdgeEndpoint<N, E>
+ > extends AbstractCloud<Object,Graph.Endpoint<?, N,E>> implements Graph<N, E, NE, EE>
{
private static final Logger LOGGER = Logger.getLogger(AbstractAdjacencyGraph.class);
// private Set<E> edges;
@@ -529,7 +529,7 @@ public abstract class AbstractAdjacencyGraph<
}
*/
- protected abstract Set<EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(Graph.NodeEndpoint<? extends N, ? extends E> nodeEndpoint);
+ protected abstract Set<EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(Graph.NodeEndpoint<?, ?> nodeEndpoint);
protected PathFinder<N,E> getPathFinder()
{
@@ -540,7 +540,7 @@ public abstract class AbstractAdjacencyGraph<
public Set<N> getNodes()
{
final Set<N> nodes = new HashSet<N>();
- for(NEP destinationEndpoint : this.getNodeEndpoints() )
+ for(NE destinationEndpoint : this.getNodeEndpoints() )
nodes.add(destinationEndpoint.getTarget());
return Collections.unmodifiableSet(nodes);
}
@@ -549,16 +549,16 @@ public abstract class AbstractAdjacencyGraph<
public Set<E> getEdges()
{
final Set<E> edges = new HashSet<E>();
- for(EEP destinationEndpoint : this.getEdgeEndpoints() )
+ for(EE destinationEndpoint : this.getEdgeEndpoints() )
edges.add(destinationEndpoint.getTarget());
return Collections.unmodifiableSet(edges);
}
@Override
- public Set<EEP> getEdgeEndpoints(Cloud<?,? extends Cloud.Endpoint<?>> cloud)
+ public Set<EE> getEdgeEndpoints(Cloud<?,? extends Cloud.Endpoint<?>> cloud)
{
- Set<EEP> matchingEndpoints = new HashSet<EEP>();
- for(final EEP endpoint : this.getEdgeEndpoints() )
+ Set<EE> matchingEndpoints = new HashSet<EE>();
+ for(final EE endpoint : this.getEdgeEndpoints() )
{
if( endpoint.getTarget().equals(cloud))
matchingEndpoints.add(endpoint);
@@ -568,10 +568,10 @@ public abstract class AbstractAdjacencyGraph<
}
@Override
- public Set<NEP> getNodeEndpoints(Object node)
+ public Set<NE> getNodeEndpoints(Object node)
{
- Set<NEP> matchingEndpoints = new HashSet<NEP>();
- for(NEP endpoint : this.getNodeEndpoints() )
+ Set<NE> matchingEndpoints = new HashSet<NE>();
+ for(NE endpoint : this.getNodeEndpoints() )
{
if( endpoint.getTarget().equals(node))
matchingEndpoints.add(endpoint);
@@ -585,7 +585,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<N> sourceNodes = new HashSet<N>();
- for(NEP destinationEndpoint : this.getNodeEndpoints(node) )
+ for(NE destinationEndpoint : this.getNodeEndpoints(node) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getAdjacentEdges())
for(Graph.NodeEndpoint<? extends N, ? extends E> nodeEndpoint : sourceEndpoint.getAdjacentNodes())
sourceNodes.add(nodeEndpoint.getTarget());
@@ -598,7 +598,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<E> sourceEdges = new HashSet<E>();
- for(NEP destinationEndpoint : this.getNodeEndpoints(node) )
+ for(NE destinationEndpoint : this.getNodeEndpoints(node) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getAdjacentEdges())
sourceEdges.add(sourceEndpoint.getTarget());
@@ -780,7 +780,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<E> destinationEdges = new HashSet<E>();
- for(NEP sourceEndpoint : this.getNodeEndpoints(source) )
+ for(NE sourceEndpoint : this.getNodeEndpoints(source) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> destinationEndpoint : sourceEndpoint.getTraversableAdjacentEdgesFrom())
destinationEdges.add(destinationEndpoint.getTarget());
@@ -792,7 +792,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<E> destinationEdges = new HashSet<E>();
- for(EEP sourceEndpoint : this.getEdgeEndpoints(source) )
+ for(EE sourceEndpoint : this.getEdgeEndpoints(source) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> destinationEndpoint : sourceEndpoint.getTraversableAdjacentEdgesFrom())
destinationEdges.add(destinationEndpoint.getTarget());
@@ -805,7 +805,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<E> sourceEdges = new HashSet<E>();
- for(NEP destinationEndpoint : this.getNodeEndpoints(destination) )
+ for(NE destinationEndpoint : this.getNodeEndpoints(destination) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getTraversableAdjacentEdgesTo())
sourceEdges.add(sourceEndpoint.getTarget());
@@ -817,7 +817,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<E> destinationEdges = new HashSet<E>();
- for(EEP destinationEndpoint : this.getEdgeEndpoints(destination) )
+ for(EE destinationEndpoint : this.getEdgeEndpoints(destination) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getTraversableAdjacentEdgesFrom())
destinationEdges.add(sourceEndpoint.getTarget());
@@ -829,7 +829,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<N> destinationNodes = new HashSet<N>();
- for(NEP sourceEndpoint : this.getNodeEndpoints(source) )
+ for(NE sourceEndpoint : this.getNodeEndpoints(source) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> destinationEndpoint : sourceEndpoint.getTraversableAdjacentEdgesTo())
for(Graph.NodeEndpoint<? extends N, ? extends E> nodeEndpoint : destinationEndpoint.getTraversableAdjacentNodesTo())
destinationNodes.add(nodeEndpoint.getTarget());
@@ -842,7 +842,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<N> destinationNodes = new HashSet<N>();
- for(EEP sourceEndpoint : this.getEdgeEndpoints(source) )
+ for(EE sourceEndpoint : this.getEdgeEndpoints(source) )
for(Graph.NodeEndpoint<? extends N, ? extends E> destinationEndpoint : sourceEndpoint.getTraversableAdjacentNodesTo())
destinationNodes.add(destinationEndpoint.getTarget());
@@ -854,7 +854,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<N> sourceNodes = new HashSet<N>();
- for(NEP destinationEndpoint : this.getNodeEndpoints(destination) )
+ for(NE destinationEndpoint : this.getNodeEndpoints(destination) )
for(Graph.EdgeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getTraversableAdjacentEdgesFrom())
for(Graph.NodeEndpoint<? extends N, ? extends E> nodeEndpoint : sourceEndpoint.getTraversableAdjacentNodesFrom())
sourceNodes.add(nodeEndpoint.getTarget());
@@ -867,7 +867,7 @@ public abstract class AbstractAdjacencyGraph<
{
final Set<N> sourceNodes = new HashSet<N>();
- for(EEP destinationEndpoint : this.getEdgeEndpoints(destination) )
+ for(EE destinationEndpoint : this.getEdgeEndpoints(destination) )
for(Graph.NodeEndpoint<? extends N, ? extends E> sourceEndpoint : destinationEndpoint.getTraversableAdjacentNodesFrom())
sourceNodes.add(sourceEndpoint.getTarget());
@@ -879,9 +879,9 @@ public abstract class AbstractAdjacencyGraph<
* @return A clone of the current object, with no changes
*/
@Override
- protected AbstractAdjacencyGraph<N, E, NEP, EEP> clone()
+ protected AbstractAdjacencyGraph<N, E, NE, EE> clone()
{
- return (AbstractAdjacencyGraph<N, E, NEP, EEP>) super.clone();
+ return (AbstractAdjacencyGraph<N, E, NE, EE>) super.clone();
}
/**
@@ -980,9 +980,6 @@ public abstract class AbstractAdjacencyGraph<
protected abstract class AbstractNodeEndpoint extends AbstractCloud<? super N,Graph.Endpoint<? super N, N,E>>.AbstractEndpoint<N> implements Graph.NodeEndpoint<N,E>
{
- protected AbstractNodeEndpoint()
- {
- }
@Override
public Set<Graph.EdgeEndpoint<N, E>> getAdjacentEdges()
@@ -1076,10 +1073,6 @@ public abstract class AbstractAdjacencyGraph<
protected abstract class AbstractEdgeEndpoint extends AbstractCloud<? super E,Graph.Endpoint<? super E, N,E>>.AbstractEndpoint<E> implements Graph.EdgeEndpoint<N,E>
{
- protected AbstractEdgeEndpoint()
- {
- }
-
@Override
public Set<Graph.NodeEndpoint<N, E>> getAdjacent()
{
@@ -1115,7 +1108,7 @@ public abstract class AbstractAdjacencyGraph<
final Set<Graph.EdgeEndpoint<N, E>> adjacentEdges = new HashSet<Graph.EdgeEndpoint<N, E>>();
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
- for( NEP neighborNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()) )
+ for( NE neighborNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()) )
adjacentEdges.addAll(AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(neighborNode));
adjacentEdges.remove(this);
@@ -1129,7 +1122,7 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsFrom().size() > 0 )
- for( NEP adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
+ for( NE adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( Graph.EdgeEndpoint<N, E> adjacentEdge : AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
if( adjacentEdge.getTarget().getTraversableFrom(adjacentNode.getTarget()).size() > 0 )
adjacentEdges.add(adjacentEdge);
@@ -1144,7 +1137,7 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsTo().size() > 0 )
- for( NEP adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
+ for( NE adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( Graph.EdgeEndpoint<N, E> adjacentEdge : AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
if( adjacentEdge.getTarget().getTraversableTo(adjacentNode.getTarget()).size() > 0 )
adjacentEdges.add(adjacentEdge);
diff --git a/src/main/java/com/syncleus/dann/graph/AbstractCloud.java b/src/main/java/com/syncleus/dann/graph/AbstractCloud.java
index 0493659e..8cf73c85 100644
--- a/src/main/java/com/syncleus/dann/graph/AbstractCloud.java
+++ b/src/main/java/com/syncleus/dann/graph/AbstractCloud.java
@@ -35,7 +35,7 @@ public abstract class AbstractCloud<
private static final Logger LOGGER = Logger.getLogger(AbstractCloud.class);
@Override
- public boolean contains(final Object node)
+ public boolean containsTarget(final Object node)
{
for( EP endpoint : this.getEndpoints() )
if( endpoint.getTarget().equals(node))
@@ -44,19 +44,46 @@ public abstract class AbstractCloud<
}
@Override
- public boolean containsAll(final Collection<?> nodes)
+ public boolean containsAllTargets(final Collection<?> nodes)
{
for( Object node : nodes )
- if( !this.contains(node) )
+ if( !this.containsTarget(node) )
return false;
return true;
}
@Override
- public boolean containsAny(final Collection<?> nodes)
+ public boolean containsAnyTargets(final Collection<?> nodes)
{
for( Object node : nodes )
- if( this.contains(node) )
+ if( this.containsTarget(node) )
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean contains(final Object endpoint)
+ {
+ for( EP otherEndpoint : this.getEndpoints() )
+ if( otherEndpoint.equals(endpoint))
+ return true;
+ return false;
+ }
+
+ @Override
+ public boolean containsAll(final Collection<? extends Endpoint<?>> endpoints)
+ {
+ for( Object endpoint : endpoints )
+ if( !this.contains(endpoint) )
+ return false;
+ return true;
+ }
+
+ @Override
+ public boolean containsAny(final Collection<? extends Endpoint<?>> endpoints)
+ {
+ for( Object endpoint : endpoints )
+ if( this.contains(endpoint) )
return true;
return false;
}
@@ -215,8 +242,43 @@ public abstract class AbstractCloud<
protected abstract class AbstractEndpoint<T> implements Cloud.Endpoint<T>
{
- protected AbstractEndpoint()
+ protected abstract boolean isTargetEquals();
+
+ /**
+ * By default this relies on the target to define equals, this means there can be only one instance of any
+ * endpoint. This should be overridden to allow for an edge to have the same element more than once.
+ */
+ @Override
+ public int hashCode()
{
+ if(!this.isTargetEquals())
+ return super.hashCode();
+ else if(this.getTarget() == null)
+ return 0;
+ else
+ return this.getTarget().hashCode();
+ }
+
+ /**
+ * By default this relies on the target to define equals, this means there can be only one instance of any
+ * endpoint. This should be overridden to allow for an edge to have the same element more than once.
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(!this.isTargetEquals())
+ return super.equals(obj);
+ else if( obj == null )
+ if( this.getTarget() == null )
+ return true;
+ else
+ return false;
+ else if( this.getTarget() == null)
+ return false;
+ else if( obj instanceof Cloud.Endpoint )
+ return ((Cloud.Endpoint<?>)obj).equals(this.getTarget());
+ else
+ return this.getTarget().equals(obj);
}
@Override
diff --git a/src/main/java/com/syncleus/dann/graph/AbstractContextMutableAdjacencyGraph.java b/src/main/java/com/syncleus/dann/graph/AbstractContextMutableAdjacencyGraph.java
new file mode 100644
index 00000000..755b53f4
--- /dev/null
+++ b/src/main/java/com/syncleus/dann/graph/AbstractContextMutableAdjacencyGraph.java
@@ -0,0 +1,173 @@
+/******************************************************************************
+ * *
+ * Copyright: (c) Syncleus, Inc. *
+ * *
+ * You may redistribute and modify this source code under the terms and *
+ * conditions of the Open Source Community License - Type C version 1.0 *
+ * or any later version as published by Syncleus, Inc. at www.syncleus.com. *
+ * There should be a copy of the license included with this file. If a copy *
+ * of the license is not included you are granted no right to distribute or *
+ * otherwise use this file except through a legal and valid license. You *
+ * should also contact Syncleus, Inc. at the information below if you cannot *
+ * find a license: *
+ * *
+ * Syncleus, Inc. *
+ * 2604 South 12th Street *
+ * Philadelphia, PA 19148 *
+ * *
+ ******************************************************************************/
+package com.syncleus.dann.graph;
+
+import java.util.*;
+import com.syncleus.dann.graph.event.context.*;
+
+public abstract class AbstractContextMutableAdjacencyGraph<
+ N,
+ E extends Cloud<N,? extends Cloud.Endpoint<N>>,
+ NE extends MutableGraph.NodeEndpoint<N, E>,
+ EE extends MutableGraph.EdgeEndpoint<N, E>
+ >
+ extends AbstractMutableAdjacencyGraph<N, E, NE, EE>
+{
+ @Override
+ public final boolean isContextEnabled()
+ {
+ return true;
+ }
+
+ @Override
+ protected void internalJoinNode(MutableGraph.NodeEndpoint<N, E> endpoint) throws InvalidGraphException
+ {
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+
+ try
+ {
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changingCloudContext(Collections.singleton(this), null);
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changingGraphContext(Collections.singleton(this), null, null);
+ if(endpoint.getTarget() instanceof ContextGraphNode)
+ ((ContextGraphNode<?,?>)endpoint.getTarget()).changingGraphNodeContext(Collections.singleton(this), null);
+ }
+ catch(RejectedContextException caught)
+ {
+ throw new InvalidGraphException("could not join node", caught);
+ }
+
+ super.internalJoinNode(endpoint);
+
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changedCloudContext(Collections.singleton(endpoint), null);
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changedGraphContext(Collections.singleton(endpoint), null, null);
+ if(endpoint.getTarget() instanceof ContextGraphNode)
+ ((ContextGraphNode<?,?>)endpoint.getTarget()).changedGraphNodeContext(Collections.singleton(endpoint), null);
+ }
+
+ @Override
+ protected void internalLeaveNode(MutableGraph.NodeEndpoint<?, ?> endpoint) throws InvalidGraphException
+ {
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+
+ try
+ {
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changingCloudContext(null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changingGraphContext(null, null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphNode)
+ ((ContextGraphNode<?,?>)endpoint.getTarget()).changingGraphNodeContext(null, Collections.singleton(endpoint));
+ }
+ catch(RejectedContextException caught)
+ {
+ throw new InvalidGraphException("could not join node", caught);
+ }
+
+ super.internalLeaveNode(endpoint);
+
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changedCloudContext(null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changedGraphContext(null, null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphNode)
+ ((ContextGraphNode<?,?>)endpoint.getTarget()).changedGraphNodeContext(null, Collections.singleton(endpoint));
+ }
+
+ @Override
+ protected void internalJoinEdge(MutableGraph.EdgeEndpoint<N, E> endpoint) throws InvalidGraphException
+ {
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+
+ try
+ {
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changingCloudContext(Collections.singleton(this), null);
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changingGraphContext(Collections.singleton(this), null, null);
+ if(endpoint.getTarget() instanceof ContextGraphEdge)
+ ((ContextGraphEdge<?,?>)endpoint.getTarget()).changingGraphEdgeContext(Collections.singleton(this), null);
+ }
+ catch(RejectedContextException caught)
+ {
+ throw new InvalidGraphException("could not join node", caught);
+ }
+
+ super.internalJoinEdge(endpoint);
+
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changedCloudContext(Collections.singleton(endpoint), null);
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changedGraphContext(Collections.singleton(endpoint), null, null);
+ if(endpoint.getTarget() instanceof ContextGraphEdge)
+ ((ContextGraphEdge<?,?>)endpoint.getTarget()).changedGraphEdgeContext(Collections.singleton(endpoint), null);
+ }
+
+ @Override
+ protected void internalLeaveEdge(MutableGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException
+ {
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+
+ try
+ {
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changingCloudContext(null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changingGraphContext(null, null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphEdge)
+ ((ContextGraphEdge<?,?>)endpoint.getTarget()).changingGraphEdgeContext(null, Collections.singleton(endpoint));
+ }
+ catch(RejectedContextException caught)
+ {
+ throw new InvalidGraphException("could not join node", caught);
+ }
+
+ super.internalLeaveEdge(endpoint);
+
+ if(endpoint.getTarget() instanceof ContextCloudElement)
+ ((ContextCloudElement<?,?>)endpoint.getTarget()).changedCloudContext(null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphElement)
+ ((ContextGraphElement<?,?>)endpoint.getTarget()).changedGraphContext(null, null, Collections.singleton(endpoint));
+ if(endpoint.getTarget() instanceof ContextGraphEdge)
+ ((ContextGraphEdge<?,?>)endpoint.getTarget()).changedGraphEdgeContext(null, Collections.singleton(endpoint));
+ }
+
+ protected abstract class AbstractNodeEndpoint extends AbstractMutableAdjacencyGraph<N,E,NE,EE>.AbstractNodeEndpoint
+ {
+ protected AbstractNodeEndpoint(final N target)
+ {
+ super(target);
+ }
+ };
+
+ protected abstract class AbstractEdgeEndpoint extends AbstractMutableAdjacencyGraph<N,E,NE,EE>.AbstractEdgeEndpoint
+ {
+ protected AbstractEdgeEndpoint(final E target)
+ {
+ super(target);
+ }
+ };
+}
diff --git a/src/main/java/com/syncleus/dann/graph/AbstractEdge.java b/src/main/java/com/syncleus/dann/graph/AbstractEdge.java
index a74d0462..35dc6dd0 100644
--- a/src/main/java/com/syncleus/dann/graph/AbstractEdge.java
+++ b/src/main/java/com/syncleus/dann/graph/AbstractEdge.java
@@ -23,7 +23,11 @@ public abstract class AbstractEdge<
EP extends Edge.Endpoint<? extends T>
> extends AbstractCloud<T,EP> implements Edge<T,EP>
{
- protected abstract class AbstractEndpoint<T> implements AbstractCloud.Endpoint<T>
+ protected abstract class AbstractEndpoint<TT> extends AbstractCloud<T,EP>.AbstractEndpoint<TT>
{
+ protected AbstractEndpoint(final boolean isTargetEquals)
+ {
+ super(isTargetEquals);
+ }
}
}
diff --git a/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java b/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java
index 3ca4cc2c..a42d832d 100644
--- a/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java
+++ b/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java
@@ -23,84 +23,95 @@ import java.util.*;
public abstract class AbstractMutableAdjacencyGraph<
N,
E extends Cloud<N,? extends Cloud.Endpoint<N>>,
- NEP extends MutableGraph.NodeEndpoint<N, E>,
- EEP extends MutableGraph.EdgeEndpoint<N, E>
+ NE extends MutableGraph.NodeEndpoint<N, E>,
+ EE extends MutableGraph.EdgeEndpoint<N, E>
>
- extends AbstractAdjacencyGraph<N, E, NEP, EEP>
- implements MutableGraph<N, E, NEP, EEP>
+ extends AbstractAdjacencyGraph<N, E, NE, EE>
+ implements MutableGraph<N, E, NE, EE>
{
private static final long serialVersionUID = -4613327727609060678L;
- private final AdjacencyMapping<NEP,EEP> adjacency = new HashAdjacencyMapping<NEP, EEP>();
- private final boolean uniqueNodes;
- private final boolean uniqueEdges;
+ private final AdjacencyMapping<MutableGraph.NodeEndpoint<N, E>,MutableGraph.EdgeEndpoint<N, E>,Cloud.Endpoint<N>> adjacency = new HashAdjacencyMapping<MutableGraph.NodeEndpoint<N, E>,MutableGraph.EdgeEndpoint<N, E>,Cloud.Endpoint<N>>();
protected AbstractMutableAdjacencyGraph()
{
- this(false);
}
- protected AbstractMutableAdjacencyGraph(final boolean uniqueEdges)
+
+
+ protected void internalJoinNode(final MutableGraph.NodeEndpoint<N, E> endpoint) throws InvalidGraphException
{
- this(uniqueEdges,true);
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+ else if( this.contains(endpoint) )
+ throw new IllegalArgumentException("endpoint is already a member of this graph!");
+
+ this.adjacency.putLeftKey(endpoint);
}
- protected AbstractMutableAdjacencyGraph(final boolean uniqueEdges, final boolean uniqueNodes)
+ protected void internalLeaveNode(MutableGraph.NodeEndpoint<?, ?> endpoint) throws InvalidGraphException
{
- this.uniqueEdges = uniqueEdges;
- this.uniqueNodes = uniqueNodes;
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+ else if( !this.adjacency.getLeftKeys().contains(endpoint) )
+ throw new IllegalArgumentException("endpoint is not an endpoint in this graph");
+ else if( this.getAdjacentEdgeEndpoints(endpoint).size() > 0)
+ throw new InvalidGraphException("Node must be an orphan in the graph to remove it");
+
+ this.adjacency.removeLeftKey(endpoint);
}
- protected final boolean isUniqueEdges()
+ protected void internalJoinEdge(final MutableGraph.EdgeEndpoint<N, E> endpoint) throws InvalidGraphException
{
- return this.uniqueEdges;
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+ //make sure all of the edge's node already belong to this graph
+ else if( !this.containsAllTargets(endpoint.getTarget().getTargets()) )
+ throw new InvalidGraphException("All of the edge's targets must already exist in this graph");
+ //we cant do anything if the endpoint already exists in the key, they are unique representations of
+ //a single membership to the graph
+ else if(this.contains(endpoint))
+ throw new IllegalArgumentException("endpoint is already a member of this graph!");
+
+ for( final Cloud.Endpoint<N> targetEndpoint : endpoint.getTarget().getEndpoints() )
+ for( final NE nodeEndpoint : this.getNodeEndpoints(targetEndpoint.getTarget()))
+ this.adjacency.put(nodeEndpoint,endpoint,targetEndpoint);
}
- protected final boolean isUniqueNodes()
+
+ protected void internalLeaveEdge(MutableGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException
{
- return this.uniqueNodes;
+ if(endpoint == null)
+ throw new IllegalArgumentException(("endpoint can not be null"));
+ else if( !this.adjacency.getRightKeys().contains(endpoint) )
+ throw new IllegalArgumentException("endpoint is not an endpoint in this graph");
+
+ this.adjacency.removeRightKey(endpoint);
}
@Override
- protected Set<Graph.EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(Graph.NodeEndpoint<? extends N, ? extends E> nodeEndpoint)
+ protected Set<Graph.EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(Graph.NodeEndpoint<?, ?> nodeEndpoint)
{
if( !this.adjacency.getLeftKeys().contains(nodeEndpoint) )
throw new IllegalArgumentException("nodeEndpoint is not an endpoint for this graph");
return Collections.<EdgeEndpoint<N,E>>unmodifiableSet(this.adjacency.getLeftAdjacency(nodeEndpoint));
}
- protected abstract NEP createNodeEndpoint(N node) throws InvalidGraphException;
- protected abstract EEP createEdgeEndpoint(E node) throws InvalidGraphException;
-
- @Override
- public NEP joinNode(N node) throws InvalidGraphException
- {
- if(this.uniqueNodes && this.contains(node))
- return this.getNodeEndpoints(node).iterator().next();
-
- final NEP endpoint = this.createNodeEndpoint(node);
- assert !this.adjacency.getLeftKeys().contains(endpoint);
-
- this.adjacency.putLeftKey(endpoint);
-
- return endpoint;
- }
-
@Override
- public Map<N, NEP> joinNodes(Set<? extends N> nodes) throws InvalidGraphException
+ public Map<N, NE> joinNodes(Set<? extends N> nodes) throws InvalidGraphException
{
- final Map<N, NEP> endpoints = new HashMap<N,NEP>();
+ final Map<N, NE> endpoints = new HashMap<N,NE>();
for(N node : nodes)
endpoints.put(node, this.joinNode(node));
return Collections.unmodifiableMap(endpoints);
}
@Override
- public Map<N, Set<NEP>> joinNodes(Map<? extends N, ? extends Integer> nodes) throws InvalidGraphException
+ public Map<N, Set<NE>> joinNodes(Map<? extends N, ? extends Integer> nodes) throws InvalidGraphException
{
- final Map<N,Set<NEP>> joinMapping = new HashMap<N, Set<NEP>>(nodes.size());
+ final Map<N,Set<NE>> joinMapping = new HashMap<N, Set<NE>>(nodes.size());
for(final Map.Entry<? extends N,? extends Integer> nodeEntry : nodes.entrySet())
{
- final Set<NEP> newEndpoints = new HashSet<NEP>(nodeEntry.getValue());
+ final Set<NE> newEndpoints = new HashSet<NE>(nodeEntry.getValue());
for(int count = 0; count < nodeEntry.getValue(); count++)
newEndpoints.add(this.joinNode(nodeEntry.getKey()));
joinMapping.put(nodeEntry.getKey(),newEndpoints);
@@ -109,61 +120,28 @@ public abstract class AbstractMutableAdjacencyGraph<
}
@Override
- public Set<EEP> leaveNode(MutableGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> endpoint) throws InvalidGraphException
+ public void leaveNodes(Set<? extends MutableGraph.NodeEndpoint<?, ?>> nodeEndpoints) throws InvalidGraphException
{
- if( !this.adjacency.getLeftKeys().contains(endpoint) )
- throw new IllegalArgumentException("endpoint is not an enpoint in this graph");
-
- //first we need to remove all associated edges
- final Set<EEP> orphanEdges = this.adjacency.getLeftAdjacency(endpoint);
- this.adjacency.getRightKeys().removeAll(orphanEdges);
- this.adjacency.removeLeftKey(endpoint);
-
- return Collections.unmodifiableSet(orphanEdges);
- }
-
- @Override
- public Set<EEP> leaveNodes(Set<? extends MutableGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>>> nodeEndpoints) throws InvalidGraphException
- {
- final Set<EEP> edgeEndpoints = new HashSet<EEP>();
for(MutableGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> node : nodeEndpoints)
- edgeEndpoints.addAll(this.leaveNode(node));
- return Collections.unmodifiableSet(edgeEndpoints);
+ this.leaveNode(node);
}
@Override
- public EEP joinEdge(E edge) throws InvalidGraphException
+ public Map<E, EE> joinEdges(Set<? extends E> edges) throws InvalidGraphException
{
- //make sure all of the edge's node already belong to this graph
- if( !this.containsAll(edge.getTargets()) )
- throw new IllegalArgumentException("All of the edge's targets must already exist in this graph");
-
- if(this.uniqueEdges && this.contains(edge))
- return this.getEdgeEndpoints(edge).iterator().next();
-
- final EEP edgeEndpoint = this.createEdgeEndpoint(edge);
- for( final N node : edge.getTargets() )
- this.adjacency.put(this.getNodeEndpoints(node).iterator().next(),edgeEndpoint);
-
- return edgeEndpoint;
- }
-
- @Override
- public Map<E, EEP> joinEdges(Set<? extends E> edges) throws InvalidGraphException
- {
- final Map<E, EEP> endpoints = new HashMap<E,EEP>();
+ final Map<E, EE> endpoints = new HashMap<E,EE>();
for(E edge : edges)
endpoints.put(edge, this.joinEdge(edge));
return Collections.unmodifiableMap(endpoints);
}
@Override
- public Map<E, Set<EEP>> joinEdges(Map<? extends E, ? extends Integer> edges) throws InvalidGraphException
+ public Map<E, Set<EE>> joinEdges(Map<? extends E, ? extends Integer> edges) throws InvalidGraphException
{
- final Map<E,Set<EEP>> joinMapping = new HashMap<E, Set<EEP>>(edges.size());
+ final Map<E,Set<EE>> joinMapping = new HashMap<E, Set<EE>>(edges.size());
for(final Map.Entry<? extends E,? extends Integer> edgeEntry : edges.entrySet())
{
- final Set<EEP> newEndpoints = new HashSet<EEP>(edgeEntry.getValue());
+ final Set<EE> newEndpoints = new HashSet<EE>(edgeEntry.getValue());
for(int count = 0; count < edgeEntry.getValue(); count++)
newEndpoints.add(this.joinEdge(edgeEntry.getKey()));
joinMapping.put(edgeEntry.getKey(),newEndpoints);
@@ -172,16 +150,7 @@ public abstract class AbstractMutableAdjacencyGraph<
}
@Override
- public void leaveEdge(MutableGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> edgeEndpoint) throws InvalidGraphException
- {
- if( !this.adjacency.getRightKeys().contains(edgeEndpoint) )
- throw new IllegalArgumentException("endpoint is not an enpoint in this graph");
-
- this.adjacency.removeRightKey(edgeEndpoint);
- }
-
- @Override
- public void leaveEdges(Set<? extends MutableGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>>> edgeEndpoints) throws InvalidGraphException
+ public void leaveEdges(Set<? extends MutableGraph.EdgeEndpoint<?, ?>> edgeEndpoints) throws InvalidGraphException
{
for(final MutableGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> edgeEndpoint : edgeEndpoints)
this.leaveEdge(edgeEndpoint);
@@ -202,27 +171,38 @@ public abstract class AbstractMutableAdjacencyGraph<
@Override
public Map<?, Graph.Endpoint<?, N, E>> reconfigure(Set<? extends N> addNodes, Set<? extends E> addEdges, Set<? extends Graph.Endpoint<?, ?, ?>> disconnectEndpoints) throws InvalidGraphException
{
- for(final Graph.Endpoint<?, ?,?> disconnectEndpoint : disconnectEndpoints)
- this.adjacency.remove(disconnectEndpoint.getTarget());
+ if( disconnectEndpoints != null )
+ {
+ for(final Graph.Endpoint<?, ?,?> disconnectEndpoint : disconnectEndpoints)
+ this.adjacency.remove(disconnectEndpoint.getTarget());
+ }
Map<Object, Graph.Endpoint<?, N,E>> newEndpoints = new HashMap<Object, Graph.Endpoint<?, N, E>>();
- newEndpoints.putAll(this.joinNodes(addNodes));
- newEndpoints.putAll(this.joinEdges(addEdges));
+ if( addNodes != null )
+ newEndpoints.putAll(this.joinNodes(addNodes));
+ if( addEdges != null )
+ newEndpoints.putAll(this.joinEdges(addEdges));
return newEndpoints;
}
@Override
- public Set<EEP> getEdgeEndpoints()
+ public Set<EE> getEdgeEndpoints()
{
return Collections.unmodifiableSet(this.adjacency.getRightKeys());
}
@Override
- public Set<NEP> getNodeEndpoints()
+ public Set<NE> getNodeEndpoints()
{
return Collections.unmodifiableSet(this.adjacency.getLeftKeys());
}
+ @Override
+ public boolean isContextEnabled()
+ {
+ return false;
+ }
+
/*
private class NodeTargetSet extends AbstractTargetSet<N>
{
@@ -313,11 +293,63 @@ public abstract class AbstractMutableAdjacencyGraph<
};
*/
- protected abstract class AbstractNodeEndpoint extends AbstractAdjacencyGraph<N,E,NEP,EEP>.AbstractNodeEndpoint implements MutableGraph.NodeEndpoint<N, E>
+ protected abstract class AbstractNodeEndpoint extends AbstractAdjacencyGraph<N,E,NE,EE>.AbstractNodeEndpoint implements MutableGraph.NodeEndpoint<N, E>
{
- }
+ private N target;
- protected abstract class AbstractEdgeEndpoint extends AbstractAdjacencyGraph<N,E,NEP,EEP>.AbstractEdgeEndpoint implements MutableGraph.EdgeEndpoint<N, E>
+ protected AbstractNodeEndpoint(final N target)
+ {
+ this.target = target;
+ }
+
+ @Override
+ public void setTarget(N newTarget) throws InvalidGraphException
+ {
+ if(this.target != null && this.target.equals(newTarget) )
+ {
+ this.target = newTarget;
+ return;
+ }
+
+ internalLeaveNode(this);
+ this.target = newTarget;
+ internalJoinNode(this);
+ }
+
+ @Override
+ public N getTarget()
+ {
+ return this.target;
+ }
+ };
+
+ protected abstract class AbstractEdgeEndpoint extends AbstractAdjacencyGraph<N,E,NE,EE>.AbstractEdgeEndpoint implements MutableGraph.EdgeEndpoint<N, E>
{
- }
+ private E target;
+
+ protected AbstractEdgeEndpoint(final E target)
+ {
+ this.target = target;
+ }
+
+ @Override
+ public void setTarget(E newTarget) throws InvalidGraphException
+ {
+ if(this.target != null && this.target.equals(newTarget) )
+ {
+ this.target = newTarget;
+ return;
+ }
+
+ internalLeaveEdge(this);
+ this.target = newTarget;
+ internalJoinEdge(this);
+ }
+
+ @Override
+ public E getTarget()
+ {
+ return this.target;
+ }
+ };
}
\ No newline at end of file
diff --git a/src/main/java/com/syncleus/dann/graph/AdjacencyMapping.java b/src/main/java/com/syncleus/dann/graph/AdjacencyMapping.java
index f1b994ac..19579732 100644
--- a/src/main/java/com/syncleus/dann/graph/AdjacencyMapping.java
+++ b/src/main/java/com/syncleus/dann/graph/AdjacencyMapping.java
@@ -18,10 +18,10 @@
******************************************************************************/
package com.syncleus.dann.graph;
-import java.util.Map;
import java.util.Set;
+import sun.awt.SunHints;
-public interface AdjacencyMapping<LK,RK> extends Set<AdjacencyMapping.Adjacency<LK,RK>>
+public interface AdjacencyMapping<LK,RK,V> extends Set<AdjacencyMapping.Adjacency<LK,RK>>
{
interface Adjacency<LK,RK>
{
@@ -35,6 +35,8 @@ public interface AdjacencyMapping<LK,RK> extends Set<AdjacencyMapping.Adjacency<
boolean putLeftKey(LK leftKey);
boolean putRightKey(RK rightKey);
boolean put(LK leftKey, RK rightKey);
+ boolean put(LK leftKey, RK rightKey, V value);
+ V get(Object leftKey, Object rightKey);
boolean contains(Object leftKey, Object rightKey);
Set<RK> getRightKeys();
Set<LK> getLeftKeys();
diff --git a/src/main/java/com/syncleus/dann/graph/Cloud.java b/src/main/java/com/syncleus/dann/graph/Cloud.java
index cbd0158a..053fb050 100644
--- a/src/main/java/com/syncleus/dann/graph/Cloud.java
+++ b/src/main/java/com/syncleus/dann/graph/Cloud.java
@@ -41,14 +41,17 @@ public interface Cloud<
};
Set<EP> getEndpoints();
- Set<EP> getEndpoints(Object node);
- boolean contains(Object node);
- boolean containsAny(Collection<?> nodes);
- boolean containsAll(Collection<?> nodes);
+ Set<EP> getEndpoints(Object target);
Set<T> getTargets();
- Set<T> getNeighbors(Object source);
- Set<T> getTraversableFrom(Object source);
- Set<T> getTraversableTo(Object destination);
- boolean isTraversable(Object source, Object destination);
+ Set<T> getNeighbors(Object target);
+ Set<T> getTraversableFrom(Object target);
+ Set<T> getTraversableTo(Object target);
+ boolean isTraversable(Object sourceTarget, Object destinationTarget);
int getDegree();
+ boolean contains( Object endpoint);
+ boolean containsAny(Collection<? extends Endpoint<?>> endpoint);
+ boolean containsAll(Collection<? extends Endpoint<?>> endpoint);
+ boolean containsTarget(Object target);
+ boolean containsAnyTargets(Collection<?> target);
+ boolean containsAllTargets(Collection<?> target);
}
diff --git a/src/main/java/com/syncleus/dann/graph/HashAdjacencyMapping.java b/src/main/java/com/syncleus/dann/graph/HashAdjacencyMapping.java
index bf9f9bc4..0c7bf837 100644
--- a/src/main/java/com/syncleus/dann/graph/HashAdjacencyMapping.java
+++ b/src/main/java/com/syncleus/dann/graph/HashAdjacencyMapping.java
@@ -20,18 +20,19 @@ package com.syncleus.dann.graph;
import java.util.*;
-public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Adjacency<LK,RK>> implements AdjacencyMapping<LK,RK>
+public class HashAdjacencyMapping<LK,RK,V> extends AbstractSet<AdjacencyMapping.Adjacency<LK,RK>> implements AdjacencyMapping<LK,RK,V>
{
private Integer size = 0;
private final Map<LK, WeakRightKeySet> leftAdjacency = new HashMap<LK, WeakRightKeySet>();
private final Map<RK, WeakLeftKeySet> rightAdjacency = new HashMap<RK, WeakLeftKeySet>();
+ private final Map<LK,Map<RK,V>> valueMapping = new HashMap<LK, Map<RK,V>>();
@Override
public boolean contains(Object o)
{
if(!(o instanceof Adjacency))
return false;
- Adjacency<? extends Object,? extends Object> adjacency = (Adjacency<? extends Object,? extends Object>) o;
+ Adjacency<?,?> adjacency = (Adjacency<?,?>) o;
return this.contains((LK)adjacency.getLeftKey(),(RK)adjacency.getRightKey());
}
@@ -356,8 +357,7 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
return true;
}
- @Override
- public boolean put(LK leftKey, RK rightKey)
+ private boolean put(LK leftKey, RK rightKey, boolean eraseValue)
{
if(leftKey == null)
{
@@ -416,11 +416,68 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
assert size >= 1;
}
+ if( eraseValue )
+ {
+ final Map<RK,V> mappings = this.valueMapping.get(leftKey);
+ if( mappings == null )
+ return true;
+ mappings.remove(rightKey);
+ if( mappings.isEmpty() )
+ this.valueMapping.remove(leftKey);
+ }
+
return true;
}
@Override
- public boolean add(Adjacency<LK, RK> adjacency)
+ public boolean put(LK leftKey, RK rightKey)
+ {
+ return this.put(leftKey, rightKey, true);
+ }
+
+ @Override
+ public boolean put(LK leftKey, RK rightKey, V value)
+ {
+ if( (leftKey == null || rightKey == null) && value != null)
+ throw new IllegalArgumentException("Can not associated a value with an orphaned key");
+
+ final KeyPairing keyPair = new KeyPairing(leftKey, rightKey);
+ final boolean valueChanged = this.put(leftKey, rightKey, false);
+
+ Map<RK,V> mappings = this.valueMapping.get(leftKey);
+ if( mappings == null )
+ {
+ mappings = new WeakHashMap<RK, V>();
+ this.valueMapping.put(leftKey,mappings);
+ }
+
+ if( mappings.put(rightKey, value) == value )
+ return valueChanged;
+ else
+ return true;
+ }
+
+ @Override
+ public V get(Object leftKey, Object rightKey)
+ {
+ if(leftKey == null || rightKey == null)
+ throw new IllegalArgumentException("Can not associated a value with an orphaned key");
+
+ final Map<RK,V> mappings = this.valueMapping.get(leftKey);
+ if( mappings == null )
+ return null;
+
+ final V value = mappings.get(rightKey);
+ if( !this.contains(leftKey,rightKey) )
+ {
+ mappings.remove(rightKey);
+ return null;
+ }
+ return value;
+ }
+
+ @Override
+ public boolean add(AdjacencyMapping.Adjacency<LK, RK> adjacency)
{
return put(adjacency.getLeftKey(), adjacency.getRightKey());
}
@@ -448,6 +505,9 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
}
assert adjacentRight.size() > 0;
this.size = null;
+
+ //cleanup our weak refrences
+ adjacentRight = null;
}
assert this.size == null || this.size >= 0;
@@ -477,6 +537,9 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
}
assert adjacentLeft.size() > 0;
this.size = null;
+
+ //cleanup our weak refrences
+ adjacentLeft = null;
}
assert this.size == null || this.size >= 0;
@@ -561,6 +624,8 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
if(this.size != null)
return this.size;
+ System.gc();
+
int newSize = 0;
for(final Map.Entry<LK,WeakRightKeySet> entry : this.leftAdjacency.entrySet())
{
@@ -698,50 +763,112 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
}
}
- private class WeakHashSet<E> implements Set<E>
+ private static class WeakHashSet<E> implements Set<E>
{
- private final Map<E, Object> backingMap = new WeakHashMap<E, Object>();
+ private final Map<E, Object> references = new WeakHashMap<E, Object>();
+// private final Set<WeakReference<E>> references = new HashSet<WeakReference<E>>();
+// private final ReferenceQueue<E> queue = new ReferenceQueue<E>();
+/*
+ private final class ElementReference
+ {
+ private final WeakReference<E> reference;
+
+ public ElementReference(E element)
+ {
+ if( element != null )
+ this.reference = new WeakReference<E>(element, queue);
+ else
+ this.reference = null;
+ }
+
+ public E get()
+ {
+ if( !isClearTag() )
+ return this.reference.get();
+ return
+ null;
+ }
+
+ private boolean isClearTag()
+ {
+ return reference == null;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ if( this.isClearTag() )
+ return 0;
+
+ final E element = reference.get();
+ if( element == null )
+ return 0;
+ else
+ return element.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(obj == null)
+ return false;
+ if( !(obj instanceof ElementReference) )
+ return false;
+ final ElementReference otherElementReference = (ElementReference) obj;
+
+ final E otherElement = otherElementReference.get();
+ if( otherElement == null )
+ return false;
+
+ final E element = reference.get();
+ if( element == null )
+ return super.;
+
+ return element.equals(otherElement);
+ }
+ };
+*/
@Override
public int size()
{
- return this.backingMap.size();
+ return this.references.size();
}
@Override
public boolean isEmpty()
{
- return this.backingMap.isEmpty();
+ return this.references.isEmpty();
}
@Override
public boolean contains(Object o)
{
- return this.backingMap.containsKey(o);
+ return this.references.containsKey(o);
}
@Override
public Iterator<E> iterator()
{
- return this.backingMap.keySet().iterator();
+ return this.references.keySet().iterator();
}
@Override
public Object[] toArray()
{
- return this.backingMap.keySet().toArray();
+ return this.references.keySet().toArray();
}
@Override
public <T> T[] toArray(T[] a)
{
- return this.backingMap.keySet().toArray(a);
+ return this.references.keySet().toArray(a);
}
@Override
public boolean add(E ee)
{
- if( this.backingMap.put(ee, null) == null )
+ if( this.references.put(ee, null) == null )
return true;
return false;
}
@@ -749,13 +876,13 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
@Override
public boolean remove(Object o)
{
- return this.backingMap.keySet().remove(0);
+ return this.references.keySet().remove(0);
}
@Override
public boolean containsAll(Collection<?> c)
{
- return this.backingMap.keySet().containsAll(c);
+ return this.references.keySet().containsAll(c);
}
@Override
@@ -771,23 +898,23 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
@Override
public boolean retainAll(Collection<?> c)
{
- return this.backingMap.keySet().retainAll(c);
+ return this.references.keySet().retainAll(c);
}
@Override
public boolean removeAll(Collection<?> c)
{
- return this.backingMap.keySet().removeAll(c);
+ return this.references.keySet().removeAll(c);
}
@Override
public void clear()
{
- this.backingMap.clear();
+ this.references.clear();
}
};
- private abstract class WeakGraphElementSet<E> extends WeakHashSet<E>
+ private static abstract class WeakGraphElementSet<E> extends WeakHashSet<E>
{
protected abstract void clean();
@@ -876,9 +1003,7 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
this.clean();
return super.removeAll(c); //To change body of overridden methods use File | Settings | File Templates.
}
- }
-
- ;
+ };
private final class WeakLeftKeySet extends WeakGraphElementSet<LK>
{
@@ -888,9 +1013,7 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
return;
this.retainAll(leftAdjacency.keySet());
}
- }
-
- ;
+ };
private final class WeakRightKeySet extends WeakGraphElementSet<RK>
{
@@ -900,7 +1023,57 @@ public class HashAdjacencyMapping<LK,RK> extends AbstractSet<AdjacencyMapping.Ad
return;
this.retainAll(rightAdjacency.keySet());
}
- }
+ };
- ;
+ private final class KeyPairing implements AdjacencyMapping.Adjacency<LK,RK>
+ {
+ private final LK leftKey;
+ private final RK rightKey;
+
+ public KeyPairing(LK leftKey, RK rightKey)
+ {
+ this.leftKey = leftKey;
+ this.rightKey = rightKey;
+ }
+
+ public LK getLeftKey()
+ {
+ return this.leftKey;
+ }
+
+ public RK getRightKey()
+ {
+ return this.rightKey;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return (leftKey == null ? 0 : leftKey.hashCode()) + (rightKey == null ? 0 : rightKey.hashCode());
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if( obj == null )
+ return false;
+ else if( !(obj instanceof KeyPairing) )
+ return false;
+
+ final KeyPairing keyPair = (KeyPairing) obj;
+ if(
+ (
+ (this.leftKey != null && (this.leftKey.equals(keyPair.getLeftKey()))) ||
+ (this.leftKey == null && keyPair.getLeftKey() == null)
+ ) &&
+ (
+ (this.rightKey != null && (this.rightKey.equals(keyPair.getRightKey()))) ||
+ (this.rightKey == null && keyPair.getRightKey() == null)
+ )
+ )
+ return true;
+
+ return false;
+ }
+ };
}
diff --git a/src/main/java/com/syncleus/dann/graph/MutableAdjacencyGraph.java b/src/main/java/com/syncleus/dann/graph/MutableAdjacencyGraph.java
index 9ee2352d..4971ff0a 100644
--- a/src/main/java/com/syncleus/dann/graph/MutableAdjacencyGraph.java
+++ b/src/main/java/com/syncleus/dann/graph/MutableAdjacencyGraph.java
@@ -18,34 +18,88 @@
******************************************************************************/
package com.syncleus.dann.graph;
+import java.util.Set;
+import com.syncleus.dann.xml.Namer;
+
public final class MutableAdjacencyGraph<
- N,
- E extends Cloud<N,Cloud.Endpoint<N>>
- > extends AbstractMutableAdjacencyGraph<N,E,MutableGraph.NodeEndpoint<N, E>,MutableGraph.EdgeEndpoint<N, E>>
-/*
- <
N,
E extends Cloud<N,? extends Cloud.Endpoint<N>>
- >*/
-// extends AbstractMutableAdjacencyGraph<N, E, MutableGraph.NodeEndpoint<N, E>//, MutableGraph.EdgeEndpoint<N, E>>
+ >
+ extends AbstractContextMutableAdjacencyGraph<N, E, MutableGraph.NodeEndpoint<N, E>, MutableGraph.EdgeEndpoint<N, E>>
{
private static final long serialVersionUID = -4613327727609060678L;
+ private final boolean areNodesUnique;
+ private final boolean areEdgesUnique;
+
+ public MutableAdjacencyGraph()
+ {
+ this(false,true);
+ }
+
+ public MutableAdjacencyGraph(final boolean areEdgesUnique)
+ {
+ this(areEdgesUnique, true);
+ }
+
+ public MutableAdjacencyGraph(final boolean areEdgesUnique, final boolean areNodesUnique)
+ {
+ this.areEdgesUnique = areEdgesUnique;
+ this.areNodesUnique = areNodesUnique;
+ }
@Override
- public boolean isContextEnabled()
+ public MutableGraph.NodeEndpoint<N, E> joinNode(N node) throws InvalidGraphException
{
- return false;
+ final NodeEndpoint endpoint = new NodeEndpoint(node);
+ this.internalJoinNode(endpoint);
+ return endpoint;
}
@Override
- protected MutableGraph.NodeEndpoint<N, E> createNodeEndpoint(N node) throws InvalidGraphException
+ public void leaveNode(MutableGraph.NodeEndpoint<?, ?> endpoint) throws InvalidGraphException
{
- return null;
+ this.internalLeaveNode(endpoint);
}
@Override
- protected MutableGraph.EdgeEndpoint<N, E> createEdgeEndpoint(E node) throws InvalidGraphException
+ public MutableGraph.EdgeEndpoint<N, E> joinEdge(E edge) throws InvalidGraphException
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ final EdgeEndpoint endpoint = new EdgeEndpoint(edge);
+ this.internalJoinEdge(endpoint);
+ return endpoint;
}
+
+ @Override
+ public void leaveEdge(MutableGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException
+ {
+ this.internalLeaveEdge(endpoint);
+ }
+
+ protected final class NodeEndpoint extends AbstractContextMutableAdjacencyGraph<N,E,MutableGraph.NodeEndpoint<N, E>,MutableGraph.EdgeEndpoint<N, E>>.AbstractNodeEndpoint
+ {
+ protected NodeEndpoint(final N target)
+ {
+ super(target);
+ }
+
+ @Override
+ protected boolean isTargetEquals()
+ {
+ return areNodesUnique;
+ }
+ };
+
+ protected final class EdgeEndpoint extends AbstractContextMutableAdjacencyGraph<N,E,MutableGraph.NodeEndpoint<N, E>,MutableGraph.EdgeEndpoint<N, E>>.AbstractEdgeEndpoint
+ {
+ protected EdgeEndpoint(final E target)
+ {
+ super(target);
+ }
+
+ @Override
+ protected boolean isTargetEquals()
+ {
+ return areEdgesUnique;
+ }
+ };
}
diff --git a/src/main/java/com/syncleus/dann/graph/MutableGraph.java b/src/main/java/com/syncleus/dann/graph/MutableGraph.java
index 138243a5..109590b7 100644
--- a/src/main/java/com/syncleus/dann/graph/MutableGraph.java
+++ b/src/main/java/com/syncleus/dann/graph/MutableGraph.java
@@ -45,17 +45,17 @@ public interface MutableGraph<
NE joinNode(N node) throws InvalidGraphException;
Map<N, NE> joinNodes(Set<? extends N> nodes) throws InvalidGraphException;
Map<N, Set<NE>> joinNodes(Map<? extends N,? extends Integer> nodes) throws InvalidGraphException;
- Set<EE> leaveNode(MutableGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Cloud.Endpoint<?>>> endpoint) throws InvalidGraphException;
- Set<EE> leaveNodes(Set<? extends MutableGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Cloud.Endpoint<?>>>> endpoint) throws InvalidGraphException;
+ void leaveNode(MutableGraph.NodeEndpoint<?,?> endpoint) throws InvalidGraphException;
+ void leaveNodes(Set<? extends MutableGraph.NodeEndpoint<?,?>> endpoint) throws InvalidGraphException;
EE joinEdge(E edge) throws InvalidGraphException;
Map<E, EE> joinEdges(Set<? extends E> edges) throws InvalidGraphException;
Map<E, Set<EE>> joinEdges(Map<? extends E,? extends Integer> edges) throws InvalidGraphException;
- void leaveEdge(MutableGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Cloud.Endpoint<?>>> endpoint) throws InvalidGraphException;
- void leaveEdges(Set<? extends MutableGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Cloud.Endpoint<?>>>> endpoints) throws InvalidGraphException;
+ void leaveEdge(MutableGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException;
+ void leaveEdges(Set<? extends MutableGraph.EdgeEndpoint<?, ?>> endpoints) throws InvalidGraphException;
void clear() throws InvalidGraphException;
void clearEdges() throws InvalidGraphException;
- Map<?, Graph.Endpoint<?, N,E>> reconfigure(Set<? extends N> addNodes, Set<? extends E> addEdges, final Set<? extends Graph.Endpoint<?, ?,?>> disconnectEndpoints) throws InvalidGraphException;
+ Map<?, Graph.Endpoint<?, N,E>> reconfigure(Set<? extends N> addNodes, Set<? extends E> addEdges, final Set<? extends Graph.Endpoint<?,?,?>> disconnectEndpoints) throws InvalidGraphException;
}
diff --git a/src/main/java/com/syncleus/dann/graph/event/context/ContextCloudElement.java b/src/main/java/com/syncleus/dann/graph/event/context/ContextCloudElement.java
index c5fd04bb..87ecafc9 100644
--- a/src/main/java/com/syncleus/dann/graph/event/context/ContextCloudElement.java
+++ b/src/main/java/com/syncleus/dann/graph/event/context/ContextCloudElement.java
@@ -21,8 +21,11 @@ package com.syncleus.dann.graph.event.context;
import java.util.Set;
import com.syncleus.dann.graph.Cloud;
-public interface ContextCloudElement< CE extends Cloud.Endpoint<?> >
+public interface ContextCloudElement<
+ CE extends Cloud.Endpoint<?>,
+ C extends Cloud<?, ? extends CE>
+ >
{
- void changingCloudContext(Set<? extends CE> joiningContexts, Set<? extends Cloud<?,? extends Cloud.Endpoint<?>>> leavingContexts) throws RejectedContextException;
- void changedCloudContext(Set<? extends CE> joinedContexts, Set<? extends Cloud<?,? extends Cloud.Endpoint<?>>> leftContexts);
+ void changingCloudContext(Set<? extends C> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
+ void changedCloudContext(Set<? extends CE> joinedContexts, Set<?> leftContexts);
}
diff --git a/src/main/java/com/syncleus/dann/graph/event/context/ContextEdgeElement.java b/src/main/java/com/syncleus/dann/graph/event/context/ContextEdgeElement.java
index 5a5d10b1..f9a843d8 100644
--- a/src/main/java/com/syncleus/dann/graph/event/context/ContextEdgeElement.java
+++ b/src/main/java/com/syncleus/dann/graph/event/context/ContextEdgeElement.java
@@ -21,8 +21,11 @@ package com.syncleus.dann.graph.event.context;
import java.util.Set;
import com.syncleus.dann.graph.*;
-public interface ContextEdgeElement< EE extends Edge.Endpoint<?> >
+public interface ContextEdgeElement<
+ EE extends Edge.Endpoint<?>,
+ E extends Edge<?, ? extends EE>
+ >
{
- void changingEdgeContext( Set<? extends EE> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
+ void changingEdgeContext( Set<? extends E> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
void changedEdgeContext(Set<? extends EE> joinedContexts, Set<?> leftContexts);
}
\ No newline at end of file
diff --git a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphEdge.java b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphEdge.java
index da1e5963..f0b519ef 100644
--- a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphEdge.java
+++ b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphEdge.java
@@ -21,8 +21,11 @@ package com.syncleus.dann.graph.event.context;
import java.util.Set;
import com.syncleus.dann.graph.Graph;
-public interface ContextGraphEdge< GEE extends Graph.EdgeEndpoint<?,?> >
+public interface ContextGraphEdge<
+ GEE extends Graph.EdgeEndpoint<?,?>,
+ G extends Graph<?, ?, ?, ? extends GEE>
+ >
{
- void changingGraphEdgeContext( Set<? extends GEE> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
+ void changingGraphEdgeContext( Set<? extends G> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
void changedGraphEdgeContext(Set<? extends GEE> joinedContexts, Set<?> leftContexts);
}
diff --git a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphElement.java b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphElement.java
index e69c9e5f..b5556bb9 100644
--- a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphElement.java
+++ b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphElement.java
@@ -19,10 +19,14 @@
package com.syncleus.dann.graph.event.context;
import java.util.Set;
+import com.syncleus.dann.genetics.Gene;
import com.syncleus.dann.graph.Graph;
-public interface ContextGraphElement< GE extends Graph.Endpoint<?, ?,?> >
+public interface ContextGraphElement<
+ GE extends Graph.Endpoint<?, ?,?>,
+ G extends Graph<?, ?, ? extends GE, ? extends GE>
+ >
{
- void changingGraphContext( Set<? extends GE> joiningAsNode, Set<? extends GE> joiningAsEdge, Set<?> leavingContexts) throws RejectedContextException;
+ void changingGraphContext( Set<? extends G> joiningAsNode, Set<? extends GE> joiningAsEdge, Set<?> leavingContexts) throws RejectedContextException;
void changedGraphContext(Set<? extends GE> joinedAsNode, Set<? extends GE> joinedAsEdge, Set<?> leftContexts);
}
diff --git a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphNode.java b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphNode.java
index 742772e9..f2d72cf2 100644
--- a/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphNode.java
+++ b/src/main/java/com/syncleus/dann/graph/event/context/ContextGraphNode.java
@@ -21,8 +21,11 @@ package com.syncleus.dann.graph.event.context;
import java.util.Set;
import com.syncleus.dann.graph.Graph;
-public interface ContextGraphNode< GNE extends Graph.NodeEndpoint<?,?> >
+public interface ContextGraphNode<
+ GNE extends Graph.NodeEndpoint<?,?>,
+ G extends Graph<?, ?, ? extends GNE, ?>
+ >
{
- void changingGraphNodeContext( Set<? extends GNE> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
+ void changingGraphNodeContext( Set<? extends G> joiningContexts, Set<?> leavingContexts) throws RejectedContextException;
void changedGraphNodeContext(Set<? extends GNE> joinedContexts, Set<?> leftContexts);
}
--
GitLab