Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package io.deephaven.engine.table.impl;
import io.deephaven.api.util.ConcurrentMethod;
import io.deephaven.engine.liveness.LivenessArtifact;
import io.deephaven.engine.liveness.LivenessReferent;
import io.deephaven.engine.table.AttributeMap;
import io.deephaven.engine.table.impl.util.FieldUtils;
import io.deephaven.engine.updategraph.DynamicNode;
import io.deephaven.util.annotations.InternalUseOnly;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
/**
* Re-usable {@link AttributeMap} implementation that is also a {@link LivenessArtifact}.
*
* @implNote Rather than rely on {@code final}, explicitly-immutable {@link Map} instances for storage, this
* implementation does allow for mutation after construction. This allows a pattern wherein operations fill
* their result {@code AttributeMap} after construction using {@link #setAttribute(String, Object)}, which by
* convention must only be done before the result is published. No mutation is permitted after first access
* using any of {@link #getAttribute(String)}, {@link #getAttributeKeys()}, {@link #hasAttribute(String)},
* {@link #getAttributes()}, or {@link AttributeMap#getAttributes(Predicate)}.
*/
public abstract class LiveAttributeMap, IMPL_TYPE extends LiveAttributeMap>
extends LivenessArtifact
implements AttributeMap {
private static final Map EMPTY_ATTRIBUTES = Collections.emptyMap();
@SuppressWarnings("rawtypes")
private static final AtomicReferenceFieldUpdater MUTABLE_ATTRIBUTES_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(LiveAttributeMap.class, Map.class, "mutableAttributes");
@SuppressWarnings("rawtypes")
private static final AtomicReferenceFieldUpdater IMMUTABLE_ATTRIBUTES_UPDATER =
AtomicReferenceFieldUpdater.newUpdater(LiveAttributeMap.class, Map.class, "immutableAttributes");
/**
* Reference to a (possibly shared) initial map instance assigned to {@link #mutableAttributes}.
*/
private Map initialAttributes;
/**
* Attribute storage while mutable, set via {@link #ensureAttributes()} on mutation if not initialized.
*/
private volatile Map mutableAttributes;
/**
* Attribute storage once immutable, set via {@link #immutableAttributes()} on first read access from the public API
* methods.
*/
@SuppressWarnings("unused")
private volatile Map immutableAttributes;
/**
* @param initialAttributes The attributes map to use until mutated, or else {@code null} to allocate a new one
*/
protected LiveAttributeMap(@Nullable final Map initialAttributes) {
this.mutableAttributes = this.initialAttributes =
Objects.requireNonNullElse(initialAttributes, EMPTY_ATTRIBUTES);
}
/**
* Set the value of an attribute. This is for internal use by operations that build result AttributeMaps, and should
* never be used from multiple threads or after a result has been published.
*
* @param key The name of the attribute; must not be {@code null}
* @param object The value to be assigned; must not be {@code null}
*/
@InternalUseOnly
public void setAttribute(@NotNull final String key, @NotNull final Object object) {
Objects.requireNonNull(key);
Objects.requireNonNull(object);
if (needsManagement(object)) {
manage((LivenessReferent) object);
}
ensureAttributes().put(key, object);
}
/**
* Read and update the value of an attribute. This is for internal use by operations that build result
* AttributeMaps, and should never be used from multiple threads or after a result has been published.
*
* @param key The name of the attribute; must not be {@code null}
* @param updater Function on the (possibly-{@code null}) existing value to produce the non-{@code null} new value
*/
@InternalUseOnly
public void setAttribute(@NotNull final String key, @NotNull final UnaryOperator