Search in sources :

Example 1 with StaticBufferEntry

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);
}
Also used : StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry) ConsistentKeyLockStatus(com.thinkaurelius.titan.diskstorage.locking.consistentkey.ConsistentKeyLockStatus) Test(org.junit.Test)

Example 2 with StaticBufferEntry

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);
}
Also used : StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry) ConsistentKeyLockStatus(com.thinkaurelius.titan.diskstorage.locking.consistentkey.ConsistentKeyLockStatus) Test(org.junit.Test)

Example 3 with StaticBufferEntry

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);
}
Also used : StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry) ConsistentKeyLockStatus(com.thinkaurelius.titan.diskstorage.locking.consistentkey.ConsistentKeyLockStatus) Test(org.junit.Test)

Example 4 with StaticBufferEntry

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);
}
Also used : StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry) Entry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.Entry) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry) ConsistentKeyLockStatus(com.thinkaurelius.titan.diskstorage.locking.consistentkey.ConsistentKeyLockStatus)

Example 5 with StaticBufferEntry

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());
}
Also used : DataOutput(com.thinkaurelius.titan.graphdb.database.serialize.DataOutput) LongArrayList(com.carrotsearch.hppc.LongArrayList) LongSet(com.carrotsearch.hppc.LongSet) EdgeDirection(com.thinkaurelius.titan.graphdb.relations.EdgeDirection) Direction(com.tinkerpop.blueprints.Direction) InternalType(com.thinkaurelius.titan.graphdb.internal.InternalType) StaticBuffer(com.thinkaurelius.titan.diskstorage.StaticBuffer) LongOpenHashSet(com.carrotsearch.hppc.LongOpenHashSet) StaticBufferEntry(com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry)

Aggregations

StaticBufferEntry (com.thinkaurelius.titan.diskstorage.keycolumnvalue.StaticBufferEntry)10 StaticBuffer (com.thinkaurelius.titan.diskstorage.StaticBuffer)8 ConsistentKeyLockStatus (com.thinkaurelius.titan.diskstorage.locking.consistentkey.ConsistentKeyLockStatus)8 Test (org.junit.Test)7 Entry (com.thinkaurelius.titan.diskstorage.keycolumnvalue.Entry)2 LongArrayList (com.carrotsearch.hppc.LongArrayList)1 LongOpenHashSet (com.carrotsearch.hppc.LongOpenHashSet)1 LongSet (com.carrotsearch.hppc.LongSet)1 TemporaryStorageException (com.thinkaurelius.titan.diskstorage.TemporaryStorageException)1 DataOutput (com.thinkaurelius.titan.graphdb.database.serialize.DataOutput)1 InternalType (com.thinkaurelius.titan.graphdb.internal.InternalType)1 EdgeDirection (com.thinkaurelius.titan.graphdb.relations.EdgeDirection)1 Direction (com.tinkerpop.blueprints.Direction)1