2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
10 import static java.util.Objects.requireNonNull;
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.Iterator;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.yangtools.concepts.Mutable;
18 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * Statement-reuse expansion of a single instance. The idea here is that a statement can end up being replicated the
25 * same way multiple times -- which does not typically happen, but when it does it is worth exploiting.
27 * @param <E> {@link EffectiveStatement} type
29 final class EffectiveInstances<E extends EffectiveStatement<?, ?>> implements Mutable {
30 private static final Logger LOG = LoggerFactory.getLogger(EffectiveInstances.class);
32 // Note on sizing: this fits three entries without expansion. Note we do not include the local copy, as it does
33 // not have the same original.
34 private final Map<EffectiveStatementState, E> copies = new HashMap<>(4);
35 private final @NonNull E local;
37 EffectiveInstances(final E local) {
38 this.local = requireNonNull(local);
41 @SuppressWarnings("unchecked")
42 static <E extends EffectiveStatement<?, ?>> @NonNull E local(final Object obj) {
43 return obj instanceof EffectiveInstances ? ((EffectiveInstances<E>) obj).local : requireNonNull((E) obj);
46 @NonNull E attachCopy(final @NonNull EffectiveStatementState key, @NonNull final E copy) {
47 final E prev = copies.putIfAbsent(requireNonNull(key), requireNonNull(copy));
49 // Nothing matching state
53 // We need to make sure substatements are actually the same. If they are not, we'll just return the copy,
55 final Collection<? extends EffectiveStatement<?, ?>> prevStmts = prev.effectiveSubstatements();
56 final Collection<? extends EffectiveStatement<?, ?>> copyStmts = copy.effectiveSubstatements();
57 if (prevStmts != copyStmts) {
58 if (prevStmts.size() != copyStmts.size()) {
59 LOG.trace("Key {} substatement count mismatch", key);
63 final Iterator<? extends EffectiveStatement<?, ?>> prevIt = prevStmts.iterator();
64 final Iterator<? extends EffectiveStatement<?, ?>> copyIt = copyStmts.iterator();
65 while (prevIt.hasNext()) {
66 if (prevIt.next() != copyIt.next()) {
67 LOG.trace("Key {} substatement mismatch", key);
73 LOG.trace("Key {} substatement reused", key);