/*
* 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.tdb.transaction ;
import static org.junit.Assert.assertEquals ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.sse.SSE ;
import org.apache.jena.system.Txn ;
import org.apache.jena.tdb.TDB ;
import org.apache.jena.tdb.TDBFactory ;
import org.apache.jena.tdb.sys.SystemTDB ;
import org.apache.jena.tdb.sys.TDBInternal ;
import org.apache.log4j.Level ;
import org.apache.log4j.Logger ;
import org.junit.* ;
/** Tests for transaction controls: batching, flushing on size, flushing on backlog of commits */
public class TestTransControl {
// Currently,
// this feature is off and needs enabling via DatasetGraphTransaction.promotion
// promotiion is implicit whe a write happens.
// See beforeClass / afterClass.
private static Logger logger1 = Logger.getLogger(SystemTDB.errlog.getName()) ;
private static Level level1 ;
private static Logger logger2 = Logger.getLogger(TDB.logInfoName) ;
private static Level level2 ;
private static int x_QueueBatchSize ;
private static int x_MaxQueueThreshold ;
private static int x_JournalThresholdSize ;
@BeforeClass
static public void beforeClass() {
level1 = logger1.getLevel() ;
level2 = logger2.getLevel() ;
x_QueueBatchSize = TransactionManager.QueueBatchSize ;
x_MaxQueueThreshold = TransactionManager.MaxQueueThreshold ;
x_JournalThresholdSize = TransactionManager.JournalThresholdSize ;
// logger1.setLevel(Level.ERROR) ;
// logger2.setLevel(Level.ERROR) ;
}
@AfterClass
static public void afterClass() {
// Restore logging setting.
logger2.setLevel(level2) ;
logger1.setLevel(level1) ;
TransactionManager.QueueBatchSize = x_QueueBatchSize ;
TransactionManager.MaxQueueThreshold = x_MaxQueueThreshold ;
TransactionManager.JournalThresholdSize = x_JournalThresholdSize ;
}
@Before
public void before() {
// Set all "off"
TransactionManager.QueueBatchSize = 1000 ;
TransactionManager.MaxQueueThreshold = -1 ;
TransactionManager.JournalThresholdSize = -1 ;
}
@After
public void after() {
}
private static Quad q1 = SSE.parseQuad("(_ :s :p1 1)") ;
private static Quad q2 = SSE.parseQuad("(_ :s :p2 2)") ;
private static Quad q3 = SSE.parseQuad("(_ :s :p3 3)") ;
protected DatasetGraph create() {
return TDBFactory.createDatasetGraph() ;
}
// ---- JournalThresholdSize
// Flush on journal size / no spill.
@Test public void journalThresholdSize_01() {
TransactionManager.QueueBatchSize = 100 ;
TransactionManager.MaxQueueThreshold = -1 ;
TransactionManager.JournalThresholdSize = 1000 ; // More than commit size, less than a block.
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
Txn.executeWrite(dsg, ()->{}); // About 20 bytes.
assertEquals(1, tMgr.getQueueLength()) ;
}
// Flush on journal size / small setting.
@Test public void journalThresholdSize_02() {
TransactionManager.QueueBatchSize = 100 ;
TransactionManager.MaxQueueThreshold = -1 ;
TransactionManager.JournalThresholdSize = 10 ; // Less than commit size.
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
txnAddData(dsg) ;
assertEquals(0, tMgr.getQueueLength()) ;
}
// Intermediate flush journal size.
@Test public void journalThresholdSize_03() {
TransactionManager.QueueBatchSize = 100 ;
TransactionManager.MaxQueueThreshold = -1 ;
TransactionManager.JournalThresholdSize = 1000 ; // More than commit size, less than block.
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
Txn.executeWrite(dsg, ()->{}); // About 20 bytes.
assertEquals(1, tMgr.getQueueLength()) ;
txnAddData(dsg) ;
assertEquals(0, tMgr.getQueueLength()) ;
}
// ---- QueueBatchSize
@Test public void queueBatchSize_01() {
TransactionManager.QueueBatchSize = 0 ; // Immediate.
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(0, tMgr.getQueueLength()) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(0, tMgr.getQueueLength()) ;
}
@Test public void queueBatchSize_02() {
TransactionManager.QueueBatchSize = 1 ;
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(1, tMgr.getQueueLength()) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(0, tMgr.getQueueLength()) ;
}
@Test public void queueBatchSize_03() {
TransactionManager.QueueBatchSize = 2 ;
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
txnAddData(dsg) ;
assertEquals(1, tMgr.getQueueLength()) ;
txnAddData(dsg) ;
assertEquals(2, tMgr.getQueueLength()) ;
txnAddData(dsg) ;
assertEquals(0, tMgr.getQueueLength()) ;
}
// ---- MaxQueueThreshold
@Test public void maxQueueThreshold_01() {
TransactionManager.MaxQueueThreshold = 1 ;
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(1, tMgr.getQueueLength()) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(0, tMgr.getQueueLength()) ;
}
@Test public void maxQueueThreshold_02() {
TransactionManager.MaxQueueThreshold = 2 ;
DatasetGraph dsg = create() ;
TransactionManager tMgr = TDBInternal.getTransactionManager(dsg) ;
txnAddData(dsg) ;
assertEquals(1, tMgr.getQueueLength()) ;
txnAddData(dsg) ;
assertEquals(2, tMgr.getQueueLength()) ;
Txn.executeWrite(dsg, ()->{});
assertEquals(0, tMgr.getQueueLength()) ;
}
private static void txnAddData(DatasetGraph dsg) {
// Unique blank node.
Quad q = SSE.parseQuad("(_ _:b :p 1)") ;
Txn.executeWrite(dsg, ()->dsg.add(q));
}
}