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);
}
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);
}
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);
}
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;
}
}
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);
}
Aggregations