/* * Copyright (C) 2018 Daniel Dietsch (dietsch@informatik.uni-freiburg.de) * Copyright (C) 2018 University of Freiburg * * This file is part of the ULTIMATE Util Library. * * The ULTIMATE Util Library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ULTIMATE Util Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ULTIMATE Util Library. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify the ULTIMATE Util Library, or any covered work, by linking * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), * containing parts covered by the terms of the Eclipse Public License, the * licensors of the ULTIMATE Util Library grant you additional permission * to convey the resulting work. */ package de.uni_freiburg.informatik.ultimate.util.datastructures; import java.util.ArrayDeque; import java.util.Collection; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * A {@link Deque} that does not contain duplicate instances. Whenever an object is added that is already present, * nothing happens instead. * * @author Daniel Dietsch (dietsch@informatik.uni-freiburg.de) * * @param * the elements of this {@link Deque}. */ public final class HashDeque implements Deque { private final Deque mDeque; private final Set mSet; public HashDeque() { mDeque = new ArrayDeque<>(); mSet = new HashSet<>(); } @Override public E pop() { final E node = mDeque.pop(); mSet.remove(node); return node; } @Override public void push(final E node) { if (mSet.add(node)) { mDeque.push(node); } } @Override public boolean isEmpty() { return mSet.isEmpty(); } @Override public Object[] toArray() { return mDeque.toArray(); } @Override public T[] toArray(final T[] a) { return mDeque.toArray(a); } @Override public boolean containsAll(final Collection c) { return mSet.containsAll(c); } @Override public boolean addAll(final Collection c) { boolean rtr = false; for (final E elem : c) { if (mSet.add(elem)) { mDeque.add(elem); rtr = true; } } return rtr; } @Override public boolean removeAll(final Collection c) { final boolean rtr = mSet.removeAll(c); mDeque.removeAll(c); return rtr; } @Override public boolean retainAll(final Collection c) { final boolean rtr = mSet.retainAll(c); mDeque.retainAll(c); return rtr; } @Override public void clear() { mSet.clear(); mDeque.clear(); } @Override public void addFirst(final E e) { if (mSet.add(e)) { mDeque.addFirst(e); } } @Override public void addLast(final E e) { if (mSet.add(e)) { mDeque.addLast(e); } } @Override public boolean offerFirst(final E e) { if (mSet.add(e)) { return mDeque.offerFirst(e); } return false; } @Override public boolean offerLast(final E e) { if (mSet.add(e)) { return mDeque.offerLast(e); } return false; } @Override public E removeFirst() { final E rtr = mDeque.removeFirst(); mSet.remove(rtr); return rtr; } @Override public E removeLast() { final E rtr = mDeque.removeLast(); mSet.remove(rtr); return rtr; } @Override public E pollFirst() { final E rtr = mDeque.pollFirst(); if (rtr != null) { mSet.remove(rtr); } return rtr; } @Override public E pollLast() { final E rtr = mDeque.pollLast(); if (rtr != null) { mSet.remove(rtr); } return rtr; } @Override public E getFirst() { return mDeque.getFirst(); } @Override public E getLast() { return mDeque.getLast(); } @Override public E peekFirst() { return mDeque.peekFirst(); } @Override public E peekLast() { return mDeque.peekLast(); } @Override public boolean removeFirstOccurrence(final Object o) { if (mSet.remove(o)) { return mDeque.removeFirstOccurrence(o); } return false; } @Override public boolean removeLastOccurrence(final Object o) { if (mSet.remove(o)) { return mDeque.removeLastOccurrence(o); } return false; } @Override public boolean add(final E e) { if (mSet.add(e)) { return mDeque.add(e); } return false; } @Override public boolean offer(final E e) { if (mSet.add(e)) { return mDeque.offer(e); } return false; } @Override public E remove() { final E rtr = mDeque.remove(); mSet.remove(rtr); return rtr; } @Override public E poll() { final E rtr = mDeque.poll(); mSet.remove(rtr); return rtr; } @Override public E element() { return mDeque.element(); } @Override public E peek() { return mDeque.peek(); } @Override public boolean remove(final Object o) { if (mSet.remove(o)) { return mDeque.remove(o); } return false; } @Override public boolean contains(final Object o) { return mSet.contains(o); } @Override public int size() { return mSet.size(); } @Override public Iterator iterator() { return mDeque.iterator(); } @Override public Iterator descendingIterator() { return mDeque.descendingIterator(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (mDeque == null ? 0 : mDeque.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final HashDeque other = (HashDeque) obj; if (mDeque == null) { if (other.mDeque != null) { return false; } } else if (!mDeque.equals(other.mDeque)) { return false; } return true; } @Override public String toString() { return mDeque.toString(); } }