use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class KCVSConfiguration method get.
/**
* Reads the configuration property for this StoreManager
*
* @param key Key identifying the configuration property
* @return Value stored for the key or null if the configuration property has not (yet) been defined.
* @throws com.thinkaurelius.titan.diskstorage.BackendException
*/
@Override
public <O> O get(final String key, final Class<O> datatype) {
StaticBuffer column = string2StaticBuffer(key);
final KeySliceQuery query = new KeySliceQuery(rowKey, column, BufferUtil.nextBiggerBuffer(column));
StaticBuffer result = BackendOperation.execute(new BackendOperation.Transactional<StaticBuffer>() {
@Override
public StaticBuffer call(StoreTransaction txh) throws BackendException {
List<Entry> entries = store.getSlice(query, txh);
if (entries.isEmpty())
return null;
return entries.get(0).getValueAs(StaticBuffer.STATIC_FACTORY);
}
@Override
public String toString() {
return "getConfiguration";
}
}, txProvider, times, maxOperationWaitTime);
if (result == null)
return null;
return staticBuffer2Object(result, datatype);
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ColumnValueStore method mutate.
synchronized void mutate(List<Entry> additions, List<StaticBuffer> deletions, StoreTransaction txh) {
//Prepare data
Entry[] add;
if (!additions.isEmpty()) {
add = new Entry[additions.size()];
int pos = 0;
for (Entry e : additions) {
add[pos] = e;
pos++;
}
Arrays.sort(add);
} else
add = new Entry[0];
//Filter out deletions that are also added
Entry[] del;
if (!deletions.isEmpty()) {
del = new Entry[deletions.size()];
int pos = 0;
for (StaticBuffer deletion : deletions) {
Entry delEntry = StaticArrayEntry.of(deletion);
if (Arrays.binarySearch(add, delEntry) >= 0)
continue;
del[pos++] = delEntry;
}
if (pos < deletions.size())
del = Arrays.copyOf(del, pos);
Arrays.sort(del);
} else
del = new Entry[0];
Lock lock = getLock(txh);
lock.lock();
try {
Entry[] olddata = data.array;
int oldsize = data.size;
Entry[] newdata = new Entry[oldsize + add.length];
//Merge sort
int i = 0, iold = 0, iadd = 0, idel = 0;
while (iold < oldsize) {
Entry e = olddata[iold];
iold++;
//Compare with additions
if (iadd < add.length) {
int compare = e.compareTo(add[iadd]);
if (compare >= 0) {
e = add[iadd];
iadd++;
//Skip duplicates
while (iadd < add.length && e.equals(add[iadd])) iadd++;
}
if (compare > 0)
iold--;
}
//Compare with deletions
if (idel < del.length) {
int compare = e.compareTo(del[idel]);
if (compare == 0)
e = null;
if (compare >= 0)
idel++;
}
if (e != null) {
newdata[i] = e;
i++;
}
}
while (iadd < add.length) {
newdata[i] = add[iadd];
i++;
iadd++;
}
if (i * 1.0 / newdata.length < SIZE_THRESHOLD) {
//shrink array to free space
Entry[] tmpdata = newdata;
newdata = new Entry[i];
System.arraycopy(tmpdata, 0, newdata, 0, i);
}
data = new Data(newdata, i);
} finally {
lock.unlock();
}
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project titan by thinkaurelius.
the class ConsistentKeyLockerSerializer method fromLockColumn.
public TimestampRid fromLockColumn(StaticBuffer lockKey, TimestampProvider provider) {
ReadBuffer r = lockKey.asReadBuffer();
int len = r.length();
long tsNS = r.getLong();
len -= 8;
byte[] curRid = new byte[len];
for (int i = 0; r.hasRemaining(); i++) {
curRid[i] = r.getByte();
}
StaticBuffer rid = new StaticArrayBuffer(curRid);
Instant time = provider.getTime(tsNS);
return new TimestampRid(time, rid);
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project incubator-atlas by apache.
the class HBaseStoreManager method normalizeKeyBounds.
/**
* Given a map produced by {@link HTable#getRegionLocations()}, transform
* each key from an {@link HRegionInfo} to a {@link KeyRange} expressing the
* region's start and end key bounds using Titan-partitioning-friendly
* conventions (start inclusive, end exclusive, zero bytes appended where
* necessary to make all keys at least 4 bytes long).
* <p/>
* This method iterates over the entries in its map parameter and performs
* the following conditional conversions on its keys. "Require" below means
* either a {@link Preconditions} invocation or an assertion. HRegionInfo
* sometimes returns start and end keys of zero length; this method replaces
* zero length keys with null before doing any of the checks described
* below. The parameter map and the values it contains are only read and
* never modified.
*
* <ul>
* <li>If an entry's HRegionInfo has null start and end keys, then first
* require that the parameter map is a singleton, and then return a
* single-entry map whose {@code KeyRange} has start and end buffers that
* are both four bytes of zeros.</li>
* <li>If the entry has a null end key (but non-null start key), put an
* equivalent entry in the result map with a start key identical to the
* input, except that zeros are appended to values less than 4 bytes long,
* and an end key that is four bytes of zeros.
* <li>If the entry has a null start key (but non-null end key), put an
* equivalent entry in the result map where the start key is four bytes of
* zeros, and the end key has zeros appended, if necessary, to make it at
* least 4 bytes long, after which one is added to the padded value in
* unsigned 32-bit arithmetic with overflow allowed.</li>
* <li>Any entry which matches none of the above criteria results in an
* equivalent entry in the returned map, except that zeros are appended to
* both keys to make each at least 4 bytes long, and the end key is then
* incremented as described in the last bullet point.</li>
* </ul>
*
* After iterating over the parameter map, this method checks that it either
* saw no entries with null keys, one entry with a null start key and a
* different entry with a null end key, or one entry with both start and end
* keys null. If any null keys are observed besides these three cases, the
* method will die with a precondition failure.
*
* @param raw
* A map of HRegionInfo and ServerName from HBase
* @return Titan-friendly expression of each region's rowkey boundaries
*/
private Map<KeyRange, ServerName> normalizeKeyBounds(NavigableMap<HRegionInfo, ServerName> raw) {
Map.Entry<HRegionInfo, ServerName> nullStart = null;
Map.Entry<HRegionInfo, ServerName> nullEnd = null;
ImmutableMap.Builder<KeyRange, ServerName> b = ImmutableMap.builder();
for (Map.Entry<HRegionInfo, ServerName> e : raw.entrySet()) {
HRegionInfo regionInfo = e.getKey();
byte[] startKey = regionInfo.getStartKey();
byte[] endKey = regionInfo.getEndKey();
if (0 == startKey.length) {
startKey = null;
logger.trace("Converted zero-length HBase startKey byte array to null");
}
if (0 == endKey.length) {
endKey = null;
logger.trace("Converted zero-length HBase endKey byte array to null");
}
if (null == startKey && null == endKey) {
Preconditions.checkState(1 == raw.size());
logger.debug("HBase table {} has a single region {}", tableName, regionInfo);
// Choose arbitrary shared value = startKey = endKey
return b.put(new KeyRange(FOUR_ZERO_BYTES, FOUR_ZERO_BYTES), e.getValue()).build();
} else if (null == startKey) {
logger.debug("Found HRegionInfo with null startKey on server {}: {}", e.getValue(), regionInfo);
Preconditions.checkState(null == nullStart);
nullStart = e;
// I thought endBuf would be inclusive from the HBase javadoc, but in practice it is exclusive
StaticBuffer endBuf = StaticArrayBuffer.of(zeroExtend(endKey));
// Replace null start key with zeroes
b.put(new KeyRange(FOUR_ZERO_BYTES, endBuf), e.getValue());
} else if (null == endKey) {
logger.debug("Found HRegionInfo with null endKey on server {}: {}", e.getValue(), regionInfo);
Preconditions.checkState(null == nullEnd);
nullEnd = e;
// Replace null end key with zeroes
b.put(new KeyRange(StaticArrayBuffer.of(zeroExtend(startKey)), FOUR_ZERO_BYTES), e.getValue());
} else {
Preconditions.checkState(null != startKey);
Preconditions.checkState(null != endKey);
// Convert HBase's inclusive end keys into exclusive Titan end keys
StaticBuffer startBuf = StaticArrayBuffer.of(zeroExtend(startKey));
StaticBuffer endBuf = StaticArrayBuffer.of(zeroExtend(endKey));
KeyRange kr = new KeyRange(startBuf, endBuf);
b.put(kr, e.getValue());
logger.debug("Found HRegionInfo with non-null end and start keys on server {}: {}", e.getValue(), regionInfo);
}
}
// Require either no null key bounds or a pair of them
Preconditions.checkState((null == nullStart) == (null == nullEnd));
// Check that every key in the result is at least 4 bytes long
Map<KeyRange, ServerName> result = b.build();
for (KeyRange kr : result.keySet()) {
Preconditions.checkState(4 <= kr.getStart().length());
Preconditions.checkState(4 <= kr.getEnd().length());
}
return result;
}
use of com.thinkaurelius.titan.diskstorage.StaticBuffer in project incubator-atlas by apache.
the class HBaseStoreManager method mutateMany.
@Override
public void mutateMany(Map<String, Map<StaticBuffer, KCVMutation>> mutations, StoreTransaction txh) throws BackendException {
logger.debug("Enter mutateMany");
final MaskedTimestamp commitTime = new MaskedTimestamp(txh);
// In case of an addition and deletion with identical timestamps, the
// deletion tombstone wins.
// http://hbase.apache.org/book/versions.html#d244e4250
Map<StaticBuffer, Pair<Put, Delete>> commandsPerKey = convertToCommands(mutations, commitTime.getAdditionTime(times.getUnit()), commitTime.getDeletionTime(times.getUnit()));
// actual batch operation
List<Row> batch = new ArrayList<>(commandsPerKey.size());
// convert sorted commands into representation required for 'batch' operation
for (Pair<Put, Delete> commands : commandsPerKey.values()) {
if (commands.getFirst() != null)
batch.add(commands.getFirst());
if (commands.getSecond() != null)
batch.add(commands.getSecond());
}
try {
TableMask table = null;
try {
table = cnx.getTable(tableName);
logger.debug("mutateMany : batch mutate started size {} ", batch.size());
table.batch(batch, new Object[batch.size()]);
logger.debug("mutateMany : batch mutate finished {} ", batch.size());
} finally {
IOUtils.closeQuietly(table);
}
} catch (IOException | InterruptedException e) {
throw new TemporaryBackendException(e);
}
sleepAfterWrite(txh, commitTime);
}
Aggregations