Skip to content

GH-3026: spatial index per graph and kryo serialization #3027

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@

package org.apache.jena.sparql.util;

import java.util.*;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.atlas.logging.Log;
Expand Down Expand Up @@ -387,6 +389,11 @@ public void clear() {
context.clear();
}

/** Atomic compute. */
public <V> Object compute(Symbol key, BiFunction<Symbol, Object, V> remappingFunction) {
return context.compute(key, remappingFunction);
}

@Override
public String toString() {
String x = "";
Expand Down
55 changes: 55 additions & 0 deletions jena-arq/src/main/java/org/apache/jena/system/AutoTxn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.system;

import org.apache.jena.sparql.core.Transactional;

/**
* Transaction wrapper object for use with try-with-resources.
* See {@linkplain Txn#autoTxn(Transactional, org.apache.jena.query.TxnType)}.
*/
public class AutoTxn
implements AutoCloseable
{
private Transactional txn;
private boolean isTxnStartedHere;

/** This constructor is called from {@linkplain Txn#autoTxn(Transactional, org.apache.jena.query.TxnType)}. */
AutoTxn(Transactional txn, boolean isTxnStartedHere) {
super();
this.txn = txn;
this.isTxnStartedHere = isTxnStartedHere;
}

public void commit() {
if ( txn.isInTransaction() ) {
// May have been explicit commit or abort.
txn.commit();
}
}

@Override
public void close() {
if ( isTxnStartedHere ) {
if ( txn.isInTransaction() )
// May have been explicit commit or abort.
txn.abort();
txn.end();
}
}
}
44 changes: 44 additions & 0 deletions jena-arq/src/main/java/org/apache/jena/system/Txn.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@

package org.apache.jena.system;

import java.util.Objects;
import java.util.function.Supplier;

import org.apache.jena.query.ReadWrite;
import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.core.Transactional;

Expand Down Expand Up @@ -137,4 +139,46 @@ private static <T extends Transactional> void onThrowable(Throwable th, T txn) {
txn.end();
} catch (Throwable th2) { th.addSuppressed(th2); }
}

/**
* Begins a transaction and returns a transaction control instance suitable
* for use with try-with-resources blocks.
* See {@link #autoTxn(Transactional, TxnType)}.
*/
public static AutoTxn autoTxn(Transactional txn, ReadWrite readWrite) {
return autoTxn(txn, TxnType.convert(readWrite));
}

/**
* Begins a transaction and returns a {@linkplain AutoTxn} instance suitable
* for use with try-with-resources blocks.
* This allows for raising checked exceptions in an idiomatic way.
* Closing the AutoTxn instance will abort the transaction unless there has
* been an explicit call to {@linkplain AutoTxn#commit()}.
* <p>
*
* Usage example:
* <pre>
* public void myMethod() throws IOException {
* try (AutoTxn txn = Txn.autoTxn(dataset, TxnType.WRITE)) {
* // Do work.
* if (someError) {
* throw new IOException();
* }
* // Explicitly call commit on success.
* txn.commit();
* }
* }
* </pre>
*/
public static AutoTxn autoTxn(Transactional txn, TxnType txnType) {
Objects.requireNonNull(txn);
Objects.requireNonNull(txnType);
boolean isTxnStartedHere = !txn.isInTransaction();
if ( !isTxnStartedHere )
TxnOp.compatibleWithPromote(txnType, txn);
else
txn.begin(txnType);
return new AutoTxn(txn, isTxnStartedHere);
}
}
2 changes: 1 addition & 1 deletion jena-arq/src/main/java/org/apache/jena/web/HttpSC.java
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ public boolean isServerError()
*/
public static Code getCode(int code)
{
if (code <= MAX_CODE)
if (code >= 0 && code <= MAX_CODE)
{
return codeMap[code];
}
Expand Down
77 changes: 52 additions & 25 deletions jena-arq/src/test/java/org/apache/jena/system/TestTxn.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotEquals;

import org.apache.jena.query.ReadWrite;
import org.apache.jena.query.TxnType;
Expand All @@ -31,7 +32,7 @@

public class TestTxn {

TxnCounter counter = new TxnCounter(0) ;
TxnCounter counter = new TxnCounter(0) ;

@Test public void txn_basic_01() {
long v1 = counter.get() ;
Expand All @@ -42,7 +43,7 @@ public class TestTxn {
}

@Test public void txn_basic_02() {
long x =
long x =
Txn.calculateRead(counter, () -> {
assertEquals("In R, value()", 0, counter.value()) ;
assertEquals("In R, get()", 0, counter.get()) ;
Expand All @@ -53,7 +54,7 @@ public class TestTxn {

@Test public void txn_basic_03() {
Txn.executeWrite(counter, counter::inc) ;
long x =
long x =
Txn.calculateRead(counter, () -> {
assertEquals("In R, value()", 1, counter.value()) ;
assertEquals("In R, get()", 1, counter.get()) ;
Expand All @@ -63,7 +64,7 @@ public class TestTxn {
}

@Test public void txn_basic_05() {
long x =
long x =
Txn.calculateWrite(counter, () -> {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
Expand All @@ -74,7 +75,7 @@ public class TestTxn {
}

@Test public void txn_write_01() {
long x =
long x =
Txn.calculateWrite(counter, () -> {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
Expand All @@ -87,7 +88,7 @@ public class TestTxn {
}

@Test public void txn_write_02() {
long x =
long x =
Txn.calculateWrite(counter, () -> {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
Expand Down Expand Up @@ -121,13 +122,13 @@ public class TestTxn {

@Test public void txn_rw_1() {
assertEquals(0, counter.get()) ;

Txn.executeWrite(counter, () -> {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
assertEquals("In W, get()",1, counter.get()) ;
}) ;

assertEquals("Direct value()", 1, counter.value()) ;
assertEquals("Direct get()", 1, counter.get()) ;

Expand All @@ -148,7 +149,7 @@ public class TestTxn {
assertEquals("In W, value()", 0, counter.value()) ;
assertEquals("In W, get()",1, counter.get()) ;
}) ;

assertEquals("Direct value()", 1, counter.get()) ;
assertEquals("Direct get()", 1, counter.get()) ;

Expand All @@ -160,11 +161,11 @@ public class TestTxn {

@Test public void txn_continue_1() {
Txn.executeWrite(counter, ()->counter.set(91)) ;

Txn.executeWrite(counter, ()-> {
assertEquals("In txn, value()", 91, counter.value()) ;
assertEquals("In txn, read()", 91, counter.read()) ;
counter.inc();
counter.inc();
Txn.executeWrite(counter, ()->{
assertEquals("In txn, value()", 91, counter.value()) ;
assertEquals("In txn, get()", 92, counter.read()) ;
Expand All @@ -175,11 +176,11 @@ public class TestTxn {

@Test public void txn_continue_2() {
Txn.executeWrite(counter, ()->counter.set(91)) ;

Txn.executeWrite(counter, ()-> {
assertEquals("In txn, value()", 91, counter.value()) ;
assertEquals("In txn, read()", 91, counter.read()) ;
counter.inc();
counter.inc();
Txn.executeWrite(counter, ()->{
assertEquals("In txn, value()", 91, counter.value()) ;
assertEquals("In txn, get()", 92, counter.read()) ;
Expand All @@ -195,7 +196,7 @@ public class TestTxn {
@Test(expected=ExceptionFromTest.class)
public void txn_exception_01() {
Txn.executeWrite(counter, counter::inc) ;

Txn.executeWrite(counter, () -> {
counter.inc() ;
assertEquals("In W, value()", 1, counter.value()) ;
Expand All @@ -207,7 +208,7 @@ public void txn_exception_01() {
@Test
public void txn_exception_02() {
Txn.executeWrite(counter, ()->counter.set(8)) ;

try {
Txn.executeWrite(counter, () -> {
counter.inc();
Expand Down Expand Up @@ -327,7 +328,7 @@ public void txn_nested_11() {
Txn.exec(counter, TxnType.WRITE, ()->{});
});
}

@Test(expected=JenaTransactionException.class)
public void txn_nested_12() {
Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
Expand All @@ -339,7 +340,7 @@ public void txn_nested_12() {
Txn.exec(counter, TxnType.WRITE, ()->{});
});
}

@Test
public void txn_nested_13() {
Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
Expand Down Expand Up @@ -378,41 +379,67 @@ public void txn_threaded_01() {
@Test
public void txn_threaded_02() {
//Transactional tx = DatasetGraphFactory.createTxnMem();
Transactional tx = counter;
Transactional tx = counter;

// Start and enter the W transaction.
ThreadAction a = ThreadTxn.threadTxnWrite(tx, ()->{});

// ThreadAction started ... in W transaction.
Txn.exec(tx, TxnType.READ_PROMOTE, ()->{
// ... have the thread action complete.
a.run();
a.run();
// Blocks promotion.
boolean b = tx.promote();
assertFalse(b);
assertEquals(ReadWrite.READ, tx.transactionMode());
});
}

@Test
public void txn_threaded_03() {
Transactional tx = DatasetGraphFactory.createTxnMem();
//Transactional tx = counter;
//Transactional tx = counter;

// Start and enter the W transaction.
ThreadAction a = ThreadTxn.threadTxnWriteAbort(tx, ()->{});

// ThreadAction started ... in W transaction.
Txn.exec(tx, TxnType.READ_PROMOTE, ()->{
// ... have the thread action abort..
a.run();
a.run();
// Does not block promotion.
boolean b = tx.promote();
assertTrue(b);
assertEquals(ReadWrite.WRITE, tx.transactionMode());
});
}

@Test public void autoTxn_write_01() {
long actualValue;
try (AutoTxn txn = Txn.autoTxn(counter, TxnType.WRITE)) {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
assertEquals("In W, get()",1, counter.get()) ;
actualValue = counter.get() ;
counter.commit() ;
}
long expectedValue = counter.get();
assertEquals("Outside W", expectedValue, actualValue) ;
}

@Test public void autoTxn_write_02() {
long expectedValue = counter.get();
try (AutoTxn txn = Txn.autoTxn(counter, TxnType.WRITE)) {
counter.inc() ;
assertEquals("In W, value()", 0, counter.value()) ;
assertEquals("In W, get()",1, counter.get()) ;
// Intermediate value will be reverted.
long intermediateValue = counter.get() ;
assertNotEquals(expectedValue, intermediateValue);
// no commit - auto-close is expected to abort.
}
long actualValue = counter.get();
assertEquals("Outside W", expectedValue, actualValue) ;
}
}


7 changes: 7 additions & 0 deletions jena-benchmarks/jena-benchmarks-jmh/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-geosparql</artifactId>
<version>5.5.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-arq</artifactId>
Expand Down
Loading