package me.xhh.hector07;
import static me.prettyprint.hector.api.factory.HFactory.createColumnQuery;
import static me.prettyprint.hector.api.factory.HFactory.createMutator;
import static me.prettyprint.hector.api.factory.HFactory.createSuperColumnQuery;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import me.prettyprint.cassandra.service.FailoverPolicy;
import me.prettyprint.hector.api.Cluster;
import me.prettyprint.hector.api.Keyspace;
import me.prettyprint.hector.api.Serializer;
import me.prettyprint.hector.api.beans.HColumn;
import me.prettyprint.hector.api.beans.HSuperColumn;
import me.prettyprint.hector.api.beans.OrderedRows;
import me.prettyprint.hector.api.beans.OrderedSuperRows;
import me.prettyprint.hector.api.beans.Row;
import me.prettyprint.hector.api.beans.SuperRow;
import me.prettyprint.hector.api.exceptions.HectorException;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.ColumnQuery;
import me.prettyprint.hector.api.query.CountQuery;
import me.prettyprint.hector.api.query.QueryResult;
import me.prettyprint.hector.api.query.RangeSlicesQuery;
import me.prettyprint.hector.api.query.RangeSubSlicesQuery;
import me.prettyprint.hector.api.query.RangeSuperSlicesQuery;
import me.prettyprint.hector.api.query.SliceQuery;
import me.prettyprint.hector.api.query.SubColumnQuery;
import me.prettyprint.hector.api.query.SubCountQuery;
import me.prettyprint.hector.api.query.SubSliceQuery;
import me.prettyprint.hector.api.query.SuperColumnQuery;
import me.prettyprint.hector.api.query.SuperCountQuery;
import me.prettyprint.hector.api.query.SuperSliceQuery;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Database Accessor for accessing the Cassandra database.
*
* @author xhh
*/
public class DBA {
private static Logger log = LoggerFactory.getLogger(DBA.class);
private DBConfig dbConfig;
private Keyspace keyspace;
public DBA() {
}
public DBA(DBConfig dbConfig) {
setDbConfig(dbConfig);
}
public <K, N, V> void insertValue(NormalColumnFamily<K, N, V> cf, K key, N colName, V colValue) {
createMutator(keyspace, cf.getKeySerializer()).insert(key, cf.getColumnFamilyName(), cf.createColumn(colName, colValue));
}
@SuppressWarnings("unchecked")
public <K, SN, N, V> void insertValue(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N colName, V colValue) {
HSuperColumn<SN, N, V> sc = cf.createSuperColumn(superColName, cf.createColumn(colName, colValue));
createMutator(keyspace, cf.getKeySerializer()).insert(key, cf.getColumnFamilyName(), sc);
}
public <K, N, V> void insertColumns(NormalColumnFamily<K, N, V> cf, K key, List<HColumn<N, V>> cols) {
if (cols == null || cols.isEmpty()) {
throw new IllegalArgumentException("Columns can not be null or empty!");
}
Mutator<K> m = createMutator(keyspace, cf.getKeySerializer());
for (HColumn<N, V> column : cols) {
m.addInsertion(key, cf.getColumnFamilyName(), column);
}
m.execute();
}
public <K, SN, N, V> void insertColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, List<HColumn<N, V>> cols) {
insertSuperColumn(cf, key, cf.createSuperColumn(superColName, cols));
}
public <K, SN, N, V> void insertSuperColumn(SuperColumnFamily<K, SN, N, V> cf, K key, HSuperColumn<SN, N, V> superCol) {
if (superCol == null) {
throw new IllegalArgumentException("Super column can not be null!");
} else {
createMutator(keyspace, cf.getKeySerializer()).insert(key, cf.getColumnFamilyName(), superCol);
}
}
public <K, SN, N, V> void insertSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, HSuperColumn<SN, N, V>... superCols) {
if (superCols == null || superCols.length == 0) {
throw new IllegalArgumentException("Super column can not be null or empty!");
} else {
Mutator<K> m = createMutator(keyspace, cf.getKeySerializer());
for (HSuperColumn<SN, N, V> sc : superCols) {
m.addInsertion(key, cf.getColumnFamilyName(), sc);
}
m.execute();
}
}
public <K, SN, N, V> void insertSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, List<HSuperColumn<SN, N, V>> superCols) {
if (superCols == null || superCols.isEmpty()) {
throw new IllegalArgumentException("Super column can not be null or empty!");
} else {
Mutator<K> m = createMutator(keyspace, cf.getKeySerializer());
for (HSuperColumn<SN, N, V> sc : superCols) {
m.addInsertion(key, cf.getColumnFamilyName(), sc);
}
m.execute();
}
}
public <K, N, V> HColumn<N, V> getColumn(NormalColumnFamily<K, N, V> cf, K key, N colName) {
ColumnQuery<K, N, V> q = createColumnQuery(keyspace, cf.getKeySerializer(), cf.getNameSerializer(), cf.getValueSerializer());
QueryResult<HColumn<N, V>> r = q.setKey(key).setName(colName).setColumnFamily(cf.getColumnFamilyName()).execute();
return r.get();
}
public <K, SN, N, V> HColumn<N, V> getColumn(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N colName) {
SubColumnQuery<K, SN, N, V> q = HFactory.createSubColumnQuery(keyspace, cf.getKeySerializer(), cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer());
QueryResult<HColumn<N, V>> r = q.setKey(key)
.setSuperColumn(superColName)
.setColumn(colName)
.setColumnFamily(cf.getColumnFamilyName())
.execute();
return r.get();
}
public <K, N, V> V getValue(NormalColumnFamily<K, N, V> cf, K key, N colName) {
HColumn<N, V> c = getColumn(cf, key, colName);
return c == null ? null : c.getValue();
}
public <K, SN, N, V> HSuperColumn<SN, N, V> getSuperColumn(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
SuperColumnQuery<K, SN, N, V> q = createSuperColumnQuery(keyspace, cf.getKeySerializer(), cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer());
QueryResult<HSuperColumn<SN, N, V>> r = q.setKey(key)
.setSuperName(superColName)
.setColumnFamily(cf.getColumnFamilyName())
.execute();
HSuperColumn<SN, N, V> s = r.get();
// XHH --- Note: treat empty SuperColumn as nonexistent
// if (sc == null || !sc.getColumnsIterator().hasNext())
// return null;
// else
// return sc;
return s;
}
public <K, SN, N, V> V getValue(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N colName) {
HColumn<N, V> c = getColumn(cf, key, superColName, colName);
return c == null ? null : c.getValue();
}
public <K, N, V> boolean columnExists(NormalColumnFamily<K, N, V> cf, K key, N colName) {
HColumn<N, V> c = getColumn(cf, key, colName);
return c != null;
}
public <K, SN, N, V> boolean columnExists(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N colName) {
HColumn<N, V> c = getColumn(cf, key, superColName, colName);
return c != null;
}
/**
* Read all columns of the column family. This does NOT applies to super column families.<br/>
* Note: reading all columns could be slow.
*
* @param cf
* the column family, can NOT be super column family
* @param key
* @return
* @throws HectorException
*/
public <K, N, V> List<HColumn<N, V>> getAllColumns(NormalColumnFamily<K, N, V> cf, K key) {
return getAllColumns(cf, key, 1000, false);
}
public <K, N, V> List<HColumn<N, V>> getAllColumns(NormalColumnFamily<K, N, V> cf, K key, boolean reversed) {
return getAllColumns(cf, key, 1000, reversed);
}
public <K, SN, N, V> List<HColumn<N, V>> getAllColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
return getAllColumns(cf, key, superColName, false);
}
/**
* Read all columns by reading 1000 columns at a time.
*
* @param cf
* @param key
* @param superColName
* @param reversed
* @return
*/
public <K, SN, N, V> List<HColumn<N, V>> getAllColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, boolean reversed) {
return getAllColumns(cf, key, superColName, 1000, reversed);
}
/**
* Read all columns of the column family.<br/>
* Note: reading all columns could be slow.
*
* @param cf
* the (super) column family
* @param key
* @param superColName
* the super column name when reading all columns from a super column family
* @param count
* how many columns to read at a time
* @return
*/
public <K, N, V> List<HColumn<N, V>> getAllColumns(NormalColumnFamily<K, N, V> cf, K key, int count, boolean reversed) {
if (count <= 1) {
throw new IllegalArgumentException("count must be bigger than 1!");
}
List<HColumn<N, V>> all = new ArrayList<HColumn<N, V>>();
Serializer<K> keySerializer = cf.getKeySerializer();
SliceQuery<K, N, V> q = HFactory.createSliceQuery(keyspace, keySerializer, cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key);
q.setRange(null, null, reversed, count);
do {
List<HColumn<N, V>> data = q.execute().get().getColumns();
int size = data.size();
if (size < count) { // end reached
all.addAll(data);
break;
} else { // continue to read more
q.setRange(data.remove(size - 1).getName(), null, reversed, count);
all.addAll(data);
}
} while (true);
return all;
}
public <K, SN, N, V> List<HColumn<N, V>> getAllColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, int count,
boolean reversed) {
if (count <= 1) {
throw new IllegalArgumentException("count must be bigger than 1!");
}
List<HColumn<N, V>> all = new ArrayList<HColumn<N, V>>();
Serializer<K> keySerializer = cf.getKeySerializer();
if (superColName == null) {
throw new IllegalArgumentException("superColName can not be null!");
} else {
SubSliceQuery<K, SN, N, V> q = HFactory.createSubSliceQuery(keyspace, keySerializer, cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer()).setSuperColumn(superColName);
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key).setSuperColumn(superColName);
q.setRange(null, null, reversed, count);
do {
List<HColumn<N, V>> data = q.execute().get().getColumns();
int size = data.size();
if (size < count) { // end reached
all.addAll(data);
break;
} else { // continue to read more
q.setRange(data.remove(size - 1).getName(), null, reversed, count);
all.addAll(data);
}
} while (true);
}
return all;
}
public <K, N, V> List<HColumn<N, V>> getColumns(NormalColumnFamily<K, N, V> cf, K key, N... colNames) {
if (colNames == null || colNames.length == 0) {
throw new IllegalArgumentException("colNames can not be null or empty!");
}
return getColumns(cf, key, colNames, null, null, 0, false);
}
public <K, SN, N, V> List<HColumn<N, V>> getColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N... colNames) {
if (colNames == null || colNames.length == 0) {
throw new IllegalArgumentException("colNames can not be null or empty!");
}
return getColumns(cf, key, superColName, colNames, null, null, 0, false);
}
public <K, N, V> List<HColumn<N, V>> getColumns(NormalColumnFamily<K, N, V> cf, K key, N start, int count) {
return getColumns(cf, key, null, start, null, count, false);
}
public <K, N, V> List<HColumn<N, V>> getColumns(NormalColumnFamily<K, N, V> cf, K key, N start, int count, boolean reversed) {
return getColumns(cf, key, null, start, null, count, reversed);
}
public <K, N, V> List<HColumn<N, V>> getColumns(NormalColumnFamily<K, N, V> cf, K key, N start, N finish, int count,
boolean reversed) {
return getColumns(cf, key, null, start, finish, count, reversed);
}
public <K, SN, N, V> List<HColumn<N, V>> getColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N start, int count) {
return getColumns(cf, key, superColName, null, start, null, count, false);
}
public <K, N, V> List<HColumn<N, V>> getColumns(NormalColumnFamily<K, N, V> cf, K key, N[] colNames, N start, N finish, int count,
boolean reversed) {
Serializer<K> keySerializer = cf.getKeySerializer();
List<HColumn<N, V>> results;
SliceQuery<K, N, V> q = HFactory.createSliceQuery(keyspace, keySerializer, cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key);
if (colNames == null) {
q.setRange(start, finish, reversed, count);
} else {
q.setColumnNames(colNames);
}
results = q.execute().get().getColumns();
return results;
}
public <K, SN, N, V> List<HColumn<N, V>> getColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N[] colNames,
N start, N finish, int count, boolean reversed) {
Serializer<K> keySerializer = cf.getKeySerializer();
List<HColumn<N, V>> results;
if (superColName == null) {
throw new IllegalArgumentException("superColName can not be null!");
} else {
SubSliceQuery<K, SN, N, V> q = HFactory.createSubSliceQuery(keyspace, keySerializer, cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer()).setSuperColumn(superColName);
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key).setSuperColumn(superColName);
if (colNames == null) {
q.setRange(start, finish, reversed, count);
} else {
q.setColumnNames(colNames);
}
results = q.execute().get().getColumns();
}
return results;
}
public <K, N, V> Map<N, V> getAllColumnsToMap(NormalColumnFamily<K, N, V> cf, K key) {
return DBUtil.columnsToMap(getAllColumns(cf, key));
}
public <K, SN, N, V> Map<N, V> getAllColumnsToMap(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
return DBUtil.columnsToMap(getAllColumns(cf, key, superColName));
}
public <K, N, V> Map<N, V> getColumnsToMap(NormalColumnFamily<K, N, V> cf, K key, N... colNames) {
return DBUtil.columnsToMap(getColumns(cf, key, colNames));
}
@SuppressWarnings("unchecked")
public <K, N, V> Map<N, V> getColumnsToMap(NormalColumnFamily<K, N, V> cf, K key, List<N> colNames) {
return DBUtil.columnsToMap(getColumns(cf, key, (N[]) colNames.toArray()));
}
public <K, SN, N, V> Map<N, V> getColumnsToMap(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N... colNames) {
return DBUtil.columnsToMap(getColumns(cf, key, superColName, colNames, null, null, 0, false));
}
@SuppressWarnings("unchecked")
public <K, SN, N, V> Map<N, V> getColumnsToMap(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, List<N> colNames) {
return DBUtil.columnsToMap(getColumns(cf, key, superColName, (N[]) colNames.toArray(), null, null, 0, false));
}
public <K, N, V> int getCount(NormalColumnFamily<K, N, V> cf, K key) {
if (key == null) {
throw new IllegalArgumentException("key can not be null!");
}
int result = 0;
// final int SIZE = 5000;
CountQuery<K, N> q = HFactory.createCountQuery(keyspace, cf.getKeySerializer(), cf.getNameSerializer());
q.setKey(key).setColumnFamily(cf.getColumnFamilyName());
// q.setRange(null, null, SIZE); // TODO hector-0.7 countQuery bug
// do {
// QueryResult<Integer> r = q.execute();
// Integer got = r.get();
// result += got;
// if (got < SIZE) {
// break;
// } else {
// q.setRange(start, finish, count)
// }
// } while (true);
result = q.setRange(null, null, Integer.MAX_VALUE).execute().get();
return result;
}
public <K, SN, N, V> int getCount(SuperColumnFamily<K, SN, N, V> cf, K key) {
if (key == null) {
throw new IllegalArgumentException("key can not be null!");
}
int result = 0;
// final int SIZE = 5000;
SuperCountQuery<K, SN> q = HFactory.createSuperCountQuery(keyspace, cf.getKeySerializer(), cf.getSuperNameSerializer());
q.setKey(key).setColumnFamily(cf.getColumnFamilyName());
// q.setRange(null, null, SIZE); // TODO hector-0.7 countQuery bug
// do {
// QueryResult<Integer> r = q.execute();
// Integer got = r.get();
// result += got;
// if (got < SIZE) {
// break;
// } else {
// q.setRange(start, finish, count)
// }
// } while (true);
result = q.setRange(null, null, Integer.MAX_VALUE).execute().get();
return result;
}
public <K, SN, N, V> int getCount(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
if (key == null) {
throw new IllegalArgumentException("key can not be null!");
}
if (superColName == null) {
throw new IllegalArgumentException("super column name can not be null!");
}
int result = 0;
// final int SIZE = 5000;
SubCountQuery<K, SN, N> q = HFactory.createSubCountQuery(keyspace, cf.getKeySerializer(), cf.getSuperNameSerializer(),
cf.getNameSerializer());
q.setKey(key).setSuperColumn(superColName).setColumnFamily(cf.getColumnFamilyName());
// q.setRange(null, null, SIZE); // TODO hector-0.7 countQuery bug
// do {
// QueryResult<Integer> r = q.execute();
// Integer got = r.get();
// result += got;
// if (got < SIZE) {
// break;
// } else {
// q.setRange(start, finish, count)
// }
// } while (true);
result = q.setRange(null, null, Integer.MAX_VALUE).execute().get();
return result;
}
public <K, SN, N, V> boolean superColumnExists(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
return getCount(cf, key, superColName) > 0;
}
/**
* Call {@link #getAllSuperColumns(ColumnFamilyBase, String, int, boolean)}<br/>
* with count: 100, reversed: false.
*
* @param cf
* @param key
* @return
* @throws HectorException
*/
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getAllSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key) {
return getAllSuperColumns(cf, key, 100, false);
}
/**
* @param cf
* @param key
* @param reversed
* @return
* @throws HectorException
* @see {@link #getAllSuperColumns(ColumnFamilyBase, String, int, boolean)}
*/
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getAllSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, boolean reversed) {
return getAllSuperColumns(cf, key, 100, reversed);
}
/**
* Read all super columns (together with all columns of each super column).<br/>
* Note: reading all super columns might be slow.
*
* @param cf
* @param key
* @param count
* @param reversed
* @param nameSerializer
* @param valueSerializer
* @return
* @throws HectorException
*/
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getAllSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, int count,
boolean reversed) {
if (count <= 1) {
throw new IllegalArgumentException("count must be bigger than 1!");
}
List<HSuperColumn<SN, N, V>> all = new ArrayList<HSuperColumn<SN, N, V>>();
Serializer<K> keySerializer = cf.getKeySerializer();
SuperSliceQuery<K, SN, N, V> q = HFactory.createSuperSliceQuery(keyspace, keySerializer, cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key);
q.setRange(null, null, reversed, count);
do {
List<HSuperColumn<SN, N, V>> data = q.execute().get().getSuperColumns();
int size = data.size();
if (size < count) { // end reached
all.addAll(data);
break;
} else { // continue to read more
q.setRange(data.remove(size - 1).getName(), null, reversed, count);
all.addAll(data);
}
} while (true);
return all;
}
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN start, int count) {
return getSuperColumns(cf, key, null, start, null, count, false);
}
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN start, int count,
boolean reversed) {
return getSuperColumns(cf, key, null, start, null, count, reversed);
}
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN start, SN finish,
int count) {
return getSuperColumns(cf, key, null, start, finish, count, false);
}
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN[] superColNames) {
return getSuperColumns(cf, key, superColNames, null, null, 0, false);
}
public <K, SN, N, V> List<HSuperColumn<SN, N, V>> getSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN[] superColNames,
SN start, SN finish, int count, boolean reversed) {
Serializer<K> keySerializer = cf.getKeySerializer();
SuperSliceQuery<K, SN, N, V> q = HFactory.createSuperSliceQuery(keyspace, keySerializer, cf.getSuperNameSerializer(),
cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKey(key);
if (superColNames == null) {
q.setRange(start, finish, reversed, count);
} else {
q.setColumnNames(superColNames);
}
List<HSuperColumn<SN, N, V>> all = q.execute().get().getSuperColumns();
return all;
/*
* XHH --- Bug here? To reproduce: Insert 10 super columns for a key, then delete 3 super columns, then delete all keys,
* then insert again the old 10 super columns, then getSuperColumn() with start=null,finish=null,count=5, then you get
* 8 super columns! If the "delete 3 super columns... insert again..." things were not done, there is no problem. Also,
* if count is 1 there is no problem (only one super column is returned).
*/
// if (count > 1 && result.size() > count)
// return result.subList(0, count);
// else
// return result;
}
public <K, N, V> List<K> getKeys(NormalColumnFamily<K, N, V> cf, K start, int count) {
return getKeys(cf, start, null, count);
}
public <K, N, V> List<K> getKeys(NormalColumnFamily<K, N, V> cf, K start, K end, int count) {
RangeSlicesQuery<K, N, V> q = HFactory.createRangeSlicesQuery(keyspace, cf.getKeySerializer(), cf.getNameSerializer(),
cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setReturnKeysOnly().setKeys(start, end).setRowCount(count);
OrderedRows<K, N, V> rows = q.execute().get();
List<K> keys = new ArrayList<K>(rows.getCount());
Iterator<Row<K, N, V>> itr = rows.getList().iterator();
while (itr.hasNext()) {
keys.add(itr.next().getKey());
}
return keys;
}
public <K, N, V> List<K> getNonemptyKeys(NormalColumnFamily<K, N, V> cf, K start, int count) {
return getNonemptyKeys(cf, start, null, count);
}
public <K, N, V> List<K> getNonemptyKeys(NormalColumnFamily<K, N, V> cf, K start, K end, final int count) {
List<K> keys = new ArrayList<K>();
int expected = count;
K _start = start;
do {
List<K> loaded = getKeys(cf, _start, end, expected);
int got = loaded.size();
for (Iterator<K> itr = loaded.iterator(); itr.hasNext();) {
_start = itr.next();
if (isKeyEmpty(cf, _start)) {
itr.remove();
}
}
keys.addAll(loaded);
int _size = keys.size();
if (count > 0 && got == expected && _size < count) {
expected = count - _size;
if (keys.contains(_start)) {
keys.remove(_start);
} else {
expected += 1;
}
} else {
break;
}
} while (true);
return keys;
}
public <K, SN, N, V> List<K> getKeys(SuperColumnFamily<K, SN, N, V> cf, K start, int count) {
return getKeys(cf, start, null, count);
}
public <K, SN, N, V> List<K> getKeys(SuperColumnFamily<K, SN, N, V> cf, K start, K end, int count) {
RangeSuperSlicesQuery<K, SN, N, V> q = HFactory.createRangeSuperSlicesQuery(keyspace, cf.getKeySerializer(),
cf.getSuperNameSerializer(), cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setRange(null, null, false, 1) // TODO hector-0.7 Improve efficiency
.setKeys(start, end)
.setRowCount(count);
OrderedSuperRows<K, SN, N, V> rows = q.execute().get();
List<K> keys = new ArrayList<K>(rows.getCount());
Iterator<SuperRow<K, SN, N, V>> itr = rows.getList().iterator();
while (itr.hasNext()) {
keys.add(itr.next().getKey());
}
return keys;
}
public <K, SN, N, V> List<K> getNonemptyKeys(SuperColumnFamily<K, SN, N, V> cf, K start, int count) {
return getNonemptyKeys(cf, start, null, count);
}
public <K, SN, N, V> List<K> getNonemptyKeys(SuperColumnFamily<K, SN, N, V> cf, K start, K end, final int count) {
List<K> keys = new ArrayList<K>();
int expected = count;
K _start = start;
do {
List<K> loaded = getKeys(cf, _start, end, expected);
int got = loaded.size();
for (Iterator<K> itr = loaded.iterator(); itr.hasNext();) {
_start = itr.next();
if (isKeyEmpty(cf, _start)) {
itr.remove();
}
}
keys.addAll(loaded);
int _size = keys.size();
if (count > 0 && got == expected && _size < count) {
expected = count - _size;
if (keys.contains(_start)) {
keys.remove(_start);
} else {
expected += 1;
}
} else {
break;
}
} while (true);
return keys;
}
/**
* @return true is returned is the key doesn't exist or is empty, i.e. has no columns
*/
public <K, SN, N, V> boolean isKeyEmpty(NormalColumnFamily<K, N, V> cf, K key) {
return getCount(cf, key) == 0;
}
/**
* @return true is returned is the key doesn't exist or is empty, i.e. has no super columns
*/
public <K, SN, N, V> boolean isKeyEmpty(SuperColumnFamily<K, SN, N, V> cf, K key) {
return getCount(cf, key) == 0;
}
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, K start, K end, int count,
SN superColName, N... colNames) {
if (colNames == null || colNames.length == 0) {
throw new IllegalArgumentException("getKeysAndColumns: you must specify the Column names!");
}
return getKeysAndColumns(cf, start, end, count, superColName, colNames, null, null, 0, false);
}
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getNonemptyKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, K start, K end,
int count, SN superColName, N... colNames) {
if (colNames == null || colNames.length == 0) {
throw new IllegalArgumentException("getKeysAndColumns: you must specify the Column names!");
}
return getNonemptyKeysAndColumns(cf, start, end, count, superColName, colNames, null, null, 0, false);
}
/**
* @param cf
* @param superColName
* @return
* @throws HectorException
* @see {@link #getAllKeysAndColumns(ColumnFamilyBase, Object, boolean)}
*/
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, SN superColName) {
return getAllKeysAndColumns(cf, superColName, false);
}
/**
* Read all keys and all columns of each key or the super column of each key (if the given super column name is not null).
*
* @param cf
* @param superColName
* super column name, should be null for normal column family (not super)
* @param colReversed
* whether to load columns reversely for each key
* @return key: key, value: columns
*/
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, SN superColName,
boolean colReversed) {
List<K> allKeys = getAllKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, getAllColumns(cf, key, superColName, colReversed));
}
return results;
}
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getAllNonemptyKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, SN superColName,
boolean colReversed) {
List<K> allKeys = getAllNonemptyKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, getAllColumns(cf, key, superColName, colReversed));
}
return results;
}
public <K, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(NormalColumnFamily<K, N, V> cf) {
return getAllKeysAndColumns(cf, false);
}
public <K, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(NormalColumnFamily<K, N, V> cf, boolean colReversed) {
List<K> allKeys = getAllKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, getAllColumns(cf, key, colReversed));
}
return results;
}
public <K, N, V> Map<K, List<HColumn<N, V>>> getAllNonemptyKeysAndColumns(NormalColumnFamily<K, N, V> cf, boolean colReversed) {
List<K> allKeys = getAllNonemptyKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, getAllColumns(cf, key, colReversed));
}
return results;
}
public <K, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(NormalColumnFamily<K, N, V> cf, N... colNames) {
List<K> allKeys = getAllKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
boolean laodAllColumns = colNames == null || colNames.length == 0;
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, laodAllColumns ? getAllColumns(cf, key) : getColumns(cf, key, colNames));
}
return results;
}
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getAllKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, SN superColName,
N... colNames) {
List<K> allKeys = getAllKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
boolean laodAllColumns = colNames == null || colNames.length == 0;
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, laodAllColumns ? getAllColumns(cf, key, superColName) : getColumns(cf, key, superColName, colNames));
}
return results;
}
public <K, N, V> Map<K, List<HColumn<N, V>>> getAllNonemptyKeysAndColumns(NormalColumnFamily<K, N, V> cf, N... colNames) {
List<K> allKeys = getAllNonemptyKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
boolean laodAllColumns = colNames == null || colNames.length == 0;
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, laodAllColumns ? getAllColumns(cf, key) : getColumns(cf, key, colNames));
}
return results;
}
public <K, SN, N, V> Map<K, List<HColumn<N, V>>> getAllNonemptyKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, SN superColName,
N... colNames) {
List<K> allKeys = getAllNonemptyKeys(cf);
if (allKeys.isEmpty()) {
return new LinkedHashMap<K, List<HColumn<N, V>>>(0);
}
boolean laodAllColumns = colNames == null || colNames.length == 0;
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(allKeys.size());
for (K key : allKeys) {
results.put(key, laodAllColumns ? getAllColumns(cf, key, superColName) : getColumns(cf, key, superColName, colNames));
}
return results;
}
public <K, SN, N, V> List<K> getAllKeys(ColumnFamilyBase<K, N, V> cf) {
if (cf.isSuperColumnFamily()) {
return getAllKeys(cf.asSuper());
} else {
return getAllKeys(cf.asNormal());
}
}
public <K, N, V> List<K> getAllKeys(NormalColumnFamily<K, N, V> cf) {
List<K> allKeys = new ArrayList<K>();
final int count = 1000;
K start = null;
while (true) {
List<K> data = getKeys(cf, start, count);
int size = data.size();
if (size < count) {
allKeys.addAll(data);
break;
} else {
start = data.remove(size - 1);
allKeys.addAll(data);
}
}
return allKeys;
}
public <K, N, V> List<K> getAllNonemptyKeys(NormalColumnFamily<K, N, V> cf) {
List<K> allKeys = new ArrayList<K>();
final int count = 1000;
K start = null;
while (true) {
List<K> data = getNonemptyKeys(cf, start, count);
int size = data.size();
if (size < count) {
allKeys.addAll(data);
break;
} else {
start = data.remove(size - 1);
allKeys.addAll(data);
}
}
return allKeys;
}
public <K, SN, N, V> List<K> getAllNonemptyKeys(SuperColumnFamily<K, SN, N, V> cf) {
List<K> allKeys = new ArrayList<K>();
final int count = 1000;
K start = null;
while (true) {
List<K> data = getNonemptyKeys(cf, start, count);
int size = data.size();
if (size < count) {
allKeys.addAll(data);
break;
} else {
start = data.remove(size - 1);
allKeys.addAll(data);
}
}
return allKeys;
}
public <K, SN, N, V> List<K> getAllKeys(SuperColumnFamily<K, SN, N, V> cf) {
List<K> allKeys = new ArrayList<K>();
final int count = 1000;
K start = null;
while (true) {
List<K> data = getKeys(cf, start, count);
int size = data.size();
if (size < count) {
allKeys.addAll(data);
break;
} else {
start = data.remove(size - 1);
allKeys.addAll(data);
}
}
return allKeys;
}
public <K, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getNonemptyKeysAndColumns(NormalColumnFamily<K, N, V> cf, final K start,
K end, final int count, N[] colNames, N colStart, N colFinish, int colCount, boolean colReversed) {
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>();
int expected = count;
K _start = start;
do {
LinkedHashMap<K, List<HColumn<N, V>>> loaded = getKeysAndColumns(cf, _start, end, expected, colNames, colStart, colFinish,
colCount, colReversed);
int got = loaded.size();
for (Iterator<K> itr = loaded.keySet().iterator(); itr.hasNext();) {
_start = itr.next();
if (loaded.get(_start).isEmpty()) {
itr.remove();
}
}
results.putAll(loaded);
int _size = results.size();
if (count > 0 && got == expected && _size < count) {
expected = count - _size;
if (results.containsKey(_start)) {
results.remove(_start);
} else {
expected += 1;
}
} else {
break;
}
} while (true);
return results;
}
public <K, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getNonemptyKeysAndColumns(NormalColumnFamily<K, N, V> cf, K start,
int count, N... colNames) {
return getNonemptyKeysAndColumns(cf, start, null, count, colNames, null, null, 0, false);
}
public <K, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getNonemptyKeysAndColumns(NormalColumnFamily<K, N, V> cf, K start, K end,
int count, N... colNames) {
return getNonemptyKeysAndColumns(cf, start, end, count, colNames, null, null, 0, false);
}
public <K, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getKeysAndColumns(NormalColumnFamily<K, N, V> cf, K start, K end,
int count, N... colNames) {
return getKeysAndColumns(cf, start, end, count, colNames, null, null, 0, false);
}
public <K, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getKeysAndColumns(NormalColumnFamily<K, N, V> cf, K start, K end,
int count, N[] colNames, N colStart, N colFinish, int colCount, boolean colReversed) {
RangeSlicesQuery<K, N, V> q = HFactory.createRangeSlicesQuery(keyspace, cf.getKeySerializer(), cf.getNameSerializer(),
cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKeys(start, end).setRowCount(count);
if (colNames == null) {
q.setRange(colStart, colFinish, colReversed, colCount);
} else {
q.setColumnNames(colNames);
}
OrderedRows<K, N, V> rows = q.execute().get();
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(rows.getCount());
for (Iterator<Row<K, N, V>> itr = rows.iterator(); itr.hasNext();) {
Row<K, N, V> row = itr.next();
results.put(row.getKey(), row.getColumnSlice().getColumns());
}
return results;
}
public <K, SN, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getNonemptyKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, K start,
K end, int count, SN superColName, N[] colNames, N colStart, N colFinish, int colCount, boolean colReversed) {
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>();
int expected = count;
K _start = start;
do {
LinkedHashMap<K, List<HColumn<N, V>>> loaded = getKeysAndColumns(cf, _start, end, expected, superColName, colNames,
colStart, colFinish, colCount, colReversed);
int got = loaded.size();
for (Iterator<K> itr = loaded.keySet().iterator(); itr.hasNext();) {
_start = itr.next();
if (loaded.get(_start).isEmpty()) {
itr.remove();
}
}
results.putAll(loaded);
int _size = results.size();
if (count > 0 && got == expected && _size < count) {
expected = count - _size;
if (results.containsKey(_start)) {
results.remove(_start);
} else {
expected += 1;
}
} else {
break;
}
} while (true);
return results;
}
public <K, SN, N, V> LinkedHashMap<K, List<HColumn<N, V>>> getKeysAndColumns(SuperColumnFamily<K, SN, N, V> cf, K start, K end,
int count, SN superColName, N[] colNames, N colStart, N colFinish, int colCount, boolean colReversed) {
if (superColName == null) {
throw new IllegalArgumentException("superColName can not be null!");
}
RangeSubSlicesQuery<K, SN, N, V> q = HFactory.createRangeSubSlicesQuery(keyspace, cf.getKeySerializer(),
cf.getSuperNameSerializer(), cf.getNameSerializer(), cf.getValueSerializer());
q.setColumnFamily(cf.getColumnFamilyName()).setKeys(start, end).setSuperColumn(superColName).setRowCount(count);
if (colNames == null) {
q.setRange(colStart, colFinish, colReversed, colCount);
} else {
q.setColumnNames(colNames);
}
OrderedRows<K, N, V> rows = q.execute().get();
LinkedHashMap<K, List<HColumn<N, V>>> results = new LinkedHashMap<K, List<HColumn<N, V>>>(rows.getCount());
for (Iterator<Row<K, N, V>> itr = rows.iterator(); itr.hasNext();) {
Row<K, N, V> row = itr.next();
results.put(row.getKey(), row.getColumnSlice().getColumns());
}
return results;
}
public <K, N, V> void deleteColumns(NormalColumnFamily<K, N, V> cf, K key, N... colNames) {
if (colNames == null || colNames.length == 0) {
return;
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
String cfName = cf.getColumnFamilyName();
Serializer<N> nameSerializer = cf.getNameSerializer();
for (N cn : colNames) {
m.addDeletion(key, cfName, cn, nameSerializer, keyspace.createClock());
}
m.execute();
}
public <K, SN, N, V> void deleteColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N... colNames) {
if (colNames == null || colNames.length == 0) {
return;
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
String cfName = cf.getColumnFamilyName();
Serializer<N> nameSerializer = cf.getNameSerializer();
if (superColName == null) {
throw new IllegalArgumentException("superColName can not be null!");
} else {
Serializer<SN> superNameSerializer = cf.getSuperNameSerializer();
for (N cn : colNames) {
m.subDelete(key, cfName, superColName, cn, superNameSerializer, nameSerializer);
}
}
}
public <K, SN, N, V> void deleteSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, SN... superColNames) {
if (superColNames == null || superColNames.length == 0) {
return;
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
String cfName = cf.getColumnFamilyName();
Serializer<SN> superNameSerializer = cf.getSuperNameSerializer();
Serializer<N> nameSerializer = cf.getNameSerializer();
for (SN sc : superColNames) {
m.subDelete(key, cfName, sc, null, superNameSerializer, nameSerializer); // TODO hector-0.7 Improve efficiency
}
m.execute();
}
public <K, SN, N, V> void deleteSuperColumns(SuperColumnFamily<K, SN, N, V> cf, K key, HSuperColumn<SN, N, V>... superColumns) {
if (superColumns == null || superColumns.length == 0) {
return;
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
String cfName = cf.getColumnFamilyName();
for (HSuperColumn<SN, N, V> sc : superColumns) {
m.addSubDelete(key, cfName, sc);
}
m.execute();
}
/**
* Delete a key.
*/
public <K, N, V> void deleteKey(ColumnFamilyBase<K, N, V> cf, K key) {
if (key == null) {
throw new IllegalArgumentException("You must specify the Key to delete!");
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
m.addDeletion(key, cf.getColumnFamilyName());
m.execute();
}
/**
* Delete a super column for a key
*/
@SuppressWarnings("unchecked")
public <K, SN, N, V> void deleteSuperColumn(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName) {
if (superColName == null) {
throw new IllegalArgumentException("You must specify the SuperColumn to delete!");
}
deleteSuperColumns(cf, key, superColName);
}
public <K, SN, N, V> void deleteColumn(SuperColumnFamily<K, SN, N, V> cf, K key, SN superColName, N colName) {
if (colName == null) {
throw new IllegalArgumentException("You must specify the Column to delete!");
}
if (superColName == null) {
throw new IllegalArgumentException("You must specify the Column to delete!");
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
m.subDelete(key, cf.getColumnFamilyName(), superColName, colName, cf.getSuperNameSerializer(), cf.getNameSerializer());
}
public <K, N, V> void deleteColumn(NormalColumnFamily<K, N, V> cf, K key, N colName) {
if (colName == null) {
throw new IllegalArgumentException("You must specify the Column to delete!");
}
Mutator<K> m = HFactory.createMutator(keyspace, cf.getKeySerializer());
m.addDeletion(key, cf.getColumnFamilyName(), colName, cf.getNameSerializer());
m.execute();
}
public DBConfig getDbConfig() {
return dbConfig;
}
public void setDbConfig(DBConfig dbConfig) {
this.dbConfig = dbConfig;
this.keyspace = createKeyspace(dbConfig);
}
public static Keyspace createKeyspace(DBConfig dbConfig) {
Cluster cluster = HFactory.getOrCreateCluster(dbConfig.clusterName, dbConfig.host);
Keyspace keyspace;
if (StringUtils.isNotEmpty(dbConfig.username) && StringUtils.isNotEmpty(dbConfig.password)) {
Map<String, String> credentials = new HashMap<String, String>(1);
credentials.put(dbConfig.username, dbConfig.password);
keyspace = HFactory.createKeyspace(dbConfig.keyspace, cluster, HFactory.createDefaultConsistencyLevelPolicy(),
FailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE, credentials);
} else {
keyspace = HFactory.createKeyspace(dbConfig.keyspace, cluster);
}
return keyspace;
}
protected <T extends DBA> T createInstance(Class<T> cls) {
try {
return cls.getConstructor(DBConfig.class).newInstance(this.dbConfig);
} catch (Exception e) {
log.error("createInstance", e);
return null;
}
}
}