You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2013/03/30 19:49:18 UTC
svn commit: r1462840 - in /jena/trunk/jena-arq/src:
main/java/org/apache/jena/riot/lang/ main/java/org/apache/jena/riot/out/
main/java/org/apache/jena/riot/system/ test/java/org/apache/jena/riot/lang/
Author: andy
Date: Sat Mar 30 18:49:17 2013
New Revision: 1462840
URL: http://svn.apache.org/r1462840
Log:
JENA-352 : Produce blank node ids based on large randon seed and the per-parser-run label.
Added:
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocator.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorHash.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestNodeToLabel.java
Modified:
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/out/NodeToLabel.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/MapWithScope.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/SyntaxLabels.java
jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TS_Lang.java
Added: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocator.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocator.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocator.java (added)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocator.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,40 @@
+/**
+ * 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.riot.lang;
+
+import com.hp.hpl.jena.graph.Node ;
+
+/** Interface to allocators for blank nodes. */
+public interface BlankNodeAllocator
+{
+ /** Allocate based on a non-null label.
+ * Calling this twice, with the same label will generate equivalent nodes
+ * but they may not be identicial (i.e they are .equals but may not be ==)
+ */
+ public Node alloc(String label) ;
+
+ /** Create a fresh blank node, different from anythign generated so far.
+ * Will not clash with a node allocated by {@linkplain #alloc}
+ */
+ public Node create() ;
+
+ /** Reset allocation state - calls to {@linkplain #alloc} or {@linkplain #create} */
+ public void reset() ;
+}
+
Added: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorHash.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorHash.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorHash.java (added)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorHash.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,109 @@
+/**
+ * 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.riot.lang;
+
+import java.security.MessageDigest ;
+import java.security.NoSuchAlgorithmException ;
+import java.util.UUID ;
+
+import org.apache.jena.atlas.lib.Bytes ;
+import org.apache.jena.atlas.lib.Cache ;
+import org.apache.jena.atlas.lib.CacheFactory ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
+import org.apache.jena.atlas.lib.cache.Getter ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+import com.hp.hpl.jena.rdf.model.AnonId ;
+
+/** Allocate bnode labels using a per-run seed and the label presented.
+ * <p>
+ * This is the most scalable, always legal allocator.
+ * <p>
+ * New allocators must be created per parser run, or .reset() called.
+ * These are fed to a digest to gve a bit string, (currently MD5, to get a 128bit bit string)
+ * that is used to form a bNode AnonId of hex digits.
+ * <p>
+ * In addition there is a cache of label->node allocations,
+ * using the natural tendendency to locality in a database dump.
+ * (subject bNodes, bNodes in lists and other datavalues structures like
+ * unit values).
+ * <p>
+ * Not thread safe.
+ */
+
+public class BlankNodeAllocatorHash implements BlankNodeAllocator
+{
+ private static String DigestAlgorithm = "MD5" ;
+ private static int CacheSize = 1000 ;
+ private MessageDigest mDigest ;
+ private byte[] seedBytes ;
+ private byte[] counterBytes = new byte[10] ; // long+2 bytes to distinguish from UTF-8 bytes.
+ private Cache<String, Node> cache ;
+ private long counter = 0 ;
+
+ public BlankNodeAllocatorHash()
+ {
+ reset() ;
+ try { mDigest = MessageDigest.getInstance(DigestAlgorithm) ; }
+ catch (NoSuchAlgorithmException e) { throw new InternalErrorException("failed to create message digest", e) ; }
+
+ Getter<String, Node> getter = new Getter<String, Node>() {
+ @Override public Node get(String key) { return alloc(key) ; }
+ } ;
+ Cache<String, Node> cache1 = CacheFactory.createCache(CacheSize) ;
+ cache = CacheFactory.createCacheWithGetter(cache1, getter) ;
+ }
+
+ @Override
+ public void reset()
+ {
+ UUID seed = UUID.randomUUID() ;
+ seedBytes = new byte[128/8] ;
+ Bytes.setLong(seed.getMostSignificantBits(), seedBytes, 0) ;
+ Bytes.setLong(seed.getLeastSignificantBits(), seedBytes, 8) ;
+ }
+
+ @Override
+ public Node alloc(String label)
+ {
+ return alloc(Bytes.string2bytes(label)) ;
+ }
+
+
+ @Override
+ public Node create()
+ {
+ counter++ ;
+ // Make illegal string bytes so can't clash with alloc(String)
+ counterBytes[0] = 0 ;
+ counterBytes[1] = 0 ;
+ Bytes.setLong(counter, counterBytes, 2) ;
+ return alloc(counterBytes) ;
+ }
+
+ private Node alloc(byte[] labelBytes)
+ {
+ mDigest.update(seedBytes) ;
+ mDigest.update(labelBytes) ;
+ byte[] bytes = mDigest.digest() ; // resets
+ String hexString = Bytes.asHexLC(bytes) ;
+ return NodeFactory.createAnon(new AnonId(hexString)) ;
+ }
+}
Added: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java (added)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/BlankNodeAllocatorTraditional.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,59 @@
+/**
+ * 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.riot.lang;
+
+import java.util.HashMap ;
+import java.util.Map ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+
+/** Allocate blank ndoes according to the traditional policy (to jena 2.10.0)
+ * This allocator has arbitrary sized state.
+ * Create a fresh one for each parser run.
+ */
+
+public class BlankNodeAllocatorTraditional implements BlankNodeAllocator
+{
+ Map<String, Node> map = new HashMap<String, Node>() ;
+
+ public BlankNodeAllocatorTraditional() {}
+
+ @Override
+ public void reset() { map.clear() ; }
+
+ @Override
+ public Node alloc(String label)
+ {
+ Node b = map.get(label) ;
+ if ( b == null )
+ {
+ b = create() ;
+ map.put(label, b) ;
+ }
+ return b ;
+ }
+
+
+ @Override
+ public Node create()
+ {
+ return NodeFactory.createAnon() ;
+ }
+}
Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/lang/LabelToNode.java Sat Mar 30 18:49:17 2013
@@ -21,6 +21,7 @@ import static java.lang.String.format ;
import java.util.HashMap ;
import java.util.Map ;
+import java.util.concurrent.atomic.AtomicLong ;
import org.apache.jena.riot.SysRIOT ;
import org.apache.jena.riot.out.NodeFmtLib ;
@@ -43,6 +44,9 @@ public class LabelToNode extends MapWith
public static LabelToNode createScopeByDocument()
{ return new LabelToNode(new SingleScopePolicy(), nodeMaker) ; }
+ public static LabelToNode createScopeByDocumentHash()
+ { return new LabelToNode(new AllocScopePolicy(), new AllocNodeHash()) ; }
+
/** Allocation scoped by graph and label. */
public static LabelToNode createScopeByGraph()
{ return new LabelToNode(new GraphScopePolicy(), nodeMaker) ; }
@@ -101,7 +105,9 @@ public class LabelToNode extends MapWith
return x ;
}
@Override
- public void clear() { map.clear(); }
+ public void clear() {
+ dftMap.clear() ;
+ map.clear(); }
}
/** No scope - use raw allocator */
@@ -114,62 +120,86 @@ public class LabelToNode extends MapWith
}
- // ======== Node Allocators
+ // ======== Node Allocators
+
+ // TODO Switch to BlankNodeAllocator and a singel wrapper.
+ // variables if the allocator is reusable across runs
+ // classes if a new one is needed each time.
+ // Shared ones must be thread-safe.
+
+
+ /** Allocate bnode labels using a per-run see and the label presented.
+ * This is the most scalable, always legal allocator.
+ * Not thread safe - not reusable.
+ * Create a new allocator for each parser run.
+ */
+ private static class AllocNodeHash implements Allocator<String, Node> {
+ private BlankNodeAllocator alloc = new BlankNodeAllocatorHash() ;
+
+ @Override public Node alloc(String label) { return alloc.alloc(label) ; }
+ @Override public Node create() { return alloc.create() ; }
+ @Override public void reset() { alloc.reset() ; }
+ } ;
private static Allocator<String, Node> nodeMaker = new Allocator<String, Node>()
{
- @Override
- public Node create(String label)
- { return NodeFactory.createAnon() ; }
+ @Override public Node alloc(String label) { return create() ;}
- @Override
- public void reset() {}
+ @Override public Node create() { return NodeFactory.createAnon() ; }
+
+ @Override public void reset() {}
} ;
private static Allocator<String, Node> nodeMakerDeterministic = new Allocator<String, Node>()
{
- private long counter = 0 ;
+ private AtomicLong counter = new AtomicLong(0) ;
@Override
- public Node create(String label)
+ public Node alloc(String label)
+ {
+ return create() ;
+ }
+
+ @Override public Node create()
{
- String $ = format("B0x%04X", ++counter) ;
+ String $ = format("B0x%04X", counter.incrementAndGet()) ;
return NodeFactory.createAnon(new AnonId($)) ;
}
+
@Override
public void reset() {}
} ;
private static Allocator<String, Node> nodeMakerByLabel = new Allocator<String, Node>()
{
- private long counter = 0 ;
+ private AtomicLong counter = new AtomicLong(0) ;
@Override
- public Node create(String label)
+ public Node alloc(String label)
{
- if ( label == null )
- label = SysRIOT.BNodeGenIdPrefix+counter++ ;
return NodeFactory.createAnon(new AnonId(label)) ;
}
+ @Override public Node create() { return alloc(SysRIOT.BNodeGenIdPrefix+(counter.getAndIncrement())) ; }
+
@Override
public void reset() {}
} ;
private static Allocator<String, Node> nodeMakerByLabelEncoded = new Allocator<String, Node>()
{
- private long counter = 0 ;
+ private AtomicLong counter = new AtomicLong(0) ;
@Override
- public Node create(String label)
+ public Node alloc(String label)
{
- if ( label == null )
- label = SysRIOT.BNodeGenIdPrefix+counter++ ;
return NodeFactory.createAnon(new AnonId(NodeFmtLib.decodeBNodeLabel(label))) ;
}
+ @Override public Node create() { return alloc(SysRIOT.BNodeGenIdPrefix+(counter.getAndIncrement())) ; }
@Override
+
public void reset() {}
} ;
}
Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/out/NodeToLabel.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/out/NodeToLabel.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/out/NodeToLabel.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/out/NodeToLabel.java Sat Mar 30 18:49:17 2013
@@ -21,6 +21,7 @@ package org.apache.jena.riot.out;
import java.util.HashMap ;
import java.util.Map ;
+import org.apache.jena.atlas.lib.InternalErrorException ;
import org.apache.jena.riot.system.MapWithScope ;
import org.apache.jena.riot.system.SyntaxLabels ;
@@ -56,7 +57,6 @@ public class NodeToLabel extends MapWith
private static final NodeToLabel _internal = createBNodeByLabelEncoded() ;
public static NodeToLabel labelByInternal() { return _internal ; }
-
private NodeToLabel(ScopePolicy<Node, String, Node> scopePolicy, Allocator<Node, String> allocator)
{
@@ -106,14 +106,21 @@ public class NodeToLabel extends MapWith
private long counter = 0 ;
@Override
- public final String create(Node node)
+ public final String alloc(Node node)
{
if ( node.isURI() ) return labelForURI(node) ;
if ( node.isLiteral() ) return labelForLiteral(node) ;
if ( node.isBlank() ) return labelForBlank(node) ;
if ( node.isVariable() ) return labelForVar(node) ;
-
- // Other??
+ throw new InternalErrorException("Node type not supported: "+node) ;
+ }
+
+ @Override
+ public final String create() { return labelCreate() ; }
+
+ // Just return a fresh label.
+ protected String labelCreate()
+ {
return Long.toString(counter++) ;
}
Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/MapWithScope.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/MapWithScope.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/MapWithScope.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/MapWithScope.java Sat Mar 30 18:49:17 2013
@@ -27,15 +27,25 @@ public class MapWithScope<A, B, S>
{
// ======== Interfaces
- protected interface ScopePolicy<A, B, S>
+ public interface ScopePolicy<A, B, S>
{
Map<A, B> getScope(S scope) ;
void clear() ;
}
-
- protected interface Allocator<A,B>
+
+ /** Allocate a B, given some A.
+ * Only called once per instance of B if the ScopePolicy map is non-null.
+ */
+ public interface Allocator<A,B>
{
- public B create(A item) ;
+ /** Allocate - return the same B for a given A.
+ * "same" means .equals, not ==
+ */
+ public B alloc(A item) ;
+
+ /** Create a fresh, unique (to within policy) B */
+ public B create() ;
+
public void reset() ;
}
@@ -59,19 +69,19 @@ public class MapWithScope<A, B, S>
Map<A, B> map = scopePolicy.getScope(scope) ;
if ( map == null )
// No map - no item->allocation tracking.
- return allocator.create(item) ;
+ return allocator.alloc(item) ;
B mappedItem = map.get(item) ;
if ( mappedItem == null )
{
- mappedItem = allocator.create(item) ;
+ mappedItem = allocator.alloc(item) ;
map.put(item, mappedItem) ;
}
return mappedItem ;
}
/** Create a label that is guaranteed to be fresh */
- public B create() { return allocator.create(null) ; }
+ public B create() { return allocator.create() ; }
/** Clear scope and allocation */
public void clear() { scopePolicy.clear() ; allocator.reset() ; }
Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/RiotLib.java Sat Mar 30 18:49:17 2013
@@ -133,7 +133,7 @@ public class RiotLib
public static ParserProfile profile(String baseIRI, boolean resolveIRIs, boolean checking, ErrorHandler handler)
{
LabelToNode labelToNode = true
- ? LabelToNode.createScopeByDocument() // SyntaxLabels.createNodeToLabel()
+ ? SyntaxLabels.createLabelToNode()
: LabelToNode.createUseLabelEncoded() ;
Prologue prologue ;
Modified: jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/SyntaxLabels.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/SyntaxLabels.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/SyntaxLabels.java (original)
+++ jena/trunk/jena-arq/src/main/java/org/apache/jena/riot/system/SyntaxLabels.java Sat Mar 30 18:49:17 2013
@@ -21,10 +21,15 @@ package org.apache.jena.riot.system;
import org.apache.jena.riot.lang.LabelToNode ;
import org.apache.jena.riot.out.NodeToLabel ;
-/** Factory for default policies for syntax labels to and from nodes */
+/** Factory for default policies for syntax labels to and from nodes
+ * For label to node (parsing) we use a scalable hashing scheme (MD5 of a seed and the label)
+ *
+ * For node to label (pretty labels output), we use a unique tracking scheme.
+ * Fully scalable writers use different polices and don't have short, pretty bNode labels.
+ */
public class SyntaxLabels
{
/** Default setup - scope by document, relabel BNodes ids to short forms */
static public NodeToLabel createNodeToLabel() { return NodeToLabel.createScopeByDocument() ; }
- static public LabelToNode createLabelToNode() { return LabelToNode.createScopeByDocument() ; }
+ static public LabelToNode createLabelToNode() { return LabelToNode.createScopeByDocumentHash() ; }
}
Modified: jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TS_Lang.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TS_Lang.java?rev=1462840&r1=1462839&r2=1462840&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TS_Lang.java (original)
+++ jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TS_Lang.java Sat Mar 30 18:49:17 2013
@@ -28,7 +28,10 @@ import org.junit.runners.Suite ;
@Suite.SuiteClasses( {
TestIRI.class
, TestLang.class
- , TestNodeAllocator.class
+ , TestBlankNodeAllocator.class
+ , TestNodeAllocator.class // Older tests
+ , TestLabelToNode.class // Newer tests
+ , TestNodeToLabel.class
, TestTurtleTerms.class
, TestLangNTriples.class
, TestLangNQuads.class
@@ -37,6 +40,7 @@ import org.junit.runners.Suite ;
, TestLangRdfJson.class
, TestParserFactory.class
, TestPipedRDFIterators.class
+
})
Added: jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java (added)
+++ jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestBlankNodeAllocator.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,90 @@
+/**
+ * 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.riot.lang;
+
+import java.util.ArrayList ;
+import java.util.List ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.junit.Test ;
+import org.junit.runner.RunWith ;
+import org.junit.runners.Parameterized ;
+import org.junit.runners.Parameterized.Parameters ;
+
+import com.hp.hpl.jena.graph.Node ;
+
+@RunWith(Parameterized.class)
+public class TestBlankNodeAllocator extends BaseTest
+{
+ public interface Factory { public BlankNodeAllocator create() ; }
+
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> data() {
+ List<Object[]> x = new ArrayList<Object[]>() ;
+ Factory fSeededHashAlloc = new Factory() {
+ @Override public BlankNodeAllocator create() { return new BlankNodeAllocatorHash() ; }
+ @Override public String toString() { return "SeededHash" ; }
+ } ;
+
+ Factory fUIDAlloc = new Factory() {
+ @Override public BlankNodeAllocator create() { return new BlankNodeAllocatorTraditional() ; }
+ @Override public String toString() { return "UID" ; }
+ } ;
+
+ x.add(new Object[]{fSeededHashAlloc}) ;
+ x.add(new Object[]{fUIDAlloc}) ;
+ return x ;
+ }
+
+ private Factory factory ;
+
+ public TestBlankNodeAllocator(Factory factory) { this.factory = factory ; }
+
+ @Test public void alloc_01()
+ {
+ BlankNodeAllocator alloc = factory.create() ;
+ Node n = alloc.create() ;
+ assertTrue(n.isBlank()) ;
+ }
+
+ @Test public void alloc_02()
+ {
+ BlankNodeAllocator alloc = factory.create() ;
+ Node n1 = alloc.create() ;
+ Node n2 = alloc.create() ;
+ assertNotEquals(n1, n2) ;
+ }
+
+ @Test public void alloc_03()
+ {
+ BlankNodeAllocator alloc = factory.create() ;
+ Node n1 = alloc.alloc("foo") ;
+ Node n2 = alloc.alloc("foo") ;
+ assertEquals(n1, n2) ;
+ }
+
+ @Test public void alloc_04()
+ {
+ BlankNodeAllocator alloc = factory.create() ;
+ Node n1 = alloc.alloc("foo") ;
+ Node n2 = alloc.alloc("bar") ;
+ assertNotEquals(n1, n2) ;
+ }
+}
+
Added: jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java (added)
+++ jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestLabelToNode.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,232 @@
+/**
+ * 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.riot.lang;
+
+import java.util.ArrayList ;
+import java.util.List ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.riot.system.SyntaxLabels ;
+import org.junit.Test ;
+import org.junit.runner.RunWith ;
+import org.junit.runners.Parameterized ;
+import org.junit.runners.Parameterized.Parameters ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+
+@RunWith(Parameterized.class)
+public class TestLabelToNode extends BaseTest
+{
+ // See also TestNodeAlloc
+
+ public interface LabelToNodeFactory { public LabelToNode create() ; }
+
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> data() {
+ List<Object[]> x = new ArrayList<Object[]>() ;
+ LabelToNodeFactory fSyntaxLabels = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return SyntaxLabels.createLabelToNode() ; }
+ @Override public String toString() { return "SyntaxLabels.createLabelToNode" ; }
+ } ;
+
+ LabelToNodeFactory fScopeByDocument = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createScopeByDocument() ; }
+ @Override public String toString() { return "ScopeByDocument" ; }
+ } ;
+ LabelToNodeFactory fScopeByGraph = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createScopeByGraph() ; }
+ @Override public String toString() { return "ScopeByGraph" ; }
+ } ;
+ LabelToNodeFactory fUseLabelAsGiven = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createUseLabelAsGiven() ; }
+ @Override public String toString() { return "UseLabelAsGiven" ; }
+ } ;
+ LabelToNodeFactory fUseLabelEncoded = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createUseLabelEncoded() ; }
+ @Override public String toString() { return "UseLabelEncoded" ; }
+ } ;
+ LabelToNodeFactory fIncremental = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createIncremental() ; }
+ @Override public String toString() { return "Incremental" ; }
+ } ;
+
+ LabelToNodeFactory fScopeDocumentHash = new LabelToNodeFactory() {
+ @Override public LabelToNode create() { return LabelToNode.createScopeByDocumentHash() ; }
+ @Override public String toString() { return "ScopeByDocumentHash" ; }
+ } ;
+
+ // (1) Factory, whether DocScoped, (2) whether unique in a document (or graph) (3) whether unique per run
+ x.add(new Object[]{fSyntaxLabels, true, true}) ;
+ x.add(new Object[]{fScopeByDocument, true, true}) ;
+ x.add(new Object[]{fScopeByGraph, false, true}) ;
+ x.add(new Object[]{fUseLabelAsGiven, true, false}) ;
+ x.add(new Object[]{fUseLabelEncoded, true, false}) ;
+ x.add(new Object[]{fIncremental, true, true}) ;
+ x.add(new Object[]{fScopeDocumentHash, true, true}) ;
+ return x ;
+ }
+
+ private LabelToNodeFactory factory ;
+ private Boolean unique ;
+ private Boolean docScope ;
+
+ public TestLabelToNode(LabelToNodeFactory factory, Boolean docScope, Boolean unique)
+ {
+ this.factory = factory ;
+ this.docScope = docScope ; // Does this LabelToNode obey the per-document uniqueness?
+ this.unique = unique ; // Does this LabelToNode give uniqueness per initialization?
+ }
+
+ @Test public void label2node_Create1()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n = mapper.create() ;
+ assertNotNull(n) ;
+ }
+
+ @Test public void label2node_Create2()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.create() ;
+ Node n2 = mapper.create() ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertNotEquals(n1, n2) ;
+ }
+
+ @Test public void label2node_Create3()
+ {
+ LabelToNode mapper1 = factory.create() ;
+ LabelToNode mapper2 = factory.create() ;
+ assertNotEquals(mapper1, mapper2) ;
+ Node n1 = mapper1.create() ;
+ Node n2 = mapper2.create() ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertNotEquals(n1, n2) ;
+ }
+
+ @Test public void label2node_Label1()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n = mapper.get(null, "label") ;
+ assertNotNull(n) ;
+ }
+
+ @Test public void label2node_Label2()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(null, "label1") ;
+ Node n2 = mapper.get(null, "label2") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertNotEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Label3()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(null, "label1") ;
+ Node n2 = mapper.get(null, "label1") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Label4()
+ {
+ Node g = NodeFactory.createURI("g") ;
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(g, "label1") ;
+ Node n2 = mapper.get(g, "label1") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Label5()
+ {
+ Node g1 = NodeFactory.createURI("g1") ;
+ Node g2 = NodeFactory.createURI("g2") ;
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(g1, "label1") ;
+ Node n2 = mapper.get(g2, "label1") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ if ( docScope )
+ assertEquals(n1,n2) ;
+ else
+ assertNotEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Label6()
+ {
+ Node g = NodeFactory.createURI("g") ;
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(g, "label1") ;
+ Node n2 = mapper.get(null, "label1") ;
+ if ( docScope )
+ assertEquals(n1,n2) ;
+ else
+ assertNotEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Label7()
+ {
+ Node g1 = NodeFactory.createURI("g1") ;
+ Node g2 = NodeFactory.createURI("g1") ;
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(g1, "label1") ;
+ Node n2 = mapper.get(g2, "label2") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ assertNotEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Reset1()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node n1 = mapper.get(null, "label1") ;
+ mapper.clear() ;
+ Node n2 = mapper.get(null, "label1") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ if ( unique )
+ assertNotEquals(n1,n2) ;
+ else
+ assertEquals(n1,n2) ;
+ }
+
+ @Test public void label2node_Reset2()
+ {
+ LabelToNode mapper = factory.create() ;
+ Node g = NodeFactory.createURI("g") ;
+ Node n1 = mapper.get(g, "label1") ;
+ mapper.clear() ;
+ Node n2 = mapper.get(g, "label1") ;
+ assertNotNull(n1) ;
+ assertNotNull(n2) ;
+ if ( unique )
+ assertNotEquals(n1,n2) ;
+ else
+ assertEquals(n1,n2) ;
+ }
+}
+
Added: jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestNodeToLabel.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestNodeToLabel.java?rev=1462840&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestNodeToLabel.java (added)
+++ jena/trunk/jena-arq/src/test/java/org/apache/jena/riot/lang/TestNodeToLabel.java Sat Mar 30 18:49:17 2013
@@ -0,0 +1,113 @@
+/**
+ * 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.riot.lang;
+
+import java.util.ArrayList ;
+import java.util.List ;
+
+import org.apache.jena.atlas.junit.BaseTest ;
+import org.apache.jena.riot.out.NodeToLabel ;
+import org.apache.jena.riot.system.SyntaxLabels ;
+import org.junit.Test ;
+import org.junit.runner.RunWith ;
+import org.junit.runners.Parameterized ;
+import org.junit.runners.Parameterized.Parameters ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+
+@RunWith(Parameterized.class)
+public class TestNodeToLabel extends BaseTest
+{
+ public interface NodeToLabelFactory { public NodeToLabel create() ; }
+
+ @Parameters(name = "{index}: {0}")
+ public static Iterable<Object[]> data() {
+ List<Object[]> x = new ArrayList<Object[]>() ;
+
+ NodeToLabelFactory f0 = new NodeToLabelFactory() {
+ @Override public NodeToLabel create() { return SyntaxLabels.createNodeToLabel() ; }
+ @Override public String toString() { return "SyntaxLabels.createNodeToLabel" ; }
+ } ;
+ NodeToLabelFactory f1 = new NodeToLabelFactory() {
+ @Override public NodeToLabel create() { return NodeToLabel.createBNodeByIRI() ; }
+ @Override public String toString() { return "NodeToLabel.createBNodeByIRI()" ; }
+ } ;
+ NodeToLabelFactory f2 = new NodeToLabelFactory() {
+ @Override public NodeToLabel create() { return NodeToLabel.createBNodeByLabelAsGiven() ; }
+ @Override public String toString() { return "NodeToLabel.createBNodeByLabelAsGiven()" ; }
+ } ;
+ NodeToLabelFactory f3 = new NodeToLabelFactory() {
+ @Override public NodeToLabel create() { return NodeToLabel.createBNodeByLabelEncoded() ; }
+ @Override public String toString() { return "NodeToLabel.createBNodeByLabelEncoded()" ; }
+ } ;
+ NodeToLabelFactory f4 = new NodeToLabelFactory() {
+ @Override public NodeToLabel create() { return NodeToLabel.labelByInternal() ; }
+ @Override public String toString() { return "NodeToLabel.labelByInternal()" ; }
+ } ;
+
+ x.add(new Object[]{f0}) ;
+ x.add(new Object[]{f1}) ;
+ x.add(new Object[]{f2}) ;
+ x.add(new Object[]{f3}) ;
+ x.add(new Object[]{f4}) ;
+ return x ;
+ }
+
+ private NodeToLabelFactory factory ;
+
+ public TestNodeToLabel(NodeToLabelFactory factory)
+ {
+ this.factory = factory ;
+ }
+
+ @Test public void node2label_01()
+ {
+ NodeToLabel mapper = factory.create() ;
+ String x1 = mapper.create() ;
+ String x2 = mapper.create() ;
+ assertNotNull(x1) ;
+ assertNotNull(x2) ;
+ assertNotEquals(x1, x2) ;
+ }
+
+ @Test public void node2label_02()
+ {
+ NodeToLabel mapper = factory.create() ;
+ Node x = NodeFactory.createAnon() ;
+ String s1 = mapper.get(null, x) ;
+ String s2 = mapper.get(null, x) ;
+ assertNotNull(s1) ;
+ assertNotNull(s2) ;
+ assertEquals(s1, s2) ;
+ }
+
+ @Test public void node2label_03()
+ {
+ NodeToLabel mapper = factory.create() ;
+ Node x1 = NodeFactory.createAnon() ;
+ Node x2 = NodeFactory.createAnon() ;
+ String s1 = mapper.get(null, x1) ;
+ String s2 = mapper.get(null, x2) ;
+ assertNotNull(s1) ;
+ assertNotNull(s2) ;
+ assertNotEquals(s1, s2) ;
+ }
+}
+