package org.egonet.graph;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class IndexedSetOfSets<N> implements Set<Set<N>> {
private Set<Set<N>> set;
private Map<N,Set<Set<N>>> index;
public Set<Set<N>> findByIndex(N item) {
Set<Set<N>> result = index.get(item);
return result == null ? new HashSet<Set<N>>() : result;
}
public IndexedSetOfSets() {
clear();
}
public boolean add(Set<N> item) {
if(set.contains(item)) {
return false;
} else {
set.add(item);
for(N n : item) {
Set<Set<N>> nIndex = index.get(n);
if(nIndex == null) {
nIndex = Sets.newHashSet();
index.put(n, nIndex);
}
nIndex.add(item);
}
return true;
}
}
public boolean addAll(Collection<? extends Set<N>> items) {
boolean modified = false;
for(Set<N> item : items) {
if(add(item)) {
modified = true;
}
}
return modified;
}
public void clear() {
set = Sets.newHashSet();
index = Maps.newHashMap();
}
public boolean contains(Object item) {
return set.contains(item);
}
public boolean containsAll(Collection<?> items) {
for(Object item : items) {
if(! contains(item)) {
return false;
}
}
return true;
}
public boolean isEmpty() {
return set.isEmpty();
}
private class IndexedIterator implements Iterator<Set<N>> {
private List<Set<N>> items;
int i = -1;
public IndexedIterator() {
items = Lists.newArrayList(set);
}
public boolean hasNext() {
return items.size() > i+1;
}
public Set<N> next() {
i++;
return items.get(i);
}
public void remove() {
IndexedSetOfSets.this.remove(items.get(i));
}
}
public Iterator<Set<N>> iterator() {
return new IndexedIterator();
}
@SuppressWarnings("unchecked")
public boolean remove(Object obj) {
Set<N> item = (Set<N>) obj;
boolean modified = set.remove(item);
if(modified) {
for(N n : item) {
index.get(n).remove(item);
}
}
return modified;
}
public boolean removeAll(Collection<?> items) {
boolean modified = false;
for(Object item : items) {
if(remove(item)) {
modified = true;
}
}
return modified;
}
@SuppressWarnings("unchecked")
public boolean retainAll(Collection<?> items) {
Set<Set<N>> keepers = Sets.newHashSet();
keepers.addAll((Collection<Set<N>>) items);
boolean modified = false;
Iterator<Set<N>> iter = iterator();
while(iter.hasNext()) {
Set<N> item = iter.next();
if(! keepers.contains(item)) {
remove(item);
}
}
return modified;
}
public int size() {
return set.size();
}
public Object[] toArray() {
return set.toArray();
}
public <T> T[] toArray(T[] t) {
return set.toArray(t);
}
public boolean equals(Object obj) {
return set.equals(obj);
}
public int hashCode() {
return set.hashCode();
}
}