use of com.cinchapi.concourse.server.model.Value in project concourse by cinchapi.
the class Database method chronologize.
@Override
public Map<Long, Set<TObject>> chronologize(String key, long record, long start, long end) {
Identifier L = Identifier.of(record);
Text K = Text.wrapCached(key);
TableRecord table = getTableRecord(L);
Map<Long, Set<Value>> data = table.chronologize(K, start, end);
return Transformers.transformMapSet(data, Functions.identity(), Value::getTObject);
}
use of com.cinchapi.concourse.server.model.Value 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.model.Value in project concourse by cinchapi.
the class AtomicOperation method browse.
@Override
public final Map<TObject, Set<Long>> browse(String key) throws AtomicStateException {
checkState();
Text key0 = Text.wrapCached(key);
RangeToken rangeToken = RangeToken.forReading(key0, Operator.BETWEEN, Value.NEGATIVE_INFINITY, Value.POSITIVE_INFINITY);
source.addVersionChangeListener(rangeToken, this);
Iterable<Range<Value>> ranges = RangeTokens.convertToRange(rangeToken);
for (Range<Value> range : ranges) {
rangeReads2Lock.put(key0, range);
}
return super.browse(key);
}
use of com.cinchapi.concourse.server.model.Value in project concourse by cinchapi.
the class AtomicOperation method explore.
@Override
public Map<Long, Set<TObject>> explore(String key, Aliases aliases) {
checkState();
Operator operator = aliases.operator();
TObject[] values = aliases.values();
Text key0 = Text.wrapCached(key);
RangeToken rangeToken = RangeToken.forReading(key0, operator, Transformers.transformArray(values, Value::wrap, Value.class));
source.addVersionChangeListener(rangeToken, this);
Iterable<Range<Value>> ranges = RangeTokens.convertToRange(rangeToken);
for (Range<Value> range : ranges) {
rangeReads2Lock.put(key0, range);
}
return super.explore(key, aliases);
}
use of com.cinchapi.concourse.server.model.Value in project concourse by cinchapi.
the class RangeLockService method isRangeBlocked.
/**
* Return {@code true} if an attempt to used {@code token} for a
* {@code type} lock is range blocked. Range blocking occurs when there is
* another READ or WRITE happening such that allowing the proposed operation
* to proceed could lead to inconsistent results (i.e. I want to write X but
* there is a READ trying to find all values less than Y).
*
* @param type
* @param token
* @return {@code true} if range blocked
*/
protected final boolean isRangeBlocked(LockType type, RangeToken token) {
Value value = token.getValues()[0];
if (type == LockType.READ) {
Preconditions.checkArgument(token.getOperator() != null);
switch(token.getOperator()) {
case EQUALS:
return info.writes(token.getKey()).contains(value);
case NOT_EQUALS:
return info.writes(token.getKey()).size() > 1 || (info.writes(token.getKey()).size() == 1 && !info.writes(token.getKey()).contains(value));
default:
Iterator<Value> it = info.writes(token.getKey()).iterator();
while (it.hasNext()) {
Iterable<Range<Value>> ranges = RangeTokens.convertToRange(token);
Value current = it.next();
Range<Value> point = Range.singleton(current);
for (Range<Value> range : ranges) {
RangeReadWriteLock lock = null;
if (range.isConnected(point) && !range.intersection(point).isEmpty() && (lock = locks.get(RangeToken.forWriting(token.getKey(), current))) != null && !lock.isWriteLockedByCurrentThread()) {
return true;
}
}
}
return false;
}
} else {
// X)
return info.reads(token.getKey()).contains(value);
}
}
Aggregations