Skip to content

Commit 3aa8be2

Browse files
committed
GH-3026: spatial index per graph and kryo serialization
1 parent 5d83141 commit 3aa8be2

File tree

78 files changed

+6625
-825
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+6625
-825
lines changed

jena-arq/src/main/java/org/apache/jena/sparql/util/Context.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818

1919
package org.apache.jena.sparql.util;
2020

21-
import java.util.*;
21+
import java.util.Map;
22+
import java.util.Set;
2223
import java.util.concurrent.ConcurrentHashMap;
2324
import java.util.concurrent.atomic.AtomicBoolean;
2425
import java.util.function.BiConsumer;
26+
import java.util.function.BiFunction;
2527

2628
import org.apache.jena.atlas.lib.Lib;
2729
import org.apache.jena.atlas.logging.Log;
@@ -387,6 +389,11 @@ public void clear() {
387389
context.clear();
388390
}
389391

392+
/** Atomic compute. */
393+
public <V> Object compute(Symbol key, BiFunction<Symbol, Object, V> remappingFunction) {
394+
return context.compute(key, remappingFunction);
395+
}
396+
390397
@Override
391398
public String toString() {
392399
String x = "";
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package org.apache.jena.system;
19+
20+
import org.apache.jena.sparql.core.Transactional;
21+
22+
/**
23+
* Transaction control for use with try-with-resources.
24+
* See {@link Txn#begin(Transactional, org.apache.jena.query.TxnType)}.
25+
*/
26+
public class AutoTxn
27+
implements AutoCloseable
28+
{
29+
private Transactional txn;
30+
private boolean isTxnStartedHere;
31+
32+
/** Created from {@link Txn#begin(Transactional, org.apache.jena.query.TxnType)}. */
33+
AutoTxn(Transactional txn, boolean isTxnStartedHere) {
34+
super();
35+
this.txn = txn;
36+
this.isTxnStartedHere = isTxnStartedHere;
37+
}
38+
39+
public void commit() {
40+
if ( txn.isInTransaction() ) {
41+
42+
// May have been explicit commit or abort.
43+
txn.commit();
44+
}
45+
}
46+
47+
@Override
48+
public void close() {
49+
if ( isTxnStartedHere ) {
50+
if ( txn.isInTransaction() )
51+
// May have been explicit commit or abort.
52+
txn.abort();
53+
txn.end();
54+
}
55+
}
56+
}

jena-arq/src/main/java/org/apache/jena/system/Txn.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
package org.apache.jena.system;
2020

21+
import java.util.Objects;
2122
import java.util.function.Supplier;
2223

24+
import org.apache.jena.query.ReadWrite;
2325
import org.apache.jena.query.TxnType;
2426
import org.apache.jena.sparql.core.Transactional;
2527

@@ -137,4 +139,46 @@ private static <T extends Transactional> void onThrowable(Throwable th, T txn) {
137139
txn.end();
138140
} catch (Throwable th2) { th.addSuppressed(th2); }
139141
}
142+
143+
/**
144+
* Begins a transaction and returns a transaction control instance suitable
145+
* for use with try-with-resources blocks.
146+
* See {@link #begin(Transactional, TxnType)}.
147+
*/
148+
public static AutoTxn begin(Transactional txn, ReadWrite readWrite) {
149+
return begin(txn, TxnType.convert(readWrite));
150+
}
151+
152+
/**
153+
* Begins a transaction and returns a transaction control instance suitable
154+
* for use with try-with-resources blocks.
155+
* Allows for raising checked exceptions in an idiomatic way.
156+
* Closing the TxnCtl instance will abort the transaction unless it
157+
* has been manually committed.
158+
* <p>
159+
*
160+
* Usage example:
161+
* <pre>
162+
* public void myMethod() throws IOException {
163+
* try (AutoTxn txn = Txn.begin(dataset, TxnType.WRITE)) {
164+
* // Do work
165+
* if (someError) {
166+
* throw new IOException();
167+
* }
168+
* // Must manually call commit on success.
169+
* txn.commit();
170+
* }
171+
* }
172+
* </pre>
173+
*/
174+
public static AutoTxn begin(Transactional txn, TxnType txnType) {
175+
Objects.requireNonNull(txn);
176+
Objects.requireNonNull(txnType);
177+
boolean isTxnStartedHere = !txn.isInTransaction();
178+
if ( !isTxnStartedHere )
179+
TxnOp.compatibleWithPromote(txnType, txn);
180+
else
181+
txn.begin(txnType);
182+
return new AutoTxn(txn, isTxnStartedHere);
183+
}
140184
}

jena-arq/src/main/java/org/apache/jena/web/HttpSC.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public boolean isServerError()
306306
*/
307307
public static Code getCode(int code)
308308
{
309-
if (code <= MAX_CODE)
309+
if (code >= 0 && code <= MAX_CODE)
310310
{
311311
return codeMap[code];
312312
}

jena-arq/src/test/java/org/apache/jena/system/TestTxn.java

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.junit.Assert.assertEquals;
2222
import static org.junit.Assert.assertFalse;
2323
import static org.junit.Assert.assertTrue;
24+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2425

2526
import org.apache.jena.query.ReadWrite;
2627
import org.apache.jena.query.TxnType;
@@ -31,7 +32,7 @@
3132

3233
public class TestTxn {
3334

34-
TxnCounter counter = new TxnCounter(0) ;
35+
TxnCounter counter = new TxnCounter(0) ;
3536

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

4445
@Test public void txn_basic_02() {
45-
long x =
46+
long x =
4647
Txn.calculateRead(counter, () -> {
4748
assertEquals("In R, value()", 0, counter.value()) ;
4849
assertEquals("In R, get()", 0, counter.get()) ;
@@ -53,7 +54,7 @@ public class TestTxn {
5354

5455
@Test public void txn_basic_03() {
5556
Txn.executeWrite(counter, counter::inc) ;
56-
long x =
57+
long x =
5758
Txn.calculateRead(counter, () -> {
5859
assertEquals("In R, value()", 1, counter.value()) ;
5960
assertEquals("In R, get()", 1, counter.get()) ;
@@ -63,7 +64,7 @@ public class TestTxn {
6364
}
6465

6566
@Test public void txn_basic_05() {
66-
long x =
67+
long x =
6768
Txn.calculateWrite(counter, () -> {
6869
counter.inc() ;
6970
assertEquals("In W, value()", 0, counter.value()) ;
@@ -74,7 +75,7 @@ public class TestTxn {
7475
}
7576

7677
@Test public void txn_write_01() {
77-
long x =
78+
long x =
7879
Txn.calculateWrite(counter, () -> {
7980
counter.inc() ;
8081
assertEquals("In W, value()", 0, counter.value()) ;
@@ -87,7 +88,7 @@ public class TestTxn {
8788
}
8889

8990
@Test public void txn_write_02() {
90-
long x =
91+
long x =
9192
Txn.calculateWrite(counter, () -> {
9293
counter.inc() ;
9394
assertEquals("In W, value()", 0, counter.value()) ;
@@ -121,13 +122,13 @@ public class TestTxn {
121122

122123
@Test public void txn_rw_1() {
123124
assertEquals(0, counter.get()) ;
124-
125+
125126
Txn.executeWrite(counter, () -> {
126127
counter.inc() ;
127128
assertEquals("In W, value()", 0, counter.value()) ;
128129
assertEquals("In W, get()",1, counter.get()) ;
129130
}) ;
130-
131+
131132
assertEquals("Direct value()", 1, counter.value()) ;
132133
assertEquals("Direct get()", 1, counter.get()) ;
133134

@@ -148,7 +149,7 @@ public class TestTxn {
148149
assertEquals("In W, value()", 0, counter.value()) ;
149150
assertEquals("In W, get()",1, counter.get()) ;
150151
}) ;
151-
152+
152153
assertEquals("Direct value()", 1, counter.get()) ;
153154
assertEquals("Direct get()", 1, counter.get()) ;
154155

@@ -160,11 +161,11 @@ public class TestTxn {
160161

161162
@Test public void txn_continue_1() {
162163
Txn.executeWrite(counter, ()->counter.set(91)) ;
163-
164+
164165
Txn.executeWrite(counter, ()-> {
165166
assertEquals("In txn, value()", 91, counter.value()) ;
166167
assertEquals("In txn, read()", 91, counter.read()) ;
167-
counter.inc();
168+
counter.inc();
168169
Txn.executeWrite(counter, ()->{
169170
assertEquals("In txn, value()", 91, counter.value()) ;
170171
assertEquals("In txn, get()", 92, counter.read()) ;
@@ -175,11 +176,11 @@ public class TestTxn {
175176

176177
@Test public void txn_continue_2() {
177178
Txn.executeWrite(counter, ()->counter.set(91)) ;
178-
179+
179180
Txn.executeWrite(counter, ()-> {
180181
assertEquals("In txn, value()", 91, counter.value()) ;
181182
assertEquals("In txn, read()", 91, counter.read()) ;
182-
counter.inc();
183+
counter.inc();
183184
Txn.executeWrite(counter, ()->{
184185
assertEquals("In txn, value()", 91, counter.value()) ;
185186
assertEquals("In txn, get()", 92, counter.read()) ;
@@ -195,7 +196,7 @@ public class TestTxn {
195196
@Test(expected=ExceptionFromTest.class)
196197
public void txn_exception_01() {
197198
Txn.executeWrite(counter, counter::inc) ;
198-
199+
199200
Txn.executeWrite(counter, () -> {
200201
counter.inc() ;
201202
assertEquals("In W, value()", 1, counter.value()) ;
@@ -207,7 +208,7 @@ public void txn_exception_01() {
207208
@Test
208209
public void txn_exception_02() {
209210
Txn.executeWrite(counter, ()->counter.set(8)) ;
210-
211+
211212
try {
212213
Txn.executeWrite(counter, () -> {
213214
counter.inc();
@@ -327,7 +328,7 @@ public void txn_nested_11() {
327328
Txn.exec(counter, TxnType.WRITE, ()->{});
328329
});
329330
}
330-
331+
331332
@Test(expected=JenaTransactionException.class)
332333
public void txn_nested_12() {
333334
Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
@@ -339,7 +340,7 @@ public void txn_nested_12() {
339340
Txn.exec(counter, TxnType.WRITE, ()->{});
340341
});
341342
}
342-
343+
343344
@Test
344345
public void txn_nested_13() {
345346
Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
@@ -378,41 +379,67 @@ public void txn_threaded_01() {
378379
@Test
379380
public void txn_threaded_02() {
380381
//Transactional tx = DatasetGraphFactory.createTxnMem();
381-
Transactional tx = counter;
382-
382+
Transactional tx = counter;
383+
383384
// Start and enter the W transaction.
384385
ThreadAction a = ThreadTxn.threadTxnWrite(tx, ()->{});
385386

386387
// ThreadAction started ... in W transaction.
387388
Txn.exec(tx, TxnType.READ_PROMOTE, ()->{
388389
// ... have the thread action complete.
389-
a.run();
390+
a.run();
390391
// Blocks promotion.
391392
boolean b = tx.promote();
392393
assertFalse(b);
393394
assertEquals(ReadWrite.READ, tx.transactionMode());
394395
});
395396
}
396-
397+
397398
@Test
398399
public void txn_threaded_03() {
399400
Transactional tx = DatasetGraphFactory.createTxnMem();
400-
//Transactional tx = counter;
401-
401+
//Transactional tx = counter;
402+
402403
// Start and enter the W transaction.
403404
ThreadAction a = ThreadTxn.threadTxnWriteAbort(tx, ()->{});
404405

405406
// ThreadAction started ... in W transaction.
406407
Txn.exec(tx, TxnType.READ_PROMOTE, ()->{
407408
// ... have the thread action abort..
408-
a.run();
409+
a.run();
409410
// Does not block promotion.
410411
boolean b = tx.promote();
411412
assertTrue(b);
412413
assertEquals(ReadWrite.WRITE, tx.transactionMode());
413414
});
414415
}
415416

417+
@Test public void txn_ctl_write_01() {
418+
long actualValue;
419+
try (AutoTxn txn = Txn.begin(counter, TxnType.WRITE)) {
420+
counter.inc() ;
421+
assertEquals("In W, value()", 0, counter.value()) ;
422+
assertEquals("In W, get()",1, counter.get()) ;
423+
actualValue = counter.get() ;
424+
counter.commit() ;
425+
}
426+
long expectedValue = counter.get();
427+
assertEquals("Outside W", expectedValue, actualValue) ;
428+
}
429+
430+
@Test public void txn_ctl_write_02() {
431+
long expectedValue = counter.get();
432+
try (AutoTxn txn = Txn.begin(counter, TxnType.WRITE)) {
433+
counter.inc() ;
434+
assertEquals("In W, value()", 0, counter.value()) ;
435+
assertEquals("In W, get()",1, counter.get()) ;
436+
// Intermediate value will be reverted.
437+
long intermediateValue = counter.get() ;
438+
assertNotEquals(expectedValue, intermediateValue);
439+
// no commit - auto-close is expected to abort.
440+
}
441+
long actualValue = counter.get();
442+
assertEquals("Outside W", expectedValue, actualValue) ;
443+
}
416444
}
417445

418-

jena-benchmarks/jena-benchmarks-jmh/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@
7171
<scope>test</scope>
7272
</dependency>
7373

74+
<dependency>
75+
<groupId>org.apache.jena</groupId>
76+
<artifactId>jena-geosparql</artifactId>
77+
<version>5.5.0-SNAPSHOT</version>
78+
<scope>test</scope>
79+
</dependency>
80+
7481
<dependency>
7582
<groupId>org.apache.jena</groupId>
7683
<artifactId>jena-arq</artifactId>

0 commit comments

Comments
 (0)