package com.appmetr.hercules.wide;
import com.appmetr.hercules.driver.DataDriver;
import me.prettyprint.cassandra.model.thrift.ThriftMultigetSliceQuery;
import me.prettyprint.cassandra.model.thrift.ThriftRangeSlicesQuery;
import me.prettyprint.cassandra.model.thrift.ThriftSliceQuery;
import me.prettyprint.hector.api.query.MultigetSliceQuery;
import me.prettyprint.hector.api.query.RangeSlicesQuery;
import me.prettyprint.hector.api.query.SliceQuery;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
public class SliceDataSpecificator<N> {
public enum SliceDataSpecificatorType {RANGE, COLUMNS}
private SliceDataSpecificatorType type;
private N[] columnsArray;
private Collection<N> columnsCollection;
private N lowEnd;
private N highEnd;
private boolean orderDesc;
private int limit;
public SliceDataSpecificator(N... columns) {
type = SliceDataSpecificatorType.COLUMNS;
this.columnsArray = columns;
}
public SliceDataSpecificator(Collection<N> columns) {
type = SliceDataSpecificatorType.COLUMNS;
this.columnsCollection = columns;
}
public SliceDataSpecificator(N lowEnd, N highEnd, boolean orderDesc, Integer limit) {
type = SliceDataSpecificatorType.RANGE;
this.lowEnd = lowEnd;
this.highEnd = highEnd;
this.orderDesc = orderDesc;
this.limit = limit == null || limit > DataDriver.MAX_TOP_COUNT ? DataDriver.MAX_TOP_COUNT : limit;
}
public <K, V> void fillRangeSliceQuery(RangeSlicesQuery<K, N, V> sliceQuery) {
if (type == SliceDataSpecificatorType.COLUMNS) {
if (columnsArray != null) {
sliceQuery.setColumnNames(columnsArray);
} else {
((ThriftRangeSlicesQuery) sliceQuery).setColumnNames(columnsCollection);
}
} else if (type == SliceDataSpecificatorType.RANGE) {
if (orderDesc) { // Cassandra's WTF requirement
sliceQuery.setRange(highEnd, lowEnd, orderDesc, limit);
} else {
sliceQuery.setRange(lowEnd, highEnd, orderDesc, limit);
}
} else {
throw new IllegalStateException("Invalid type: " + type);
}
}
public <K, V> void fillMultigetSliceQuery(MultigetSliceQuery<K, N, V> sliceQuery) {
if (type == SliceDataSpecificatorType.COLUMNS) {
if (columnsArray != null) {
sliceQuery.setColumnNames(columnsArray);
} else {
((ThriftMultigetSliceQuery) sliceQuery).setColumnNames(columnsCollection);
}
} else if (type == SliceDataSpecificatorType.RANGE) {
if (orderDesc) { // Cassandra's WTF requirement
sliceQuery.setRange(highEnd, lowEnd, orderDesc, limit);
} else {
sliceQuery.setRange(lowEnd, highEnd, orderDesc, limit);
}
} else {
throw new IllegalStateException("Invalid type: " + type);
}
}
public <K, V> void fillSliceQuery(SliceQuery<K, N, V> sliceQuery) {
if (type == SliceDataSpecificatorType.COLUMNS) {
if (columnsArray != null) {
sliceQuery.setColumnNames(columnsArray);
} else {
((ThriftSliceQuery) sliceQuery).setColumnNames(columnsCollection);
}
} else if (type == SliceDataSpecificatorType.RANGE) {
if (orderDesc) { // Cassandra's WTF requirement
sliceQuery.setRange(highEnd, lowEnd, orderDesc, limit);
} else {
sliceQuery.setRange(lowEnd, highEnd, orderDesc, limit);
}
} else {
throw new IllegalStateException("Invalid type: " + type);
}
}
public SliceDataSpecificatorType getType() {
return type;
}
public N[] getColumnsArray() {
return columnsArray;
}
public Collection<N> getColumnsCollection() {
return columnsCollection;
}
public Iterator<N> getColumnsIterator() {
return columnsArray != null ? Arrays.asList(columnsArray).iterator() : columnsCollection.iterator();
}
public N getLowEnd() {
return lowEnd;
}
public N getHighEnd() {
return highEnd;
}
public boolean isOrderDesc() {
return orderDesc;
}
public int getLimit() {
return limit;
}
}