use of org.apache.accumulo.tserver.ConditionalMutationSet.DeferFilter in project accumulo by apache.
the class RowLocks method acquireRowlocks.
List<RowLock> acquireRowlocks(Map<KeyExtent, List<ServerConditionalMutation>> updates, Map<KeyExtent, List<ServerConditionalMutation>> deferred) {
ArrayList<RowLock> locks = new ArrayList<>();
// assume that mutations are in sorted order to avoid deadlock
synchronized (rowLocks) {
for (List<ServerConditionalMutation> scml : updates.values()) {
for (ServerConditionalMutation scm : scml) {
locks.add(getRowLock(new ArrayByteSequence(scm.getRow())));
}
}
}
HashSet<ByteSequence> rowsNotLocked = null;
// acquire as many locks as possible, not blocking on rows that are already locked
if (locks.size() > 1) {
for (RowLock rowLock : locks) {
if (!rowLock.tryLock()) {
if (rowsNotLocked == null)
rowsNotLocked = new HashSet<>();
rowsNotLocked.add(rowLock.rowSeq);
}
}
} else {
// if there is only one lock, then wait for it
locks.get(0).lock();
}
if (rowsNotLocked != null) {
final HashSet<ByteSequence> rnlf = rowsNotLocked;
// assume will get locks needed, do something expensive otherwise
ConditionalMutationSet.defer(updates, deferred, new DeferFilter() {
@Override
public void defer(List<ServerConditionalMutation> scml, List<ServerConditionalMutation> okMutations, List<ServerConditionalMutation> deferred) {
for (ServerConditionalMutation scm : scml) {
if (rnlf.contains(new ArrayByteSequence(scm.getRow())))
deferred.add(scm);
else
okMutations.add(scm);
}
}
});
ArrayList<RowLock> filteredLocks = new ArrayList<>();
ArrayList<RowLock> locksToReturn = new ArrayList<>();
for (RowLock rowLock : locks) {
if (rowsNotLocked.contains(rowLock.rowSeq)) {
locksToReturn.add(rowLock);
} else {
filteredLocks.add(rowLock);
}
}
synchronized (rowLocks) {
for (RowLock rowLock : locksToReturn) {
returnRowLock(rowLock);
}
}
locks = filteredLocks;
}
return locks;
}
Aggregations