org.neo4j.kernel.impl.api.parallel.ThreadExecutionContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-kernel Show documentation
Show all versions of neo4j-kernel Show documentation
Neo4j kernel is a lightweight, embedded Java database designed to
store data structured as graphs rather than tables. For more
information, see http://neo4j.org.
The newest version!
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.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.api.parallel;
import static org.neo4j.function.Suppliers.singleton;
import static org.neo4j.io.IOUtils.closeAllUnchecked;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.neo4j.collection.Dependencies;
import org.neo4j.internal.kernel.api.EntityLocks;
import org.neo4j.internal.kernel.api.IndexMonitor;
import org.neo4j.internal.kernel.api.Locks;
import org.neo4j.internal.kernel.api.Procedures;
import org.neo4j.internal.kernel.api.QueryContext;
import org.neo4j.internal.kernel.api.Read;
import org.neo4j.internal.kernel.api.SchemaRead;
import org.neo4j.internal.kernel.api.TokenRead;
import org.neo4j.internal.kernel.api.security.SecurityAuthorizationHandler;
import org.neo4j.internal.kernel.api.security.SecurityContext;
import org.neo4j.internal.schema.SchemaState;
import org.neo4j.io.pagecache.context.CursorContext;
import org.neo4j.kernel.api.AccessModeProvider;
import org.neo4j.kernel.api.ExecutionContext;
import org.neo4j.kernel.api.KernelTransaction;
import org.neo4j.kernel.api.procedure.ProcedureView;
import org.neo4j.kernel.api.txstate.TransactionState;
import org.neo4j.kernel.api.txstate.TxStateHolder;
import org.neo4j.kernel.impl.api.ClockContext;
import org.neo4j.kernel.impl.api.CloseableResourceManager;
import org.neo4j.kernel.impl.api.OverridableSecurityContext;
import org.neo4j.kernel.impl.api.index.IndexingService;
import org.neo4j.kernel.impl.api.index.stats.IndexStatisticsStore;
import org.neo4j.kernel.impl.locking.LockManager.Client;
import org.neo4j.kernel.impl.newapi.DefaultPooledCursors;
import org.neo4j.kernel.impl.newapi.KernelProcedures;
import org.neo4j.kernel.impl.newapi.KernelProcedures.ForThreadExecutionContextScope;
import org.neo4j.kernel.impl.newapi.KernelRead;
import org.neo4j.kernel.impl.newapi.KernelSchemaRead;
import org.neo4j.lock.LockTracer;
import org.neo4j.memory.MemoryTracker;
import org.neo4j.storageengine.api.StorageLocks;
import org.neo4j.storageengine.api.StorageReader;
import org.neo4j.storageengine.api.cursor.StoreCursors;
import org.neo4j.values.ElementIdMapper;
public class ThreadExecutionContext implements ExecutionContext, AutoCloseable {
public static final TxStateHolder THREAD_EXECUTION_STATE_HOLDER = new TxStateHolder() {
@Override
public TransactionState txState() {
throw new UnsupportedOperationException(
"Accessing transaction state is not allowed during parallel execution");
}
@Override
public boolean hasTxStateWithChanges() {
return false;
}
};
private final CloseableResourceManager resourceManager = new CloseableResourceManager();
private final DefaultPooledCursors cursors;
private final CursorContext context;
private final OverridableSecurityContext overridableSecurityContext;
private final ExecutionContextCursorTracer cursorTracer;
private final CursorContext ktxContext;
private final KernelRead kernelRead;
private final KernelProcedures.ForThreadExecutionContextScope procedures;
private final TokenRead tokenRead;
private final StoreCursors storageCursors;
private final MemoryTracker contextTracker;
private final SecurityAuthorizationHandler securityAuthorizationHandler;
private final ElementIdMapper elementIdMapper;
private final List otherResources;
private final ExecutionContextProcedureKernelTransaction ktx;
private final Supplier clockContextSupplier;
private final QueryContext queryContext;
private final EntityLocks entityLocks;
private final SchemaRead schemaRead;
private final AccessModeProvider accessModeProvider;
public ThreadExecutionContext(
DefaultPooledCursors cursors,
CursorContext context,
OverridableSecurityContext overridableSecurityContext,
ExecutionContextCursorTracer cursorTracer,
CursorContext ktxContext,
TokenRead tokenRead,
StoreCursors storageCursors,
IndexMonitor monitor,
MemoryTracker contextTracker,
SecurityAuthorizationHandler securityAuthorizationHandler,
StorageReader storageReader,
SchemaState schemaState,
IndexingService indexingService,
IndexStatisticsStore indexStatisticsStore,
Dependencies databaseDependencies,
StorageLocks storageLocks,
Client lockClient,
LockTracer lockTracer,
ElementIdMapper elementIdMapper,
KernelTransaction ktx,
Supplier clockContextSupplier,
List otherResources,
ProcedureView procedureView,
boolean multiVersioned) {
this.cursors = cursors;
this.context = context;
this.overridableSecurityContext = overridableSecurityContext;
this.cursorTracer = cursorTracer;
this.ktxContext = ktxContext;
this.tokenRead = tokenRead;
this.storageCursors = storageCursors;
this.contextTracker = contextTracker;
this.securityAuthorizationHandler = securityAuthorizationHandler;
this.otherResources = otherResources;
this.elementIdMapper = elementIdMapper;
this.ktx = new ExecutionContextProcedureKernelTransaction(ktx, this);
this.clockContextSupplier = clockContextSupplier;
this.queryContext = new ThreadExecutionQueryContext(this::dataRead, cursors, context, contextTracker, monitor);
this.entityLocks = new EntityLocks(storageLocks, singleton(lockTracer), lockClient, this.ktx);
this.procedures = new ForThreadExecutionContextScope(
this,
databaseDependencies,
overridableSecurityContext,
this.ktx,
securityAuthorizationHandler,
clockContextSupplier,
procedureView);
this.accessModeProvider =
() -> overridableSecurityContext.currentSecurityContext().mode();
this.schemaRead = new KernelSchemaRead(
schemaState,
indexStatisticsStore,
storageReader,
entityLocks,
this.ktx,
indexingService,
this.ktx,
accessModeProvider);
this.kernelRead = new KernelRead(
storageReader,
this.tokenRead(),
cursors,
storageCursors,
entityLocks,
queryContext,
THREAD_EXECUTION_STATE_HOLDER,
schemaRead,
indexingService,
this.memoryTracker(),
multiVersioned,
this.ktx,
accessModeProvider,
true);
}
public Supplier clockContextSupplier() {
return clockContextSupplier;
}
public OverridableSecurityContext overridableSecurityContext() {
return overridableSecurityContext;
}
@Override
public CursorContext cursorContext() {
return context;
}
@Override
public DefaultPooledCursors cursors() {
return cursors;
}
@Override
public SecurityContext securityContext() {
return overridableSecurityContext.currentSecurityContext();
}
@Override
public Read dataRead() {
return kernelRead;
}
@Override
public TokenRead tokenRead() {
return tokenRead;
}
@Override
public SchemaRead schemaRead() {
return schemaRead;
}
@Override
public Procedures procedures() {
return procedures;
}
@Override
public void complete() {
List resources = new ArrayList<>(otherResources);
resources.add(resourceManager::closeAllCloseableResources);
resources.add(cursors::release);
resources.add(storageCursors);
closeAllUnchecked(resources);
cursorTracer.complete();
}
@Override
public void report() {
mergeBlocked(cursorTracer, contextTracker);
}
@Override
public ElementIdMapper elementIdMapper() {
return elementIdMapper;
}
@Override
public void performCheckBeforeOperation() {
ktx.assertOpen();
}
@Override
public boolean isTransactionOpen() {
return ktx.isOpen();
}
@Override
public QueryContext queryContext() {
return queryContext;
}
@Override
public AccessModeProvider accessModeProvider() {
return accessModeProvider;
}
@Override
public TxStateHolder txStateHolder() {
return THREAD_EXECUTION_STATE_HOLDER;
}
@Override
public MemoryTracker memoryTracker() {
return contextTracker;
}
@Override
public Locks locks() {
return entityLocks;
}
@Override
public SecurityAuthorizationHandler securityAuthorizationHandler() {
return securityAuthorizationHandler;
}
@Override
public void close() {
if (!cursorTracer.isCompleted()) {
// this indicates incorrect usage
throw new IllegalStateException("Execution context closed before it was marked as completed.");
}
mergeBlocked(cursorTracer, contextTracker);
}
private void mergeBlocked(ExecutionContextCursorTracer cursorTracer, MemoryTracker contextTracker) {
synchronized (ktxContext) {
mergeUnblocked(cursorTracer, contextTracker);
}
VarHandle.fullFence();
}
private void mergeUnblocked(ExecutionContextCursorTracer cursorTracer, MemoryTracker contextTracker) {
ktxContext.merge(cursorTracer.snapshot());
contextTracker.reset();
}
@Override
public void registerCloseableResource(AutoCloseable closeableResource) {
resourceManager.registerCloseableResource(closeableResource);
}
@Override
public void unregisterCloseableResource(AutoCloseable closeableResource) {
resourceManager.unregisterCloseableResource(closeableResource);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy