|
17 | 17 | import org.gephi.graph.api.UndirectedSubgraph; |
18 | 18 |
|
19 | 19 | import java.awt.Color; |
| 20 | +import java.util.ArrayList; |
20 | 21 | import java.util.Arrays; |
21 | 22 | import java.util.Collection; |
22 | 23 | import java.util.HashSet; |
23 | 24 | import java.util.Iterator; |
| 25 | +import java.util.List; |
24 | 26 | import java.util.Map; |
25 | 27 | import java.util.Set; |
| 28 | +import java.util.concurrent.Callable; |
26 | 29 |
|
27 | 30 | public class HierarchicalGraphDecorator implements DirectedSubgraph, UndirectedSubgraph { |
28 | 31 | private final boolean undirected; |
@@ -74,49 +77,44 @@ public Edge getEdge(Node node1, Node node2, int type) { |
74 | 77 | } |
75 | 78 |
|
76 | 79 | @Override |
77 | | - public EdgeIterable getEdges(Node node1, Node node2) { |
78 | | - final Set<Edge> set = new HashSet<Edge>(); |
79 | | - graphStore.autoReadLock(); |
80 | | - try { |
81 | | - for (final Node n1 : view.mapWithHidden(node1)) { |
82 | | - for (final Node n2 : view.mapWithHidden(node2)) { |
83 | | - EdgeImpl edge = graphStore.edgeStore.get(n1, n2, undirected); |
84 | | - if (edge != null && view.containsEdge(edge)) { |
85 | | - set.add(edge); |
| 80 | + public EdgeIterable getEdges(final Node node1, final Node node2) { |
| 81 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 82 | + for (final Node n1 : view.mapWithHidden(node1)) { |
| 83 | + for (final Node n2 : view.mapWithHidden(node2)) { |
| 84 | + list.add(new Callable<Iterator<Edge>>() { |
| 85 | + @Override |
| 86 | + public Iterator<Edge> call() throws Exception { |
| 87 | + return graphStore.edgeStore.getAll(n1, n2, undirected); |
86 | 88 | } |
87 | | - } |
| 89 | + }); |
88 | 90 | } |
89 | | - } finally { |
90 | | - graphStore.autoReadUnlock(); |
91 | 91 | } |
92 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 92 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
93 | 93 | } |
94 | 94 |
|
95 | 95 | @Override |
96 | | - public EdgeIterable getEdges(Node node1, Node node2, int type) { |
97 | | - final Set<Edge> set = new HashSet<Edge>(); |
98 | | - graphStore.autoReadLock(); |
99 | | - try { |
100 | | - for (final Node n1 : view.mapWithHidden(node1)) { |
101 | | - for (final Node n2 : view.mapWithHidden(node2)) { |
102 | | - EdgeImpl edge = graphStore.edgeStore.get(n1, n2, type, undirected); |
103 | | - if (edge != null && view.containsEdge(edge)) { |
104 | | - set.add(edge); |
| 96 | + public EdgeIterable getEdges(final Node node1, final Node node2, final int type) { |
| 97 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 98 | + for (final Node n1 : view.mapWithHidden(node1)) { |
| 99 | + for (final Node n2 : view.mapWithHidden(node2)) { |
| 100 | + list.add(new Callable<Iterator<Edge>>() { |
| 101 | + @Override |
| 102 | + public Iterator<Edge> call() throws Exception { |
| 103 | + return graphStore.edgeStore.getAll(n1, n2, type, undirected); |
105 | 104 | } |
106 | | - } |
| 105 | + }); |
107 | 106 | } |
108 | | - } finally { |
109 | | - graphStore.autoReadUnlock(); |
110 | 107 | } |
111 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 108 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
112 | 109 | } |
113 | 110 |
|
114 | 111 | @Override |
115 | 112 | public Edge getMutualEdge(Edge edge) { |
116 | 113 | graphStore.autoReadLock(); |
117 | 114 | try { |
118 | | - for (final Node n1 : view.mapWithHidden(edge.getSource())) { |
119 | | - for (final Node n2 : view.mapWithHidden(edge.getTarget())) { |
| 115 | + final Edge unpacked = undecorateEdge(edge); |
| 116 | + for (final Node n1 : view.mapWithHidden(unpacked.getSource())) { |
| 117 | + for (final Node n2 : view.mapWithHidden(unpacked.getTarget())) { |
120 | 118 | Edge e = graphStore.getEdge(n1, n2); |
121 | 119 | EdgeImpl mutual = graphStore.edgeStore.getMutualEdge(e); |
122 | 120 | if (mutual != null && view.containsEdge(mutual)) { |
@@ -161,85 +159,61 @@ public NodeIterable getSuccessors(Node node, int type) { |
161 | 159 | @Override |
162 | 160 | public EdgeIterable getInEdges(Node node) { |
163 | 161 | checkValidInViewNodeObject(node); |
164 | | - Set<Edge> set = new HashSet<Edge>(); |
165 | | - graphStore.autoReadLock(); |
166 | | - try { |
167 | | - for (final Node n : view.mapWithHidden(node)) { |
168 | | - final EdgeStore.EdgeInIterator itr = graphStore.edgeStore.edgeInIterator(n); |
169 | | - while (itr.hasNext()) { |
170 | | - final Edge edge = itr.next(); |
171 | | - if (edge != null) { |
172 | | - set.add(edge); |
173 | | - } |
| 162 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 163 | + for (final Node n : view.mapWithHidden(node)) { |
| 164 | + list.add(new Callable<Iterator<Edge>>() { |
| 165 | + @Override |
| 166 | + public Iterator<Edge> call() throws Exception { |
| 167 | + return graphStore.edgeStore.edgeInIterator(n); |
174 | 168 | } |
175 | | - } |
176 | | - } finally { |
177 | | - graphStore.autoReadUnlock(); |
| 169 | + }); |
178 | 170 | } |
179 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 171 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
180 | 172 | } |
181 | 173 |
|
182 | 174 | @Override |
183 | | - public EdgeIterable getInEdges(Node node, int type) { |
| 175 | + public EdgeIterable getInEdges(final Node node, final int type) { |
184 | 176 | checkValidInViewNodeObject(node); |
185 | | - Set<Edge> set = new HashSet<Edge>(); |
186 | | - graphStore.autoReadLock(); |
187 | | - try { |
188 | | - for (final Node n : view.mapWithHidden(node)) { |
189 | | - final EdgeStore.EdgeTypeInIterator itr = graphStore.edgeStore.edgeInIterator(n, type); |
190 | | - while (itr.hasNext()) { |
191 | | - final Edge edge = itr.next(); |
192 | | - if (edge != null) { |
193 | | - set.add(edge); |
194 | | - } |
| 177 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 178 | + for (final Node n : view.mapWithHidden(node)) { |
| 179 | + list.add(new Callable<Iterator<Edge>>() { |
| 180 | + @Override |
| 181 | + public Iterator<Edge> call() throws Exception { |
| 182 | + return graphStore.edgeStore.edgeInIterator(n, type); |
195 | 183 | } |
196 | | - } |
197 | | - } finally { |
198 | | - graphStore.autoReadUnlock(); |
| 184 | + }); |
199 | 185 | } |
200 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 186 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
201 | 187 | } |
202 | 188 |
|
203 | 189 | @Override |
204 | | - public EdgeIterable getOutEdges(Node node) { |
| 190 | + public EdgeIterable getOutEdges(final Node node) { |
205 | 191 | checkValidInViewNodeObject(node); |
206 | | - Set<Edge> set = new HashSet<Edge>(); |
207 | | - graphStore.autoReadLock(); |
208 | | - try { |
209 | | - for (final Node n : view.mapWithHidden(node)) { |
210 | | - final EdgeStore.EdgeOutIterator itr = graphStore.edgeStore.edgeOutIterator(n); |
211 | | - while (itr.hasNext()) { |
212 | | - final Edge edge = itr.next(); |
213 | | - if (edge != null) { |
214 | | - set.add(edge); |
215 | | - } |
| 192 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 193 | + for (final Node n : view.mapWithHidden(node)) { |
| 194 | + list.add(new Callable<Iterator<Edge>>() { |
| 195 | + @Override |
| 196 | + public Iterator<Edge> call() throws Exception { |
| 197 | + return graphStore.edgeStore.edgeOutIterator(n); |
216 | 198 | } |
217 | | - } |
218 | | - } finally { |
219 | | - graphStore.autoReadUnlock(); |
| 199 | + }); |
220 | 200 | } |
221 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 201 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
222 | 202 | } |
223 | 203 |
|
224 | 204 | @Override |
225 | | - public EdgeIterable getOutEdges(Node node, int type) { |
| 205 | + public EdgeIterable getOutEdges(final Node node, final int type) { |
226 | 206 | checkValidInViewNodeObject(node); |
227 | | - Set<Edge> set = new HashSet<Edge>(); |
228 | | - graphStore.autoReadLock(); |
229 | | - try { |
230 | | - for (final Node n : view.mapWithHidden(node)) { |
231 | | - final EdgeStore.EdgeTypeOutIterator itr = graphStore.edgeStore.edgeOutIterator(n, type); |
232 | | - while (itr.hasNext()) { |
233 | | - final Edge edge = itr.next(); |
234 | | - if (edge != null) { |
235 | | - set.add(edge); |
236 | | - } |
| 207 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
| 208 | + for (final Node n : view.mapWithHidden(node)) { |
| 209 | + list.add(new Callable<Iterator<Edge>>() { |
| 210 | + @Override |
| 211 | + public Iterator<Edge> call() throws Exception { |
| 212 | + return graphStore.edgeStore.edgeOutIterator(n, type); |
237 | 213 | } |
238 | | - } |
239 | | - } finally { |
240 | | - graphStore.autoReadUnlock(); |
| 214 | + }); |
241 | 215 | } |
242 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 216 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
243 | 217 | } |
244 | 218 |
|
245 | 219 | @Override |
@@ -514,43 +488,39 @@ public NodeIterable getNeighbors(Node node, int type) { |
514 | 488 | @Override |
515 | 489 | public EdgeIterable getEdges(Node node) { |
516 | 490 | checkValidInViewNodeObject(node); |
517 | | - Set<Edge> set = new HashSet<Edge>(); |
| 491 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
518 | 492 | for (final Node n : view.mapWithHidden(node)) { |
519 | | - final Iterator<Edge> itr; |
520 | | - if (undirected) { |
521 | | - itr = new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node)); |
522 | | - } else { |
523 | | - itr = graphStore.edgeStore.edgeIterator(node); |
524 | | - } |
525 | | - while (itr.hasNext()) { |
526 | | - final Edge edge = itr.next(); |
527 | | - if (edge != null) { |
528 | | - set.add(edge); |
| 493 | + list.add(new Callable<Iterator<Edge>>() { |
| 494 | + @Override |
| 495 | + public Iterator<Edge> call() throws Exception { |
| 496 | + if (undirected) { |
| 497 | + return new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(n)); |
| 498 | + } else { |
| 499 | + return graphStore.edgeStore.edgeIterator(n); |
| 500 | + } |
529 | 501 | } |
530 | | - } |
| 502 | + }); |
531 | 503 | } |
532 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 504 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
533 | 505 | } |
534 | 506 |
|
535 | 507 | @Override |
536 | | - public EdgeIterable getEdges(Node node, int type) { |
| 508 | + public EdgeIterable getEdges(final Node node, final int type) { |
537 | 509 | checkValidInViewNodeObject(node); |
538 | | - Set<Edge> set = new HashSet<Edge>(); |
| 510 | + List<Callable<Iterator<Edge>>> list = new ArrayList<Callable<Iterator<Edge>>>(); |
539 | 511 | for (final Node n : view.mapWithHidden(node)) { |
540 | | - final Iterator<Edge> itr; |
541 | | - if (undirected) { |
542 | | - itr = new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node, type)); |
543 | | - } else { |
544 | | - itr = graphStore.edgeStore.edgeIterator(node, type); |
545 | | - } |
546 | | - while (itr.hasNext()) { |
547 | | - final Edge edge = itr.next(); |
548 | | - if (edge != null) { |
549 | | - set.add(edge); |
| 512 | + list.add(new Callable<Iterator<Edge>>() { |
| 513 | + @Override |
| 514 | + public Iterator<Edge> call() throws Exception { |
| 515 | + if (undirected) { |
| 516 | + return new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(n, type)); |
| 517 | + } else { |
| 518 | + return graphStore.edgeStore.edgeIterator(n, type); |
| 519 | + } |
550 | 520 | } |
551 | | - } |
| 521 | + }); |
552 | 522 | } |
553 | | - return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(set.iterator())); |
| 523 | + return graphStore.getEdgeIterableWrapper(new EdgeViewIterator(new ChainedFutureIterator<Edge>(list))); |
554 | 524 | } |
555 | 525 |
|
556 | 526 | @Override |
@@ -1019,6 +989,53 @@ boolean isUndirectedToIgnore(final EdgeImpl edge) { |
1019 | 989 | return false; |
1020 | 990 | } |
1021 | 991 |
|
| 992 | + private final class ChainedFutureIterator<T> implements Iterator<T> { |
| 993 | + private final List<Callable<Iterator<T>>> delegates; |
| 994 | + |
| 995 | + private Iterator<Callable<Iterator<T>>> itr = null; |
| 996 | + |
| 997 | + private Iterator<T> delegatePointer = null; |
| 998 | + |
| 999 | + private T itemPointer = null; |
| 1000 | + |
| 1001 | + private ChainedFutureIterator(final Collection<? extends Callable<Iterator<T>>> c) { |
| 1002 | + this.delegates = new ArrayList<Callable<Iterator<T>>>(c); |
| 1003 | + } |
| 1004 | + |
| 1005 | + @Override |
| 1006 | + public boolean hasNext() { |
| 1007 | + itemPointer = null; |
| 1008 | + |
| 1009 | + if (null == this.itr) { |
| 1010 | + itr = delegates.iterator(); |
| 1011 | + } |
| 1012 | + |
| 1013 | + while (null == itemPointer) { |
| 1014 | + while (null == delegatePointer || !delegatePointer.hasNext()) { |
| 1015 | + if (!itr.hasNext()) { |
| 1016 | + return false; |
| 1017 | + } |
| 1018 | + try { |
| 1019 | + delegatePointer = itr.next().call(); |
| 1020 | + } catch (final Exception e) { |
| 1021 | + throw new IllegalStateException(e); |
| 1022 | + } |
| 1023 | + } |
| 1024 | + |
| 1025 | + if (delegatePointer.hasNext()) { |
| 1026 | + itemPointer = delegatePointer.next(); |
| 1027 | + } |
| 1028 | + } |
| 1029 | + |
| 1030 | + return true; |
| 1031 | + } |
| 1032 | + |
| 1033 | + @Override |
| 1034 | + public T next() { |
| 1035 | + return itemPointer; |
| 1036 | + } |
| 1037 | + } |
| 1038 | + |
1022 | 1039 | private final class NodeViewIterator implements Iterator<Node> { |
1023 | 1040 | private final Iterator<Node> nodeIterator; |
1024 | 1041 |
|
|
0 commit comments