diff --git a/src/main/java/org/gephi/graph/api/Graph.java b/src/main/java/org/gephi/graph/api/Graph.java index 5d64337c..ad56cc8d 100644 --- a/src/main/java/org/gephi/graph/api/Graph.java +++ b/src/main/java/org/gephi/graph/api/Graph.java @@ -89,6 +89,24 @@ public interface Graph { */ public boolean removeAllNodes(Collection extends Node> nodes); + /** + * Retains only nodes in this graph that are contained in the specified + * collection. + * + * @param nodes the node collection + * @return true if at least one node has been removed, false otherwise + */ + public boolean retainNodes(Collection extends Node> nodes); + + /** + * Retains only edges in this graph that are contained in the specified + * collection. + * + * @param edges the edge collection + * @return true if at least one edge has been removed, false otherwise + */ + public boolean retainEdges(Collection extends Edge> edges); + /** * Returns true if node is contained in this graph. * diff --git a/src/main/java/org/gephi/graph/api/Subgraph.java b/src/main/java/org/gephi/graph/api/Subgraph.java index 00e88a8b..8d8c4cd6 100644 --- a/src/main/java/org/gephi/graph/api/Subgraph.java +++ b/src/main/java/org/gephi/graph/api/Subgraph.java @@ -110,6 +110,17 @@ public interface Subgraph extends Graph { @Override public boolean removeAllNodes(Collection extends Node> nodes); + /** + * Retains only nodes in this subgraph that are contained in the specified + * collection. + *
+ * The nodes should be part of the root graph. + * + * @param nodes the node collection + * @return true if at least one node has been removed, false otherwise + */ + public boolean retainNodes(Collection extends Node> nodes); + /** * Removes an edge from this subgraph. *
@@ -132,6 +143,17 @@ public interface Subgraph extends Graph { @Override public boolean removeAllEdges(Collection extends Edge> edges); + /** + * Retains only edges in this subgraph that are contained in the specified + * collection. + *
+ * The edges should be part of the root graph.
+ *
+ * @param edges the edge collection
+ * @return true if at least one edge has been removed, false otherwise
+ */
+ public boolean retainEdges(Collection extends Edge> edges);
+
/**
* Fills the subgraph so all elements in the graph are in the subgraph.
*/
diff --git a/src/main/java/org/gephi/graph/impl/EdgeStore.java b/src/main/java/org/gephi/graph/impl/EdgeStore.java
index 0120304f..3707b6fc 100644
--- a/src/main/java/org/gephi/graph/impl/EdgeStore.java
+++ b/src/main/java/org/gephi/graph/impl/EdgeStore.java
@@ -1021,8 +1021,9 @@ public boolean retainAll(Collection> c) {
}
}
return changed;
- } else {
+ } else if (size > 0) {
clear();
+ return true;
}
return false;
}
diff --git a/src/main/java/org/gephi/graph/impl/GraphStore.java b/src/main/java/org/gephi/graph/impl/GraphStore.java
index 09cb3c07..77386112 100644
--- a/src/main/java/org/gephi/graph/impl/GraphStore.java
+++ b/src/main/java/org/gephi/graph/impl/GraphStore.java
@@ -16,6 +16,7 @@
package org.gephi.graph.impl;
+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -297,6 +298,16 @@ public boolean removeAllNodes(Collection extends Node> nodes) {
}
}
+ @Override
+ public boolean retainNodes(Collection extends Node> nodes) {
+ autoWriteLock();
+ try {
+ return nodeStore.retainAll(nodes);
+ } finally {
+ autoWriteUnlock();
+ }
+ }
+
@Override
public boolean removeAllEdges(Collection extends Edge> edges) {
autoWriteLock();
@@ -307,6 +318,16 @@ public boolean removeAllEdges(Collection extends Edge> edges) {
}
}
+ @Override
+ public boolean retainEdges(Collection extends Edge> edges) {
+ autoWriteLock();
+ try {
+ return edgeStore.retainAll(edges);
+ } finally {
+ autoWriteUnlock();
+ }
+ }
+
public NodeStore getNodeStore() {
return nodeStore;
}
diff --git a/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java b/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java
index d3bfdc94..f949c7f0 100644
--- a/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java
+++ b/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java
@@ -264,6 +264,26 @@ public boolean removeAllNodes(Collection extends Node> nodes) {
}
}
+ @Override
+ public boolean retainNodes(Collection extends Node> nodes) {
+ graphStore.autoWriteLock();
+ try {
+ return view.retainNodes(nodes);
+ } finally {
+ graphStore.autoWriteUnlock();
+ }
+ }
+
+ @Override
+ public boolean retainEdges(Collection extends Edge> edges) {
+ graphStore.autoWriteLock();
+ try {
+ return view.retainEdges(edges);
+ } finally {
+ graphStore.autoWriteUnlock();
+ }
+ }
+
@Override
public boolean contains(Node node) {
checkValidNodeObject(node);
diff --git a/src/main/java/org/gephi/graph/impl/GraphViewImpl.java b/src/main/java/org/gephi/graph/impl/GraphViewImpl.java
index 083c7d66..42b8f592 100644
--- a/src/main/java/org/gephi/graph/impl/GraphViewImpl.java
+++ b/src/main/java/org/gephi/graph/impl/GraphViewImpl.java
@@ -17,6 +17,9 @@
import cern.colt.bitvector.BitVector;
import cern.colt.bitvector.QuickBitVector;
+import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
+import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+import it.unimi.dsi.fastutil.objects.ObjectSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -264,6 +267,61 @@ public boolean removeNodeAll(final Collection extends Node> nodes) {
return false;
}
+ public boolean retainNodes(final Collection extends Node> c) {
+ if (nodeView) {
+ if (!c.isEmpty()) {
+ IntOpenHashSet set = new IntOpenHashSet(c.size());
+ for (Node o : c) {
+ checkValidNodeObject(o);
+ set.add(o.getStoreId());
+ }
+
+ boolean changed = false;
+ int nodeSize = nodeBitVector.size();
+ for (int i = 0; i < nodeSize; i++) {
+ boolean t = nodeBitVector.get(i);
+ if (t && !set.contains(i)) {
+ if (removeNode(getNode(i))) {
+ changed = true;
+ }
+ }
+ }
+ return changed;
+ } else if (nodeCount != 0) {
+ clear();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean retainEdges(final Collection extends Edge> c) {
+ if (edgeView) {
+ if (!c.isEmpty()) {
+ IntOpenHashSet set = new IntOpenHashSet(c.size());
+ for (Edge o : c) {
+ checkValidEdgeObject(o);
+ set.add(o.getStoreId());
+ }
+
+ boolean changed = false;
+ int edgeSize = edgeBitVector.size();
+ for (int i = 0; i < edgeSize; i++) {
+ boolean t = edgeBitVector.get(i);
+ if (t && !set.contains(i)) {
+ removeEdge(getEdge(i));
+ changed = true;
+ }
+ }
+ return changed;
+ } else if (edgeCount != 0) {
+ clearEdges();
+ return true;
+ }
+ }
+ return false;
+ }
+
public boolean removeEdge(final Edge edge) {
checkEdgeView();
diff --git a/src/main/java/org/gephi/graph/impl/NodeStore.java b/src/main/java/org/gephi/graph/impl/NodeStore.java
index 841eb1a7..9c2c8add 100644
--- a/src/main/java/org/gephi/graph/impl/NodeStore.java
+++ b/src/main/java/org/gephi/graph/impl/NodeStore.java
@@ -443,8 +443,9 @@ public boolean retainAll(final Collection> c) {
}
}
return changed;
- } else {
+ } else if (size > 0) {
clear();
+ return true;
}
return false;
}
diff --git a/src/main/java/org/gephi/graph/impl/UndirectedDecorator.java b/src/main/java/org/gephi/graph/impl/UndirectedDecorator.java
index 189d5885..13ea499a 100644
--- a/src/main/java/org/gephi/graph/impl/UndirectedDecorator.java
+++ b/src/main/java/org/gephi/graph/impl/UndirectedDecorator.java
@@ -87,6 +87,16 @@ public boolean removeAllNodes(Collection extends Node> nodes) {
return store.removeAllNodes(nodes);
}
+ @Override
+ public boolean retainNodes(Collection extends Node> nodes) {
+ return store.retainNodes(nodes);
+ }
+
+ @Override
+ public boolean retainEdges(Collection extends Edge> edges) {
+ return store.retainEdges(edges);
+ }
+
@Override
public boolean contains(Node node) {
return store.contains(node);
diff --git a/src/test/java/org/gephi/graph/impl/BasicGraphStore.java b/src/test/java/org/gephi/graph/impl/BasicGraphStore.java
index 84818c0a..ddd0fc68 100644
--- a/src/test/java/org/gephi/graph/impl/BasicGraphStore.java
+++ b/src/test/java/org/gephi/graph/impl/BasicGraphStore.java
@@ -172,6 +172,28 @@ public boolean removeAllNodes(Collection extends Node> nodes) {
return true;
}
+ @Override
+ public boolean retainNodes(Collection extends Node> nodes) {
+ Set