package nl.thanod.cassandra.alpha.map.supercolumn; import java.util.*; import javax.management.RuntimeErrorException; import nl.thanod.cassandra.CassandraConstants; import nl.thanod.cassandra.alpha.bytes.ByteObjectTranslator; import nl.thanod.cassandra.alpha.bytes.NoTranslatorException; import org.apache.cassandra.thrift.*; import org.apache.cassandra.thrift.Cassandra.Iface; import sun.reflect.generics.reflectiveObjects.NotImplementedException; public final class SuperColumnFamilyKeyedKeySet<K> implements Set<K> { public static int BUFFER_SIZE = 100; protected final ByteObjectTranslator<K> translator; protected final Iface client; protected final String keyspace; protected final String column_family; protected final String key; protected final ConsistencyLevel readLevel; protected final ConsistencyLevel writeLevel; protected final boolean reversed = false; public SuperColumnFamilyKeyedKeySet(Class<K> keyVal, Cassandra.Iface client, String keyspace, String column_family, String key) throws NoTranslatorException { this(keyVal, client, keyspace, column_family, key, ConsistencyLevel.ONE, ConsistencyLevel.ZERO); } public SuperColumnFamilyKeyedKeySet(Class<K> keyVal, Cassandra.Iface client, String keyspace, String column_family, String key, ConsistencyLevel level) throws NoTranslatorException { this(keyVal, client, keyspace, column_family, key, level, level); } public SuperColumnFamilyKeyedKeySet(Class<K> keyVal, Cassandra.Iface client, String keyspace, String column_family, String key, ConsistencyLevel readLevel, ConsistencyLevel writeLevel) throws NoTranslatorException { this(ByteObjectTranslator.getTranslatorFor(keyVal), client, keyspace, column_family, key, readLevel, writeLevel); } public SuperColumnFamilyKeyedKeySet(ByteObjectTranslator<K> translator, Cassandra.Iface client, String keyspace, String column_family, String key, ConsistencyLevel readLevel, ConsistencyLevel writeLevel) { if (translator == null) throw new NullPointerException(); this.translator = translator; this.client = client; this.keyspace = keyspace; this.column_family = column_family; this.key = key; this.readLevel = readLevel; this.writeLevel = writeLevel; } @Override public boolean add(K e) { throw new UnsupportedOperationException(); } @Override public boolean addAll(Collection<? extends K> c) { for (K o : c) if (!add(o)) return false; return true; } @Override public void clear() { Iterator<K> it = this.iterator(); while (it.hasNext()) { it.next(); it.remove(); } } @Override public boolean contains(Object o) { throw new NotImplementedException(); } @Override public boolean containsAll(Collection<?> c) { for (Object o : c) if (!contains(o)) return false; return true; } @Override public boolean isEmpty() { throw new NotImplementedException(); } @Override public Iterator<K> iterator() { throw new NotImplementedException(); } @Override public boolean remove(Object o) { throw new NotImplementedException(); } @Override public boolean removeAll(Collection<?> c) { for (Object o : c) if (!remove(o)) return false; return true; } @Override public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } @Override public int size() { throw new NotImplementedException(); } @Override public Object[] toArray() { throw new UnsupportedOperationException(); } @Override public <T> T[] toArray(T[] a) { throw new UnsupportedOperationException(); } class KeyedKeyIterator implements Iterator<K> { private final Queue<K> buffer = new LinkedList<K>(); private K working = null; private boolean finished = false; private byte[] lastKey = CassandraConstants.EMPTY_BYTES; private void fillBuffer() { if (finished) return; try { ColumnParent column_parent = new ColumnParent(column_family); column_parent.column_family = key; SlicePredicate predicate = new SlicePredicate(); predicate.slice_range = new SliceRange(lastKey, CassandraConstants.EMPTY_BYTES, reversed, BUFFER_SIZE); List<ColumnOrSuperColumn> corsc = client.get_slice(keyspace, key, column_parent, predicate, readLevel); if (corsc.size() > 0) { ColumnOrSuperColumn sc = corsc.get(0); if (sc.super_column == null) throw new RuntimeException("A SuperColumn was expexted"); else if (Arrays.equals(sc.super_column.name, lastKey)) corsc.remove(0); } if (corsc.size() > 0) { for (ColumnOrSuperColumn c : corsc) { if (c.super_column == null) throw new RuntimeException("A SuperColumn was expexted"); lastKey = c.super_column.name; if (c.super_column.columns.size() > 0) buffer.add(translator.get(c.super_column.name)); } } else { finished = true; } } catch (Throwable ball) { throw new RuntimeException("Unable to recover from " + ball.getClass().getCanonicalName(), ball); } } @Override public boolean hasNext() { if (buffer.size() == 0) fillBuffer(); return buffer.size() > 0; } @Override public K next() { if (hasNext()) return working = this.buffer.poll(); throw new NoSuchElementException(); } @Override public void remove() { throw new NotImplementedException(); } } }