package org.apache.cassandra.db;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import org.apache.cassandra.db.marshal.AbstractType;
public abstract class CBuilder
{
public static CBuilder STATIC_BUILDER = new CBuilder()
{
public int count()
{
return 0;
}
public int remainingCount()
{
return 0;
}
public ClusteringComparator comparator()
{
throw new UnsupportedOperationException();
}
public CBuilder add(ByteBuffer value)
{
throw new UnsupportedOperationException();
}
public CBuilder add(Object value)
{
throw new UnsupportedOperationException();
}
public Clustering build()
{
return Clustering.STATIC_CLUSTERING;
}
public ClusteringBound buildBound(boolean isStart, boolean isInclusive)
{
throw new UnsupportedOperationException();
}
public Slice buildSlice()
{
throw new UnsupportedOperationException();
}
public Clustering buildWith(ByteBuffer value)
{
throw new UnsupportedOperationException();
}
public Clustering buildWith(List<ByteBuffer> newValues)
{
throw new UnsupportedOperationException();
}
public ClusteringBound buildBoundWith(ByteBuffer value, boolean isStart, boolean isInclusive)
{
throw new UnsupportedOperationException();
}
public ClusteringBound buildBoundWith(List<ByteBuffer> newValues, boolean isStart, boolean isInclusive)
{
throw new UnsupportedOperationException();
}
};
public static CBuilder create(ClusteringComparator comparator)
{
return new ArrayBackedBuilder(comparator);
}
public abstract int count();
public abstract int remainingCount();
public abstract ClusteringComparator comparator();
public abstract CBuilder add(ByteBuffer value);
public abstract CBuilder add(Object value);
public abstract Clustering build();
public abstract ClusteringBound buildBound(boolean isStart, boolean isInclusive);
public abstract Slice buildSlice();
public abstract Clustering buildWith(ByteBuffer value);
public abstract Clustering buildWith(List<ByteBuffer> newValues);
public abstract ClusteringBound buildBoundWith(ByteBuffer value, boolean isStart, boolean isInclusive);
public abstract ClusteringBound buildBoundWith(List<ByteBuffer> newValues, boolean isStart, boolean isInclusive);
private static class ArrayBackedBuilder extends CBuilder
{
private final ClusteringComparator type;
private final ByteBuffer[] values;
private int size;
private boolean built;
public ArrayBackedBuilder(ClusteringComparator type)
{
this.type = type;
this.values = new ByteBuffer[type.size()];
}
public int count()
{
return size;
}
public int remainingCount()
{
return values.length - size;
}
public ClusteringComparator comparator()
{
return type;
}
public CBuilder add(ByteBuffer value)
{
if (isDone())
throw new IllegalStateException();
values[size++] = value;
return this;
}
public CBuilder add(Object value)
{
return add(((AbstractType)type.subtype(size)).decompose(value));
}
private boolean isDone()
{
return remainingCount() == 0 || built;
}
public Clustering build()
{
built = true;
return size == 0 ? Clustering.EMPTY : Clustering.make(values);
}
public ClusteringBound buildBound(boolean isStart, boolean isInclusive)
{
built = true;
if (size == 0)
return isStart ? ClusteringBound.BOTTOM : ClusteringBound.TOP;
return ClusteringBound.create(ClusteringBound.boundKind(isStart, isInclusive),
size == values.length ? values : Arrays.copyOfRange(values, 0, size));
}
public Slice buildSlice()
{
built = true;
if (size == 0)
return Slice.ALL;
return Slice.make(buildBound(true, true), buildBound(false, true));
}
public Clustering buildWith(ByteBuffer value)
{
assert size+1 <= type.size();
ByteBuffer[] newValues = Arrays.copyOf(values, type.size());
newValues[size] = value;
return Clustering.make(newValues);
}
public Clustering buildWith(List<ByteBuffer> newValues)
{
assert size + newValues.size() <= type.size();
ByteBuffer[] buffers = Arrays.copyOf(values, type.size());
int newSize = size;
for (ByteBuffer value : newValues)
buffers[newSize++] = value;
return Clustering.make(buffers);
}
public ClusteringBound buildBoundWith(ByteBuffer value, boolean isStart, boolean isInclusive)
{
ByteBuffer[] newValues = Arrays.copyOf(values, size+1);
newValues[size] = value;
return ClusteringBound.create(ClusteringBound.boundKind(isStart, isInclusive), newValues);
}
public ClusteringBound buildBoundWith(List<ByteBuffer> newValues, boolean isStart, boolean isInclusive)
{
ByteBuffer[] buffers = Arrays.copyOf(values, size + newValues.size());
int newSize = size;
for (ByteBuffer value : newValues)
buffers[newSize++] = value;
return ClusteringBound.create(ClusteringBound.boundKind(isStart, isInclusive), buffers);
}
}
}