/******************************************************************************* * 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.collect; import java.util.AbstractCollection; import java.util.Iterator; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; /** * Base implementation of {@link IHeap} with default implementation * of some methods. * * @author Christopher Barber * @since 0.05 */ public abstract class AbstractHeap<E> extends AbstractCollection<E> implements IHeap<E> { /** * Base implementation for heap entries. * * @since 0.05 */ public abstract static class AbstractEntry<E> implements IEntry<E> { private final E _element; protected double _priority; protected AbstractEntry(E element, double priority) { _element = element; _priority = priority; } protected AbstractEntry(AbstractEntry<E> that) { this(that._element, that._priority); } @Override public abstract AbstractEntry<E> clone(); @NonNull // FIXME - workaround for Eclipse JDT bug (467610?) @Override public final E getElement() { return _element; } @Override public final double getPriority() { return _priority; } } @Override public abstract AbstractHeap<E> clone(); /*------------------ * Iterable methods */ @Override public Iterator<E> iterator() { final Iterator<? extends IEntry<E>> entries = entryIterator(); return new Iterator<E>() { @Override public boolean hasNext() { return entries.hasNext(); } @Override public E next() { return entries.next().getElement(); } @Override public void remove() { throw new UnsupportedOperationException(); } }; } /*-------------------- * Collection methods */ @Override public abstract void clear(); @Override public boolean contains(@Nullable Object object) { return entryForElement(object) != null; } @Override public boolean remove(@Nullable Object object) { IEntry<E> entry = entryForElement(object); return entry != null ? removeEntry(entry) : false; } /*--------------- * IHeap methods */ @Override public boolean containsEntry(IEntry<E> entry) { if (entry.isOwned()) { Iterator<? extends IEntry<E>> iter = entryIterator(); while (iter.hasNext()) { if (entry == iter.next()) { return true; } } } return false; } @Override public @Nullable IEntry<E> entryForElement(@Nullable Object element) { Iterator<? extends IEntry<E>> iter = entryIterator(); while (iter.hasNext()) { IEntry<E> entry = iter.next(); if (entry.getElement().equals(element)) { return entry; } } return null; } @Override public void ensureCapacity(int capacity) { } @Override public boolean isOrdered() { return true; } @Override public boolean deferOrdering() { return false; } @Override public boolean deferOrdering(boolean defer) { return !defer; } @Override public boolean deferOrderingForBulkAdd(int n) { return false; } @Override public boolean deferOrderingForBulkChange(int n) { return false; } @Override public boolean merge(IHeap<E> other) { Iterator<? extends IEntry<E>> entries = other.entryIterator(); while (entries.hasNext()) { IEntry<E> entry = entries.next(); offer(entry.getElement(), entry.getPriority()); } other.clear(); return false; } @Override public @Nullable E peek() { final IEntry<E> entry = peekEntry(); return entry != null ? entry.getElement() : null; } @Override public @Nullable E poll() { final IEntry<E> entry = pollEntry(); return entry != null ? entry.getElement() : null; } }