• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gephi / graphstore / #562

09 May 2026 07:38AM UTC coverage: 91.239%. Remained the same
#562

push

mbastian
Formatting fix

11800 of 12933 relevant lines covered (91.24%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.82
/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java
1
/*
2
 * Copyright 2012-2013 Gephi Consortium
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5
 * use this file except in compliance with the License. You may obtain a copy of
6
 * the License at
7
 *
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
 * License for the specific language governing permissions and limitations under
14
 * the License.
15
 */
16
package org.gephi.graph.impl;
17

18
import java.util.Collection;
19
import java.util.Iterator;
20
import java.util.Set;
21
import java.util.Spliterator;
22
import java.util.ConcurrentModificationException;
23
import java.util.function.Consumer;
24
import java.util.function.Predicate;
25
import org.gephi.graph.api.DirectedSubgraph;
26
import org.gephi.graph.api.Edge;
27
import org.gephi.graph.api.EdgeIterable;
28
import org.gephi.graph.api.Graph;
29
import org.gephi.graph.api.GraphModel;
30
import org.gephi.graph.api.GraphView;
31
import org.gephi.graph.api.Interval;
32
import org.gephi.graph.api.Node;
33
import org.gephi.graph.api.NodeIterable;
34
import org.gephi.graph.api.Rect2D;
35
import org.gephi.graph.api.SpatialIndex;
36
import org.gephi.graph.api.Subgraph;
37
import org.gephi.graph.api.UndirectedSubgraph;
38

39
public class GraphViewDecorator implements DirectedSubgraph, UndirectedSubgraph, SpatialIndex {
40

41
    protected final boolean undirected;
42
    protected final GraphViewImpl view;
43
    protected final GraphStore graphStore;
44

45
    public GraphViewDecorator(GraphStore graphStore, GraphViewImpl view, boolean undirected) {
1✔
46
        this.graphStore = graphStore;
1✔
47
        this.view = view;
1✔
48
        this.undirected = undirected;
1✔
49
    }
1✔
50

51
    @Override
52
    public Edge getEdge(Node node1, Node node2) {
53
        graphStore.autoReadLock();
1✔
54
        try {
55
            EdgeImpl edge = graphStore.edgeStore.get(node1, node2, undirected);
1✔
56
            if (edge != null && view.containsEdge(edge)) {
1✔
57
                return edge;
1✔
58
            }
59
            return null;
1✔
60
        } finally {
61
            graphStore.autoReadUnlock();
1✔
62
        }
63
    }
64

65
    @Override
66
    public EdgeIterable getEdges(Node node1, Node node2) {
67
        return new EdgeIterableWrapper(
×
68
                () -> new EdgeViewIterator(graphStore.edgeStore.getAll(node1, node2, undirected)),
×
69
                graphStore.getAutoLock());
×
70
    }
71

72
    @Override
73
    public Edge getEdge(Node node1, Node node2, int type) {
74
        graphStore.autoReadLock();
1✔
75
        try {
76
            EdgeImpl edge = graphStore.edgeStore.get(node1, node2, type, undirected);
1✔
77
            if (edge != null && view.containsEdge(edge)) {
1✔
78
                return edge;
1✔
79
            }
80
            return null;
1✔
81
        } finally {
82
            graphStore.autoReadUnlock();
1✔
83
        }
84
    }
85

86
    @Override
87
    public EdgeIterable getEdges(Node node1, Node node2, int type) {
88
        return new EdgeIterableWrapper(
×
89
                () -> new EdgeViewIterator(graphStore.edgeStore.getAll(node1, node2, type, undirected)),
×
90
                graphStore.getAutoLock());
×
91
    }
92

93
    @Override
94
    public Edge getMutualEdge(Edge e) {
95
        graphStore.autoReadLock();
1✔
96
        try {
97
            EdgeImpl edge = graphStore.edgeStore.getMutualEdge(e);
1✔
98
            if (edge != null && view.containsEdge(edge)) {
1✔
99
                return edge;
1✔
100
            }
101
            return null;
1✔
102
        } finally {
103
            graphStore.autoReadUnlock();
1✔
104
        }
105
    }
106

107
    @Override
108
    public NodeIterable getPredecessors(Node node) {
109
        checkValidInViewNodeObject(node);
1✔
110
        return new NodeIterableWrapper(() -> new NeighborsIterator((NodeImpl) node,
1✔
111
                new EdgeViewIterator(graphStore.edgeStore.edgeInIterator(node))), graphStore.getAutoLock());
1✔
112
    }
113

114
    @Override
115
    public NodeIterable getPredecessors(Node node, int type) {
116
        checkValidInViewNodeObject(node);
1✔
117
        return new NodeIterableWrapper(
1✔
118
                () -> new NeighborsIterator((NodeImpl) node,
1✔
119
                        new EdgeViewIterator(graphStore.edgeStore.edgeInIterator(node, type))),
1✔
120
                graphStore.getAutoLock());
1✔
121
    }
122

123
    @Override
124
    public NodeIterable getSuccessors(Node node) {
125
        checkValidInViewNodeObject(node);
1✔
126
        return new NodeIterableWrapper(() -> new NeighborsIterator((NodeImpl) node,
1✔
127
                new EdgeViewIterator(graphStore.edgeStore.edgeOutIterator(node))), graphStore.getAutoLock());
1✔
128
    }
129

130
    @Override
131
    public NodeIterable getSuccessors(Node node, int type) {
132
        checkValidInViewNodeObject(node);
1✔
133
        return new NodeIterableWrapper(
1✔
134
                () -> new NeighborsIterator((NodeImpl) node,
1✔
135
                        new EdgeViewIterator(graphStore.edgeStore.edgeOutIterator(node, type))),
1✔
136
                graphStore.getAutoLock());
1✔
137
    }
138

139
    @Override
140
    public EdgeIterable getInEdges(Node node) {
141
        checkValidInViewNodeObject(node);
1✔
142
        return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeInIterator(node)),
1✔
143
                graphStore.getAutoLock());
1✔
144
    }
145

146
    @Override
147
    public EdgeIterable getInEdges(Node node, int type) {
148
        checkValidInViewNodeObject(node);
1✔
149
        return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeInIterator(node, type)),
1✔
150
                graphStore.getAutoLock());
1✔
151
    }
152

153
    @Override
154
    public EdgeIterable getOutEdges(Node node) {
155
        checkValidInViewNodeObject(node);
1✔
156
        return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeOutIterator(node)),
1✔
157
                graphStore.getAutoLock());
1✔
158
    }
159

160
    @Override
161
    public EdgeIterable getOutEdges(Node node, int type) {
162
        checkValidInViewNodeObject(node);
1✔
163
        return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeOutIterator(node, type)),
1✔
164
                graphStore.getAutoLock());
1✔
165
    }
166

167
    @Override
168
    public boolean isAdjacent(Node source, Node target) {
169
        checkValidInViewNodeObject(source);
1✔
170
        checkValidInViewNodeObject(target);
1✔
171
        graphStore.autoReadLock();
1✔
172
        try {
173
            EdgeImpl edge = graphStore.edgeStore.get(source, target, undirected);
1✔
174
            return edge != null && view.containsEdge(edge);
1✔
175
        } finally {
176
            graphStore.autoReadUnlock();
1✔
177
        }
178
    }
179

180
    @Override
181
    public boolean isAdjacent(Node source, Node target, int type) {
182
        checkValidInViewNodeObject(source);
1✔
183
        checkValidInViewNodeObject(target);
1✔
184
        graphStore.autoReadLock();
1✔
185
        try {
186
            EdgeImpl edge = graphStore.edgeStore.get(source, target, type, undirected);
1✔
187
            return edge != null && view.containsEdge(edge);
1✔
188
        } finally {
189
            graphStore.autoReadUnlock();
1✔
190
        }
191
    }
192

193
    @Override
194
    public boolean addEdge(Edge edge) {
195
        checkValidEdgeObject(edge);
1✔
196
        graphStore.autoWriteLock();
1✔
197
        try {
198
            return view.addEdge(edge);
1✔
199
        } finally {
200
            graphStore.autoWriteUnlock();
1✔
201
        }
202

203
    }
204

205
    @Override
206
    public boolean addNode(Node node) {
207
        checkValidNodeObject(node);
1✔
208
        graphStore.autoWriteLock();
1✔
209
        try {
210
            return view.addNode(node);
1✔
211
        } finally {
212
            graphStore.autoWriteUnlock();
1✔
213
        }
214
    }
215

216
    @Override
217
    public boolean addAllEdges(Collection<? extends Edge> edges) {
218
        graphStore.autoWriteLock();
1✔
219
        try {
220
            return view.addAllEdges(edges);
1✔
221
        } finally {
222
            graphStore.autoWriteUnlock();
1✔
223
        }
224
    }
225

226
    @Override
227
    public boolean addAllNodes(Collection<? extends Node> nodes) {
228
        graphStore.autoWriteLock();
1✔
229
        try {
230
            return view.addAllNodes(nodes);
1✔
231
        } finally {
232
            graphStore.autoWriteUnlock();
1✔
233
        }
234
    }
235

236
    @Override
237
    public boolean removeEdge(Edge edge) {
238
        checkValidEdgeObject(edge);
1✔
239
        graphStore.autoWriteLock();
1✔
240
        try {
241
            return view.removeEdge(edge);
1✔
242
        } finally {
243
            graphStore.autoWriteUnlock();
1✔
244
        }
245
    }
246

247
    @Override
248
    public boolean removeNode(Node node) {
249
        checkValidNodeObject(node);
1✔
250
        graphStore.autoWriteLock();
1✔
251
        try {
252
            return view.removeNode(node);
1✔
253
        } finally {
254
            graphStore.autoWriteUnlock();
1✔
255
        }
256
    }
257

258
    @Override
259
    public boolean removeAllEdges(Collection<? extends Edge> edges) {
260
        graphStore.autoWriteLock();
1✔
261
        try {
262
            return view.removeEdgeAll(edges);
1✔
263
        } finally {
264
            graphStore.autoWriteUnlock();
1✔
265
        }
266
    }
267

268
    @Override
269
    public boolean removeAllNodes(Collection<? extends Node> nodes) {
270
        graphStore.autoWriteLock();
1✔
271
        try {
272
            return view.removeNodeAll(nodes);
1✔
273
        } finally {
274
            graphStore.autoWriteUnlock();
1✔
275
        }
276
    }
277

278
    @Override
279
    public boolean retainNodes(Collection<? extends Node> nodes) {
280
        graphStore.autoWriteLock();
1✔
281
        try {
282
            return view.retainNodes(nodes);
1✔
283
        } finally {
284
            graphStore.autoWriteUnlock();
1✔
285
        }
286
    }
287

288
    @Override
289
    public boolean retainEdges(Collection<? extends Edge> edges) {
290
        graphStore.autoWriteLock();
1✔
291
        try {
292
            return view.retainEdges(edges);
1✔
293
        } finally {
294
            graphStore.autoWriteUnlock();
1✔
295
        }
296
    }
297

298
    @Override
299
    public boolean contains(Node node) {
300
        checkValidNodeObject(node);
1✔
301
        graphStore.autoReadLock();
1✔
302
        try {
303
            return view.containsNode(node);
1✔
304
        } finally {
305
            graphStore.autoReadUnlock();
1✔
306
        }
307
    }
308

309
    @Override
310
    public boolean contains(Edge edge) {
311
        checkValidEdgeObject(edge);
1✔
312
        graphStore.autoReadLock();
1✔
313
        try {
314
            return view.containsEdge((EdgeImpl) edge);
1✔
315
        } finally {
316
            graphStore.autoReadUnlock();
1✔
317
        }
318
    }
319

320
    @Override
321
    public Node getNode(Object id) {
322
        graphStore.autoReadLock();
1✔
323
        try {
324
            NodeImpl node = graphStore.getNode(id);
1✔
325
            if (node != null && view.containsNode(node)) {
1✔
326
                return node;
1✔
327
            }
328
            return null;
1✔
329
        } finally {
330
            graphStore.autoReadUnlock();
1✔
331
        }
332
    }
333

334
    @Override
335
    public Node getNodeByStoreId(int id) {
336
        graphStore.autoReadLock();
×
337
        try {
338
            NodeImpl node = graphStore.getNodeByStoreId(id);
×
339
            if (node != null && view.containsNode(node)) {
×
340
                return node;
×
341
            }
342
            return null;
×
343
        } finally {
344
            graphStore.autoReadUnlock();
×
345
        }
346
    }
347

348
    @Override
349
    public boolean hasNode(final Object id) {
350
        return getNode(id) != null;
1✔
351
    }
352

353
    @Override
354
    public Edge getEdge(Object id) {
355
        graphStore.autoReadLock();
1✔
356
        try {
357
            EdgeImpl edge = graphStore.getEdge(id);
1✔
358
            if (edge != null && view.containsEdge(edge)) {
1✔
359
                return edge;
1✔
360
            }
361
            return null;
1✔
362
        } finally {
363
            graphStore.autoReadUnlock();
1✔
364
        }
365
    }
366

367
    @Override
368
    public Edge getEdgeByStoreId(int id) {
369
        graphStore.autoReadLock();
×
370
        try {
371
            EdgeImpl edge = graphStore.getEdgeByStoreId(id);
×
372
            if (edge != null && view.containsEdge(edge)) {
×
373
                return edge;
×
374
            }
375
            return null;
×
376
        } finally {
377
            graphStore.autoReadUnlock();
×
378
        }
379
    }
380

381
    @Override
382
    public boolean hasEdge(final Object id) {
383
        return getEdge(id) != null;
1✔
384
    }
385

386
    @Override
387
    public NodeIterable getNodes() {
388
        if (!view.isNodeView()) {
1✔
389
            return graphStore.getNodes();
1✔
390
        }
391
        return new NodeIterableWrapper(() -> new NodeViewIterator(graphStore.nodeStore.iterator()),
1✔
392
                NodeViewSpliterator::new, graphStore.getAutoLock());
1✔
393
    }
394

395
    @Override
396
    public EdgeIterable getEdges() {
397
        if (undirected) {
1✔
398
            return new EdgeIterableWrapper(() -> new UndirectedEdgeViewIterator(graphStore.edgeStore.iterator()),
1✔
399
                    () -> graphStore.edgeStore
1✔
400
                            .newFilteredSizedSpliterator(e -> view.containsEdge(e) && !isUndirectedToIgnore(e), view
1✔
401
                                    .getUndirectedEdgeCount()),
1✔
402
                    graphStore.getAutoLock());
1✔
403
        } else {
404
            return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.iterator()),
1✔
405
                    () -> graphStore.edgeStore.newFilteredSizedSpliterator(view::containsEdge, view.getEdgeCount()),
1✔
406
                    graphStore.getAutoLock());
1✔
407
        }
408
    }
409

410
    @Override
411
    public EdgeIterable getEdges(int type) {
412
        if (undirected) {
×
413
            return new EdgeIterableWrapper(
×
414
                    () -> new UndirectedEdgeViewIterator(graphStore.edgeStore.iteratorType(type, undirected)),
×
415
                    () -> graphStore.edgeStore.newFilteredSizedSpliterator(e -> e.getType() == type && view
×
416
                            .containsEdge(e) && !isUndirectedToIgnore(e), view.getUndirectedEdgeCount(type)),
×
417
                    graphStore.getAutoLock());
×
418
        } else {
419
            return new EdgeIterableWrapper(
×
420
                    () -> new EdgeViewIterator(graphStore.edgeStore.iteratorType(type, undirected)),
×
421
                    () -> graphStore.edgeStore
×
422
                            .newFilteredSizedSpliterator(e -> e.getType() == type && view.containsEdge(e), view
×
423
                                    .getEdgeCount(type)),
×
424
                    graphStore.getAutoLock());
×
425
        }
426
    }
427

428
    @Override
429
    public EdgeIterable getSelfLoops() {
430
        return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.iteratorSelfLoop()),
1✔
431
                () -> graphStore.edgeStore.newFilteredSpliterator(e -> e.isSelfLoop() && view.containsEdge(e)),
1✔
432
                graphStore.getAutoLock());
1✔
433
    }
434

435
    @Override
436
    public NodeIterable getNeighbors(Node node) {
437
        checkValidInViewNodeObject(node);
1✔
438
        return new NodeIterableWrapper(
1✔
439
                () -> new NeighborsIterator((NodeImpl) node,
1✔
440
                        new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node, true))),
1✔
441
                graphStore.getAutoLock());
1✔
442
    }
443

444
    @Override
445
    public NodeIterable getNeighbors(Node node, int type) {
446
        checkValidInViewNodeObject(node);
1✔
447
        return new NodeIterableWrapper(
1✔
448
                () -> new NeighborsIterator((NodeImpl) node,
1✔
449
                        new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node, type))),
1✔
450
                graphStore.getAutoLock());
1✔
451
    }
452

453
    @Override
454
    public EdgeIterable getEdges(Node node) {
455
        checkValidInViewNodeObject(node);
1✔
456
        if (undirected) {
1✔
457
            return new EdgeIterableWrapper(
1✔
458
                    () -> new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node, true)),
1✔
459
                    graphStore.getAutoLock());
1✔
460
        } else {
461
            return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeIterator(node, true)),
1✔
462
                    graphStore.getAutoLock());
1✔
463
        }
464
    }
465

466
    @Override
467
    public EdgeIterable getEdges(Node node, int type) {
468
        checkValidInViewNodeObject(node);
1✔
469
        if (undirected) {
1✔
470
            return new EdgeIterableWrapper(
1✔
471
                    () -> new UndirectedEdgeViewIterator(graphStore.edgeStore.edgeIterator(node, type)),
1✔
472
                    graphStore.getAutoLock());
1✔
473
        } else {
474
            return new EdgeIterableWrapper(() -> new EdgeViewIterator(graphStore.edgeStore.edgeIterator(node, type)),
1✔
475
                    graphStore.getAutoLock());
1✔
476
        }
477
    }
478

479
    @Override
480
    public int getNodeCount() {
481
        return view.getNodeCount();
1✔
482
    }
483

484
    @Override
485
    public int getEdgeCount() {
486
        if (undirected) {
1✔
487
            return view.getUndirectedEdgeCount();
1✔
488
        } else {
489
            return view.getEdgeCount();
1✔
490
        }
491
    }
492

493
    @Override
494
    public int getEdgeCount(int type) {
495
        if (undirected) {
1✔
496
            return view.getUndirectedEdgeCount(type);
1✔
497
        } else {
498
            return view.getEdgeCount(type);
1✔
499
        }
500
    }
501

502
    @Override
503
    public Node getOpposite(Node node, Edge edge) {
504
        checkValidInViewNodeObject(node);
1✔
505
        checkValidInViewEdgeObject(edge);
1✔
506

507
        return graphStore.getOpposite(node, edge);
1✔
508
    }
509

510
    @Override
511
    public int getDegree(Node node) {
512
        if (undirected) {
1✔
513
            int count = 0;
1✔
514
            EdgeStore.EdgeInOutIterator itr = graphStore.edgeStore.edgeIterator(node, true);
1✔
515
            while (itr.hasNext()) {
1✔
516
                EdgeImpl edge = itr.next();
1✔
517
                if (view.containsEdge(edge) && !isUndirectedToIgnore(edge)) {
1✔
518
                    count++;
1✔
519
                    if (edge.isSelfLoop()) {
1✔
520
                        count++;
1✔
521
                    }
522
                }
523
            }
1✔
524
            return count;
1✔
525
        } else {
526
            int count = 0;
1✔
527
            EdgeStore.EdgeInOutIterator itr = graphStore.edgeStore.edgeIterator(node, true);
1✔
528
            while (itr.hasNext()) {
1✔
529
                EdgeImpl edge = itr.next();
1✔
530
                if (view.containsEdge(edge)) {
1✔
531
                    count++;
1✔
532
                    if (edge.isSelfLoop()) {
1✔
533
                        count++;
1✔
534
                    }
535
                }
536
            }
1✔
537
            return count;
1✔
538
        }
539
    }
540

541
    @Override
542
    public int getInDegree(Node node) {
543
        int count = 0;
1✔
544
        EdgeStore.EdgeInIterator itr = graphStore.edgeStore.edgeInIterator(node);
1✔
545
        while (itr.hasNext()) {
1✔
546
            if (view.containsEdge(itr.next())) {
1✔
547
                count++;
1✔
548
            }
549
        }
550
        return count;
1✔
551
    }
552

553
    @Override
554
    public int getOutDegree(Node node) {
555
        int count = 0;
1✔
556
        EdgeStore.EdgeOutIterator itr = graphStore.edgeStore.edgeOutIterator(node);
1✔
557
        while (itr.hasNext()) {
1✔
558
            if (view.containsEdge(itr.next())) {
1✔
559
                count++;
1✔
560
            }
561
        }
562
        return count;
1✔
563
    }
564

565
    @Override
566
    public boolean isSelfLoop(Edge edge) {
567
        return edge.isSelfLoop();
1✔
568
    }
569

570
    @Override
571
    public boolean isDirected(Edge edge) {
572
        return edge.isDirected();
1✔
573
    }
574

575
    @Override
576
    public boolean isIncident(Edge edge1, Edge edge2) {
577
        graphStore.autoReadLock();
1✔
578
        try {
579
            checkValidInViewEdgeObject(edge1);
1✔
580
            checkValidInViewEdgeObject(edge2);
1✔
581

582
            return graphStore.edgeStore.isIncident((EdgeImpl) edge1, (EdgeImpl) edge2);
1✔
583
        } finally {
584
            graphStore.autoReadUnlock();
1✔
585
        }
586
    }
587

588
    @Override
589
    public boolean isIncident(final Node node, final Edge edge) {
590
        graphStore.autoReadLock();
1✔
591
        try {
592
            checkValidInViewNodeObject(node);
1✔
593
            checkValidInViewEdgeObject(edge);
1✔
594

595
            return graphStore.edgeStore.isIncident((NodeImpl) node, (EdgeImpl) edge);
1✔
596
        } finally {
597
            graphStore.autoReadUnlock();
1✔
598
        }
599
    }
600

601
    @Override
602
    public void clearEdges(Node node) {
603
        graphStore.autoWriteLock();
1✔
604
        try {
605
            EdgeStore.EdgeInOutIterator itr = graphStore.edgeStore.edgeIterator(node, false);
1✔
606
            while (itr.hasNext()) {
1✔
607
                EdgeImpl edge = itr.next();
1✔
608
                view.removeEdge(edge);
1✔
609
            }
1✔
610
        } finally {
611
            graphStore.autoWriteUnlock();
1✔
612
        }
613
    }
1✔
614

615
    @Override
616
    public void clearEdges(Node node, int type) {
617
        graphStore.autoWriteLock();
1✔
618
        try {
619
            EdgeStore.EdgeTypeInOutIterator itr = graphStore.edgeStore.edgeIterator(node, type);
1✔
620
            while (itr.hasNext()) {
1✔
621
                EdgeImpl edge = itr.next();
1✔
622
                view.removeEdge(edge);
1✔
623
            }
1✔
624
        } finally {
625
            graphStore.autoWriteUnlock();
1✔
626
        }
627
    }
1✔
628

629
    @Override
630
    public void clear() {
631
        view.clear();
1✔
632
    }
1✔
633

634
    @Override
635
    public void clearEdges() {
636
        view.clearEdges();
1✔
637
    }
1✔
638

639
    @Override
640
    public Object getAttribute(String key) {
641
        return view.attributes.getValue(key);
1✔
642
    }
643

644
    @Override
645
    public Object getAttribute(String key, double timestamp) {
646
        return view.attributes.getValue(key, timestamp);
1✔
647
    }
648

649
    @Override
650
    public Object getAttribute(String key, Interval interval) {
651
        return view.attributes.getValue(key, interval);
1✔
652
    }
653

654
    @Override
655
    public Set<String> getAttributeKeys() {
656
        return view.attributes.getKeys();
1✔
657
    }
658

659
    @Override
660
    public void setAttribute(String key, Object value) {
661
        view.attributes.setValue(key, value);
1✔
662
    }
1✔
663

664
    @Override
665
    public void setAttribute(String key, Object value, double timestamp) {
666
        view.attributes.setValue(key, value, timestamp);
1✔
667
    }
1✔
668

669
    @Override
670
    public void setAttribute(String key, Object value, Interval interval) {
671
        view.attributes.setValue(key, value, interval);
1✔
672
    }
1✔
673

674
    @Override
675
    public void removeAttribute(String key) {
676
        view.attributes.removeValue(key);
1✔
677
    }
1✔
678

679
    @Override
680
    public void removeAttribute(String key, double timestamp) {
681
        view.attributes.removeValue(key, timestamp);
1✔
682
    }
1✔
683

684
    @Override
685
    public void removeAttribute(String key, Interval interval) {
686
        view.attributes.removeValue(key, interval);
1✔
687
    }
1✔
688

689
    @Override
690
    public GraphModel getModel() {
691
        return graphStore.graphModel;
×
692
    }
693

694
    @Override
695
    public int getVersion() {
696
        return view.getVersion();
×
697
    }
698

699
    @Override
700
    public boolean isDirected() {
701
        return graphStore.isDirected();
1✔
702
    }
703

704
    @Override
705
    public boolean isUndirected() {
706
        return graphStore.isUndirected();
1✔
707
    }
708

709
    @Override
710
    public boolean isMixed() {
711
        return graphStore.isMixed();
×
712
    }
713

714
    @Override
715
    public void readLock() {
716
        graphStore.lock.readLock();
1✔
717
    }
1✔
718

719
    @Override
720
    public void readUnlock() {
721
        graphStore.lock.readUnlock();
1✔
722
    }
1✔
723

724
    @Override
725
    public void readUnlockAll() {
726
        graphStore.lock.readUnlockAll();
×
727
    }
×
728

729
    @Override
730
    public void writeLock() {
731
        graphStore.lock.writeLock();
1✔
732
    }
1✔
733

734
    @Override
735
    public GraphLockImpl getLock() {
736
        return graphStore.lock;
1✔
737
    }
738

739
    @Override
740
    public void writeUnlock() {
741
        graphStore.lock.writeUnlock();
1✔
742
    }
1✔
743

744
    @Override
745
    public GraphView getView() {
746
        return view;
1✔
747
    }
748

749
    @Override
750
    public void fill() {
751
        graphStore.autoWriteLock();
1✔
752
        try {
753
            view.fill();
1✔
754
        } finally {
755
            graphStore.autoWriteUnlock();
1✔
756
        }
757
    }
1✔
758

759
    @Override
760
    public void union(Subgraph subGraph) {
761
        checkValidViewObject(subGraph.getView());
1✔
762

763
        graphStore.autoWriteLock();
1✔
764
        try {
765
            view.union((GraphViewImpl) subGraph.getView());
1✔
766
        } finally {
767
            graphStore.autoWriteUnlock();
1✔
768
        }
769
    }
1✔
770

771
    @Override
772
    public void intersection(Subgraph subGraph) {
773
        checkValidViewObject(subGraph.getView());
1✔
774

775
        graphStore.autoWriteLock();
1✔
776
        try {
777
            view.intersection((GraphViewImpl) subGraph.getView());
1✔
778
        } finally {
779
            graphStore.autoWriteUnlock();
1✔
780
        }
781
    }
1✔
782

783
    @Override
784
    public void not() {
785
        graphStore.autoWriteLock();
×
786
        try {
787
            view.not();
×
788
        } finally {
789
            graphStore.autoWriteUnlock();
×
790
        }
791
    }
×
792

793
    @Override
794
    public Graph getRootGraph() {
795
        return graphStore;
×
796
    }
797

798
    @Override
799
    public SpatialIndex getSpatialIndex() {
800
        if (graphStore.spatialIndex == null) {
1✔
801
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
802
        }
803
        return this;
1✔
804
    }
805

806
    void checkWriteLock() {
807
        if (graphStore.lock != null) {
×
808
            graphStore.lock.checkHoldWriteLock();
×
809
        }
810
    }
×
811

812
    void checkValidNodeObject(final Node n) {
813
        if (n == null) {
1✔
814
            throw new NullPointerException();
×
815
        }
816
        if (!(n instanceof NodeImpl)) {
1✔
817
            throw new ClassCastException("Object must be a NodeImpl object");
×
818
        }
819
        if (n.getStoreId() == NodeStore.NULL_ID) {
1✔
820
            throw new IllegalArgumentException("Node should belong to a store");
×
821
        }
822
    }
1✔
823

824
    void checkValidInViewNodeObject(final Node n) {
825
        checkValidNodeObject(n);
1✔
826

827
        if (!view.containsNode(n)) {
1✔
828
            throw new RuntimeException("Node doesn't belong to this view");
1✔
829
        }
830
    }
1✔
831

832
    void checkValidEdgeObject(final Edge n) {
833
        if (n == null) {
1✔
834
            throw new NullPointerException();
×
835
        }
836
        if (!(n instanceof EdgeImpl)) {
1✔
837
            throw new ClassCastException("Object must be a EdgeImpl object");
×
838
        }
839
        if (n.getStoreId() == EdgeStore.NULL_ID) {
1✔
840
            throw new IllegalArgumentException("Edge should belong to a store");
×
841
        }
842
    }
1✔
843

844
    void checkValidInViewEdgeObject(final Edge e) {
845
        checkValidEdgeObject(e);
1✔
846

847
        if (!view.containsEdge(e)) {
1✔
848
            throw new RuntimeException("Edge doesn't belong to this view");
×
849
        }
850
    }
1✔
851

852
    void checkValidViewObject(final GraphView view) {
853
        if (view == null) {
1✔
854
            throw new NullPointerException();
×
855
        }
856
        if (!(view instanceof GraphViewImpl)) {
1✔
857
            throw new ClassCastException("Object must be a GraphViewImpl object");
×
858
        }
859
        if (((GraphViewImpl) view).graphStore != graphStore) {
1✔
860
            throw new RuntimeException("The view doesn't belong to this store");
×
861
        }
862
    }
1✔
863

864
    boolean isUndirectedToIgnore(final EdgeImpl edge) {
865
        if (edge.isMutual() && edge.source.storeId < edge.target.storeId) {
1✔
866
            if (view.containsEdge(graphStore.edgeStore.get(edge.target, edge.source, edge.type, false))) {
1✔
867
                return true;
1✔
868
            }
869
        }
870
        return false;
1✔
871
    }
872

873
    @Override
874
    public NodeIterable getNodesInArea(Rect2D rect) {
875
        if (graphStore.spatialIndex == null) {
×
876
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
877
        }
878
        return graphStore.spatialIndex.getNodesInArea(rect, view::containsNode);
×
879
    }
880

881
    @Override
882
    public NodeIterable getNodesInArea(Rect2D rect, Predicate<? super Node> predicate) {
883
        if (graphStore.spatialIndex == null) {
×
884
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
885
        }
886
        return graphStore.spatialIndex.getNodesInArea(rect, (node) -> view.containsNode(node) && predicate.test(node));
×
887
    }
888

889
    @Override
890
    public NodeIterable getApproximateNodesInArea(Rect2D rect) {
891
        if (graphStore.spatialIndex == null) {
×
892
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
893
        }
894
        return graphStore.spatialIndex.getApproximateNodesInArea(rect, view::containsNode);
×
895
    }
896

897
    @Override
898
    public NodeIterable getApproximateNodesInArea(Rect2D rect, Predicate<? super Node> predicate) {
899
        if (graphStore.spatialIndex == null) {
×
900
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
901
        }
902
        return graphStore.spatialIndex
×
903
                .getApproximateNodesInArea(rect, (node) -> view.containsNode(node) && predicate.test(node));
×
904
    }
905

906
    @Override
907
    public EdgeIterable getEdgesInArea(Rect2D rect) {
908
        if (graphStore.spatialIndex == null) {
×
909
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
910
        }
911
        return graphStore.spatialIndex.getEdgesInArea(rect, view::containsEdge);
×
912
    }
913

914
    @Override
915
    public EdgeIterable getEdgesInArea(Rect2D rect, Predicate<? super Edge> predicate) {
916
        if (graphStore.spatialIndex == null) {
×
917
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
918
        }
919
        return graphStore.spatialIndex.getEdgesInArea(rect, (edge) -> view.containsEdge(edge) && predicate.test(edge));
×
920
    }
921

922
    @Override
923
    public EdgeIterable getApproximateEdgesInArea(Rect2D rect) {
924
        if (graphStore.spatialIndex == null) {
×
925
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
926
        }
927
        return graphStore.spatialIndex.getApproximateEdgesInArea(rect, view::containsEdge);
×
928
    }
929

930
    @Override
931
    public EdgeIterable getApproximateEdgesInArea(Rect2D rect, Predicate<? super Edge> predicate) {
932
        if (graphStore.spatialIndex == null) {
×
933
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
934
        }
935
        return graphStore.spatialIndex
×
936
                .getApproximateEdgesInArea(rect, (edge) -> view.containsEdge(edge) && predicate.test(edge));
×
937
    }
938

939
    @Override
940
    public Rect2D getBoundaries() {
941
        if (graphStore.spatialIndex == null) {
1✔
942
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
943
        }
944
        return graphStore.spatialIndex.getBoundaries(view::containsNode);
1✔
945
    }
946

947
    @Override
948
    public void spatialIndexReadLock() {
949
        if (graphStore.spatialIndex == null) {
×
950
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
951
        }
952
        graphStore.spatialIndex.spatialIndexReadLock();
×
953
    }
×
954

955
    @Override
956
    public void spatialIndexReadUnlock() {
957
        if (graphStore.spatialIndex == null) {
×
958
            throw new UnsupportedOperationException("Spatial index is disabled (from Configuration)");
×
959
        }
960
        graphStore.spatialIndex.spatialIndexReadUnlock();
×
961
    }
×
962

963
    private final class NodeViewSpliterator implements Spliterator<Node> {
964

965
        private final int endBlockExclusive;
966
        private int blockIndex;
967
        private int indexInBlock;
968
        private NodeImpl[] currentArray;
969
        private int currentLength;
970
        private final int expectedVersion;
971
        private int totalSize;
972
        private int consumed;
973
        // True only for the root spliterator, where totalSize comes from view.getNodeCount().
974
        // Sub-ranges only have a proportional estimate and must drop SIZED.
975
        private boolean exactSize;
976

977
        NodeViewSpliterator() {
978
            this(0, graphStore.nodeStore.blocksCount);
1✔
979
        }
1✔
980

981
        NodeViewSpliterator(int startBlock, int endBlockExclusive) {
1✔
982
            this.blockIndex = startBlock;
1✔
983
            this.endBlockExclusive = endBlockExclusive;
1✔
984
            this.expectedVersion = graphStore.version != null ? graphStore.version.getNodeVersion() : 0;
1✔
985
            this.consumed = 0;
1✔
986

987
            // Root spliterator uses the exact view count; sub-ranges fall back to an estimate.
988
            if (startBlock == 0 && endBlockExclusive == graphStore.nodeStore.blocksCount) {
1✔
989
                this.totalSize = view.getNodeCount();
1✔
990
                this.exactSize = true;
1✔
991
            } else {
992
                this.totalSize = computeSizeEstimate(startBlock, endBlockExclusive);
1✔
993
                this.exactSize = false;
1✔
994
            }
995

996
            if (startBlock < endBlockExclusive) {
1✔
997
                NodeStore.NodeBlock b = graphStore.nodeStore.blocks[startBlock];
1✔
998
                currentArray = b.backingArray;
1✔
999
                currentLength = b.nodeLength;
1✔
1000
                indexInBlock = 0;
1✔
1001
            } else {
1✔
1002
                currentArray = null;
×
1003
                currentLength = 0;
×
1004
                indexInBlock = 0;
×
1005
            }
1006
        }
1✔
1007

1008
        private void advanceBlock() {
1009
            blockIndex++;
1✔
1010
            if (blockIndex < endBlockExclusive) {
1✔
1011
                NodeStore.NodeBlock b = graphStore.nodeStore.blocks[blockIndex];
×
1012
                currentArray = b.backingArray;
×
1013
                currentLength = b.nodeLength;
×
1014
                indexInBlock = 0;
×
1015
            } else {
×
1016
                currentArray = null;
1✔
1017
                currentLength = 0;
1✔
1018
                indexInBlock = 0;
1✔
1019
            }
1020
        }
1✔
1021

1022
        private void checkForComodification() {
1023
            if (graphStore.version != null && expectedVersion != graphStore.version.getNodeVersion()) {
1✔
1024
                throw new ConcurrentModificationException();
×
1025
            }
1026
        }
1✔
1027

1028
        private int computeSizeEstimate(int start, int end) {
1029
            int sum = 0;
1✔
1030
            for (int i = start; i < end; i++) {
1✔
1031
                NodeStore.NodeBlock b = graphStore.nodeStore.blocks[i];
1✔
1032
                if (b != null) {
1✔
1033
                    // Exact count: nodeLength minus garbageLength
1034
                    sum += (b.nodeLength - b.garbageLength);
1✔
1035
                }
1036
            }
1037
            if (sum > 0) {
1✔
1038
                // Scale by view ratio to estimate number of nodes in view
1039
                double viewRatio = (double) view.getNodeCount() / graphStore.nodeStore.size;
1✔
1040
                sum = (int) Math.round(sum * viewRatio);
1✔
1041
            }
1042
            return sum;
1✔
1043
        }
1044

1045
        @Override
1046
        public boolean tryAdvance(Consumer<? super Node> action) {
1047
            checkForComodification();
1✔
1048
            while (currentArray != null) {
1✔
1049
                while (indexInBlock < currentLength) {
1✔
1050
                    NodeImpl n = currentArray[indexInBlock++];
1✔
1051
                    if (n != null && view.containsNode(n)) {
1✔
1052
                        consumed++;
1✔
1053
                        action.accept(n);
1✔
1054
                        return true;
1✔
1055
                    }
1056
                }
1✔
1057
                advanceBlock();
1✔
1058
            }
1059
            return false;
1✔
1060
        }
1061

1062
        @Override
1063
        public Spliterator<Node> trySplit() {
1064
            // Only split at block boundaries to preserve encounter order
1065
            if (indexInBlock != 0) {
1✔
1066
                return null;
×
1067
            }
1068

1069
            int currentPos = blockIndex;
1✔
1070
            int remainingBlocks = endBlockExclusive - currentPos;
1✔
1071

1072
            if (remainingBlocks <= 1) {
1✔
1073
                return null;
1✔
1074
            }
1075

1076
            int mid = currentPos + remainingBlocks / 2;
1✔
1077

1078
            // Create left half
1079
            NodeViewSpliterator left = new NodeViewSpliterator(currentPos, mid);
1✔
1080

1081
            // Update this spliterator to become the right half
1082
            blockIndex = mid;
1✔
1083
            if (mid < endBlockExclusive) {
1✔
1084
                NodeStore.NodeBlock b = graphStore.nodeStore.blocks[mid];
1✔
1085
                currentArray = b.backingArray;
1✔
1086
                currentLength = b.nodeLength;
1✔
1087
                indexInBlock = 0;
1✔
1088
            } else {
1✔
1089
                currentArray = null;
×
1090
                currentLength = 0;
×
1091
                indexInBlock = 0;
×
1092
            }
1093

1094
            this.totalSize = Math.max(0, totalSize - left.totalSize);
1✔
1095
            // Once split, neither half can guarantee an exact view-aware size, so drop SIZED.
1096
            this.exactSize = false;
1✔
1097
            left.exactSize = false;
1✔
1098

1099
            return left;
1✔
1100
        }
1101

1102
        @Override
1103
        public long estimateSize() {
1104
            // Use the exact view size minus what we've consumed
1105
            long remaining = totalSize - consumed;
1✔
1106
            return remaining < 0 ? 0 : remaining;
1✔
1107
        }
1108

1109
        @Override
1110
        public int characteristics() {
1111
            int base = Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.NONNULL;
1✔
1112
            return exactSize ? base | Spliterator.SIZED : base;
1✔
1113
        }
1114
    }
1115

1116
    protected final class NodeViewIterator implements Iterator<Node> {
1117

1118
        private final Iterator<Node> nodeIterator;
1119
        private NodeImpl pointer;
1120

1121
        public NodeViewIterator(Iterator<Node> nodeIterator) {
1✔
1122
            this.nodeIterator = nodeIterator;
1✔
1123
        }
1✔
1124

1125
        @Override
1126
        public boolean hasNext() {
1127
            pointer = null;
1✔
1128
            while (pointer == null) {
1✔
1129
                if (!nodeIterator.hasNext()) {
1✔
1130
                    return false;
1✔
1131
                }
1132
                pointer = (NodeImpl) nodeIterator.next();
1✔
1133
                if (!view.containsNode(pointer)) {
1✔
1134
                    pointer = null;
1✔
1135
                }
1136
            }
1137
            return true;
1✔
1138
        }
1139

1140
        @Override
1141
        public Node next() {
1142
            return pointer;
1✔
1143
        }
1144

1145
        @Override
1146
        public void remove() {
1147
            checkWriteLock();
×
1148
            removeNode(pointer);
×
1149
        }
×
1150
    }
1151

1152
    protected final class EdgeViewIterator implements Iterator<Edge> {
1153

1154
        private final Iterator<Edge> edgeIterator;
1155
        private EdgeImpl pointer;
1156

1157
        public EdgeViewIterator(Iterator<Edge> edgeIterator) {
1✔
1158
            this.edgeIterator = edgeIterator;
1✔
1159
        }
1✔
1160

1161
        @Override
1162
        public boolean hasNext() {
1163
            pointer = null;
1✔
1164
            while (pointer == null) {
1✔
1165
                if (!edgeIterator.hasNext()) {
1✔
1166
                    return false;
1✔
1167
                }
1168
                pointer = (EdgeImpl) edgeIterator.next();
1✔
1169
                if (!view.containsEdge(pointer)) {
1✔
1170
                    pointer = null;
1✔
1171
                }
1172
            }
1173
            return true;
1✔
1174
        }
1175

1176
        @Override
1177
        public Edge next() {
1178
            return pointer;
1✔
1179
        }
1180

1181
        @Override
1182
        public void remove() {
1183
            checkWriteLock();
×
1184
            removeEdge(pointer);
×
1185
        }
×
1186
    }
1187

1188
    protected final class UndirectedEdgeViewIterator implements Iterator<Edge> {
1189

1190
        protected final Iterator<Edge> itr;
1191
        protected EdgeImpl pointer;
1192

1193
        public UndirectedEdgeViewIterator(Iterator<Edge> itr) {
1✔
1194
            this.itr = itr;
1✔
1195
        }
1✔
1196

1197
        @Override
1198
        public boolean hasNext() {
1199
            pointer = null;
1✔
1200
            while (pointer == null || !view.containsEdge(pointer) || isUndirectedToIgnore(pointer)) {
1✔
1201
                if (!itr.hasNext()) {
1✔
1202
                    return false;
1✔
1203
                }
1204
                pointer = (EdgeImpl) itr.next();
1✔
1205
            }
1206
            return true;
1✔
1207
        }
1208

1209
        @Override
1210
        public EdgeImpl next() {
1211
            return pointer;
1✔
1212
        }
1213

1214
        @Override
1215
        public void remove() {
1216
            itr.remove();
×
1217
        }
×
1218
    }
1219

1220
    protected static class NeighborsIterator implements Iterator<Node> {
1221

1222
        protected final NodeImpl node;
1223
        protected final Iterator<Edge> itr;
1224

1225
        public NeighborsIterator(NodeImpl node, Iterator<Edge> itr) {
1✔
1226
            this.node = node;
1✔
1227
            this.itr = itr;
1✔
1228
        }
1✔
1229

1230
        @Override
1231
        public boolean hasNext() {
1232
            return itr.hasNext();
1✔
1233
        }
1234

1235
        @Override
1236
        public Node next() {
1237
            Edge e = itr.next();
1✔
1238
            return e.getSource() == node ? e.getTarget() : e.getSource();
1✔
1239
        }
1240

1241
        @Override
1242
        public void remove() {
1243
            throw new UnsupportedOperationException("Remove not supported for this iterator");
×
1244
        }
1245
    }
1246
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc