Streamers are based on immutable data, hence we can safely drop
their cache to release/acquire instead of the globally-ordered
volatile semantics.
JIRA: MDSAL-498
Change-Id: I36036908b0ae35dccc2b9016057ca1014373510d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
import java.util.List;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import java.util.List;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
abstract class DataContainerCodecContext<D extends DataObject, T extends WithStatus> extends NodeCodecContext
implements BindingDataObjectCodecTreeNode<D> {
abstract class DataContainerCodecContext<D extends DataObject, T extends WithStatus> extends NodeCodecContext
implements BindingDataObjectCodecTreeNode<D> {
+ private static final VarHandle EVENT_STREAM_SERIALIZER;
+
+ static {
+ try {
+ EVENT_STREAM_SERIALIZER = MethodHandles.lookup().findVarHandle(DataContainerCodecContext.class,
+ "eventStreamSerializer", DataObjectSerializer.class);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
private final @NonNull DataContainerCodecPrototype<T> prototype;
private final @NonNull DataContainerCodecPrototype<T> prototype;
+ // Accessed via a VarHandle
+ @SuppressWarnings("unused")
private volatile DataObjectSerializer eventStreamSerializer;
private volatile DataObjectSerializer eventStreamSerializer;
- protected DataContainerCodecContext(final DataContainerCodecPrototype<T> prototype) {
+ DataContainerCodecContext(final DataContainerCodecPrototype<T> prototype) {
this.prototype = requireNonNull(prototype);
}
this.prototype = requireNonNull(prototype);
}
throw IncorrectNestingException.create(message, args);
}
throw IncorrectNestingException.create(message, args);
}
- DataObjectSerializer eventStreamSerializer() {
- if (eventStreamSerializer == null) {
- eventStreamSerializer = factory().getEventStreamSerializer(getBindingClass());
- }
- return eventStreamSerializer;
+ final DataObjectSerializer eventStreamSerializer() {
+ final DataObjectSerializer existing = (DataObjectSerializer) EVENT_STREAM_SERIALIZER.getAcquire(this);
+ return existing != null ? existing : loadEventStreamSerializer();
+ }
+
+ // Split out to aid inlining
+ private DataObjectSerializer loadEventStreamSerializer() {
+ final DataObjectSerializer loaded = factory().getEventStreamSerializer(getBindingClass());
+ final Object witness = EVENT_STREAM_SERIALIZER.compareAndExchangeRelease(this, null, loaded);
+ return witness == null ? loaded : (DataObjectSerializer) witness;