mirror of https://github.com/apache/cassandra
make get_key_range act on a single CF.
patch by jbellis; reviewed by Eric Evans for CASSANDRA-280 git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@791961 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
23fa1bc0bd
commit
2b18bade55
|
|
@ -1,4 +1,5 @@
|
|||
0.4 dev
|
||||
* Added columnFamily argument to get_key_range.
|
||||
* Change signature of get_slice and get_slice_super to accept
|
||||
starting and ending columns as well as an offset. (This allows use
|
||||
of indexes.) Added "ascending" flag to allow reasonably-efficient
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ service Cassandra {
|
|||
throws (1: InvalidRequestException ire, 2: UnavailableException ue),
|
||||
|
||||
# range query: returns matching keys
|
||||
list<string> get_key_range(1:string tablename, 2:list<string> columnFamilies=[], 3:string startWith="", 4:string stopAt="", 5:i32 maxResults=100) throws (1: InvalidRequestException ire),
|
||||
list<string> get_key_range(1:string tablename, 2:string columnFamily, 3:string startWith="", 4:string stopAt="", 5:i32 maxResults=100)
|
||||
throws (1: InvalidRequestException ire),
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// The following are beta APIs being introduced for CLI and/or CQL support. //
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class Cassandra {
|
|||
|
||||
public void batch_insert_superColumn(batch_mutation_super_t batchMutationSuper, int block_for) throws InvalidRequestException, UnavailableException, TException;
|
||||
|
||||
public List<String> get_key_range(String tablename, List<String> columnFamilies, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException;
|
||||
public List<String> get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException;
|
||||
|
||||
public String getStringProperty(String propertyName) throws TException;
|
||||
|
||||
|
|
@ -572,18 +572,18 @@ public class Cassandra {
|
|||
return;
|
||||
}
|
||||
|
||||
public List<String> get_key_range(String tablename, List<String> columnFamilies, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException
|
||||
public List<String> get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException
|
||||
{
|
||||
send_get_key_range(tablename, columnFamilies, startWith, stopAt, maxResults);
|
||||
send_get_key_range(tablename, columnFamily, startWith, stopAt, maxResults);
|
||||
return recv_get_key_range();
|
||||
}
|
||||
|
||||
public void send_get_key_range(String tablename, List<String> columnFamilies, String startWith, String stopAt, int maxResults) throws TException
|
||||
public void send_get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults) throws TException
|
||||
{
|
||||
oprot_.writeMessageBegin(new TMessage("get_key_range", TMessageType.CALL, seqid_));
|
||||
get_key_range_args args = new get_key_range_args();
|
||||
args.tablename = tablename;
|
||||
args.columnFamilies = columnFamilies;
|
||||
args.columnFamily = columnFamily;
|
||||
args.startWith = startWith;
|
||||
args.stopAt = stopAt;
|
||||
args.maxResults = maxResults;
|
||||
|
|
@ -1160,7 +1160,7 @@ public class Cassandra {
|
|||
iprot.readMessageEnd();
|
||||
get_key_range_result result = new get_key_range_result();
|
||||
try {
|
||||
result.success = iface_.get_key_range(args.tablename, args.columnFamilies, args.startWith, args.stopAt, args.maxResults);
|
||||
result.success = iface_.get_key_range(args.tablename, args.columnFamily, args.startWith, args.stopAt, args.maxResults);
|
||||
} catch (InvalidRequestException ire) {
|
||||
result.ire = ire;
|
||||
} catch (Throwable th) {
|
||||
|
|
@ -10515,15 +10515,15 @@ public class Cassandra {
|
|||
public static class get_key_range_args implements TBase, java.io.Serializable, Cloneable {
|
||||
private static final TStruct STRUCT_DESC = new TStruct("get_key_range_args");
|
||||
private static final TField TABLENAME_FIELD_DESC = new TField("tablename", TType.STRING, (short)1);
|
||||
private static final TField COLUMN_FAMILIES_FIELD_DESC = new TField("columnFamilies", TType.LIST, (short)2);
|
||||
private static final TField COLUMN_FAMILY_FIELD_DESC = new TField("columnFamily", TType.STRING, (short)2);
|
||||
private static final TField START_WITH_FIELD_DESC = new TField("startWith", TType.STRING, (short)3);
|
||||
private static final TField STOP_AT_FIELD_DESC = new TField("stopAt", TType.STRING, (short)4);
|
||||
private static final TField MAX_RESULTS_FIELD_DESC = new TField("maxResults", TType.I32, (short)5);
|
||||
|
||||
public String tablename;
|
||||
public static final int TABLENAME = 1;
|
||||
public List<String> columnFamilies;
|
||||
public static final int COLUMNFAMILIES = 2;
|
||||
public String columnFamily;
|
||||
public static final int COLUMNFAMILY = 2;
|
||||
public String startWith;
|
||||
public static final int STARTWITH = 3;
|
||||
public String stopAt;
|
||||
|
|
@ -10539,9 +10539,8 @@ public class Cassandra {
|
|||
public static final Map<Integer, FieldMetaData> metaDataMap = Collections.unmodifiableMap(new HashMap<Integer, FieldMetaData>() {{
|
||||
put(TABLENAME, new FieldMetaData("tablename", TFieldRequirementType.DEFAULT,
|
||||
new FieldValueMetaData(TType.STRING)));
|
||||
put(COLUMNFAMILIES, new FieldMetaData("columnFamilies", TFieldRequirementType.DEFAULT,
|
||||
new ListMetaData(TType.LIST,
|
||||
new FieldValueMetaData(TType.STRING))));
|
||||
put(COLUMNFAMILY, new FieldMetaData("columnFamily", TFieldRequirementType.DEFAULT,
|
||||
new FieldValueMetaData(TType.STRING)));
|
||||
put(STARTWITH, new FieldMetaData("startWith", TFieldRequirementType.DEFAULT,
|
||||
new FieldValueMetaData(TType.STRING)));
|
||||
put(STOPAT, new FieldMetaData("stopAt", TFieldRequirementType.DEFAULT,
|
||||
|
|
@ -10555,8 +10554,6 @@ public class Cassandra {
|
|||
}
|
||||
|
||||
public get_key_range_args() {
|
||||
this.columnFamilies = new ArrayList<String>();
|
||||
|
||||
this.startWith = "";
|
||||
|
||||
this.stopAt = "";
|
||||
|
|
@ -10567,14 +10564,14 @@ public class Cassandra {
|
|||
|
||||
public get_key_range_args(
|
||||
String tablename,
|
||||
List<String> columnFamilies,
|
||||
String columnFamily,
|
||||
String startWith,
|
||||
String stopAt,
|
||||
int maxResults)
|
||||
{
|
||||
this();
|
||||
this.tablename = tablename;
|
||||
this.columnFamilies = columnFamilies;
|
||||
this.columnFamily = columnFamily;
|
||||
this.startWith = startWith;
|
||||
this.stopAt = stopAt;
|
||||
this.maxResults = maxResults;
|
||||
|
|
@ -10588,12 +10585,8 @@ public class Cassandra {
|
|||
if (other.isSetTablename()) {
|
||||
this.tablename = other.tablename;
|
||||
}
|
||||
if (other.isSetColumnFamilies()) {
|
||||
List<String> __this__columnFamilies = new ArrayList<String>();
|
||||
for (String other_element : other.columnFamilies) {
|
||||
__this__columnFamilies.add(other_element);
|
||||
}
|
||||
this.columnFamilies = __this__columnFamilies;
|
||||
if (other.isSetColumnFamily()) {
|
||||
this.columnFamily = other.columnFamily;
|
||||
}
|
||||
if (other.isSetStartWith()) {
|
||||
this.startWith = other.startWith;
|
||||
|
|
@ -10633,41 +10626,26 @@ public class Cassandra {
|
|||
}
|
||||
}
|
||||
|
||||
public int getColumnFamiliesSize() {
|
||||
return (this.columnFamilies == null) ? 0 : this.columnFamilies.size();
|
||||
public String getColumnFamily() {
|
||||
return this.columnFamily;
|
||||
}
|
||||
|
||||
public java.util.Iterator<String> getColumnFamiliesIterator() {
|
||||
return (this.columnFamilies == null) ? null : this.columnFamilies.iterator();
|
||||
public void setColumnFamily(String columnFamily) {
|
||||
this.columnFamily = columnFamily;
|
||||
}
|
||||
|
||||
public void addToColumnFamilies(String elem) {
|
||||
if (this.columnFamilies == null) {
|
||||
this.columnFamilies = new ArrayList<String>();
|
||||
}
|
||||
this.columnFamilies.add(elem);
|
||||
public void unsetColumnFamily() {
|
||||
this.columnFamily = null;
|
||||
}
|
||||
|
||||
public List<String> getColumnFamilies() {
|
||||
return this.columnFamilies;
|
||||
// Returns true if field columnFamily is set (has been asigned a value) and false otherwise
|
||||
public boolean isSetColumnFamily() {
|
||||
return this.columnFamily != null;
|
||||
}
|
||||
|
||||
public void setColumnFamilies(List<String> columnFamilies) {
|
||||
this.columnFamilies = columnFamilies;
|
||||
}
|
||||
|
||||
public void unsetColumnFamilies() {
|
||||
this.columnFamilies = null;
|
||||
}
|
||||
|
||||
// Returns true if field columnFamilies is set (has been asigned a value) and false otherwise
|
||||
public boolean isSetColumnFamilies() {
|
||||
return this.columnFamilies != null;
|
||||
}
|
||||
|
||||
public void setColumnFamiliesIsSet(boolean value) {
|
||||
public void setColumnFamilyIsSet(boolean value) {
|
||||
if (!value) {
|
||||
this.columnFamilies = null;
|
||||
this.columnFamily = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -10749,11 +10727,11 @@ public class Cassandra {
|
|||
}
|
||||
break;
|
||||
|
||||
case COLUMNFAMILIES:
|
||||
case COLUMNFAMILY:
|
||||
if (value == null) {
|
||||
unsetColumnFamilies();
|
||||
unsetColumnFamily();
|
||||
} else {
|
||||
setColumnFamilies((List<String>)value);
|
||||
setColumnFamily((String)value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -10791,8 +10769,8 @@ public class Cassandra {
|
|||
case TABLENAME:
|
||||
return getTablename();
|
||||
|
||||
case COLUMNFAMILIES:
|
||||
return getColumnFamilies();
|
||||
case COLUMNFAMILY:
|
||||
return getColumnFamily();
|
||||
|
||||
case STARTWITH:
|
||||
return getStartWith();
|
||||
|
|
@ -10813,8 +10791,8 @@ public class Cassandra {
|
|||
switch (fieldID) {
|
||||
case TABLENAME:
|
||||
return isSetTablename();
|
||||
case COLUMNFAMILIES:
|
||||
return isSetColumnFamilies();
|
||||
case COLUMNFAMILY:
|
||||
return isSetColumnFamily();
|
||||
case STARTWITH:
|
||||
return isSetStartWith();
|
||||
case STOPAT:
|
||||
|
|
@ -10848,12 +10826,12 @@ public class Cassandra {
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean this_present_columnFamilies = true && this.isSetColumnFamilies();
|
||||
boolean that_present_columnFamilies = true && that.isSetColumnFamilies();
|
||||
if (this_present_columnFamilies || that_present_columnFamilies) {
|
||||
if (!(this_present_columnFamilies && that_present_columnFamilies))
|
||||
boolean this_present_columnFamily = true && this.isSetColumnFamily();
|
||||
boolean that_present_columnFamily = true && that.isSetColumnFamily();
|
||||
if (this_present_columnFamily || that_present_columnFamily) {
|
||||
if (!(this_present_columnFamily && that_present_columnFamily))
|
||||
return false;
|
||||
if (!this.columnFamilies.equals(that.columnFamilies))
|
||||
if (!this.columnFamily.equals(that.columnFamily))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -10910,19 +10888,9 @@ public class Cassandra {
|
|||
TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
break;
|
||||
case COLUMNFAMILIES:
|
||||
if (field.type == TType.LIST) {
|
||||
{
|
||||
TList _list59 = iprot.readListBegin();
|
||||
this.columnFamilies = new ArrayList<String>(_list59.size);
|
||||
for (int _i60 = 0; _i60 < _list59.size; ++_i60)
|
||||
{
|
||||
String _elem61;
|
||||
_elem61 = iprot.readString();
|
||||
this.columnFamilies.add(_elem61);
|
||||
}
|
||||
iprot.readListEnd();
|
||||
}
|
||||
case COLUMNFAMILY:
|
||||
if (field.type == TType.STRING) {
|
||||
this.columnFamily = iprot.readString();
|
||||
} else {
|
||||
TProtocolUtil.skip(iprot, field.type);
|
||||
}
|
||||
|
|
@ -10971,15 +10939,9 @@ public class Cassandra {
|
|||
oprot.writeString(this.tablename);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
if (this.columnFamilies != null) {
|
||||
oprot.writeFieldBegin(COLUMN_FAMILIES_FIELD_DESC);
|
||||
{
|
||||
oprot.writeListBegin(new TList(TType.STRING, this.columnFamilies.size()));
|
||||
for (String _iter62 : this.columnFamilies) {
|
||||
oprot.writeString(_iter62);
|
||||
}
|
||||
oprot.writeListEnd();
|
||||
}
|
||||
if (this.columnFamily != null) {
|
||||
oprot.writeFieldBegin(COLUMN_FAMILY_FIELD_DESC);
|
||||
oprot.writeString(this.columnFamily);
|
||||
oprot.writeFieldEnd();
|
||||
}
|
||||
if (this.startWith != null) {
|
||||
|
|
@ -11012,11 +10974,11 @@ public class Cassandra {
|
|||
}
|
||||
first = false;
|
||||
if (!first) sb.append(", ");
|
||||
sb.append("columnFamilies:");
|
||||
if (this.columnFamilies == null) {
|
||||
sb.append("columnFamily:");
|
||||
if (this.columnFamily == null) {
|
||||
sb.append("null");
|
||||
} else {
|
||||
sb.append(this.columnFamilies);
|
||||
sb.append(this.columnFamily);
|
||||
}
|
||||
first = false;
|
||||
if (!first) sb.append(", ");
|
||||
|
|
@ -11271,13 +11233,13 @@ public class Cassandra {
|
|||
case SUCCESS:
|
||||
if (field.type == TType.LIST) {
|
||||
{
|
||||
TList _list63 = iprot.readListBegin();
|
||||
this.success = new ArrayList<String>(_list63.size);
|
||||
for (int _i64 = 0; _i64 < _list63.size; ++_i64)
|
||||
TList _list59 = iprot.readListBegin();
|
||||
this.success = new ArrayList<String>(_list59.size);
|
||||
for (int _i60 = 0; _i60 < _list59.size; ++_i60)
|
||||
{
|
||||
String _elem65;
|
||||
_elem65 = iprot.readString();
|
||||
this.success.add(_elem65);
|
||||
String _elem61;
|
||||
_elem61 = iprot.readString();
|
||||
this.success.add(_elem61);
|
||||
}
|
||||
iprot.readListEnd();
|
||||
}
|
||||
|
|
@ -11313,8 +11275,8 @@ public class Cassandra {
|
|||
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
|
||||
{
|
||||
oprot.writeListBegin(new TList(TType.STRING, this.success.size()));
|
||||
for (String _iter66 : this.success) {
|
||||
oprot.writeString(_iter66);
|
||||
for (String _iter62 : this.success) {
|
||||
oprot.writeString(_iter62);
|
||||
}
|
||||
oprot.writeListEnd();
|
||||
}
|
||||
|
|
@ -12121,13 +12083,13 @@ public class Cassandra {
|
|||
case SUCCESS:
|
||||
if (field.type == TType.LIST) {
|
||||
{
|
||||
TList _list67 = iprot.readListBegin();
|
||||
this.success = new ArrayList<String>(_list67.size);
|
||||
for (int _i68 = 0; _i68 < _list67.size; ++_i68)
|
||||
TList _list63 = iprot.readListBegin();
|
||||
this.success = new ArrayList<String>(_list63.size);
|
||||
for (int _i64 = 0; _i64 < _list63.size; ++_i64)
|
||||
{
|
||||
String _elem69;
|
||||
_elem69 = iprot.readString();
|
||||
this.success.add(_elem69);
|
||||
String _elem65;
|
||||
_elem65 = iprot.readString();
|
||||
this.success.add(_elem65);
|
||||
}
|
||||
iprot.readListEnd();
|
||||
}
|
||||
|
|
@ -12155,8 +12117,8 @@ public class Cassandra {
|
|||
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
|
||||
{
|
||||
oprot.writeListBegin(new TList(TType.STRING, this.success.size()));
|
||||
for (String _iter70 : this.success) {
|
||||
oprot.writeString(_iter70);
|
||||
for (String _iter66 : this.success) {
|
||||
oprot.writeString(_iter66);
|
||||
}
|
||||
oprot.writeListEnd();
|
||||
}
|
||||
|
|
@ -12627,27 +12589,27 @@ public class Cassandra {
|
|||
case SUCCESS:
|
||||
if (field.type == TType.MAP) {
|
||||
{
|
||||
TMap _map71 = iprot.readMapBegin();
|
||||
this.success = new HashMap<String,Map<String,String>>(2*_map71.size);
|
||||
for (int _i72 = 0; _i72 < _map71.size; ++_i72)
|
||||
TMap _map67 = iprot.readMapBegin();
|
||||
this.success = new HashMap<String,Map<String,String>>(2*_map67.size);
|
||||
for (int _i68 = 0; _i68 < _map67.size; ++_i68)
|
||||
{
|
||||
String _key73;
|
||||
Map<String,String> _val74;
|
||||
_key73 = iprot.readString();
|
||||
String _key69;
|
||||
Map<String,String> _val70;
|
||||
_key69 = iprot.readString();
|
||||
{
|
||||
TMap _map75 = iprot.readMapBegin();
|
||||
_val74 = new HashMap<String,String>(2*_map75.size);
|
||||
for (int _i76 = 0; _i76 < _map75.size; ++_i76)
|
||||
TMap _map71 = iprot.readMapBegin();
|
||||
_val70 = new HashMap<String,String>(2*_map71.size);
|
||||
for (int _i72 = 0; _i72 < _map71.size; ++_i72)
|
||||
{
|
||||
String _key77;
|
||||
String _val78;
|
||||
_key77 = iprot.readString();
|
||||
_val78 = iprot.readString();
|
||||
_val74.put(_key77, _val78);
|
||||
String _key73;
|
||||
String _val74;
|
||||
_key73 = iprot.readString();
|
||||
_val74 = iprot.readString();
|
||||
_val70.put(_key73, _val74);
|
||||
}
|
||||
iprot.readMapEnd();
|
||||
}
|
||||
this.success.put(_key73, _val74);
|
||||
this.success.put(_key69, _val70);
|
||||
}
|
||||
iprot.readMapEnd();
|
||||
}
|
||||
|
|
@ -12683,13 +12645,13 @@ public class Cassandra {
|
|||
oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
|
||||
{
|
||||
oprot.writeMapBegin(new TMap(TType.STRING, TType.MAP, this.success.size()));
|
||||
for (Map.Entry<String, Map<String,String>> _iter79 : this.success.entrySet()) {
|
||||
oprot.writeString(_iter79.getKey());
|
||||
for (Map.Entry<String, Map<String,String>> _iter75 : this.success.entrySet()) {
|
||||
oprot.writeString(_iter75.getKey());
|
||||
{
|
||||
oprot.writeMapBegin(new TMap(TType.STRING, TType.STRING, _iter79.getValue().size()));
|
||||
for (Map.Entry<String, String> _iter80 : _iter79.getValue().entrySet()) {
|
||||
oprot.writeString(_iter80.getKey());
|
||||
oprot.writeString(_iter80.getValue());
|
||||
oprot.writeMapBegin(new TMap(TType.STRING, TType.STRING, _iter75.getValue().size()));
|
||||
for (Map.Entry<String, String> _iter76 : _iter75.getValue().entrySet()) {
|
||||
oprot.writeString(_iter76.getKey());
|
||||
oprot.writeString(_iter76.getValue());
|
||||
}
|
||||
oprot.writeMapEnd();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,15 +38,15 @@ public class RangeCommand
|
|||
private static RangeCommandSerializer serializer = new RangeCommandSerializer();
|
||||
|
||||
public final String table;
|
||||
public final List<String> columnFamilyNames;
|
||||
public final String columnFamily;
|
||||
public final String startWith;
|
||||
public final String stopAt;
|
||||
public final int maxResults;
|
||||
|
||||
public RangeCommand(String table, List<String> columnFamilyNames, String startWith, String stopAt, int maxResults)
|
||||
public RangeCommand(String table, String columnFamily, String startWith, String stopAt, int maxResults)
|
||||
{
|
||||
this.table = table;
|
||||
this.columnFamilyNames = Collections.unmodifiableList(columnFamilyNames);
|
||||
this.columnFamily = columnFamily;
|
||||
this.startWith = startWith;
|
||||
this.stopAt = stopAt;
|
||||
this.maxResults = maxResults;
|
||||
|
|
@ -74,7 +74,7 @@ public class RangeCommand
|
|||
{
|
||||
return "RangeCommand(" +
|
||||
"table='" + table + '\'' +
|
||||
", columnFamilyNames=[" + StringUtils.join(columnFamilyNames, ", ") + "]" +
|
||||
", columnFamily=" + columnFamily +
|
||||
", startWith='" + startWith + '\'' +
|
||||
", stopAt='" + stopAt + '\'' +
|
||||
", maxResults=" + maxResults +
|
||||
|
|
@ -86,12 +86,8 @@ class RangeCommandSerializer implements ICompactSerializer<RangeCommand>
|
|||
{
|
||||
public void serialize(RangeCommand command, DataOutputStream dos) throws IOException
|
||||
{
|
||||
dos.writeInt(command.columnFamilyNames.size());
|
||||
for (String cfName : command.columnFamilyNames)
|
||||
{
|
||||
dos.writeUTF(cfName);
|
||||
}
|
||||
dos.writeUTF(command.table);
|
||||
dos.writeUTF(command.columnFamily);
|
||||
dos.writeUTF(command.startWith);
|
||||
dos.writeUTF(command.stopAt);
|
||||
dos.writeInt(command.maxResults);
|
||||
|
|
@ -99,11 +95,6 @@ class RangeCommandSerializer implements ICompactSerializer<RangeCommand>
|
|||
|
||||
public RangeCommand deserialize(DataInputStream dis) throws IOException
|
||||
{
|
||||
String[] cfNames = new String[dis.readInt()];
|
||||
for (int i = 0; i < cfNames.length; i++)
|
||||
{
|
||||
cfNames[i] = dis.readUTF();
|
||||
}
|
||||
return new RangeCommand(dis.readUTF(), Arrays.asList(cfNames), dis.readUTF(), dis.readUTF(), dis.readInt());
|
||||
return new RangeCommand(dis.readUTF(), dis.readUTF(), dis.readUTF(), dis.readUTF(), dis.readInt());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -695,73 +695,59 @@ public class Table
|
|||
* @param maxResults
|
||||
* @return list of keys between startWith and stopAt
|
||||
*/
|
||||
public List<String> getKeyRange(Collection<String> columnFamilyNames, final String startWith, final String stopAt, int maxResults)
|
||||
public List<String> getKeyRange(String columnFamily, final String startWith, final String stopAt, int maxResults)
|
||||
throws IOException, ExecutionException, InterruptedException
|
||||
{
|
||||
// TODO we need a better way to keep compactions from stomping on reads than One Big Lock per CF.
|
||||
if (columnFamilyNames.isEmpty())
|
||||
{
|
||||
columnFamilyNames = getApplicationColumnFamilies();
|
||||
}
|
||||
assert getColumnFamilyStore(columnFamily) != null : columnFamily;
|
||||
|
||||
for (String cfName : columnFamilyNames)
|
||||
{
|
||||
getColumnFamilyStore(cfName).getReadLock().lock();
|
||||
}
|
||||
getColumnFamilyStore(columnFamily).getReadLock().lock();
|
||||
try
|
||||
{
|
||||
return getKeyRangeUnsafe(columnFamilyNames, startWith, stopAt, maxResults);
|
||||
return getKeyRangeUnsafe(columnFamily, startWith, stopAt, maxResults);
|
||||
}
|
||||
finally
|
||||
{
|
||||
for (String cfName : columnFamilyNames)
|
||||
{
|
||||
getColumnFamilyStore(cfName).getReadLock().unlock();
|
||||
}
|
||||
getColumnFamilyStore(columnFamily).getReadLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getKeyRangeUnsafe(final Collection<String> columnFamilyNames, final String startWith, final String stopAt, int maxResults) throws IOException, ExecutionException, InterruptedException
|
||||
private List<String> getKeyRangeUnsafe(final String columnFamily, final String startWith, final String stopAt, int maxResults) throws IOException, ExecutionException, InterruptedException
|
||||
{
|
||||
assert !columnFamilyNames.isEmpty(); // checked by the 'safe' method
|
||||
|
||||
// (OPP key decoration is a no-op so using the "decorated" comparator against raw keys is fine)
|
||||
final Comparator<String> comparator = StorageService.getPartitioner().getDecoratedKeyComparator();
|
||||
|
||||
// create a CollatedIterator that will return unique keys from different sources
|
||||
// (current memtable, historical memtables, and SSTables) in the correct order.
|
||||
List<Iterator<String>> iterators = new ArrayList<Iterator<String>>();
|
||||
for (String cfName : columnFamilyNames)
|
||||
ColumnFamilyStore cfs = getColumnFamilyStore(columnFamily);
|
||||
|
||||
// we iterate through memtables with a priorityqueue to avoid more sorting than necessary.
|
||||
// this predicate throws out the keys before the start of our range.
|
||||
Predicate p = new Predicate()
|
||||
{
|
||||
ColumnFamilyStore cfs = getColumnFamilyStore(cfName);
|
||||
|
||||
// we iterate through memtables with a priorityqueue to avoid more sorting than necessary.
|
||||
// this predicate throws out the keys before the start of our range.
|
||||
Predicate p = new Predicate()
|
||||
public boolean evaluate(Object key)
|
||||
{
|
||||
public boolean evaluate(Object key)
|
||||
{
|
||||
String st = (String)key;
|
||||
return comparator.compare(startWith, st) <= 0 && (stopAt.isEmpty() || comparator.compare(st, stopAt) <= 0);
|
||||
}
|
||||
};
|
||||
|
||||
// current memtable keys. have to go through the CFS api for locking.
|
||||
iterators.add(IteratorUtils.filteredIterator(cfs.memtableKeyIterator(), p));
|
||||
// historical memtables
|
||||
for (Memtable memtable : ColumnFamilyStore.getUnflushedMemtables(cfName))
|
||||
{
|
||||
iterators.add(IteratorUtils.filteredIterator(Memtable.getKeyIterator(memtable.getKeys()), p));
|
||||
String st = (String)key;
|
||||
return comparator.compare(startWith, st) <= 0 && (stopAt.isEmpty() || comparator.compare(st, stopAt) <= 0);
|
||||
}
|
||||
};
|
||||
|
||||
// sstables
|
||||
for (SSTableReader sstable : cfs.getSSTables())
|
||||
{
|
||||
FileStruct fs = sstable.getFileStruct();
|
||||
fs.seekTo(startWith);
|
||||
iterators.add(fs);
|
||||
}
|
||||
// current memtable keys. have to go through the CFS api for locking.
|
||||
iterators.add(IteratorUtils.filteredIterator(cfs.memtableKeyIterator(), p));
|
||||
// historical memtables
|
||||
for (Memtable memtable : ColumnFamilyStore.getUnflushedMemtables(columnFamily))
|
||||
{
|
||||
iterators.add(IteratorUtils.filteredIterator(Memtable.getKeyIterator(memtable.getKeys()), p));
|
||||
}
|
||||
|
||||
// sstables
|
||||
for (SSTableReader sstable : cfs.getSSTables())
|
||||
{
|
||||
FileStruct fs = sstable.getFileStruct();
|
||||
fs.seekTo(startWith);
|
||||
iterators.add(fs);
|
||||
}
|
||||
|
||||
Iterator<String> collated = IteratorUtils.collatedIterator(comparator, iterators);
|
||||
Iterable<String> reduced = new ReducingIterator<String>(collated) {
|
||||
String current;
|
||||
|
|
@ -790,15 +776,9 @@ public class Table
|
|||
}
|
||||
// make sure there is actually non-tombstone content associated w/ this key
|
||||
// TODO record the key source(s) somehow and only check that source (e.g., memtable or sstable)
|
||||
for (String cfName : columnFamilyNames)
|
||||
if (cfs.getColumnFamily(current, columnFamily, new IdentityFilter(), Integer.MAX_VALUE) != null)
|
||||
{
|
||||
ColumnFamilyStore cfs = getColumnFamilyStore(cfName);
|
||||
ColumnFamily cf = cfs.getColumnFamily(current, cfName, new IdentityFilter(), Integer.MAX_VALUE);
|
||||
if (cf != null && cf.getColumns().size() > 0)
|
||||
{
|
||||
keys.add(current);
|
||||
break;
|
||||
}
|
||||
keys.add(current);
|
||||
}
|
||||
if (keys.size() >= maxResults)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -500,10 +500,10 @@ public class CassandraServer implements Cassandra.Iface
|
|||
return result;
|
||||
}
|
||||
|
||||
public List<String> get_key_range(String tablename, List<String> columnFamilies, String startWith, String stopAt, int maxResults) throws InvalidRequestException
|
||||
public List<String> get_key_range(String tablename, String columnFamily, String startWith, String stopAt, int maxResults) throws InvalidRequestException, TException
|
||||
{
|
||||
logger.debug("get_key_range");
|
||||
ThriftValidation.validateCommand(tablename, columnFamilies.toArray(new String[columnFamilies.size()]));
|
||||
ThriftValidation.validateCommand(tablename, columnFamily);
|
||||
if (!(StorageService.getPartitioner() instanceof OrderPreservingPartitioner))
|
||||
{
|
||||
throw new InvalidRequestException("range queries may only be performed against an order-preserving partitioner");
|
||||
|
|
@ -513,7 +513,7 @@ public class CassandraServer implements Cassandra.Iface
|
|||
throw new InvalidRequestException("maxResults must be positive");
|
||||
}
|
||||
|
||||
return StorageProxy.getKeyRange(new RangeCommand(tablename, columnFamilies, startWith, stopAt, maxResults));
|
||||
return StorageProxy.getKeyRange(new RangeCommand(tablename, columnFamily, startWith, stopAt, maxResults));
|
||||
}
|
||||
|
||||
// main method moved to CassandraDaemon
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class RangeVerbHandler implements IVerbHandler
|
|||
{
|
||||
RangeCommand command = RangeCommand.read(message);
|
||||
Table table = Table.open(command.table);
|
||||
keys = table.getKeyRange(command.columnFamilyNames, command.startWith, command.stopAt, command.maxResults);
|
||||
keys = table.getKeyRange(command.columnFamily, command.startWith, command.stopAt, command.maxResults);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ class TestMutations(CassandraTester):
|
|||
_expect_exception(lambda: client.get_column('Table1', 'key1', 'Super1'), InvalidRequestException)
|
||||
_expect_exception(lambda: client.get_column('Table1', 'key1', 'Super1:x'), InvalidRequestException)
|
||||
_expect_exception(lambda: client.get_column('Table1', 'key1', 'Super1:x:y:z'), InvalidRequestException)
|
||||
_expect_exception(lambda: client.get_key_range('Table1', ['S'], '', '', 1000), InvalidRequestException)
|
||||
_expect_exception(lambda: client.get_key_range('Table1', 'S', '', '', 1000), InvalidRequestException)
|
||||
|
||||
def test_batch_insert_super(self):
|
||||
cfmap = {'Super1': _SUPER_COLUMNS,
|
||||
|
|
@ -275,23 +275,22 @@ class TestMutations(CassandraTester):
|
|||
|
||||
|
||||
def test_empty_range(self):
|
||||
assert client.get_key_range('Table1', [], '', '', 1000) == []
|
||||
assert client.get_key_range('Table1', ['Standard1'], '', '', 1000) == []
|
||||
assert client.get_key_range('Table1', 'Standard1', '', '', 1000) == []
|
||||
_insert_simple()
|
||||
assert client.get_key_range('Table1', ['Super1'], '', '', 1000) == []
|
||||
assert client.get_key_range('Table1', 'Super1', '', '', 1000) == []
|
||||
|
||||
def test_range_with_remove(self):
|
||||
_insert_simple()
|
||||
assert client.get_key_range('Table1', [], 'key1', '', 1000) == ['key1']
|
||||
assert client.get_key_range('Table1', 'Standard1', 'key1', '', 1000) == ['key1']
|
||||
|
||||
client.remove('Table1', 'key1', 'Standard1:c1', 1, True)
|
||||
client.remove('Table1', 'key1', 'Standard1:c2', 1, True)
|
||||
assert client.get_key_range('Table1', [], '', '', 1000) == []
|
||||
assert client.get_key_range('Table1', 'Standard1', '', '', 1000) == []
|
||||
|
||||
def test_range_collation(self):
|
||||
for key in ['-a', '-b', 'a', 'b'] + [str(i) for i in xrange(100)]:
|
||||
client.insert('Table1', key, 'Standard1:' + key, 'v', 0, True)
|
||||
L = client.get_key_range('Table1', ['Standard1'], '', '', 1000)
|
||||
L = client.get_key_range('Table1', 'Standard1', '', '', 1000)
|
||||
# note the collated ordering rather than ascii
|
||||
assert L == ['0', '1', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '21', '22', '23', '24', '25', '26', '27','28', '29', '3', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '4', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '5', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '6', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '7', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '8', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '9', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', 'a', '-a', 'b', '-b'], L
|
||||
|
||||
|
|
@ -299,16 +298,16 @@ class TestMutations(CassandraTester):
|
|||
for key in ['-a', '-b', 'a', 'b'] + [str(i) for i in xrange(100)]:
|
||||
client.insert('Table1', key, 'Standard1:' + key, 'v', 0, True)
|
||||
|
||||
L = client.get_key_range('Table1', [], 'a', '', 1000)
|
||||
L = client.get_key_range('Table1', 'Standard1', 'a', '', 1000)
|
||||
assert L == ['a', '-a', 'b', '-b'], L
|
||||
|
||||
L = client.get_key_range('Table1', [], '', '15', 1000)
|
||||
L = client.get_key_range('Table1', 'Standard1', '', '15', 1000)
|
||||
assert L == ['0', '1', '10', '11', '12', '13', '14', '15'], L
|
||||
|
||||
L = client.get_key_range('Table1', [], '50', '51', 1000)
|
||||
L = client.get_key_range('Table1', 'Standard1', '50', '51', 1000)
|
||||
assert L == ['50', '51'], L
|
||||
|
||||
L = client.get_key_range('Table1', [], '1', '', 10)
|
||||
L = client.get_key_range('Table1', 'Standard1', '1', '', 10)
|
||||
assert L == ['1', '10', '11', '12', '13', '14', '15', '16', '17', '18'], L
|
||||
|
||||
def test_get_slice_range(self):
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class CompactionsTest extends CleanupHelper
|
|||
inserted.add(key);
|
||||
}
|
||||
store.forceBlockingFlush();
|
||||
assertEquals(table.getKeyRange(Arrays.asList("Standard1"), "", "", 10000).size(), inserted.size());
|
||||
assertEquals(table.getKeyRange("Standard1", "", "", 10000).size(), inserted.size());
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -63,6 +63,6 @@ public class CompactionsTest extends CleanupHelper
|
|||
{
|
||||
store.doCompaction(store.getSSTables().size());
|
||||
}
|
||||
assertEquals(table.getKeyRange(Arrays.asList("Standard1"), "", "", 10000).size(), inserted.size());
|
||||
assertEquals(table.getKeyRange("Standard1", "", "", 10000).size(), inserted.size());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ public class OneCompactionTest
|
|||
rm.apply();
|
||||
inserted.add(key);
|
||||
store.forceBlockingFlush();
|
||||
assertEquals(table.getKeyRange(Arrays.asList(columnFamilyName), "", "", 10000).size(), inserted.size());
|
||||
assertEquals(table.getKeyRange(columnFamilyName, "", "", 10000).size(), inserted.size());
|
||||
}
|
||||
Future<Integer> ft = MinorCompactionManager.instance().submit(store, 2);
|
||||
ft.get();
|
||||
assertEquals(1, store.getSSTables().size());
|
||||
assertEquals(table.getKeyRange(Arrays.asList(columnFamilyName), "", "", 10000).size(), inserted.size());
|
||||
assertEquals(table.getKeyRange(columnFamilyName, "", "", 10000).size(), inserted.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public class RecoveryManager2Test extends CleanupHelper
|
|||
table1.getColumnFamilyStore("Standard1").clearUnsafe();
|
||||
RecoveryManager.doRecovery();
|
||||
|
||||
Set<String> foundKeys = new HashSet<String>(table1.getKeyRange(Arrays.asList("Standard1"), "", "", 1000));
|
||||
Set<String> foundKeys = new HashSet<String>(table1.getKeyRange("Standard1", "", "", 1000));
|
||||
assert keys.equals(foundKeys);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue