/******************************************************************************* * Copyright 2014 Analog Devices, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ package com.analog.lyric.dimple.model.values; import java.util.AbstractList; import java.util.Iterator; import java.util.concurrent.atomic.AtomicReference; import net.jcip.annotations.NotThreadSafe; import com.analog.lyric.collect.IKeyed; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import com.google.common.collect.Iterators; import com.google.common.primitives.Ints; /** * Represents an association between an index and a {@link Value} object. * <p> * For purposes of comparison only the {@link #getIndex()} value is considered. */ @NotThreadSafe public class IndexedValue implements Comparable<IndexedValue>, IKeyed<Integer> { /*------- * State */ private int _index; private Value _value; /*-------------- * Construction */ public IndexedValue(int index, Value value) { _index = index; _value = value; } /*---------------- * Object methods */ /** * True if {@code other} is an {@code IndexedValue} with same {@link #getIndex()} value. */ @Override public boolean equals(@Nullable Object other) { if (this == other) { return true; } return other instanceof IndexedValue && _index == ((IndexedValue)other)._index; } /** * Hash code is based soley on {@code #getIndex()} value. */ @Override public int hashCode() { return Ints.hashCode(_index); } /*-------------------- * Comparable methods */ /** * Comparison based on integer comparison of {@link #getIndex()} values. */ @Override @NonNullByDefault(false) public int compareTo(IndexedValue other) { return Ints.compare(_index, other._index); } /*---------------- * IKeyed methods */ /** * Returns {@link #getIndex()}. */ @Override public Integer getKey() { return _index; } /*---------------------- * IndexedValue methods */ public int getIndex() { return _index; } public Value getValue() { return _value; } /*---------------- * Nested classes */ public static class SingleList extends AbstractList<IndexedValue> { private final IndexedValue _value; private final static AtomicReference<SingleList> _cachedInstance = new AtomicReference<SingleList>(); /*-------------- * Construction */ private SingleList(int index, Value value) { _value = new IndexedValue(index, value); } public static SingleList create(int index, Value value) { SingleList list = _cachedInstance.getAndSet(null); if (list == null) { list = new SingleList(index, value); } else { list._value._index = index; list._value._value = value; } return list; } public void release() { _cachedInstance.set(this); } /*------------------ * Iterable methods */ @Override public Iterator<IndexedValue> iterator() { return Iterators.singletonIterator(_value); } /*-------------- * List methods */ @Override public IndexedValue get(int i) { if (i != 0) throw new IndexOutOfBoundsException(); return _value; } @Override public int size() { return 1; } } }