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 2017/09/28 11:08:42 UTC
[26/50] [abbrv] jena git commit: JENA-1396: Merge //github/afs/mantis
as subdirectory jena-db/
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionLock.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionLock.java
index 0000000,0000000..ad87de7
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionLock.java
@@@ -1,0 -1,0 +1,71 @@@
++/*
++ * 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.seaborne.tdb2.store;
++
++import static org.junit.Assert.*;
++import org.junit.Rule;
++import org.junit.Test;
++import org.junit.rules.TemporaryFolder;
++import org.seaborne.dboe.base.file.AlreadyLocked;
++import org.seaborne.dboe.base.file.Location;
++import org.seaborne.dboe.base.file.ProcessFileLock;
++import org.seaborne.tdb2.sys.StoreConnection;
++
++/**
++ * Tests for {@link ProcessFileLock} in conjunction with {@link StoreConnection}s
++ */
++public class TestStoreConnectionLock {
++ @Rule
++ public TemporaryFolder tempDir = new TemporaryFolder();
++
++ @Test
++ public void lock_store_connection_01() {
++ Location dir = Location.create(tempDir.getRoot().getAbsolutePath());
++ ProcessFileLock lock = StoreConnection.lockForLocation(dir);
++ assertFalse(lock.isLockedHere());
++
++ StoreConnection sConn = StoreConnection.connectCreate(dir);
++ assertEquals(dir, sConn.getLocation());
++ assertEquals(lock, sConn.getLock());
++ assertTrue(lock.isLockedHere());
++
++ StoreConnection.release(dir);
++ assertFalse(lock.isLockedHere());
++ }
++
++ @Test(expected=AlreadyLocked.class)
++ public void lock_store_connection_02() {
++ Location dir = Location.create(tempDir.getRoot().getAbsolutePath());
++ ProcessFileLock lock = StoreConnection.lockForLocation(dir);
++ lock.lockEx();
++ StoreConnection sConn = StoreConnection.connectCreate(dir);
++ }
++// Location dir = Location.create(tempDir.getRoot().getAbsolutePath());
++// // Creating a StoreConnection on the location will obtain the lock
++// StoreConnection.make(dir);
++// // Releasing the connection releases the lock
++// StoreConnection.release(dir);
++// }
++//
++// @Test(expected = TDBException.class)
++// public void location_lock_store_connection_02() throws IOException {
++// Location dir = Location.create(tempDir.getRoot().getAbsolutePath());
++// StoreConnection.make(dir);
++// }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMapped.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMapped.java
index 0000000,0000000..ac3127a
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMapped.java
@@@ -1,0 -1,0 +1,50 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import org.junit.AfterClass ;
++import org.junit.BeforeClass ;
++import org.seaborne.dboe.base.block.FileMode ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.ConfigTest ;
++import org.seaborne.tdb2.sys.SystemTDB ;
++import org.seaborne.tdb2.sys.TestOps ;
++
++/** Slow tests - complete cleaning of disk areas each time */
++public class TestStoreConnectionMapped extends AbstractTestStoreConnectionBasics
++{
++ static FileMode mode ;
++
++ @BeforeClass
++ public static void beforeClassFileMode()
++ {
++ mode = SystemTDB.fileMode() ;
++ TestOps.setFileMode(FileMode.mapped) ;
++ }
++
++ @AfterClass
++ public static void afterClassFileMode()
++ {
++ TestOps.setFileMode(mode) ;
++ }
++
++ @Override
++ protected Location getLocation() {
++ return Location.create(ConfigTest.getCleanDir()) ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMem.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMem.java
index 0000000,0000000..6da2c57
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestStoreConnectionMem.java
@@@ -1,0 -1,0 +1,28 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import org.seaborne.dboe.base.file.Location ;
++
++public class TestStoreConnectionMem extends AbstractTestStoreConnectionBasics
++{
++ @Override
++ protected Location getLocation() {
++ return Location.mem("TestStoreConnection") ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestSuiteGraphTDB.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestSuiteGraphTDB.java
index 0000000,0000000..cacbb35
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestSuiteGraphTDB.java
@@@ -1,0 -1,0 +1,40 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import junit.framework.TestSuite ;
++
++import org.junit.runner.RunWith ;
++import org.junit.runners.AllTests ;
++import org.seaborne.tdb2.ConfigTest ;
++import org.seaborne.tdb2.junit.TestFactoryTDB ;
++
++/** Scripted test generation */
++
++@RunWith(AllTests.class)
++public class TestSuiteGraphTDB extends TestSuite
++{
++ static public TestSuite suite() { return new TestSuiteGraphTDB() ; }
++
++ private TestSuiteGraphTDB()
++ {
++ super("TDB-Scripts") ;
++ String manifestMain = ConfigTest.getTestingDataRoot()+"/manifest.ttl" ;
++ TestFactoryTDB.make(this, manifestMain, "TDB-") ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransPromoteTDB.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransPromoteTDB.java
index 0000000,0000000..2814f32
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransPromoteTDB.java
@@@ -1,0 -1,0 +1,72 @@@
++/*
++ * 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.seaborne.tdb2.store;
++
++import org.apache.jena.sparql.core.DatasetGraph;
++import org.apache.log4j.Logger;
++import org.seaborne.dboe.transaction.txn.Transaction;
++import org.seaborne.dboe.transaction.txn.TransactionCoordinator;
++import org.seaborne.dboe.transaction.txn.TransactionException;
++import org.seaborne.tdb2.DatabaseMgr ;
++
++public class TestTransPromoteTDB extends AbstractTestTransPromoteTDB2 {
++
++ public TestTransPromoteTDB() {
++ super(getLoggers());
++ }
++
++ private static Logger[] getLoggers() {
++ return new Logger[]{ Logger.getLogger(Transaction.class) } ;
++ }
++
++ @Override
++ protected void setPromotion(boolean b) {
++ TransactionCoordinator.promotion = b ;
++ }
++
++ @Override
++ protected boolean getPromotion() {
++ return TransactionCoordinator.promotion ;
++ }
++
++ @Override
++ protected void setReadCommitted(boolean b) {
++ TransactionCoordinator.readCommittedPromotion = b ;
++ }
++
++ @Override
++ protected boolean getReadCommitted() {
++ return TransactionCoordinator.readCommittedPromotion ;
++ }
++
++ @Override
++ protected Class<? extends Exception> getTransactionExceptionClass() {
++ return TransactionException.class;
++ }
++
++ @Override
++ protected DatasetGraph create() {
++ return DatabaseMgr.createDatasetGraph();
++ }
++
++ @Override
++ protected boolean supportsReadCommitted() {
++ return true;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactionLifecycleTDB.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactionLifecycleTDB.java
index 0000000,0000000..7f1add3
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactionLifecycleTDB.java
@@@ -1,0 -1,0 +1,33 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import org.apache.jena.query.Dataset ;
++import org.apache.jena.sparql.transaction.AbstractTestTransactionLifecycle;
++import org.seaborne.tdb2.TDB2Factory ;
++
++/** Transaction tests - from ARQ */
++public class TestTransactionLifecycleTDB extends AbstractTestTransactionLifecycle
++{
++ @Override
++ protected Dataset create() {
++ return TDB2Factory.createDataset() ;
++ }
++}
++
++
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactions.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactions.java
index 0000000,0000000..1aed0a6
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTransactions.java
@@@ -1,0 -1,0 +1,204 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import java.io.StringReader ;
++import java.util.Iterator;
++
++import org.apache.jena.atlas.iterator.Iter ;
++import static org.junit.Assert.*;
++import org.apache.jena.atlas.lib.StrUtils ;
++import org.apache.jena.query.Dataset ;
++import org.apache.jena.query.ReadWrite;
++import org.apache.jena.rdf.model.Model ;
++import org.apache.jena.rdf.model.Statement;
++import org.apache.jena.riot.Lang ;
++import org.apache.jena.riot.RDFDataMgr ;
++import org.apache.jena.sparql.core.Quad;
++import org.junit.After ;
++import org.junit.Before ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.dboe.jenax.Txn ;
++import org.seaborne.dboe.transaction.txn.TransactionException;
++import org.seaborne.tdb2.TDB2Factory ;
++import org.seaborne.tdb2.sys.TDBInternal;
++
++/** Transactions and store connections - extended tests assuming the
++ * basics work. Hence these tests use memory databases.
++ *
++ * For tests of StoreConnection basics:
++ * @see AbstractTestStoreConnectionBasics
++ * @see TestStoreConnectionDirect
++ * @see TestStoreConnectionMapped
++ * @see TestStoreConnectionMem
++ */
++public class TestTransactions
++{
++ // Per-test unique-ish.
++ static int count = 0 ;
++ long x = System.currentTimeMillis()+(count++) ;
++
++ String ns = "http://example/TestTransactions#" ;
++ String data1 = StrUtils.strjoinNL
++ ("prefix : <"+ns+">"
++ ,":s :p '000-"+x+"' ."
++ ,":s :p '111-"+x+"' ."
++ ," :g {"
++ ," :s :p '222-"+x+"' ."
++ ," :s :p '333-"+x+"' ."
++ ," :s :p '444-"+x+"' ."
++ ,"}"
++ ) ;
++ String data2 = StrUtils.strjoinNL
++ ("prefix : <"+ns+">"
++ ,":s :p 'AAA-"+x+"' ."
++ ,":s :p 'BBB-"+x+"' ."
++ ,":s :p 'CCC-"+x+"' ."
++ ,":s :p 'DDD-"+x+"' ."
++ ) ;
++
++ Dataset dataset ;
++ Location location ;
++
++ @Before public void before() {
++ location = Location.mem() ;
++ dataset = TDB2Factory.connectDataset(location) ;
++ }
++
++ @After public void after() {
++ dataset.close() ;
++ TDBInternal.expel(dataset.asDatasetGraph());
++ }
++
++ // Models across transactions
++ @Test public void trans_01() {
++ Model named = dataset.getNamedModel(ns+"g") ;
++ Txn.executeWrite(dataset, ()->{
++ RDFDataMgr.read(dataset, new StringReader(data1), null, Lang.TRIG) ;
++ }) ;
++
++ Txn.executeRead(dataset, ()->{
++ long x1 = Iter.count(dataset.getDefaultModel().listStatements()) ;
++ assertEquals(2, x1) ;
++ long x2 = Iter.count(named.listStatements()) ;
++ assertEquals(3, x2) ;
++ }) ;
++
++ }
++
++ @Test public void trans_02() {
++ Model model = dataset.getDefaultModel() ;
++ Txn.executeWrite(dataset, ()->{
++ RDFDataMgr.read(model, new StringReader(data2), null, Lang.TURTLE) ;
++ }) ;
++ Txn.executeRead(dataset, ()->{
++ assertEquals(4, model.size()) ;
++ }) ;
++ }
++
++ // Iterators and trasnaxction scope.
++
++ private void load(String data) {
++ Txn.executeWrite(dataset, ()->{
++ RDFDataMgr.read(dataset, new StringReader(data), null, Lang.TURTLE) ;
++ }) ;
++ }
++
++ public void iterator_01() {
++ load(data2);
++
++ dataset.begin(ReadWrite.READ);
++ Iterator<Quad> iter = TDBInternal.getDatasetGraphTDB(dataset).find();
++ Iter.consume(iter);
++ dataset.end();
++ }
++
++ @Test(expected=TransactionException.class)
++ public void iterator_02() {
++ load(data2);
++
++ dataset.begin(ReadWrite.READ);
++ Iterator<Quad> iter = dataset.asDatasetGraph().find();
++ dataset.end();
++ iter.next();
++ }
++
++ @Test(expected=TransactionException.class)
++ public void iterator_03() {
++ load(data2);
++
++ dataset.begin(ReadWrite.READ);
++ Iterator<Quad> iter = TDBInternal.getDatasetGraphTDB(dataset).find();
++ dataset.end();
++ iter.next();
++ }
++
++ @Test(expected=TransactionException.class)
++ public void iterator_04() {
++ load(data2);
++ Iterator<Statement> iter = Txn.calculateRead(dataset, ()->dataset.getDefaultModel().listStatements());
++ iter.next();
++ }
++
++ @Test(expected=TransactionException.class)
++ public void iterator_05() {
++ load(data2);
++ Iterator<Statement> iter = Txn.calculateWrite(dataset, ()->dataset.getDefaultModel().listStatements());
++ iter.next();
++ }
++
++ @Test(expected=TransactionException.class)
++ public void iterator_06() {
++ load(data2);
++
++ dataset.begin(ReadWrite.READ);
++ Iterator<Quad> iter = dataset.asDatasetGraph().find();
++ dataset.end();
++
++ dataset.begin(ReadWrite.READ);
++ iter.next();
++ dataset.end();
++ }
++
++// @Test
++// public void iterator_07() {
++// load(data2);
++//
++// // Isolated by copy.
++// Iterator<Quad> iter = TDBInternal.getDatasetGraphTDB(dataset).find();
++//
++// dataset.begin(ReadWrite.READ);
++// iter.next();
++// dataset.end();
++// }
++//
++// @Test
++// public void iterator_08() {
++// load(data2);
++//
++// // Isolated by copy.
++// Iterator<Quad> iter = TDBInternal.getDatasetGraphTDB(dataset).find();
++//
++// dataset.begin(ReadWrite.READ);
++// dataset.end();
++// iter.next();
++// }
++}
++
++
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTripleTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTripleTable.java
index 0000000,0000000..98e48d1
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/TestTripleTable.java
@@@ -1,0 -1,0 +1,132 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import java.util.Iterator ;
++
++import static org.junit.Assert.*;
++import org.apache.jena.graph.Node ;
++import org.apache.jena.graph.Triple ;
++import org.apache.jena.query.ReadWrite ;
++import org.apache.jena.sparql.util.NodeFactoryExtra ;
++import org.apache.log4j.Level ;
++import org.apache.log4j.Logger ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.setup.TDBBuilder ;
++
++public class TestTripleTable
++{
++ static {
++ Logger.getLogger("org.apache.jena.tdb.info").setLevel(Level.WARN) ;
++ Logger.getLogger("org.apache.jena.tdb.exec").setLevel(Level.WARN) ;
++ }
++
++ private static void add(TripleTable table, Node s, Node p, Node o)
++ {
++ table.add(new Triple(s,p,o)) ;
++ }
++
++ private static void notMatch(TripleTable table, Node s, Node p, Node o)
++ {
++ Iterator<Triple> iter = table.find(s, p, o) ;
++ assertNotNull(iter) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ private static void match(TripleTable table, Node s, Node p, Node o)
++ {
++ Iterator<Triple> iter = table.find(s, p, o) ;
++ assertNotNull(iter) ;
++ assertTrue(iter.hasNext()) ;
++ }
++
++
++ private static void contains(TripleTable table, Node s, Node p, Node o)
++ {
++ Iterator<Triple> iter = table.find(s, p, o) ;
++ assertNotNull(iter) ;
++ assertTrue(iter.hasNext()) ;
++ assertEquals(new Triple(s, p, o), iter.next()) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ static Node n1 = NodeFactoryExtra.parseNode("<http://example/n1>") ;
++ static Node n2 = NodeFactoryExtra.parseNode("<http://example/n2>") ;
++ static Node n3 = NodeFactoryExtra.parseNode("<http://example/n3>") ;
++ static Node n4 = NodeFactoryExtra.parseNode("<http://example/n4>") ;
++ static Node n5 = NodeFactoryExtra.parseNode("<http://example/n5>") ;
++ static Node n6 = NodeFactoryExtra.parseNode("<http://example/n6>") ;
++
++ @Test public void createTripleTable1()
++ {
++ TripleTable table = createTripleTableMem() ;
++ notMatch(table, n1, n2, n3) ;
++ }
++
++ @Test public void add1()
++ {
++ TripleTable table = createTripleTableMem() ;
++ table.add(new Triple(n1,n2,n3)) ;
++ }
++
++ @Test public void find1()
++ {
++ TripleTable table = createTripleTableMem() ;
++ add(table, n1, n2, n3) ;
++ contains(table, n1, n2, n3) ;
++ notMatch(table, n1, n2, n4) ;
++ }
++
++ @Test public void find2()
++ {
++ TripleTable table = createTripleTableMem() ;
++ add(table, n1, n2, n3) ;
++ add(table, n1, n2, n4) ;
++ contains(table, n1, n2, n3) ;
++ contains(table, n1, n2, n4) ;
++ }
++
++ @Test public void find3()
++ {
++ TripleTable table = createTripleTableMem() ;
++ add(table, n1, n2, n3) ;
++ add(table, n4, n5, n6) ;
++ contains(table, n1, n2, n3) ;
++ contains(table, n4, n5, n6) ;
++ notMatch(table, n1, n2, n4) ;
++ }
++
++ @Test public void find4()
++ {
++ TripleTable table = createTripleTableMem() ;
++ add(table, n1, n2, n3) ;
++ add(table, n4, n5, n6) ;
++ match(table, Node.ANY, n2, n3) ;
++ match(table, null, n2, n3) ;
++ match(table, null, null, null) ;
++ }
++
++ private TripleTable createTripleTableMem()
++ {
++ DatasetGraphTxn dsx = TDBBuilder.build(Location.mem()) ;
++ dsx.begin(ReadWrite.WRITE);
++ DatasetGraphTDB ds = (DatasetGraphTDB)dsx ;
++ return ds.getTripleTable() ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/Test_SPARQL_TDB.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/Test_SPARQL_TDB.java
index 0000000,0000000..0ab4cb4
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/Test_SPARQL_TDB.java
@@@ -1,0 -1,0 +1,221 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store;
++
++import static org.junit.Assert.*;
++import org.apache.jena.atlas.lib.StrUtils ;
++import org.apache.jena.graph.Graph ;
++import org.apache.jena.graph.NodeFactory ;
++import org.apache.jena.graph.Triple ;
++import org.apache.jena.query.* ;
++import org.apache.jena.rdf.model.Model ;
++import org.apache.jena.sparql.sse.SSE ;
++import org.apache.jena.update.* ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.dboe.jenax.Txn ;
++import org.seaborne.tdb2.TDB2 ;
++import org.seaborne.tdb2.TDB2Factory ;
++
++/**
++ * Test SPARQL
++ */
++public class Test_SPARQL_TDB
++{
++ private static Dataset create() {
++ return TDB2Factory.createDataset() ;
++ }
++
++ private static Dataset create(Location location) {
++ return TDB2Factory.connectDataset(location) ;
++ }
++
++ private static String graphName = "http://example/" ;
++ private static Triple triple = SSE.parseTriple("(<x> <y> 123)") ;
++
++ // Standalone graph.
++ @Test public void sparql1()
++ {
++ // Test OpExecutor.execute(OpBGP) for a named graph used as a standalone model
++ Dataset ds = create() ;
++ add(ds, graphName, triple) ;
++ Txn.executeRead(ds, ()->{
++ Model m = ds.getNamedModel(graphName) ;
++ String qs = "SELECT * { ?s ?p ?o . }" ;
++ Query query = QueryFactory.create(qs) ;
++ QueryExecution qexec = QueryExecutionFactory.create(query, m) ;
++ ResultSet rs = qexec.execSelect() ;
++ ResultSetFormatter.consume(rs) ;
++ }) ;
++ }
++
++ // Standalone graph.
++ @Test public void sparql2()
++ {
++ // Test OpExecutor.execute(OpFilter)for a named graph used as a standalone model
++ Dataset ds = create() ;
++ add(ds, graphName, triple) ;
++
++ Txn.executeRead(ds, ()->{
++ Model m = ds.getNamedModel(graphName) ;
++ String qs = "SELECT * { ?s ?p ?o . FILTER ( ?o < 456 ) }" ;
++ Query query = QueryFactory.create(qs) ;
++ try(QueryExecution qexec = QueryExecutionFactory.create(query, m)) {
++ ResultSet rs = qexec.execSelect() ;
++ ResultSetFormatter.consume(rs) ;
++ }
++ }) ;
++ }
++
++ // Requires OpDatasetNames
++ @Test public void sparql3()
++ {
++ Dataset dataset = create() ;
++ // No triple added
++ Txn.executeRead(dataset, ()->{
++ Query query = QueryFactory.create("SELECT ?g { GRAPH ?g {} }") ;
++ QueryExecution qExec = QueryExecutionFactory.create(query, dataset) ;
++ ResultSet rs = qExec.execSelect() ;
++ int n = ResultSetFormatter.consume(rs) ;
++ assertEquals(0, n) ;
++ }) ;
++ }
++
++ @Test public void sparql4()
++ {
++ Dataset dataset = create() ;
++ add(dataset, graphName, triple) ;
++ Txn.executeRead(dataset, ()->{
++ Query query = QueryFactory.create("SELECT ?g { GRAPH ?g {} }") ;
++ QueryExecution qExec = QueryExecutionFactory.create(query, dataset) ;
++ ResultSet rs = qExec.execSelect() ;
++ int n = ResultSetFormatter.consume(rs) ;
++ assertEquals(1, n) ;
++ }) ;
++ }
++
++ @Test public void sparql5()
++ {
++ Dataset dataset = create() ;
++ add(dataset, graphName, triple);
++ Txn.executeRead(dataset, ()->{
++ Query query = QueryFactory.create("ASK { GRAPH <"+graphName+"> {} }") ;
++ boolean b = QueryExecutionFactory.create(query, dataset).execAsk() ;
++ assertEquals(true, b) ;
++ }) ;
++ }
++
++ @Test public void sparql6()
++ {
++ Dataset dataset = create() ;
++ add(dataset, graphName, triple);
++ Txn.executeRead(dataset, ()->{
++ Query query = QueryFactory.create("ASK { GRAPH <http://example/x> {} }") ;
++ boolean b = QueryExecutionFactory.create(query, dataset).execAsk() ;
++ assertEquals(false, b) ;
++ }) ;
++ }
++
++ private static void add(Dataset dataset, String graphName, Triple triple) {
++ Txn.executeWrite(dataset, ()->{
++ Graph g2 = dataset.asDatasetGraph().getGraph(NodeFactory.createURI(graphName)) ;
++ g2.add(triple) ;
++ });
++ }
++
++ // Test transactions effective.
++
++ @Test public void sparql_txn_1()
++ {
++ Dataset dataset = create() ;
++ Txn.executeWrite(dataset, ()->{
++ update(dataset, "INSERT DATA { <x:s> <x:p> <x:o> }") ;
++ }) ;
++ // Explicit trasnaction steps.
++ dataset.begin(ReadWrite.READ) ;
++ try {
++ int n = count(dataset) ;
++ assertEquals(1, n) ;
++ n = count(dataset, "SELECT * { <x:s> <x:p> <x:o>}") ;
++ assertEquals(1, n) ;
++ } finally { dataset.end() ; }
++ }
++
++ @Test public void sparql_txn_2()
++ {
++ Dataset dataset1 = create(Location.mem("foo")) ;
++ Dataset dataset2 = create(Location.mem("foo")) ;
++
++ Txn.executeWrite(dataset1, ()->{
++ update(dataset1, "INSERT DATA { <x:s> <x:p> <x:o> }") ;
++ }) ;
++
++ Txn.executeRead(dataset1, ()->{
++ assertEquals(1, count(dataset1)) ;
++ }) ;
++
++ // Same location.
++ Txn.executeRead(dataset2, ()->{
++ assertEquals(1, count(dataset2)) ;
++ }) ;
++ }
++
++ @Test public void sparql_update_unionGraph()
++ {
++ Dataset ds = TDB2Factory.createDataset() ;
++ // Update concrete default graph
++ Txn.executeWrite(ds, ()->{
++ ds.asDatasetGraph().add(SSE.parseQuad("(<g> <s> <p> 123)")) ;
++ }) ;
++ ds.getContext().setTrue(TDB2.symUnionDefaultGraph) ;
++
++ Txn.executeWrite(ds, ()->{
++ // Update by looking in union graph
++ String us = StrUtils.strjoinNL(
++ "INSERT { GRAPH <http://example/g2> { ?s ?p 'NEW' } }",
++ "WHERE { ",
++ "?s ?p 123",
++ " }" ) ;
++ UpdateRequest req = UpdateFactory.create(us) ;
++ UpdateAction.execute(req, ds) ;
++ }) ;
++
++ Txn.executeRead(ds, ()->{
++ Model m = ds.getNamedModel("http://example/g2") ;
++ assertEquals("Did not find 1 statement in named graph", 1, m.size()) ;
++ }) ;
++ }
++
++ private int count(Dataset dataset)
++ { return count(dataset, "SELECT * { ?s ?p ?o }") ; }
++
++ private int count(Dataset dataset, String queryString)
++
++ {
++ Query query = QueryFactory.create(queryString) ;
++ QueryExecution qExec = QueryExecutionFactory.create(query, dataset) ;
++ ResultSet rs = qExec.execSelect() ;
++ return ResultSetFormatter.consume(rs) ;
++ }
++ private void update(Dataset dataset, String string)
++ {
++ UpdateRequest req = UpdateFactory.create(string) ;
++ UpdateProcessor proc = UpdateExecutionFactory.create(req, dataset) ;
++ proc.execute() ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/AbstractTestNodeTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/AbstractTestNodeTable.java
index 0000000,0000000..158e2ff
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/AbstractTestNodeTable.java
@@@ -1,0 -1,0 +1,66 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import static org.junit.Assert.assertEquals ;
++import static org.junit.Assert.assertNotEquals ;
++import static org.junit.Assert.assertNotNull ;
++
++import org.apache.jena.graph.Node ;
++import org.apache.jena.sparql.util.NodeFactoryExtra ;
++import org.junit.Test ;
++import org.seaborne.tdb2.store.NodeId ;
++
++public abstract class AbstractTestNodeTable
++{
++ protected abstract NodeTable createEmptyNodeTable() ;
++
++ protected void testNode(String str) {
++ testNode(NodeFactoryExtra.parseNode(str)) ;
++ }
++
++ protected void testNode(Node n) {
++ NodeTable nt = createEmptyNodeTable() ;
++ writeNode(nt, n) ;
++ }
++
++ protected static void writeNode(NodeTable nt, String str) {
++ writeNode(nt, NodeFactoryExtra.parseNode(str)) ;
++ }
++
++ protected static void writeNode(NodeTable nt, Node n) {
++ NodeId nodeId = nt.getAllocateNodeId(n) ;
++ assertNotNull(nodeId) ;
++ assertNotEquals(NodeId.NodeDoesNotExist, nodeId) ;
++ assertNotEquals(NodeId.NodeIdAny, nodeId) ;
++
++ Node n2 = nt.getNodeForNodeId(nodeId) ;
++ assertEquals(n, n2) ;
++
++ NodeId nodeId2 = nt.getNodeIdForNode(n) ;
++ assertEquals(nodeId, nodeId2) ;
++ }
++
++ @Test public void nodetable_01() { testNode("<http://example/x>") ; }
++ @Test public void nodetable_02() { testNode("1") ; }
++ @Test public void nodetable_03() { testNode("_:x") ; }
++ @Test public void nodetable_04() { testNode("'x'") ; }
++ @Test public void nodetable_05() { testNode("'x'@en") ; }
++ @Test public void nodetable_06() { testNode("'x'^^<http://example/dt>") ; }
++ @Test public void nodetable_07() { testNode("'نواف'") ; }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TS_NodeTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TS_NodeTable.java
index 0000000,0000000..62f9388
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TS_NodeTable.java
@@@ -1,0 -1,0 +1,33 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import org.junit.runner.RunWith ;
++import org.junit.runners.Suite ;
++
++@RunWith(Suite.class)
++@Suite.SuiteClasses( {
++ TestNodeTableBase.class
++ , TestNodeTableStoredBase.class
++ , TestNodeTableStored.class
++ , TestNodeTable.class
++})
++public class TS_NodeTable
++{
++
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTable.java
index 0000000,0000000..9b7eda2
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTable.java
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.setup.StoreParamsBuilder ;
++
++public class TestNodeTable extends AbstractTestNodeTable
++{
++ @Override
++ protected NodeTable createEmptyNodeTable()
++ {
++ StoreParams params =
++ StoreParamsBuilder.create()
++ .nodeId2NodeCacheSize(10)
++ .node2NodeIdCacheSize(10)
++ .nodeMissCacheSize(10).build() ;
++ return BuildTestLib.makeNodeTable(Location.mem(), "test", params) ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableBase.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableBase.java
index 0000000,0000000..d4bf131
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableBase.java
@@@ -1,0 -1,0 +1,39 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.setup.StoreParamsBuilder ;
++
++public class TestNodeTableBase extends AbstractTestNodeTable
++{
++ @Override
++ protected NodeTable createEmptyNodeTable()
++ {
++ StoreParams params =
++ StoreParamsBuilder.create()
++ .nodeId2NodeCacheSize(-1)
++ .node2NodeIdCacheSize(-1)
++ .nodeMissCacheSize(-1).build() ;
++
++ // No cache, no inlining.
++ return BuildTestLib.makeNodeTableBase(Location.mem(), "test", params) ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStored.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStored.java
index 0000000,0000000..12063e0
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStored.java
@@@ -1,0 -1,0 +1,45 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import org.apache.jena.atlas.lib.FileOps ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.ConfigTest ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.setup.StoreParamsBuilder ;
++
++
++public class TestNodeTableStored extends AbstractTestNodeTable
++{
++ static String base = ConfigTest.getTestingDir() ;
++ static Location location = Location.create(base+"/nodetable-test") ;
++
++ @Override
++ protected NodeTable createEmptyNodeTable()
++ {
++ FileOps.ensureDir(location.getDirectoryPath());
++ FileOps.clearDirectory(location.getDirectoryPath());
++ StoreParams params =
++ StoreParamsBuilder.create()
++ .nodeId2NodeCacheSize(10)
++ .node2NodeIdCacheSize(10)
++ .nodeMissCacheSize(10).build() ;
++ return BuildTestLib.makeNodeTable(location, "test", params) ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStoredBase.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStoredBase.java
index 0000000,0000000..edbc2d8
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/nodetable/TestNodeTableStoredBase.java
@@@ -1,0 -1,0 +1,46 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.nodetable;
++
++import org.apache.jena.atlas.lib.FileOps ;
++import org.seaborne.dboe.base.file.Location ;
++import org.seaborne.tdb2.ConfigTest ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.setup.StoreParamsBuilder ;
++
++
++public class TestNodeTableStoredBase extends AbstractTestNodeTable
++{
++
++ static String base = ConfigTest.getTestingDir() ;
++ static Location location = Location.create(base+"/nodetable-test") ;
++
++ @Override
++ protected NodeTable createEmptyNodeTable()
++ {
++ FileOps.ensureDir(location.getDirectoryPath());
++ FileOps.clearDirectory(location.getDirectoryPath());
++ StoreParams params =
++ StoreParamsBuilder.create()
++ .nodeId2NodeCacheSize(-1)
++ .node2NodeIdCacheSize(-1)
++ .nodeMissCacheSize(-1).build() ;
++ return BuildTestLib.makeNodeTableBase(location, "test", params) ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/AbstractTestTupleIndex.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/AbstractTestTupleIndex.java
index 0000000,0000000..6a2e138
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/AbstractTestTupleIndex.java
@@@ -1,0 -1,0 +1,264 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import static org.apache.jena.atlas.lib.tuple.TupleFactory.tuple ;
++
++import java.util.Iterator ;
++import java.util.Set ;
++
++import org.apache.jena.atlas.iterator.Iter ;
++import static org.junit.Assert.*;
++import org.apache.jena.atlas.lib.tuple.Tuple ;
++import org.junit.Test ;
++import org.seaborne.tdb2.store.NodeId ;
++import org.seaborne.tdb2.store.tupletable.TupleIndex ;
++import static org.seaborne.tdb2.store.tupletable.NData.*;
++
++/** Test TupleIndexes (general) */
++public abstract class AbstractTestTupleIndex
++{
++ protected abstract TupleIndex create(String description) ;
++
++ protected static void add(TupleIndex index, NodeId x1, NodeId x2, NodeId x3)
++ {
++ Tuple<NodeId> tuple = tuple(x1, x2, x3) ;
++ index.add(tuple) ;
++ }
++
++ @Test public void TupleIndex_1()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_1()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_2()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, null) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_3()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_4()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_5()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertFalse(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_6()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(2, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertTrue(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_7()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(2, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertTrue(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_8()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n2, n3, n4) ;
++
++ {
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ }
++
++ {
++ Tuple<NodeId> tuple2 = tuple(n2, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n2, n3, n4))) ;
++ }
++ }
++
++ @Test public void TupleIndexRecordPOS_1()
++ {
++ TupleIndex index = create("POS") ;
++ add(index, n1, n2, n3) ;
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue("Can't find tuple", iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordPOS_2()
++ {
++ TupleIndex index = create("POS") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(null, n2, null) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue("Can't find tuple",iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++
++ @Test public void TupleIndexRecordPOS_3()
++ {
++ TupleIndex index = create("POS") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(null, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertTrue("Can't find tuple", iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_1()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n4, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertNotNull(iter) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_2()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_3()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_4()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n4, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_5()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n2, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_6()
++ {
++ TupleIndex index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n4, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.find(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/NData.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/NData.java
index 0000000,0000000..c22451f
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/NData.java
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import org.apache.jena.atlas.lib.BitsLong;
++import org.seaborne.tdb2.store.NodeId;
++import org.seaborne.tdb2.store.NodeIdFactory;
++import org.seaborne.tdb2.store.NodeIdType;
++
++public class NData {
++ public static NodeId n1 = create(1) ;
++ public static NodeId n2 = create(2) ;
++ public static NodeId n3 = create(3) ;
++ public static NodeId n4 = NodeIdFactory.createValue(NodeIdType.XSD_INTEGER, 1);
++ public static NodeId n5 = NodeIdFactory.createValue(NodeIdType.XSD_INTEGER, 2);
++ // -2 as inlined.
++ public static NodeId n6 = NodeIdFactory.createValue(NodeIdType.XSD_INTEGER, BitsLong.clear(-2L, 56, 64));
++
++ private static NodeId create(long v) {
++ return NodeIdFactory.createPtr(v);
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TS_TupleTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TS_TupleTable.java
index 0000000,0000000..607ffe8
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TS_TupleTable.java
@@@ -1,0 -1,0 +1,31 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import org.junit.runner.RunWith;
++import org.junit.runners.Suite;
++
++@RunWith(Suite.class)
++@Suite.SuiteClasses( {
++ TestTupleIndexRecord.class,
++ TestTupleIndexRecordDirect.class,
++ TestTupleTable.class
++} )
++
++public class TS_TupleTable
++{ }
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecord.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecord.java
index 0000000,0000000..ce62f16
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecord.java
@@@ -1,0 -1,0 +1,42 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import org.apache.jena.atlas.lib.tuple.TupleMap ;
++import org.seaborne.dboe.base.file.FileSet ;
++import org.seaborne.dboe.base.record.RecordFactory ;
++import org.seaborne.dboe.index.IndexParams ;
++import org.seaborne.dboe.index.RangeIndex ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.sys.SystemTDB ;
++
++public class TestTupleIndexRecord extends AbstractTestTupleIndex
++{
++ static RecordFactory factory = new RecordFactory(3*SystemTDB.SizeOfNodeId, 0) ;
++
++ @Override
++ protected TupleIndexRecord create(String description)
++ {
++ IndexParams indexParams = StoreParams.getDftStoreParams() ;
++ RangeIndex rIdx = BuildTestLib.buildRangeIndex(FileSet.mem(), factory, indexParams) ;
++ TupleMap tmap = TupleMap.create("SPO", description) ;
++ TupleIndexRecord index = new TupleIndexRecord(3, tmap, description, factory, rIdx) ;
++ return index ;
++ }
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecordDirect.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecordDirect.java
index 0000000,0000000..a48c87b
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleIndexRecordDirect.java
@@@ -1,0 -1,0 +1,314 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import static org.seaborne.tdb2.store.tupletable.NData.*;
++import static org.apache.jena.atlas.lib.tuple.TupleFactory.tuple ;
++
++import java.util.Iterator ;
++import java.util.Set ;
++
++import org.apache.jena.atlas.iterator.Iter ;
++import static org.junit.Assert.*;
++import org.apache.jena.atlas.lib.tuple.Tuple ;
++import org.apache.jena.atlas.lib.tuple.TupleMap ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.file.FileSet ;
++import org.seaborne.dboe.base.record.RecordFactory ;
++import org.seaborne.dboe.index.IndexParams ;
++import org.seaborne.dboe.index.RangeIndex ;
++import org.seaborne.tdb2.junit.BuildTestLib ;
++import org.seaborne.tdb2.setup.StoreParams ;
++import org.seaborne.tdb2.store.NodeId ;
++import org.seaborne.tdb2.sys.SystemTDB ;
++
++public class TestTupleIndexRecordDirect
++{
++ static RecordFactory factory = new RecordFactory(3*SystemTDB.SizeOfNodeId, 0) ;
++
++ static TupleIndexRecord create(String description)
++ {
++ IndexParams indexParams = StoreParams.getDftStoreParams() ;
++ RangeIndex rIdx = BuildTestLib.buildRangeIndex(FileSet.mem(), factory, indexParams) ;
++ TupleMap tmap = TupleMap.create("SPO", description) ;
++ TupleIndexRecord index = new TupleIndexRecord(3, tmap, description, factory, rIdx) ;
++ return index ;
++ }
++
++ static void add(TupleIndexRecord index, NodeId x1, NodeId x2, NodeId x3)
++ {
++ Tuple<NodeId> tuple = tuple(x1, x2, x3) ;
++ index.add(tuple) ;
++ }
++
++ @Test public void TupleIndexRecord_1()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_1()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_2()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, null) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_3()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertNull(iter) ;
++ iter = index.findOrPartialScan(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_4()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_5()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertFalse(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_6()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n2, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(2, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertTrue(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_7()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(2, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ assertTrue(x.contains(tuple(n1, n2, n4))) ;
++ }
++
++ @Test public void TupleIndexRecordSPO_8()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n2, n3, n4) ;
++
++ {
++ Tuple<NodeId> tuple2 = tuple(n1, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n1, n2, n3))) ;
++ }
++
++ {
++ Tuple<NodeId> tuple2 = tuple(n2, NodeId.NodeIdAny, NodeId.NodeIdAny) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ Set<Tuple<NodeId>> x = Iter.toSet(iter) ;
++ assertEquals(1, x.size()) ;
++ assertTrue(x.contains(tuple(n2, n3, n4))) ;
++ }
++ }
++
++ @Test public void TupleIndexRecordPOS_1()
++ {
++ TupleIndexRecord index = create("POS") ;
++ add(index, n1, n2, n3) ;
++ Tuple<NodeId> tuple2 = tuple(n1, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue("Can't find tuple", iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordPOS_2()
++ {
++ TupleIndexRecord index = create("POS") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(null, n2, null) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue("Can't find tuple",iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++
++ @Test public void TupleIndexRecordPOS_3()
++ {
++ TupleIndexRecord index = create("POS") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(null, n2, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertTrue("Can't find tuple", iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindScan_1()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ Tuple<NodeId> tuple2 = tuple(n1, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertNull(iter) ;
++ iter = index.findOrPartialScan(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindScan_2()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n2, n4) ;
++
++
++ Tuple<NodeId> tuple2 = tuple(null, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertNull(iter) ;
++
++ iter = index.findOrPartialScan(tuple2) ;
++ assertNull(iter) ;
++
++ iter = index.findOrScan(tuple2) ;
++ assertTrue(iter.hasNext()) ;
++ iter.next();
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_1()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n4, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertNotNull(iter) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_2()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_3()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findOrPartialScan(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_4()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n4, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_5()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n1, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n2, n5, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findByIndex(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++ @Test public void TupleIndexRecordFindNot_6()
++ {
++ TupleIndexRecord index = create("SPO") ;
++ add(index, n1, n2, n3) ;
++ add(index, n4, n5, n6) ;
++
++ Tuple<NodeId> tuple2 = tuple(n1, null, n6) ;
++ Iterator<Tuple<NodeId>> iter = index.findOrPartialScan(tuple2) ;
++ assertFalse(iter.hasNext()) ;
++ }
++
++
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleTable.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleTable.java
index 0000000,0000000..4d27266
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/tupletable/TestTupleTable.java
@@@ -1,0 -1,0 +1,151 @@@
++/*
++ * Licensed 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.
++ *
++ * See the NOTICE file distributed with this work for additional
++ * information regarding copyright ownership.
++ */
++
++package org.seaborne.tdb2.store.tupletable;
++
++import static org.apache.jena.atlas.lib.tuple.TupleFactory.tuple ;
++
++import java.util.Iterator ;
++import java.util.List ;
++
++import org.apache.jena.atlas.iterator.Iter ;
++import static org.junit.Assert.*;
++import org.apache.jena.atlas.lib.tuple.Tuple ;
++import org.junit.Test ;
++import org.seaborne.dboe.base.record.RecordFactory ;
++import org.seaborne.tdb2.store.NodeId ;
++import org.seaborne.tdb2.sys.SystemTDB ;
++import static org.seaborne.tdb2.store.tupletable.NData.*;
++
++public class TestTupleTable
++{
++ static RecordFactory factory = new RecordFactory(3*SystemTDB.SizeOfNodeId, 0) ;
++
++ static private TupleTable create()
++ {
++ TupleIndex idxSPO = TestTupleIndexRecordDirect.create("SPO") ;
++ TupleIndex idxPOS = TestTupleIndexRecordDirect.create("POS") ;
++ TupleIndex idxOSP = TestTupleIndexRecordDirect.create("OSP") ;
++ TupleIndex x[] = { idxSPO, idxPOS, idxOSP } ;
++ TupleTable table = new TupleTable(3, x) ;
++ return table ;
++ }
++
++ static private TupleTable create2()
++ {
++ TupleIndex idxSPO = TestTupleIndexRecordDirect.create("SPO") ;
++ TupleIndex x[] = { idxSPO } ;
++ TupleTable table = new TupleTable(3, x) ;
++ return table ;
++ }
++
++ static void add(TupleTable table, NodeId x1, NodeId x2, NodeId x3)
++ {
++ Tuple<NodeId> tuple = tuple(x1, x2, x3) ;
++ table.add(tuple) ;
++ }
++
++ @Test public void create1() { create() ; }
++
++ @Test public void createFind1()
++ {
++ TupleTable table = create() ;
++ add(table, n1, n2, n3) ;
++ // Cast removes compile lint warning.
++ Tuple<NodeId> pat = tuple((NodeId)null, null, null) ;
++ Iterator<Tuple<NodeId>> iter = table.find(pat) ;
++ List<Tuple<NodeId>> x = Iter.toList(iter) ;
++ int z = x.size() ;
++ assertEquals(1, z) ;
++ Tuple<NodeId> e1 = x.get(0) ;
++ assertEquals(tuple(n1, n2, n3) , e1) ;
++ }
++
++ @Test public void createFind2()
++ {
++ TupleTable table = create() ;
++ add(table, n1, n2, n3) ;
++ add(table, n1, n2, n4) ;
++
++ Tuple<NodeId> pat = tuple(null, n2, null) ;
++ Iterator<Tuple<NodeId>> iter = table.find(pat) ;
++ assertNotNull(iter) ;
++ List<Tuple<NodeId>> x = Iter.toList(iter) ;
++ int z = x.size() ;
++ assertEquals(2, z) ;
++
++ Tuple<NodeId> e1 = x.get(0) ;
++ Tuple<NodeId> e2 = x.get(1) ;
++ assertEquals(tuple(n1, n2, n3) , e1) ;
++ assertEquals(tuple(n1, n2, n4) , e2) ;
++ }
++
++ @Test public void createFind3()
++ {
++ // test scan
++ TupleTable table = create2() ;
++ add(table, n1, n2, n3) ;
++ add(table, n1, n2, n4) ;
++
++ Tuple<NodeId> pat = tuple(n1, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = table.find(pat) ;
++ assertNotNull(iter) ;
++ List<Tuple<NodeId>> x = Iter.toList(iter) ;
++ int z = x.size() ;
++ assertEquals(1, z) ;
++
++ Tuple<NodeId> e1 = x.get(0) ;
++ assertEquals(tuple(n1, n2, n3) , e1) ;
++ }
++
++ @Test public void createFind4()
++ {
++ // test scan
++ TupleTable table = create2() ;
++ add(table, n1, n2, n3) ;
++ add(table, n1, n2, n4) ;
++
++ Tuple<NodeId> pat = tuple(null, null, n3) ;
++ Iterator<Tuple<NodeId>> iter = table.find(pat) ;
++ assertNotNull(iter) ;
++ List<Tuple<NodeId>> x = Iter.toList(iter) ;
++ int z = x.size() ;
++ assertEquals(1, z) ;
++
++ Tuple<NodeId> e1 = x.get(0) ;
++ assertEquals(tuple(n1, n2, n3) , e1) ;
++ }
++
++ @Test public void createFind5()
++ {
++ // test scan
++ TupleTable table = create2() ;
++ add(table, n1, n2, n3) ;
++ add(table, n1, n2, n4) ;
++
++ Tuple<NodeId> pat = tuple(null, NodeId.NodeIdAny, n3) ;
++ Iterator<Tuple<NodeId>> iter = table.find(pat) ;
++ assertNotNull(iter) ;
++ List<Tuple<NodeId>> x = Iter.toList(iter) ;
++ int z = x.size() ;
++ assertEquals(1, z) ;
++
++ Tuple<NodeId> e1 = x.get(0) ;
++ assertEquals(tuple(n1, n2, n3) , e1) ;
++ }
++
++}
http://git-wip-us.apache.org/repos/asf/jena/blob/d9da3592/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/value/TestDoubleNode62.java
----------------------------------------------------------------------
diff --cc jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/value/TestDoubleNode62.java
index 0000000,0000000..112bd52
new file mode 100644
--- /dev/null
+++ b/jena-db/tdb2/src/test/java/org/seaborne/tdb2/store/value/TestDoubleNode62.java
@@@ -1,0 -1,0 +1,123 @@@
++/*
++ * 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.seaborne.tdb2.store.value;
++
++import org.apache.jena.atlas.lib.BitsLong;
++import org.junit.Test;
++import org.seaborne.tdb2.store.value.DoubleNode62;
++
++import static org.junit.Assert.*;
++
++public class TestDoubleNode62 {
++ @Test public void double_01() { testRoundTripDouble(1d); }
++ @Test public void double_02() { testRoundTripDouble(-1d); }
++ @Test public void double_03() { testRoundTripDouble(-1111111111e50d); }
++ @Test public void double_04() { testRoundTripDouble(1111111111e50d); }
++
++ @Test public void double_05() { testNoEncoding(1e300); }
++ @Test public void double_06() { testNoEncoding(1e100); }
++ @Test public void double_07() { testNoEncoding(1e78); }
++ @Test public void double_08() { testNoEncoding(2e77); }
++ @Test public void double_09() { testRoundTripDouble(1e77); }
++
++ @Test public void double_10() { testNoEncoding(3e-300); }
++ @Test public void double_11() { testNoEncoding(3e-100); }
++ @Test public void double_12() { testNoEncoding(3e-77); }
++ @Test public void double_13() { testRoundTripDouble(3.5e-77); }
++ @Test public void double_14() { testRoundTripDouble(4e-77); }
++ @Test public void double_15() { testRoundTripDouble(1e-76); }
++ @Test public void double_16() { testRoundTripDouble(1e-75); }
++
++ @Test public void double_20() { testRoundTripDouble(Double.POSITIVE_INFINITY); }
++ @Test public void double_21() { testRoundTripDouble(Double.NEGATIVE_INFINITY); }
++ @Test public void double_22() { testRoundTripDouble(Double.NaN); }
++ @Test public void double_23() { testNoEncoding(Double.MAX_VALUE); }
++ @Test public void double_24() { testNoEncoding(Double.MIN_NORMAL); }
++ @Test public void double_25() { testNoEncoding(Double.MIN_VALUE); }
++
++ @Test public void double_30() { testRoundTripDouble(DoubleNode62.POSITIVE_INFINITY); }
++ @Test public void double_31() { testRoundTripDouble(DoubleNode62.NEGATIVE_INFINITY); }
++ @Test public void double_32() { testRoundTripDouble(DoubleNode62.NaN); }
++ @Test public void double_33() { testNoEncoding(DoubleNode62.MAX_VALUE); }
++ @Test public void double_34() { testNoEncoding(DoubleNode62.MIN_NORMAL); }
++ @Test public void double_35() { testNoEncoding(DoubleNode62.MIN_VALUE); }
++
++ @Test public void double_40() { sameValue(DoubleNode62.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); }
++ @Test public void double_41() { sameValue(DoubleNode62.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); }
++ @Test public void double_42() { sameValue(DoubleNode62.NaN, Double.NaN); }
++
++ @Test public void double_50() { testConst(DoubleNode62.POSITIVE_INFINITY_BITS, 0x1ff0000000000000L); }
++ @Test public void double_51() { testConst(DoubleNode62.NEGATIVE_INFINITY_BITS, 0x3ff0000000000000L); }
++ @Test public void double_52() { testConst(DoubleNode62.NaN_BITS, 0x1ff8000000000000L); }
++ @Test public void double_53() { testConst(DoubleNode62.MAX_VALUE_BITS, 0x3fefffffffffffffL); }
++ @Test public void double_54() { testConst(DoubleNode62.MIN_NORMAL_BITS, 0x0010000000000000L); }
++ @Test public void double_55() { testConst(DoubleNode62.MIN_VALUE_BITS, 0x01L); }
++
++ private void sameValue(double d1, double d2) {
++ // Not d1 == d2 - NaN != NaN
++ assertEquals(Double.valueOf(d1), Double.valueOf(d2));
++ }
++
++ private static void testConst(long x, long expected) {
++ //print(expected);
++ //print(x);
++ assertEquals(expected, x);
++ double d = DoubleNode62.unpack(x);
++ long z = DoubleNode62.pack(d);
++ assertEquals(expected, z);
++ }
++
++ private void testNoEncoding(double d) {
++ testRoundTripDouble(d, false);
++ }
++
++ private static void testRoundTripDouble(double d) {
++ testRoundTripDouble(d, true);
++ }
++
++ private static void testRoundTripDouble(double d, boolean valid) {
++ //System.out.printf("Double: %.2e\n", d);
++ long x0 = Double.doubleToRawLongBits(d);
++ //print(x0);
++ long x = DoubleNode62.pack(d);
++ //print(x);
++ if ( x == DoubleNode62.NO_ENCODING ) {
++ if ( valid )
++ fail("Expect no encoding");
++
++ //System.out.println("No encoding");
++ //System.out.println();
++ return;
++ }
++
++ double d2 = DoubleNode62.unpack(x);
++
++ Double double1 = d ;
++ Double double2 = d2 ;
++ assertEquals(double1, double2);
++ }
++
++ private static void print(long x) {
++ long z[] = new long[4];
++ for ( int i = 0 ; i < 4 ; i++ ) {
++ z[3-i] = BitsLong.unpack(x, i*16, (i+1)*16) ;
++ }
++ System.out.printf("0x%04X %04X %04X %04X\n", z[0], z[1], z[2], z[3]);
++ }
++}