From 9d4a6ed5dfb1d8c5aaf78a878220b367f41422c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Fri, 12 Jul 2019 13:18:55 +0200 Subject: [PATCH] https://github.com/eclipse/rdf4j/issues/1441 switched to LinkedHashModel and also fixed size for LinkedHashModel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: HaĚŠvard Ottestad --- .../rdf4j/model/impl/LinkedHashModel.java | 55 ++++++++++++------- .../org/eclipse/rdf4j/model/util/Models.java | 16 ++++-- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModel.java b/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModel.java index 2906e501f6e..516fc16fcee 100644 --- a/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModel.java +++ b/model/src/main/java/org/eclipse/rdf4j/model/impl/LinkedHashModel.java @@ -7,6 +7,14 @@ *******************************************************************************/ package org.eclipse.rdf4j.model.impl; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.Namespace; +import org.eclipse.rdf4j.model.Resource; +import org.eclipse.rdf4j.model.Statement; +import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.model.util.PatternIterator; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -20,14 +28,6 @@ import java.util.Optional; import java.util.Set; -import org.eclipse.rdf4j.model.IRI; -import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.model.Namespace; -import org.eclipse.rdf4j.model.Resource; -import org.eclipse.rdf4j.model.Statement; -import org.eclipse.rdf4j.model.Value; -import org.eclipse.rdf4j.model.util.PatternIterator; - /** * Hash table based implementation of the {@link Model} interface. *

@@ -43,11 +43,11 @@ * unsynchronized access to the LinkedHashModel instance (though the synchronization guarantee is only when accessing * via the Set interface methods): *

- * + * *
  * Set s = Collections.synchronizedSet(new LinkedHashModel(...));
  * 
- * + * * @author James Leigh */ @SuppressWarnings("unchecked") @@ -79,8 +79,12 @@ public LinkedHashModel(Collection c) { public LinkedHashModel(int size) { super(); - values = new HashMap<>(size * 2); - statements = new LinkedHashSet<>(size); + + // assume fewer unique values than statements (eg. some reuse of nodes instatements) + values = new HashMap<>(size, 0.75f); + + // compensate for the loadfactor by multiplying by 2 + statements = new LinkedHashSet<>(size * 2, 0.75f); } public LinkedHashModel(Set namespaces, Collection c) { @@ -143,8 +147,9 @@ public int size() { @Override public boolean add(Resource subj, IRI pred, Value obj, Resource... contexts) { - if (subj == null || pred == null || obj == null) + if (subj == null || pred == null || obj == null) { throw new UnsupportedOperationException("Incomplete statement"); + } Value[] ctxs = notNull(contexts); if (ctxs.length == 0) { ctxs = NULL_CTX; @@ -391,12 +396,15 @@ public Resource getContext() { @Override public boolean equals(Object other) { - if (this == other) + if (this == other) { return true; - if (!super.equals(other)) + } + if (!super.equals(other)) { return false; - if (getContext() == null) + } + if (getContext() == null) { return ((Statement) other).getContext() == null; + } return getContext().equals(((Statement) other).getContext()); } } @@ -444,23 +452,27 @@ private Set choose(Resource subj, IRI pred, Value obj, Resource. Set p = null; Set o = null; if (subj != null) { - if (!values.containsKey(subj)) + if (!values.containsKey(subj)) { return Collections.emptySet(); + } s = values.get(subj).subjects; } if (pred != null) { - if (!values.containsKey(pred)) + if (!values.containsKey(pred)) { return Collections.emptySet(); + } p = values.get(pred).predicates; } if (obj != null) { - if (!values.containsKey(obj)) + if (!values.containsKey(obj)) { return Collections.emptySet(); + } o = values.get(obj).objects; } if (contexts.length == 1) { - if (!values.containsKey(contexts[0])) + if (!values.containsKey(contexts[0])) { return Collections.emptySet(); + } Set c = values.get(contexts[0]).contexts; return smallest(statements, s, p, o, c); } else { @@ -513,8 +525,9 @@ private Set smallest(Set... sets) { private ModelNode asNode(V value) { ModelNode node = values.get(value); - if (node != null) + if (node != null) { return node; + } node = new ModelNode<>(value); values.put(value, node); return node; diff --git a/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java b/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java index 965dfd6e3f7..306ff766133 100644 --- a/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java +++ b/model/src/main/java/org/eclipse/rdf4j/model/util/Models.java @@ -15,7 +15,7 @@ import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.URI; import org.eclipse.rdf4j.model.Value; -import org.eclipse.rdf4j.model.impl.TreeModel; +import org.eclipse.rdf4j.model.impl.LinkedHashModel; import java.util.ArrayDeque; import java.util.ArrayList; @@ -782,7 +782,7 @@ private static boolean statementsMatch(Statement st1, Statement st2, Map iterable) { if (iterable instanceof Model) { return (Model) iterable; } - final Model set = new TreeModel(); - StreamSupport.stream(iterable.spliterator(), false).filter(Objects::nonNull).forEach(st -> set.add(st)); + + final Model set; + if (iterable instanceof List) { + int size = ((List) iterable).size(); + set = new LinkedHashModel(size); + } else { + set = new LinkedHashModel(); + } + + StreamSupport.stream(iterable.spliterator(), false).filter(Objects::nonNull).forEach(set::add); return set; }