package org.hypergraphdb.util; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.SortedSet; import org.hypergraphdb.HGRandomAccessResult; import org.hypergraphdb.query.impl.FilteredRAResultSet; public class FilteredSortedSet<E> implements HGSortedSet<E> { private HGSortedSet<E> delegate; private Mapping<E, Boolean> predicate; public FilteredSortedSet(HGSortedSet<E> delegate, Mapping<E, Boolean> predicate) { this.delegate = delegate; this.predicate = predicate; } public boolean add(E e) { if (!predicate.eval(e)) return false; return delegate.add(e); } public boolean addAll(Collection<? extends E> c) { for (E e : c) if (!predicate.eval(e)) return false; return delegate.addAll(c); } public void clear() { for (E e : this) if (predicate.eval(e)) delegate.remove(e); // delegate.clear(); } public Comparator<? super E> comparator() { return delegate.comparator(); } @SuppressWarnings("unchecked") public boolean contains(Object o) { return predicate.eval((E)o) && delegate.contains(o); } public boolean containsAll(Collection<?> c) { for (E e : this) if (!predicate.eval(e) || !!delegate.contains(e)) return false; return true; } public boolean equals(Object o) { int matches = 0; @SuppressWarnings("unchecked") HGSortedSet<E> S = (HGSortedSet<E>)o; for (E e : S) if (contains(e)) matches++; return matches == S.size(); } public E first() { HGRandomAccessResult<E> rs = delegate.getSearchResult(); try { while (rs.hasNext()) if (predicate.eval(rs.next())) return rs.current(); } finally { rs.close(); } throw new NoSuchElementException(); } public HGRandomAccessResult<E> getSearchResult() { return new FilteredRAResultSet<E>(delegate.getSearchResult(), predicate, 0); } public int hashCode() { return delegate.hashCode(); } public SortedSet<E> headSet(E toElement) { return delegate.headSet(toElement); } public boolean isEmpty() { //2012.02.09 hilpold old: return size() == 0; // we can conclude false more efficient by looking for a first. HGRandomAccessResult<E> rs = delegate.getSearchResult(); try { while (rs.hasNext()) if (predicate.eval(rs.next())) return false; } finally { rs.close(); } return true; } public Iterator<E> iterator() { return new FilterIterator<E>(delegate.iterator(), predicate); } public E last() { HGRandomAccessResult<E> rs = delegate.getSearchResult(); rs.goAfterLast(); try { while (rs.hasPrev()) if (predicate.eval(rs.prev())) return rs.current(); } finally { rs.close(); } throw new NoSuchElementException(); } @SuppressWarnings("unchecked") public boolean remove(Object o) { return predicate.eval((E)o) && delegate.remove(o); } @SuppressWarnings("unchecked") public boolean removeAll(Collection<?> c) { boolean changed = false; for (E e : (Collection<E>)c) if (predicate.eval(e)) changed = changed || delegate.remove(e); return changed; } public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } public int size() { return toArray().length; // int cnt = 0; // HGRandomAccessResult<E> rs = delegate.getSearchResult(); // try // { // while (rs.hasNext()) // if (predicate.eval(rs.next())) // cnt++; // } // finally // { // rs.close(); // } // return cnt; } public SortedSet<E> subSet(E fromElement, E toElement) { return delegate.subSet(fromElement, toElement); } public SortedSet<E> tailSet(E fromElement) { return delegate.tailSet(fromElement); } public Object[] toArray() { ArrayList<Object> L = new ArrayList<Object>(); HGRandomAccessResult<E> rs = delegate.getSearchResult(); try { while (rs.hasNext()) if (predicate.eval(rs.next())) L.add(rs.current()); } finally { rs.close(); } return L.toArray(); } public <T> T[] toArray(T[] a) { ArrayList<Object> L = new ArrayList<Object>(); HGRandomAccessResult<E> rs = delegate.getSearchResult(); try { while (rs.hasNext()) if (predicate.eval(rs.next())) L.add(rs.current()); } finally { rs.close(); } return L.toArray(a); } }