+++ /dev/null
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.stmt.reactor;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Mutable;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Statement-reuse expansion of a single instance. The idea here is that a statement can end up being replicated the
- * same way multiple times -- which does not typically happen, but when it does it is worth exploiting.
- *
- * @param E {@link EffectiveStatement} type
- */
-final class EffectiveInstances<E extends EffectiveStatement<?, ?>> implements Mutable {
- private static final Logger LOG = LoggerFactory.getLogger(EffectiveInstances.class);
-
- // Note on sizing: this fits three entries without expansion. Note we do not include the local copy, as it does
- // not have the same original.
- private final Map<EffectiveStatementState, E> copies = new HashMap<>(4);
- private final @NonNull E local;
-
- EffectiveInstances(final @NonNull E local) {
- this.local = requireNonNull(local);
- }
-
- @SuppressWarnings("unchecked")
- static <E extends EffectiveStatement<?, ?>> @NonNull E local(final Object obj) {
- return obj instanceof EffectiveInstances ? ((EffectiveInstances<E>) obj).local : requireNonNull((E) obj);
- }
-
- @NonNull E attachCopy(final @NonNull EffectiveStatementState key, @NonNull final E copy) {
- final E prev = copies.putIfAbsent(requireNonNull(key), requireNonNull(copy));
- if (prev == null) {
- // Nothing matching state
- return copy;
- }
-
- // We need to make sure substatements are actually the same. If they are not, we'll just return the copy,
- // playing it safe.
- final Collection<? extends EffectiveStatement<?, ?>> prevStmts = prev.effectiveSubstatements();
- final Collection<? extends EffectiveStatement<?, ?>> copyStmts = copy.effectiveSubstatements();
- if (prevStmts != copyStmts) {
- if (prevStmts.size() != copyStmts.size()) {
- LOG.trace("Key {} substatement count mismatch", key);
- return copy;
- }
-
- final Iterator<? extends EffectiveStatement<?, ?>> prevIt = prevStmts.iterator();
- final Iterator<? extends EffectiveStatement<?, ?>> copyIt = copyStmts.iterator();
- while (prevIt.hasNext()) {
- if (prevIt.next() != copyIt.next()) {
- LOG.trace("Key {} substatement mismatch", key);
- return copy;
- }
- }
- }
-
- LOG.trace("Key {} substatement reused", key);
- return prev;
- }
-}
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
-import static com.google.common.base.Verify.verifyNotNull;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
-import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
* {@link #buildEffective()} instance. If this context is reused, it can be inflated to {@link EffectiveInstances}
* and also act as a common instance reuse site.
*/
- private @Nullable Object effectiveInstance;
+ private @Nullable E effectiveInstance;
// Master flag controlling whether this context can yield an effective statement
// FIXME: investigate the mechanics that are being supported by this, as it would be beneficial if we can get rid
@Override
public final <X, Z extends EffectiveStatement<X, ?>> @NonNull Optional<X> findSubstatementArgument(
final @NonNull Class<Z> type) {
- final Object existing = effectiveInstance;
- return existing != null ? EffectiveInstances.local(existing).findFirstEffectiveSubstatementArgument(type)
+ final E existing = effectiveInstance;
+ return existing != null ? existing.findFirstEffectiveSubstatementArgument(type)
: findSubstatementArgumentImpl(type);
}
@Override
public final boolean hasSubstatement(final @NonNull Class<? extends EffectiveStatement<?, ?>> type) {
- final Object existing = effectiveInstance;
- return existing != null ? EffectiveInstances.local(existing).findFirstEffectiveSubstatement(type).isPresent()
- : hasSubstatementImpl(type);
+ final E existing = effectiveInstance;
+ return existing != null ? existing.findFirstEffectiveSubstatement(type).isPresent() : hasSubstatementImpl(type);
}
// Visible due to InferredStatementContext's override. At this point we do not have an effective instance available.
@Override
public final E buildEffective() {
- final Object existing;
- return (existing = effectiveInstance) != null ? EffectiveInstances.local(existing) : loadEffective();
+ final E existing;
+ return (existing = effectiveInstance) != null ? existing : loadEffective();
}
private @NonNull E loadEffective() {
abstract @NonNull E createEffective();
-
- /**
- * Attach an effective copy of this statement. This essentially acts as a map, where we make a few assumptions:
- * <ul>
- * <li>{@code copy} and {@code this} statement share {@link #getOriginalCtx()} if it exists</li>
- * <li>{@code copy} did not modify any statements relative to {@code this}</li>
- * </ul>
- *
- *
- * @param state effective statement state, acting as a lookup key
- * @param copy New copy to append
- * @return {@code copy} or a previously-created instances with the same {@code state}
- */
- @SuppressWarnings("unchecked")
- final @NonNull E attachCopy(final @NonNull EffectiveStatementState state, final @NonNull E copy) {
- final Object effective = verifyNotNull(effectiveInstance, "Attaching copy to a unbuilt %s", this);
- final EffectiveInstances<E> instances;
- if (effective instanceof EffectiveInstances) {
- instances = (EffectiveInstances<E>) effective;
- } else {
- effectiveInstance = instances = new EffectiveInstances<>((E) effective);
- }
- return instances.attachCopy(state, copy);
- }
-
/**
* Walk this statement's copy history and return the statement closest to original which has not had its effective
* statements modified. This statement and returned substatement logically have the same set of substatements, hence
+++ /dev/null
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.spi.meta;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects.ToStringHelper;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Immutable;
-
-@Beta
-public final class EffectiveSchemaTreeStatementState extends EffectiveStatementState {
- private final int flags;
-
- public EffectiveSchemaTreeStatementState(final @NonNull Immutable identity, final int flags) {
- super(identity);
- this.flags = flags;
- }
-
- @Override
- public int hashCode() {
- return identity().hashCode() * 31 + Integer.hashCode(flags);
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof EffectiveSchemaTreeStatementState)) {
- return false;
- }
- final EffectiveSchemaTreeStatementState other = (EffectiveSchemaTreeStatementState) obj;
- return flags == other.flags && identity().equals(other.identity());
- }
-
- @Override
- protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
- return super.addToStringAttributes(helper).add("flags", flags);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.parser.spi.meta;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-/**
- * Effective summary of a {@link EffectiveStatement}'s implementation state. This class serves as a shared concept
- * between {@link StatementFactory} and common reactor, driving statement reuse.
- *
- * <p>
- * {@link StatementFactory} implementations are expected to subclass {@link EffectiveStatementState}, adding whatever
- * additional state is needed and implement {@link #hashCode()} and {@link #equals(Object)} accordingly.
- */
-@Beta
-public abstract class EffectiveStatementState implements Immutable {
- private final @NonNull Immutable identity;
-
- protected EffectiveStatementState(final @NonNull Immutable identity) {
- this.identity = requireNonNull(identity);
- }
-
- protected final @NonNull Immutable identity() {
- return identity;
- }
-
- @Override
- public abstract int hashCode();
-
- @Override
- public abstract boolean equals(Object obj);
-
- @Override
- public final String toString() {
- return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
- }
-
- protected @NonNull ToStringHelper addToStringAttributes(final @NonNull ToStringHelper helper) {
- return helper.add("identity", identity);
- }
-}