/*******************************************************************************
* 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;
}
}