use of com.cinchapi.concourse.server.concurrent.RangeToken in project concourse by cinchapi.
the class Engine method add.
@Override
public boolean add(String key, TObject value, long record) {
Token sharedToken = Token.shareable(record);
Token writeToken = Token.wrap(key, record);
RangeToken rangeToken = RangeToken.forWriting(Text.wrap(key), Value.wrap(value));
Lock shared = lockService.getWriteLock(sharedToken);
Lock write = lockService.getWriteLock(writeToken);
Lock range = rangeLockService.getWriteLock(rangeToken);
shared.lock();
write.lock();
range.lock();
try {
return addUnlocked(Write.add(key, value, record), Sync.YES, sharedToken, writeToken, rangeToken);
} finally {
shared.unlock();
write.unlock();
range.unlock();
}
}
use of com.cinchapi.concourse.server.concurrent.RangeToken in project concourse by cinchapi.
the class Engine method accept.
/**
* <p>
* The Engine is the destination for Transaction commits, which means that
* this method will accept Writes from Transactions and create new Writes
* within the Engine BufferedStore (e.g. a new Write will be created in the
* Buffer and eventually transported to the Database). Creating a new Write
* does associate a new timestamp with the transactional data, but this is
* the desired behaviour because data from a Transaction should always have
* a post commit timestamp.
* </p>
* <p>
* It is also worth calling out the fact that this method does not have any
* locks to prevent multiple transactions from concurrently invoking meaning
* that two transactions that don't have any overlapping reads/writes
* (meaning they don't touch any of the same data) can commit at the same
* time and its possible that their writes will be interleaved since calls
* to this method don't globally lock. This is <em>okay</em> and does not
* violate ACID because the <strong>observed</strong> state of the system
* will be the same as if the transactions transported all their Writes
* serially.
* </p>
*/
@Override
@DoNotInvoke
public void accept(Write write, boolean sync) {
checkArgument(write.getType() != Action.COMPARE);
String key = write.getKey().toString();
TObject value = write.getValue().getTObject();
long record = write.getRecord().longValue();
Token sharedToken = Token.shareable(record);
Token writeToken = Token.wrap(key, record);
RangeToken rangeToken = RangeToken.forWriting(Text.wrap(key), Value.wrap(value));
boolean accepted;
if (write.getType() == Action.ADD) {
accepted = addUnlocked(write, sync ? Sync.YES : Sync.NO, sharedToken, writeToken, rangeToken);
} else {
accepted = removeUnlocked(write, sync ? Sync.YES : Sync.NO, sharedToken, writeToken, rangeToken);
}
if (!accepted) {
Logger.warn("Write {} was rejected by the Engine " + "because it was previously accepted " + "but not offset. This implies that a " + "premature shutdown occurred and the parent" + "Transaction is attempting to restore " + "itself from backup and finish committing.", write);
} else {
Logger.debug("'{}' was accepted by the Engine", write);
}
}
use of com.cinchapi.concourse.server.concurrent.RangeToken in project concourse by cinchapi.
the class Engine method remove.
@Override
public boolean remove(String key, TObject value, long record) {
Token sharedToken = Token.shareable(record);
Token writeToken = Token.wrap(key, record);
RangeToken rangeToken = RangeToken.forWriting(Text.wrap(key), Value.wrap(value));
Lock shared = lockService.getWriteLock(sharedToken);
Lock write = lockService.getWriteLock(writeToken);
Lock range = rangeLockService.getWriteLock(rangeToken);
shared.lock();
write.lock();
range.lock();
try {
return removeUnlocked(Write.remove(key, value, record), Sync.YES, sharedToken, writeToken, rangeToken);
} finally {
shared.unlock();
write.unlock();
range.unlock();
}
}
use of com.cinchapi.concourse.server.concurrent.RangeToken in project concourse by cinchapi.
the class AtomicOperation method add.
@Override
protected final boolean add(Write write, Sync sync, Verify verify) throws AtomicStateException {
checkState();
String key = write.getKey().toString();
long record = write.getRecord().longValue();
Token token = Token.wrap(key, record);
RangeToken rangeToken = RangeToken.forWriting(write.getKey(), write.getValue());
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);
return super.add(write, sync, verify);
}
use of com.cinchapi.concourse.server.concurrent.RangeToken in project concourse by cinchapi.
the class AtomicOperation method remove.
@Override
protected final boolean remove(Write write, Sync sync, Verify verify) throws AtomicStateException {
checkState();
String key = write.getKey().toString();
long record = write.getRecord().longValue();
Token token = Token.wrap(key, record);
RangeToken rangeToken = RangeToken.forWriting(write.getKey(), write.getValue());
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);
return super.remove(write, sync, verify);
}
Aggregations