RangeLockService extends AbstractLockService<RangeToken, RangeReadWriteLock> { 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 { return info.reads(token.getKey()).contains(value); } } private  RangeLockService(); private  RangeLockService(
            ConcurrentMap<RangeToken, RangeReadWriteLock> locks); static RangeLockService create(); static RangeLockService noOp(); ReadLock getReadLock(String key, Operator operator,
            TObject... values); ReadLock getReadLock(Text key, Operator operator, Value... values); WriteLock getWriteLock(String key, TObject value); WriteLock getWriteLock(Text key, Value value);  }
@Test public void testWriteNotRangeBlockedIfNoReading() { Text key = Variables.register("key", TestData.getText()); Value value = Variables.register("value", TestData.getValue()); Assert.assertFalse(rangeLockService.isRangeBlocked(LockType.WRITE, RangeToken.forWriting(key, value))); }