use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testCheckLocksFailsWithSeniorClaimsByOthers.
/**
* If the checker reads its own lock column preceeded by a lock column from
* another rid with an earlier timestamp and the timestamps on both columns
* are unexpired, then the checker must throw a TemporaryLockingException.
*
* @throws InterruptedException shouldn't happen
* @throws StorageException shouldn't happen (we expect a TemporaryLockingException but
* we catch and swallow it)
*/
@Test
public void testCheckLocksFailsWithSeniorClaimsByOthers() throws InterruptedException, StorageException {
// Make a pre-existing valid lock by some other tx (written by another process)
StaticBuffer otherSeniorLockCol = codec.toLockCol(currentTimeNS, otherLockRid);
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
// Expect checker to fetch locks for defaultTx; return just our own lock (not the other guy's)
StaticBuffer ownJuniorLockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
ConsistentKeyLockStatus ownJuniorLS = makeStatusNow();
expect(lockState.getLocksForTx(defaultTx)).andReturn(ImmutableMap.of(defaultLockID, ownJuniorLS));
currentTimeNS += TimeUnit.NANOSECONDS.convert(10, TimeUnit.SECONDS);
// Return defaultTx's lock in a map when requested
expect(times.sleepUntil(ownJuniorLS.getWriteTimestamp(TimeUnit.NANOSECONDS) + defaultWaitNS)).andReturn(currentTimeNS);
// When the checker slices the store, return the senior lock col by a
// foreign tx and the junior lock col by defaultTx (in that order)
recordLockGetSlice(ImmutableList.<Entry>of(new StaticBufferEntry(otherSeniorLockCol, defaultLockVal), new StaticBufferEntry(ownJuniorLockCol, defaultLockVal)));
ctrl.replay();
TemporaryLockingException tle = null;
try {
locker.checkLocks(defaultTx);
} catch (TemporaryLockingException e) {
tle = e;
}
assertNotNull(tle);
}
use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testCheckLocksSucceedsWithSeniorAndJuniorClaimsBySelf.
/**
* If the checker retrieves a timestamp-ordered list of columns, where the
* list starts with an unbroken series of columns with the checker's rid but
* differing timestamps, then consider the lock successfully checked if the
* checker's expected timestamp occurs anywhere in that series of columns.
* <p/>
* This relaxation of the normal checking rules only triggers when either
* writeLock(...) issued mutate calls that appeared to fail client-side but
* which actually succeeded (e.g. hinted handoff or timeout)
*
* @throws InterruptedException shouldn't happen
* @throws StorageException shouldn't happen
*/
@Test
public void testCheckLocksSucceedsWithSeniorAndJuniorClaimsBySelf() throws InterruptedException, StorageException {
// Setup three lock columns differing only in timestamp
StaticBuffer myFirstLockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
StaticBuffer mySecondLockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
ConsistentKeyLockStatus mySecondLS = makeStatusNow();
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
StaticBuffer myThirdLockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
expect(lockState.getLocksForTx(defaultTx)).andReturn(ImmutableMap.of(defaultLockID, mySecondLS));
// Return defaultTx's second lock in a map when requested
currentTimeNS += TimeUnit.NANOSECONDS.convert(10, TimeUnit.SECONDS);
expect(times.sleepUntil(mySecondLS.getWriteTimestamp(TimeUnit.NANOSECONDS) + defaultWaitNS)).andReturn(currentTimeNS);
// When the checker slices the store, return the senior lock col by a
// foreign tx and the junior lock col by defaultTx (in that order)
recordLockGetSlice(ImmutableList.<Entry>of(new StaticBufferEntry(myFirstLockCol, defaultLockVal), new StaticBufferEntry(mySecondLockCol, defaultLockVal), new StaticBufferEntry(myThirdLockCol, defaultLockVal)));
ctrl.replay();
locker.checkLocks(defaultTx);
}
use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method testCheckLocksSucceedsWithJuniorClaimsByOthers.
/**
* When the checker retrieves its own lock column followed by a lock column
* with a later timestamp (both with unexpired timestamps), it should
* consider the lock successfully checked.
*
* @throws InterruptedException shouldn't happen
* @throws StorageException shouldn't happen
*/
@Test
public void testCheckLocksSucceedsWithJuniorClaimsByOthers() throws InterruptedException, StorageException {
// Expect checker to fetch locks for defaultTx; return just our own lock (not the other guy's)
StaticBuffer ownSeniorLockCol = codec.toLockCol(currentTimeNS, defaultLockRid);
ConsistentKeyLockStatus ownSeniorLS = makeStatusNow();
currentTimeNS += TimeUnit.NANOSECONDS.convert(1, TimeUnit.NANOSECONDS);
// Make junior lock
StaticBuffer otherJuniorLockCol = codec.toLockCol(currentTimeNS, otherLockRid);
expect(lockState.getLocksForTx(defaultTx)).andReturn(ImmutableMap.of(defaultLockID, ownSeniorLS));
currentTimeNS += TimeUnit.NANOSECONDS.convert(10, TimeUnit.SECONDS);
// Return defaultTx's lock in a map when requested
expect(times.sleepUntil(ownSeniorLS.getWriteTimestamp(TimeUnit.NANOSECONDS) + defaultWaitNS)).andReturn(currentTimeNS);
// When the checker slices the store, return the senior lock col by a
// foreign tx and the junior lock col by defaultTx (in that order)
recordLockGetSlice(ImmutableList.<Entry>of(new StaticBufferEntry(ownSeniorLockCol, defaultLockVal), new StaticBufferEntry(otherJuniorLockCol, defaultLockVal)));
ctrl.replay();
locker.checkLocks(defaultTx);
}
use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry in project titan by thinkaurelius.
the class ConsistentKeyLockerTest method recordSuccessfulLockWrite.
private LockInfo recordSuccessfulLockWrite(StoreTransaction tx, long duration, TimeUnit tu, StaticBuffer del) throws StorageException {
expect(times.getApproxNSSinceEpoch()).andReturn(++currentTimeNS);
final long lockNS = currentTimeNS;
StaticBuffer lockCol = codec.toLockCol(lockNS, defaultLockRid);
Entry add = new StaticBufferEntry(lockCol, defaultLockVal);
StaticBuffer k = eq(defaultLockKey);
// assert null != add;
final List<Entry> adds = eq(Arrays.<Entry>asList(add));
// assert null != adds;
final List<StaticBuffer> dels;
if (null != del) {
dels = eq(Arrays.<StaticBuffer>asList(del));
} else {
dels = eq(ImmutableList.<StaticBuffer>of());
}
store.mutate(k, adds, dels, eq(tx));
currentTimeNS += TimeUnit.NANOSECONDS.convert(duration, tu);
expect(times.getApproxNSSinceEpoch()).andReturn(currentTimeNS);
ConsistentKeyLockStatus status = new ConsistentKeyLockStatus(lockNS, TimeUnit.NANOSECONDS, lockNS + defaultExpireNS, TimeUnit.NANOSECONDS);
return new LockInfo(lockNS, status, lockCol);
}
use of com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry in project titan by thinkaurelius.
the class EdgeSerializer method writeRelation.
public Entry writeRelation(InternalRelation relation, int position, StandardTitanTx tx) {
Preconditions.checkArgument(position < relation.getLen());
TitanType type = relation.getType();
long typeid = type.getID();
Direction dir = EdgeDirection.fromPosition(position);
int dirID = getDirID(dir, relation.isProperty() ? RelationType.PROPERTY : RelationType.EDGE);
DataOutput colOut = serializer.getDataOutput(DEFAULT_COLUMN_CAPACITY, true);
IDHandler.writeEdgeType(colOut, typeid, dirID);
InternalType definition = (InternalType) type;
long[] sortKey = definition.getSortKey();
int startPosition = colOut.getPosition();
if (!type.isUnique(dir)) {
writeInlineTypes(sortKey, relation, colOut, tx);
}
int endPosition = colOut.getPosition();
DataOutput writer = colOut;
long vertexIdDiff = 0;
long relationIdDiff = relation.getID() - relation.getVertex(position).getID();
if (relation.isEdge())
vertexIdDiff = relation.getVertex((position + 1) % 2).getID() - relation.getVertex(position).getID();
if (type.isUnique(dir)) {
writer = serializer.getDataOutput(DEFAULT_VALUE_CAPACITY, true);
if (relation.isEdge())
VariableLong.write(writer, vertexIdDiff);
VariableLong.write(writer, relationIdDiff);
} else {
if (relation.isEdge())
VariableLong.writeBackward(writer, vertexIdDiff);
VariableLong.writeBackward(writer, relationIdDiff);
}
if (!type.isUnique(dir)) {
writer = serializer.getDataOutput(DEFAULT_VALUE_CAPACITY, true);
}
if (relation.isProperty()) {
Preconditions.checkArgument(relation.isProperty());
Object value = ((TitanProperty) relation).getValue();
Preconditions.checkNotNull(value);
TitanKey key = (TitanKey) type;
assert key.getDataType().isInstance(value);
if (hasGenericDataType(key)) {
writer.writeClassAndObject(value);
} else {
writer.writeObjectNotNull(value);
}
}
// Write signature & sort key if unique
if (type.isUnique(dir)) {
writeInlineTypes(sortKey, relation, writer, tx);
}
long[] signature = definition.getSignature();
writeInlineTypes(signature, relation, writer, tx);
// Write remaining properties
LongSet writtenTypes = new LongOpenHashSet(sortKey.length + signature.length);
if (sortKey.length > 0 || signature.length > 0) {
for (long id : sortKey) writtenTypes.add(id);
for (long id : signature) writtenTypes.add(id);
}
LongArrayList remainingTypes = new LongArrayList(8);
for (TitanType t : relation.getPropertyKeysDirect()) {
if (!writtenTypes.contains(t.getID())) {
remainingTypes.add(t.getID());
}
}
// Sort types before writing to ensure that value is always written the same way
long[] remaining = remainingTypes.toArray();
Arrays.sort(remaining);
for (long tid : remaining) {
TitanType t = tx.getExistingType(tid);
writeInline(writer, t, relation.getProperty(t), true);
}
StaticBuffer column = ((InternalType) type).getSortOrder() == Order.DESC ? colOut.getStaticBufferFlipBytes(startPosition, endPosition) : colOut.getStaticBuffer();
return new StaticBufferEntry(column, writer.getStaticBuffer());
}
Aggregations