-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An SPI for interacting with local context storage.
The existing implementation uses on a concurrent hash map guarded by the context instance. This new implementation relies on prior knowledge of the set of context locals, so the context allocates upfront the required space to hold the local storage, reducing synchronisation and simplifying lookup that uses allocated index instead of hashed string lookups. The existing local context data is retrofit as a context local.
- Loading branch information
Showing
21 changed files
with
611 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* | ||
* Copyright (c) 2011-2023 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*/ | ||
package io.vertx.core.impl; | ||
|
||
import io.vertx.core.spi.context.storage.AccessMode; | ||
import io.vertx.core.spi.context.storage.ContextLocal; | ||
|
||
import java.util.concurrent.atomic.AtomicReferenceArray; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* Base class for context. | ||
* | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
*/ | ||
class ContextBase extends AtomicReferenceArray<Object> { | ||
|
||
private final int localsLength; | ||
|
||
ContextBase(int localsLength) { | ||
super(localsLength); | ||
this.localsLength = localsLength; | ||
} | ||
|
||
ContextBase(ContextBase another) { | ||
super(another.localsLength); | ||
this.localsLength = another.localsLength; | ||
} | ||
|
||
public final <T> T getLocal(ContextLocal<T> key, AccessMode accessMode) { | ||
ContextLocalImpl<T> internalKey = (ContextLocalImpl<T>) key; | ||
int index = internalKey.index; | ||
if (index >= localsLength) { | ||
throw new IllegalArgumentException(); | ||
} | ||
Object res = accessMode.get(this, index); | ||
return (T) res; | ||
} | ||
|
||
public final <T> T getLocal(ContextLocal<T> key, AccessMode accessMode, Supplier<? extends T> initialValueSupplier) { | ||
ContextLocalImpl<T> internalKey = (ContextLocalImpl<T>) key; | ||
int index = internalKey.index; | ||
if (index >= localsLength) { | ||
throw new IllegalArgumentException("Invalid key index: " + index); | ||
} | ||
Object res = accessMode.getOrCreate(this, index, (Supplier<Object>) initialValueSupplier); | ||
return (T) res; | ||
} | ||
|
||
public final <T> void putLocal(ContextLocal<T> key, AccessMode accessMode, T value) { | ||
ContextLocalImpl<T> internalKey = (ContextLocalImpl<T>) key; | ||
int index = internalKey.index; | ||
if (index >= localsLength) { | ||
throw new IllegalArgumentException(); | ||
} | ||
accessMode.put(this, index, value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ | |
* @author <a href="http://tfox.org">Tim Fox</a> | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
*/ | ||
public final class ContextImpl implements ContextInternal { | ||
public final class ContextImpl extends ContextBase implements ContextInternal { | ||
|
||
static <T> void setResultHandler(ContextInternal ctx, Future<T> fut, Handler<AsyncResult<T>> resultHandler) { | ||
if (resultHandler != null) { | ||
|
@@ -52,14 +52,14 @@ static <T> void setResultHandler(ContextInternal ctx, Future<T> fut, Handler<Asy | |
private final EventLoop eventLoop; | ||
private final EventExecutor executor; | ||
private ConcurrentMap<Object, Object> data; | ||
private ConcurrentMap<Object, Object> localData; | ||
private volatile Handler<Throwable> exceptionHandler; | ||
final TaskQueue internalOrderedTasks; | ||
final WorkerPool internalWorkerPool; | ||
final WorkerPool workerPool; | ||
final TaskQueue orderedTasks; | ||
|
||
public ContextImpl(VertxInternal vertx, | ||
int localsLength, | ||
ThreadingModel threadingModel, | ||
EventLoop eventLoop, | ||
EventExecutor executor, | ||
|
@@ -69,6 +69,7 @@ public ContextImpl(VertxInternal vertx, | |
Deployment deployment, | ||
CloseFuture closeFuture, | ||
ClassLoader tccl) { | ||
super(localsLength); | ||
this.threadingModel = threadingModel; | ||
this.deployment = deployment; | ||
this.config = deployment != null ? deployment.config() : new JsonObject(); | ||
|
@@ -250,14 +251,6 @@ public synchronized ConcurrentMap<Object, Object> contextData() { | |
return data; | ||
} | ||
|
||
@Override | ||
public synchronized ConcurrentMap<Object, Object> localContextData() { | ||
if (localData == null) { | ||
localData = new ConcurrentHashMap<>(); | ||
} | ||
return localData; | ||
} | ||
|
||
public void reportException(Throwable t) { | ||
Handler<Throwable> handler = exceptionHandler; | ||
if (handler == null) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright (c) 2011-2023 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*/ | ||
package io.vertx.core.impl; | ||
|
||
import io.vertx.core.spi.context.storage.ContextLocal; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
*/ | ||
public class ContextLocalImpl<T> implements ContextLocal<T> { | ||
|
||
final int index; | ||
|
||
public ContextLocalImpl(int index) { | ||
this.index = index; | ||
} | ||
|
||
public ContextLocalImpl() { | ||
this.index = LocalSeq.next(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,12 +31,12 @@ | |
* | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
*/ | ||
class DuplicatedContext implements ContextInternal { | ||
final class DuplicatedContext extends ContextBase implements ContextInternal { | ||
|
||
protected final ContextImpl delegate; | ||
private ConcurrentMap<Object, Object> localData; | ||
final ContextImpl delegate; | ||
|
||
DuplicatedContext(ContextImpl delegate) { | ||
super(delegate); | ||
this.delegate = delegate; | ||
} | ||
|
||
|
@@ -116,16 +116,6 @@ public final ConcurrentMap<Object, Object> contextData() { | |
return delegate.contextData(); | ||
} | ||
|
||
@Override | ||
public final ConcurrentMap<Object, Object> localContextData() { | ||
synchronized (this) { | ||
if (localData == null) { | ||
localData = new ConcurrentHashMap<>(); | ||
} | ||
return localData; | ||
} | ||
} | ||
|
||
@Override | ||
public final <T> Future<T> executeBlockingInternal(Handler<Promise<T>> action) { | ||
return ContextImpl.executeBlocking(this, action, delegate.internalWorkerPool, delegate.internalOrderedTasks); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright (c) 2011-2023 Contributors to the Eclipse Foundation | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
*/ | ||
package io.vertx.core.impl; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Julien Viet</a> | ||
*/ | ||
class LocalSeq { | ||
|
||
// 0 : reserved slot for local context map | ||
private static final AtomicInteger seq = new AtomicInteger(1); | ||
|
||
/** | ||
* Hook for testing purposes | ||
*/ | ||
static void reset() { | ||
seq.set((1)); | ||
} | ||
|
||
static int get() { | ||
return seq.get(); | ||
} | ||
|
||
static int next() { | ||
return seq.getAndIncrement(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.