diff --git a/community/io/src/main/java/org/neo4j/io/pagecache/tracing/cursor/DefaultPageCursorTracer.java b/community/io/src/main/java/org/neo4j/io/pagecache/tracing/cursor/DefaultPageCursorTracer.java index 36e1832481475..c3ceaeed3dd54 100644 --- a/community/io/src/main/java/org/neo4j/io/pagecache/tracing/cursor/DefaultPageCursorTracer.java +++ b/community/io/src/main/java/org/neo4j/io/pagecache/tracing/cursor/DefaultPageCursorTracer.java @@ -67,12 +67,12 @@ public void reportEvents() if ( hits > 0 ) { pageCacheTracer.hits( hits ); - historicalHits = Math.addExact( historicalHits, hits ); + historicalHits = historicalHits + hits; } if ( faults > 0 ) { pageCacheTracer.faults( faults ); - historicalFaults = Math.addExact( historicalFaults, faults ); + historicalFaults = historicalFaults + faults; } if ( bytesRead > 0 ) { @@ -100,13 +100,13 @@ public void reportEvents() @Override public long accumulatedHits() { - return Math.addExact( historicalHits, hits ); + return historicalHits + hits; } @Override public long accumulatedFaults() { - return Math.addExact( historicalFaults, faults ); + return historicalFaults + faults; } private void reset() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransactionHandle.java b/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransactionHandle.java index ae23a1d0c4616..fe7bb79ca810c 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransactionHandle.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/KernelTransactionHandle.java @@ -109,12 +109,20 @@ public interface KernelTransactionHandle boolean isUnderlyingTransaction( KernelTransaction tx ); /** - * User transaction id of underlying transaction. User transaction id is positive long number. + * User transaction id of underlying transaction. User transaction id is a not negative long number. * Should be unique across transactions. * @return user transaction id */ long getUserTransactionId(); + /** + * User transaction name of the underlying transaction. + * User transaction name consists of the name prefix and user transaction id. + * Should be unique across transactions. + * @return user transaction name + */ + String getUserTransactionName(); + /** * @return a list of all queries currently executing that use the underlying transaction */ diff --git a/community/kernel/src/main/java/org/neo4j/kernel/api/query/ExecutingQueryStatus.java b/community/kernel/src/main/java/org/neo4j/kernel/api/query/ExecutingQueryStatus.java index 94fc9a8463326..f7537334238f0 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/api/query/ExecutingQueryStatus.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/api/query/ExecutingQueryStatus.java @@ -58,7 +58,7 @@ boolean isPlanning() /** * Is query waiting on a locks - * @return true if waiting on a locks, false otherwise + * @return true if waiting on locks, false otherwise */ boolean isWaitingOnLocks() { @@ -66,7 +66,7 @@ boolean isWaitingOnLocks() } /** - * List of locks query is waiting on. Will be empty for all of the statuses except + * List of locks query is waiting on. Will be empty for all of the statuses except for {@link WaitingOnLock}. * @return list of locks query is waiting on, empty list if query is not waiting. */ List waitingOnLocks() diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementationHandle.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementationHandle.java index 860b245ef0994..48ba2f528ac55 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementationHandle.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactionImplementationHandle.java @@ -39,6 +39,8 @@ */ class KernelTransactionImplementationHandle implements KernelTransactionHandle { + private static final String USER_TRANSACTION_NAME_PREFIX = "transaction-"; + private final long txReuseCount; private final long lastTransactionIdWhenStarted; private final long lastTransactionTimestampWhenStarted; @@ -134,6 +136,12 @@ public long getUserTransactionId() return userTransactionId; } + @Override + public String getUserTransactionName() + { + return USER_TRANSACTION_NAME_PREFIX + getUserTransactionId(); + } + @Override public Stream executingQueries() { diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java index f8019fbf37476..4668a1f1387d9 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/KernelTransactions.java @@ -87,7 +87,7 @@ public class KernelTransactions extends LifecycleAdapter implements Supplier explicitIndexTxStateSupplier; private final SystemNanoClock clock; private final ReentrantReadWriteLock newTransactionsLock = new ReentrantReadWriteLock(); - private final MonotonicCounter userTransactionIdCounter = MonotonicCounter.newAtomicMonotonicCounter(); + private final MonotonicCounter userTransactionIdCounter = MonotonicCounter.newCounter(); /** * Used to enumerate all transactions in the system, active and idle ones. diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StackingQueryRegistrationOperations.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StackingQueryRegistrationOperations.java index 6b4fc440e924f..8339e8a2cdfe8 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StackingQueryRegistrationOperations.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/StackingQueryRegistrationOperations.java @@ -32,7 +32,7 @@ public class StackingQueryRegistrationOperations implements QueryRegistrationOperations { - private final MonotonicCounter lastQueryId = MonotonicCounter.newAtomicMonotonicCounter(); + private final MonotonicCounter lastQueryId = MonotonicCounter.newCounter(); private final SystemNanoClock clock; private final CpuClock cpuClock; private final HeapAllocation heapAllocation; diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/util/MonotonicCounter.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/util/MonotonicCounter.java index aae03a2cf11ee..9d46f1832df6f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/util/MonotonicCounter.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/util/MonotonicCounter.java @@ -21,29 +21,54 @@ import java.util.concurrent.atomic.AtomicLong; +/** + * Counter that produce sequence of incremental numbers + */ public interface MonotonicCounter { long increment(); - static MonotonicCounter newAtomicMonotonicCounter() + /** + * Create new counter with specified initial value + * @param initialValue initial value + * @return counter newly created counter + */ + static MonotonicCounter newCounter( int initialValue ) { - return new MonotonicCounter() + assert initialValue >= 0; + return new NaturalCounter( initialValue ); + } + + /** + * Create new counter with default 0 as its initial value + * @return counter newly created counter + */ + static MonotonicCounter newCounter() + { + return new NaturalCounter( 0 ); + } + + class NaturalCounter implements MonotonicCounter + { + private final AtomicLong value; + + NaturalCounter( int initialValue ) { - private final AtomicLong value = new AtomicLong( 0L ); + value = new AtomicLong( initialValue ); + } - @Override - public long increment() + @Override + public long increment() + { + int initialValue; + int incrementedValue; + do { - int initialValue; - int incrementedValue; - do - { - initialValue = value.intValue(); - incrementedValue = initialValue < 0 ? 0 : initialValue + 1; - } - while ( !value.compareAndSet( initialValue, incrementedValue ) ); - return incrementedValue; + initialValue = value.intValue(); + incrementedValue = initialValue == Integer.MAX_VALUE ? 0 : initialValue + 1; } - }; + while ( !value.compareAndSet( initialValue, incrementedValue ) ); + return incrementedValue; + } } } diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TestKernelTransactionHandle.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TestKernelTransactionHandle.java index 7aa1e8165b9b3..007949446507b 100644 --- a/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TestKernelTransactionHandle.java +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/api/TestKernelTransactionHandle.java @@ -37,6 +37,7 @@ */ public class TestKernelTransactionHandle implements KernelTransactionHandle { + private static final String USER_TRANSACTION_NAME_PREFIX = "transaction-"; private final KernelTransaction tx; public TestKernelTransactionHandle( KernelTransaction tx ) @@ -111,6 +112,12 @@ public long getUserTransactionId() return tx.getTransactionId(); } + @Override + public String getUserTransactionName() + { + return USER_TRANSACTION_NAME_PREFIX + getUserTransactionId(); + } + @Override public Stream executingQueries() { diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/util/MonotonicCounterTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/util/MonotonicCounterTest.java new file mode 100644 index 0000000000000..6e2e9bcd87ad3 --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/util/MonotonicCounterTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2002-2017 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.util; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class MonotonicCounterTest +{ + @Test + public void counterProducePositiveNumbers() + { + MonotonicCounter monotonicCounter = MonotonicCounter.newCounter( Integer.MAX_VALUE - 10 ); + for ( int i = 0; i < 100; i++ ) + { + assertTrue( monotonicCounter.increment() >= 0 ); + } + } +} diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolver.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolver.java index 112f4f4e226e1..bbebc6bb50f9c 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolver.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolver.java @@ -168,7 +168,7 @@ private String describe( Set allBlockers ) StringJoiner stringJoiner = new StringJoiner( ", ", "[", "]" ); for ( KernelTransactionHandle blocker : allBlockers ) { - stringJoiner.add( TransactionId.ofTransactionHandle( blocker ) ); + stringJoiner.add( blocker.getUserTransactionName() ); } return stringJoiner.toString(); } diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionId.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionId.java deleted file mode 100644 index 4100b8e1d4aab..0000000000000 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionId.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2002-2017 "Neo Technology," - * Network Engine for Objects in Lund AB [http://neotechnology.com] - * - * This file is part of Neo4j. - * - * Neo4j is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.neo4j.kernel.enterprise.builtinprocs; - -import org.neo4j.kernel.api.KernelTransactionHandle; - -public class TransactionId -{ - private static final String USER_TRANSACTION_ID_PREFIX = "transaction-"; - - private TransactionId() - { - } - - static String ofTransactionHandle( KernelTransactionHandle transaction ) - { - return USER_TRANSACTION_ID_PREFIX + transaction.getUserTransactionId(); - } -} diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResult.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResult.java index 94d2581ef19ad..13a5bdc87ed5a 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResult.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResult.java @@ -68,7 +68,7 @@ public TransactionStatusResult( KernelTransactionHandle transaction, TransactionDependenciesResolver transactionDependenciesResolver, Map> handleSnapshotsMap ) throws InvalidArgumentsException { - this.transactionId = toUserTransactionId( transaction ); + this.transactionId = transaction.getUserTransactionName(); this.username = transaction.securityContext().subject().username(); this.startTime = ProceduresTimeFormatHelper.formatTime( transaction.startTime() ); Optional terminationReason = transaction.terminationReason(); @@ -106,11 +106,6 @@ public TransactionStatusResult( KernelTransactionHandle transaction, this.metaData = transaction.getMetaData(); } - private String toUserTransactionId( KernelTransactionHandle transaction ) - { - return TransactionId.ofTransactionHandle( transaction ); - } - private String getStatus( KernelTransactionHandle handle, Optional terminationReason, TransactionDependenciesResolver transactionDependenciesResolver ) { diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolverTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolverTest.java index c052262a32769..ce5a1309aaa25 100644 --- a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolverTest.java +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionDependenciesResolverTest.java @@ -169,7 +169,8 @@ private ExecutingQuery createExecutingQuery( long queryId ) { return new ExecutingQuery( queryId, ClientConnectionInfo.EMBEDDED_CONNECTION, "test", "testQuey", VirtualValues.EMPTY_MAP, Collections.emptyMap(), () -> 1L, PageCursorTracer.NULL, - Thread.currentThread(), Clocks.nanoClock(), CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE ); + Thread.currentThread().getId(), Thread.currentThread().getName(), + Clocks.nanoClock(), CpuClock.NOT_AVAILABLE, HeapAllocation.NOT_AVAILABLE ); } private static class TestKernelTransactionHandleWithLocks extends TestKernelTransactionHandle diff --git a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResultTest.java b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResultTest.java index 074cd542bea2c..cc2da44d57ae3 100644 --- a/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResultTest.java +++ b/enterprise/kernel/src/test/java/org/neo4j/kernel/enterprise/builtinprocs/TransactionStatusResultTest.java @@ -154,7 +154,8 @@ private QuerySnapshot createQuerySnapshot( long queryId ) private ExecutingQuery createExecutingQuery( long queryId ) { return new ExecutingQuery( queryId, getTestConnectionInfo(), "testUser", "testQuery", VirtualValues.EMPTY_MAP, - Collections.emptyMap(), () -> 1L, PageCursorTracer.NULL, Thread.currentThread(), + Collections.emptyMap(), () -> 1L, PageCursorTracer.NULL, + Thread.currentThread().getId(), Thread.currentThread().getName(), new CountingSystemNanoClock(), new CountingCpuClock(), new CountingHeapAllocation() ); }