Search in sources :

Example 1 with Token

use of com.cinchapi.concourse.server.concurrent.Token in project concourse by cinchapi.

the class AtomicOperation method verify.

@Override
public final boolean verify(Write write) throws AtomicStateException {
    checkState();
    Token token = Token.wrap(write.getKey().toString(), write.getRecord().longValue());
    source.addVersionChangeListener(token, this);
    reads2Lock.add(token);
    return super.verify(write);
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token)

Example 2 with Token

use of com.cinchapi.concourse.server.concurrent.Token in project concourse by cinchapi.

the class AtomicOperation method review.

@Override
public final Map<Long, List<String>> review(String key, long record) throws AtomicStateException {
    checkState();
    Token token = Token.wrap(key, record);
    source.addVersionChangeListener(token, this);
    reads2Lock.add(token);
    return super.review(key, record);
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token)

Example 3 with Token

use of com.cinchapi.concourse.server.concurrent.Token in project concourse by cinchapi.

the class AtomicOperation method gather.

@Override
public final Set<TObject> gather(String key, long record) throws AtomicStateException {
    checkState();
    Token token = Token.wrap(key, record);
    source.addVersionChangeListener(token, this);
    reads2Lock.add(token);
    return super.gather(key, record);
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token)

Example 4 with Token

use of com.cinchapi.concourse.server.concurrent.Token in project concourse by cinchapi.

the class AtomicOperation method grabLocks.

/**
 * Check each one of the {@link #intentions} against the
 * {@link #durable} and grab the appropriate locks along the way. This
 * method will return {@code true} if all expectations are met and all
 * necessary locks are grabbed. Otherwise it will return {@code false}, in
 * which case this operation should be aborted immediately.
 *
 * @return {@code true} if all expectations are met and all necessary locks
 *         are grabbed.
 */
private boolean grabLocks() {
    if (isReadOnly()) {
        return true;
    } else {
        // NOTE: If we can't grab a lock immediately because it is held by
        // someone else, then we must fail immediately because the
        // AtomicOperation can't properly commit.
        locks = Maps.newHashMap();
        try {
            // intentions
            for (Token token : writes2Lock) {
                if (notifiedAboutVersionChange) {
                    return false;
                }
                LockType type;
                if (token instanceof RangeToken) {
                    RangeToken rangeToken = (RangeToken) token;
                    if (!rangeReads2Lock.isEmpty(rangeToken.getKey())) {
                        Range<Value> containing = rangeReads2Lock.get(rangeToken.getKey(), rangeToken.getValues()[0]);
                        if (containing != null) {
                            rangeReads2Lock.remove(rangeToken.getKey(), containing);
                            Iterable<Range<Value>> xor = Ranges.xor(Range.singleton(rangeToken.getValues()[0]), containing);
                            for (Range<Value> range : xor) {
                                rangeReads2Lock.put(rangeToken.getKey(), range);
                            }
                        }
                    }
                    type = LockType.RANGE_WRITE;
                } else {
                    reads2Lock.remove(token);
                    type = LockType.WRITE;
                }
                LockDescription lock = LockDescription.forToken(token, lockService, rangeLockService, type);
                if (lock.getLock().tryLock()) {
                    locks.put(lock.getToken(), lock);
                } else {
                    return false;
                }
            }
            // grabbed previously.
            for (Token token : reads2Lock) {
                if (notifiedAboutVersionChange) {
                    return false;
                }
                LockDescription lock = LockDescription.forToken(token, lockService, rangeLockService, LockType.READ);
                if (lock.getLock().tryLock()) {
                    locks.put(lock.getToken(), lock);
                } else {
                    return false;
                }
            }
            // grabbed previously.
            for (Entry<Text, RangeSet<Value>> entry : rangeReads2Lock.ranges.entrySet()) {
                /* (Authorized) */
                if (notifiedAboutVersionChange) {
                    return false;
                }
                Text key = entry.getKey();
                for (Range<Value> range : entry.getValue().asRanges()) {
                    RangeToken rangeToken = Ranges.convertToRangeToken(key, range);
                    LockDescription lock = LockDescription.forToken(rangeToken, lockService, rangeLockService, LockType.RANGE_READ);
                    if (lock.getLock().tryLock()) {
                        locks.put(lock.getToken(), lock);
                    } else {
                        return false;
                    }
                }
            }
        } catch (NullPointerException e) {
            // abort immediately which means that #locks will become null.
            return false;
        }
        return true;
    }
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Value(com.cinchapi.concourse.server.model.Value) RangeSet(com.google.common.collect.RangeSet) TreeRangeSet(com.google.common.collect.TreeRangeSet) RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token) Text(com.cinchapi.concourse.server.model.Text) Range(com.google.common.collect.Range) LockType(com.cinchapi.concourse.server.concurrent.LockType)

Example 5 with Token

use of com.cinchapi.concourse.server.concurrent.Token in project concourse by cinchapi.

the class AtomicOperation method set.

@Override
public final void set(String key, TObject value, long record) throws AtomicStateException {
    checkState();
    Token token = Token.wrap(key, record);
    RangeToken rangeToken = RangeToken.forWriting(Text.wrapCached(key), Value.wrap(value));
    Token wide = wideReads.get(record);
    if (wide != null) {
        wide.upgrade();
        writes2Lock.add(wide);
    } else {
        source.addVersionChangeListener(token, this);
        writes2Lock.add(token);
        // CON-669: Prevent a
        writes2Lock.add(Token.shareable(record));
    // conflicting wide read,
    // but don't listen for
    // wide version change
    }
    writes2Lock.add(rangeToken);
    super.set(key, value, record);
}
Also used : RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) RangeToken(com.cinchapi.concourse.server.concurrent.RangeToken) Token(com.cinchapi.concourse.server.concurrent.Token)

Aggregations

Token (com.cinchapi.concourse.server.concurrent.Token)18 RangeToken (com.cinchapi.concourse.server.concurrent.RangeToken)17 PriorityReadWriteLock (com.cinchapi.concourse.server.concurrent.PriorityReadWriteLock)3 Lock (java.util.concurrent.locks.Lock)3 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)3 DoNotInvoke (com.cinchapi.concourse.annotate.DoNotInvoke)1 LockType (com.cinchapi.concourse.server.concurrent.LockType)1 Text (com.cinchapi.concourse.server.model.Text)1 Value (com.cinchapi.concourse.server.model.Value)1 TObject (com.cinchapi.concourse.thrift.TObject)1 Range (com.google.common.collect.Range)1 RangeSet (com.google.common.collect.RangeSet)1 TreeRangeSet (com.google.common.collect.TreeRangeSet)1