try {
HStoreKey [] keys = new HStoreKey[rdrs.length];
ImmutableBytesWritable [] vals = new ImmutableBytesWritable[rdrs.length];
boolean [] done = new boolean[rdrs.length];
for(int i = 0; i < rdrs.length; i++) {
keys[i] = new HStoreKey(HConstants.EMPTY_BYTE_ARRAY, this.info);
vals[i] = new ImmutableBytesWritable();
done[i] = false;
}
// Now, advance through the readers in order. This will have the
// effect of a run-time sort of the entire dataset.
int numDone = 0;
for (int i = 0; i < rdrs.length; i++) {
rdrs[i].reset();
done[i] = !rdrs[i].next(keys[i], vals[i]);
if (done[i]) {
numDone++;
}
}
long now = System.currentTimeMillis();
int timesSeen = 0;
HStoreKey lastSeen = new HStoreKey();
HStoreKey lastDelete = null;
while (numDone < done.length) {
// Get lowest key in all store files.
int lowestKey = getLowestKey(rdrs, keys, done);
HStoreKey sk = keys[lowestKey];
// If its same row and column as last key, increment times seen.
if (HStoreKey.equalsTwoRowKeys(info, lastSeen.getRow(), sk.getRow())
&& Bytes.equals(lastSeen.getColumn(), sk.getColumn())) {
timesSeen++;
// Reset last delete if not exact timestamp -- lastDelete only stops
// exactly the same key making it out to the compacted store file.
if (lastDelete != null &&
lastDelete.getTimestamp() != sk.getTimestamp()) {
lastDelete = null;
}
} else {
timesSeen = 1;
lastDelete = null;
}
// Don't write empty rows or columns. Only remove cells on major
// compaction. Remove if expired of > VERSIONS
if (sk.getRow().length != 0 && sk.getColumn().length != 0) {
ImmutableBytesWritable value = vals[lowestKey];
if (!majorCompaction) {
// Write out all values if not a major compaction.
compactedOut.append(sk, value);
} else {
boolean expired = false;
boolean deleted = false;
if (timesSeen <= family.getMaxVersions() &&
!(expired = isExpired(sk, ttl, now))) {
// If this value key is same as a deleted key, skip
if (lastDelete != null && sk.equals(lastDelete)) {
deleted = true;
} else if (HLogEdit.isDeleted(value.get())) {
// If a deleted value, skip
deleted = true;
lastDelete = new HStoreKey(sk);
} else {
compactedOut.append(sk, vals[lowestKey]);
}
}
if (expired || deleted) {
// HBASE-855 remove one from timesSeen because it did not make it
// past expired check -- don't count against max versions.
timesSeen--;
}
}
}
// Update last-seen items
lastSeen = new HStoreKey(sk);
// Advance the smallest key. If that reader's all finished, then
// mark it as done.
if (!rdrs[lowestKey].next(keys[lowestKey], vals[lowestKey])) {
done[lowestKey] = true;