byte[] qualifier,
long newValue,
long now) {
this.lock.readLock().lock();
try {
KeyValue firstKv = KeyValue.createFirstOnRow(
row, family, qualifier);
// Is there a KeyValue in 'snapshot' with the same TS? If so, upgrade the timestamp a bit.
SortedSet<KeyValue> snSs = snapshot.tailSet(firstKv);
if (!snSs.isEmpty()) {
KeyValue snKv = snSs.first();
// is there a matching KV in the snapshot?
if (snKv.matchingRow(firstKv) && snKv.matchingQualifier(firstKv)) {
if (snKv.getTimestamp() == now) {
// poop,
now += 1;
}
}
}
// logic here: the new ts MUST be at least 'now'. But it could be larger if necessary.
// But the timestamp should also be max(now, mostRecentTsInMemstore)
// so we cant add the new KV w/o knowing what's there already, but we also
// want to take this chance to delete some kvs. So two loops (sad)
SortedSet<KeyValue> ss = kvset.tailSet(firstKv);
Iterator<KeyValue> it = ss.iterator();
while ( it.hasNext() ) {
KeyValue kv = it.next();
// if this isnt the row we are interested in, then bail:
if (!kv.matchingColumn(family,qualifier) || !kv.matchingRow(firstKv) ) {
break; // rows dont match, bail.
}
// if the qualifier matches and it's a put, just RM it out of the kvset.
if (kv.getType() == KeyValue.Type.Put.getCode() &&
kv.getTimestamp() > now && firstKv.matchingQualifier(kv)) {
now = kv.getTimestamp();
}
}
// create or update (upsert) a new KeyValue with
// 'now' and a 0 memstoreTS == immediately visible
return upsert(Arrays.asList(
new KeyValue(row, family, qualifier, now, Bytes.toBytes(newValue)))
);
} finally {
this.lock.readLock().unlock();
}
}