in core/src/main/java/org/apache/accumulo/core/file/rfile/RelativeKey.java [218:433]
public static SkippR fastSkip(DataInput in, Key seekKey, ArrayByteSequence value, Key prevKey,
Key currKey, int entriesLeft) throws IOException {
// this method mostly avoids object allocation and only does compares when the row changes
ArrayByteSequence row, cf, cq, cv;
ArrayByteSequence prow, pcf, pcq, pcv;
ByteSequence stopRow = seekKey.getRowData();
ByteSequence stopCF = seekKey.getColumnFamilyData();
ByteSequence stopCQ = seekKey.getColumnQualifierData();
long ts = -1;
long pts = -1;
boolean pdel = false;
int rowCmp = -1, cfCmp = -1, cqCmp = -1;
if (currKey != null) {
prow = new ArrayByteSequence(currKey.getRowData());
pcf = new ArrayByteSequence(currKey.getColumnFamilyData());
pcq = new ArrayByteSequence(currKey.getColumnQualifierData());
pcv = new ArrayByteSequence(currKey.getColumnVisibilityData());
pts = currKey.getTimestamp();
row = new ArrayByteSequence(currKey.getRowData());
cf = new ArrayByteSequence(currKey.getColumnFamilyData());
cq = new ArrayByteSequence(currKey.getColumnQualifierData());
cv = new ArrayByteSequence(currKey.getColumnVisibilityData());
ts = currKey.getTimestamp();
rowCmp = row.compareTo(stopRow);
cfCmp = cf.compareTo(stopCF);
cqCmp = cq.compareTo(stopCQ);
if (rowCmp >= 0) {
if (rowCmp > 0) {
RelativeKey rk = new RelativeKey();
rk.key = rk.prevKey = new Key(currKey);
return new SkippR(rk, 0, prevKey);
}
if (cfCmp >= 0) {
if (cfCmp > 0) {
RelativeKey rk = new RelativeKey();
rk.key = rk.prevKey = new Key(currKey);
return new SkippR(rk, 0, prevKey);
}
if (cqCmp >= 0) {
RelativeKey rk = new RelativeKey();
rk.key = rk.prevKey = new Key(currKey);
return new SkippR(rk, 0, prevKey);
}
}
}
} else {
row = new ArrayByteSequence(new byte[64], 0, 0);
cf = new ArrayByteSequence(new byte[64], 0, 0);
cq = new ArrayByteSequence(new byte[64], 0, 0);
cv = new ArrayByteSequence(new byte[64], 0, 0);
prow = new ArrayByteSequence(new byte[64], 0, 0);
pcf = new ArrayByteSequence(new byte[64], 0, 0);
pcq = new ArrayByteSequence(new byte[64], 0, 0);
pcv = new ArrayByteSequence(new byte[64], 0, 0);
}
byte fieldsSame = -1;
byte fieldsPrefixed = 0;
int count = 0;
Key newPrevKey = null;
while (count < entriesLeft) {
pdel = (fieldsSame & DELETED) == DELETED;
fieldsSame = in.readByte();
if ((fieldsSame & PREFIX_COMPRESSION_ENABLED) == PREFIX_COMPRESSION_ENABLED) {
fieldsPrefixed = in.readByte();
} else {
fieldsPrefixed = 0;
}
boolean changed = false;
if ((fieldsSame & ROW_SAME) != ROW_SAME) {
ArrayByteSequence tmp = prow;
prow = row;
row = tmp;
if ((fieldsPrefixed & ROW_COMMON_PREFIX) == ROW_COMMON_PREFIX) {
readPrefix(in, row, prow);
} else {
read(in, row);
}
// read a new row, so need to compare...
rowCmp = row.compareTo(stopRow);
changed = true;
} // else the row is the same as the last, so no need to compare
if ((fieldsSame & CF_SAME) != CF_SAME) {
ArrayByteSequence tmp = pcf;
pcf = cf;
cf = tmp;
if ((fieldsPrefixed & CF_COMMON_PREFIX) == CF_COMMON_PREFIX) {
readPrefix(in, cf, pcf);
} else {
read(in, cf);
}
cfCmp = cf.compareTo(stopCF);
changed = true;
}
if ((fieldsSame & CQ_SAME) != CQ_SAME) {
ArrayByteSequence tmp = pcq;
pcq = cq;
cq = tmp;
if ((fieldsPrefixed & CQ_COMMON_PREFIX) == CQ_COMMON_PREFIX) {
readPrefix(in, cq, pcq);
} else {
read(in, cq);
}
cqCmp = cq.compareTo(stopCQ);
changed = true;
}
if ((fieldsSame & CV_SAME) != CV_SAME) {
ArrayByteSequence tmp = pcv;
pcv = cv;
cv = tmp;
if ((fieldsPrefixed & CV_COMMON_PREFIX) == CV_COMMON_PREFIX) {
readPrefix(in, cv, pcv);
} else {
read(in, cv);
}
}
if ((fieldsSame & TS_SAME) != TS_SAME) {
pts = ts;
if ((fieldsPrefixed & TS_DIFF) == TS_DIFF) {
ts = WritableUtils.readVLong(in) + pts;
} else {
ts = WritableUtils.readVLong(in);
}
}
readValue(in, value);
count++;
if (changed && rowCmp >= 0) {
if (rowCmp > 0) {
break;
}
if (cfCmp >= 0) {
if (cfCmp > 0) {
break;
}
if (cqCmp >= 0) {
break;
}
}
}
}
if (count > 1) {
ArrayByteSequence trow, tcf, tcq, tcv;
long tts;
// when the current keys field is same as the last, then
// set the prev keys field the same as the current key
trow = (fieldsSame & ROW_SAME) == ROW_SAME ? row : prow;
tcf = (fieldsSame & CF_SAME) == CF_SAME ? cf : pcf;
tcq = (fieldsSame & CQ_SAME) == CQ_SAME ? cq : pcq;
tcv = (fieldsSame & CV_SAME) == CV_SAME ? cv : pcv;
tts = (fieldsSame & TS_SAME) == TS_SAME ? ts : pts;
newPrevKey = new Key(trow.getBackingArray(), trow.offset(), trow.length(),
tcf.getBackingArray(), tcf.offset(), tcf.length(), tcq.getBackingArray(), tcq.offset(),
tcq.length(), tcv.getBackingArray(), tcv.offset(), tcv.length(), tts);
newPrevKey.setDeleted(pdel);
} else if (count == 1) {
if (currKey != null) {
newPrevKey = currKey;
} else {
newPrevKey = prevKey;
}
} else {
throw new IllegalStateException();
}
RelativeKey result = new RelativeKey();
result.key = new Key(row.getBackingArray(), row.offset(), row.length(), cf.getBackingArray(),
cf.offset(), cf.length(), cq.getBackingArray(), cq.offset(), cq.length(),
cv.getBackingArray(), cv.offset(), cv.length(), ts);
result.key.setDeleted((fieldsSame & DELETED) != 0);
result.prevKey = result.key;
return new SkippR(result, count, newPrevKey);
}