kinow commented on code in PR #1752:
URL: https://github.com/apache/jena/pull/1752#discussion_r1105035106
##########
jena-arq/src/main/java/org/apache/jena/riot/other/G.java:
##########
@@ -845,4 +850,110 @@ public static <X> X calcTxn(Graph graph, Supplier<X>
action) {
return action.get();
}
+
+ /**
+ * Find triples and execute an action on each triple found.
+ */
+ public static void findExec(Graph graph, Consumer<Triple> action, Node s,
Node p , Node o) {
+ ExtendedIterator<Triple> eIter = G.find(graph, s, p, o);
+ try {
+ eIter.forEach(action);
+ } finally { eIter.close(); }
+ }
+
+ // From GraphUtils.
+
+ /** Add triples into the destination (arg 1) from the source (arg 2)*/
+ public static void addInto(Graph dstGraph, Graph srcGraph ) {
+ if ( dstGraph == srcGraph && ! dstGraph.getEventManager().listening() )
+ return ;
+ dstGraph.getPrefixMapping().setNsPrefixes(srcGraph.getPrefixMapping())
;
+ findExec(srcGraph, dstGraph::add, ANY, ANY, ANY);
+ dstGraph.getEventManager().notifyAddGraph( dstGraph, srcGraph );
+ }
+
+ private static void addIteratorWorker( Graph graph, Iterator<Triple> it ) {
+ List<Triple> s = IteratorCollection.iteratorToList( it );
+ addIteratorWorkerDirect(graph, s.iterator());
+ }
+
+ private static void addIteratorWorkerDirect( Graph graph, Iterator<Triple>
it ) {
+ it.forEachRemaining(graph::add);
+// if ( OldStyle && graph instanceof GraphWithPerform ) {
+// GraphWithPerform g = (GraphWithPerform)graph;
+// it.forEachRemaining(g::performAdd);
+// } else {
+// it.forEachRemaining(graph::add);
+// }
+ }
+
+ /**
+ * Test whether a graph contains by "same term", regardless of whether the
graph
+ * implements "same value" or "same term".
+ */
+ public static boolean containsBySameTerm(Graph graph, Triple triple) {
+ return containsBySameTerm(graph, triple.getSubject(),
triple.getPredicate(), triple.getObject());
+ }
+
+ /**
+ * Test whether a graph contains by "same term", regardless of whether the
graph
+ * implements "same value" or "same term".
+ */
+ public static boolean containsBySameTerm(Graph graph, Node s, Node p, Node
o) {
+ // Do direct for efficiency.
+ if ( ! graph.contains(s,p,o) )
+ return false;
+ // May have matched by value. Do a term test find to restrict to RDF
terms.
+ ExtendedIterator<Triple> iter = graph.find(s, p, o);
+ // Unless generalized RDF, only need to test object.
+ Predicate<Triple> predicate = (dataTriple) -> sameTermMatch(s, p, o,
dataTriple);
+ iter = iter.filterKeep(predicate);
+ try {
+ return iter.hasNext();
+ } finally { iter.close(); }
+
+// // For reference - just object
+// if ( !o.isConcrete() || o.isLiteral() ) {
+// Predicate<Triple> predicate = (t) -> sameTermMatch(o, t.getObject())
;
+// iter = iter.filterKeep(predicate) ;
+// }
+
+ }
+
+ /**
+ * Match a ground triple (even ANY and variables are considered ground
terms in the
+ * data triple) with S/P/O which can be wildcards (ANY or null).
+ */
+ public static boolean sameTermMatch(Node matchSubj, Node matchPred, Node
matchObj, Triple dataTriple) {
+ return sameTermMatch(matchSubj, dataTriple.getSubject()) &&
+ sameTermMatch(matchPred, dataTriple.getPredicate()) &&
+ sameTermMatch(matchObj, dataTriple.getObject());
+ }
+
+ /**
+ * Match a ground RDF Term (ANY and variables are considered ground terms
in the
+ * data term) with a node which can be a wildcard (ANY or null).
+ * Language tags compare case-insensitively.
+ */
+ public static boolean sameTermMatch(Node match, Node data) {
+ if ( false ) {
+ if ( match==null || Node.ANY.equals(match) )
+ return true;
+ // If lang tags are compared case-insensitively.
+ return match.equals(data);
+ }
+
+ // Allow for case-insensitive language tag comparison.
+ // Two literals.
+ if ( ! Util.isLangString(data) || ! Util.isLangString(match) )
+ // Not both strings with lang tags.
+ return (match==null) || (match == Node.ANY) || match.equals(data) ;
+
+ // Language tags compare case insensitively.
+ String lex1 = data.getLiteralLexicalForm();
+ String lex2 = data.getLiteralLexicalForm();
+ String lang1 = data.getLiteralLanguage();
+ String lang2 = data.getLiteralLanguage();
Review Comment:
Doing just a quick review as I don't know much about this part of the code
(and it's late) so this comment could be something silly, :bow:
@afs, won't `lex1` and `lex2` be identical? I haven't checked the code to
see if `getLiteralLexicalForm` will return a new object, but maybe one was
supposed to use `match` instead? Ditto for the `lang` vars?
##########
jena-arq/src/main/java/org/apache/jena/system/buffering/BufferingPrefixMapping.java:
##########
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.system.buffering;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.shared.impl.PrefixMappingImpl;
+
+/** A {@link PrefixMapping} that buffers changes until {@link #flush()} is
called. */
+public class BufferingPrefixMapping extends PrefixMappingImpl implements
BufferingCtl {
+
+ private static final boolean CHECK = false;
+ // Depends on the fact that PrefixMappingImpl maps everything
get/set/remove.
+ private final PrefixMapping added = new PrefixMappingImpl();
+ private final Set<String> deleted = new HashSet<>();
+ private final PrefixMapping other;
+
+ public BufferingPrefixMapping(PrefixMapping other) {
+ this.other = other;
+ }
+
+ public PrefixMapping base() { return other; }
+
+ @Override
+ public void flush() {
+ deleted.forEach(prefix->other.removeNsPrefix(prefix));
+ other.setNsPrefixes(added);
+
+ deleted.clear();
+ added.clearNsPrefixMap();
+ }
+
+ public PrefixMapping getAdded() {
+ return added;
+ }
+
+ public Set<String> getDeleted() {
+ return deleted;
+ }
+
+ @Override
+ protected void set(String prefix, String uri) {
+ if ( CHECK ) {
+ String u = other.getNsPrefixURI(prefix);
+ if ( uri.equals(u) )
+ return;
+ }
+ added.setNsPrefix(prefix, uri);
+ }
+
+ @Override
+ protected String get(String prefix) {
+ if ( deleted.contains(prefix) )
+ return null;
+ String uri = added.getNsPrefixURI(prefix);
+ if ( uri != null )
+ return uri;
+ return other.getNsPrefixURI(prefix);
+ }
+
+ @Override
+ protected void remove(String prefix) {
+ deleted.add(prefix);
+ added.removeNsPrefix(prefix);
+ }
+
+ @Override
+ public int numPrefixes() {
+ return added.numPrefixes() - deleted.size() + other.numPrefixes();
Review Comment:
Was curious if `numPrefixes` could return a negative value but I think
that's not possible (or at least I couldn't come up with a scenario for that).
What about concurrency? Is there any risk of `numPrefixes` accessing
`deleted.size()` while it's updated concurrently, and does it matter?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]