Skip to content

Package: PendingReferenceRegistry

PendingReferenceRegistry

nameinstructionbranchcomplexitylinemethod
PendingReferenceRegistry()
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addPendingAssertion(NamedResource, Assertion, Object, URI)
M: 12 C: 38
76%
M: 3 C: 5
63%
M: 3 C: 2
40%
M: 0 C: 8
100%
M: 0 C: 1
100%
addPendingListReference(Object, ListValueDescriptor, List)
M: 0 C: 41
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
getPendingResources()
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
hasPendingResources()
M: 0 C: 15
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$addPendingListReference$0(ListValueDescriptor, Integer)
M: 0 C: 10
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removeAndGetPendingListReferencesWith$1(ListValueDescriptor, Integer)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingListReferences$5(Map.Entry)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$2(NamedResource, PendingAssertion)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$3(Map.Entry)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$4(NamedResource, ListValueDescriptor)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$6(NamedResource, Assertion, PendingAssertion)
M: 0 C: 14
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$7(Map.Entry)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$removePendingReferences$8(NamedResource, Assertion, ListValueDescriptor)
M: 0 C: 14
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 1
100%
M: 0 C: 1
100%
removeAndGetPendingAssertionsWith(Object)
M: 4 C: 15
79%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 3
100%
M: 0 C: 1
100%
removeAndGetPendingListReferencesWith(Object)
M: 8 C: 62
89%
M: 2 C: 10
83%
M: 2 C: 5
71%
M: 0 C: 14
100%
M: 0 C: 1
100%
removePendingListReferences(Predicate)
M: 0 C: 58
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
removePendingReferences(NamedResource)
M: 4 C: 32
89%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 7
88%
M: 0 C: 1
100%
removePendingReferences(NamedResource, Assertion)
M: 5 C: 34
87%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 7
88%
M: 0 C: 1
100%
static {...}
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2020 Czech Technical University in Prague
3: * <p>
4: * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
5: * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
6: * version.
7: * <p>
8: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9: * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
10: * details. You should have received a copy of the GNU General Public License along with this program. If not, see
11: * <http://www.gnu.org/licenses/>.
12: */
13: package cz.cvut.kbss.jopa.oom;
14:
15: import cz.cvut.kbss.ontodriver.descriptor.ListValueDescriptor;
16: import cz.cvut.kbss.ontodriver.model.Assertion;
17: import cz.cvut.kbss.ontodriver.model.NamedResource;
18: import org.slf4j.Logger;
19: import org.slf4j.LoggerFactory;
20:
21: import java.net.URI;
22: import java.util.*;
23: import java.util.function.Predicate;
24:
25: /**
26: * Used to track references to unpersisted instances during transaction.
27: * <p>
28: * The general rule is that on commit, this registry must be empty.
29: */
30: class PendingReferenceRegistry {
31:
32: private static final Logger LOG = LoggerFactory.getLogger(PendingReferenceRegistry.class);
33:
34: private final Map<Object, Set<PendingAssertion>> pendingAssertions = new IdentityHashMap<>();
35:
36: private Map<Object, Set<PendingListReference>> pendingLists;
37: /**
38: * Counts number of pending items per each list
39: */
40: private Map<ListValueDescriptor, Integer> pendingListItems;
41:
42: /**
43: * Registers a new pending assertion.
44: *
45: * @param owner Subject of the assertion
46: * @param assertion The assertion representation
47: * @param object The value of the assertion. Always an individual identifier
48: * @param context Context into which the assertion will be added
49: */
50: void addPendingAssertion(NamedResource owner, Assertion assertion, Object object, URI context) {
51:• assert owner != null;
52:• assert assertion != null;
53:• assert object != null;
54:
55: final PendingAssertion pa = new PendingAssertion(owner, assertion, context);
56:• if (!pendingAssertions.containsKey(object)) {
57: pendingAssertions.put(object, new HashSet<>());
58: }
59: pendingAssertions.get(object).add(pa);
60: }
61:
62: /**
63: * Registers a pending reference to a sequence (simple or referenced).
64: *
65: * @param item The pending (unpersisted) item
66: * @param valueDescriptor Descriptor containing info about list owner, linking property etc.
67: * @param values Values of the sequence
68: */
69: void addPendingListReference(Object item, ListValueDescriptor valueDescriptor, List<?> values) {
70:• if (pendingLists == null) {
71: this.pendingLists = new IdentityHashMap<>();
72: this.pendingListItems = new HashMap<>();
73: }
74: pendingLists.putIfAbsent(item, new HashSet<>());
75: pendingLists.get(item).add(new PendingListReference(valueDescriptor, values));
76:• pendingListItems.compute(valueDescriptor, (k, v) -> v == null ? 1 : v + 1);
77: }
78:
79: /**
80: * Removes any pending persists with the specified object (value of the assertion).
81: *
82: * @param object Object which is no longer considered pending, so all assertions referencing it should be removed
83: * from this registry
84: */
85: Set<PendingAssertion> removeAndGetPendingAssertionsWith(Object object) {
86:• assert object != null;
87: final Set<PendingAssertion> pending = pendingAssertions.remove(object);
88:• return pending != null ? pending : Collections.emptySet();
89: }
90:
91: Set<PendingListReference> removeAndGetPendingListReferencesWith(Object object) {
92:• assert object != null;
93:• final Set<PendingListReference> refs = pendingLists == null ? null : pendingLists.remove(object);
94:• if (refs == null) {
95: return Collections.emptySet();
96: }
97: final Iterator<PendingListReference> it = refs.iterator();
98:• while (it.hasNext()) {
99: final PendingListReference ref = it.next();
100:• assert pendingListItems.get(ref.descriptor) != null;
101: pendingListItems.compute(ref.descriptor, (k, v) -> v - 1);
102:• if (pendingListItems.get(ref.descriptor) == 0) {
103: pendingListItems.remove(ref.descriptor);
104: } else {
105: it.remove();
106: }
107: }
108: return refs;
109: }
110:
111: Set<Object> getPendingResources() {
112: final Set<Object> pending = new HashSet<>(pendingAssertions.keySet());
113:• if (pendingLists != null) {
114: pending.addAll(pendingLists.keySet());
115: }
116: return pending;
117: }
118:
119: boolean hasPendingResources() {
120:• return !pendingAssertions.isEmpty() || pendingLists != null && !pendingLists.isEmpty();
121: }
122:
123: /**
124: * Removes all pending assertions which have the same subject (owner).
125: *
126: * @param subject The subject of assertions to remove
127: */
128: void removePendingReferences(NamedResource subject) {
129:• if (LOG.isTraceEnabled()) {
130: LOG.trace("Removing pending assertions for subject {}.", subject);
131: }
132:• for (Set<PendingAssertion> pending : pendingAssertions.values()) {
133: pending.removeIf(item -> item.getOwner().equals(subject));
134: }
135: pendingAssertions.entrySet().removeIf(e -> e.getValue().isEmpty());
136: removePendingListReferences(desc -> desc.getListOwner().equals(subject));
137: }
138:
139: private void removePendingListReferences(Predicate<ListValueDescriptor> condition) {
140:• if (pendingLists == null) {
141: return;
142: }
143: final Set<ListValueDescriptor> removed = new HashSet<>();
144:• for (Set<PendingListReference> pending : pendingLists.values()) {
145: final Iterator<PendingListReference> it = pending.iterator();
146:• while (it.hasNext()) {
147: final ListValueDescriptor desc = it.next().descriptor;
148:• if (condition.test(desc)) {
149: it.remove();
150: removed.add(desc);
151: }
152: }
153: }
154: pendingLists.entrySet().removeIf(e -> e.getValue().isEmpty());
155: removed.forEach(pendingListItems::remove);
156: }
157:
158: /**
159: * Removes pending references representing the specified assertion about the specified subject.
160: *
161: * @param subject Assertion subject
162: * @param assertion The assertion
163: */
164: void removePendingReferences(NamedResource subject, Assertion assertion) {
165:• if (LOG.isTraceEnabled()) {
166: LOG.trace("Removing pending assertions {} for subject {}.", assertion, subject);
167: }
168:• for (Set<PendingAssertion> pending : pendingAssertions.values()) {
169:• pending.removeIf(item -> item.getOwner().equals(subject) && item.getAssertion().equals(assertion));
170: }
171: pendingAssertions.entrySet().removeIf(e -> e.getValue().isEmpty());
172: removePendingListReferences(
173:• desc -> desc.getListOwner().equals(subject) && desc.getListProperty().equals(assertion));
174: }
175:
176: static class PendingListReference {
177: private final ListValueDescriptor descriptor;
178: private final List<?> values;
179:
180: private PendingListReference(ListValueDescriptor descriptor, List<?> values) {
181: this.descriptor = descriptor;
182: this.values = values;
183: }
184:
185: public ListValueDescriptor getDescriptor() {
186: return descriptor;
187: }
188:
189: public List<?> getValues() {
190: return values;
191: }
192: }
193: }