private IEnumerable<KeyValuePair<RecordKey, RecordData>> _scan(IScanner<RecordKey> scanner, bool direction_is_forward)
{
long max_valid_timestamp = 0;
var max_valid_record = new KeyValuePair<RecordKey, RecordData>(null, null);
RecordKey last_key = null;
IEnumerable<KeyValuePair<RecordKey, RecordData>> scan_enumerable;
if (direction_is_forward) {
scan_enumerable = next_stage.scanForward(scanner);
} else {
scan_enumerable = next_stage.scanBackward(scanner);
}
foreach (KeyValuePair<RecordKey, RecordData> row in scan_enumerable) {
#if DEBUG_SNAPSHOT_SCAN
if (this.is_frozen) {
Console.WriteLine("Frozen Snapshot(0x{0:X}) stage saw: {1}",
this.frozen_at_snapshotnumber, row);
} else {
Console.WriteLine("Snapshot stage saw: {0}", row);
}
#endif
RecordKeyType_AttributeTimestamp our_attr =
(RecordKeyType_AttributeTimestamp)row.Key.key_parts[row.Key.key_parts.Count - 1];
long cur_timestamp = our_attr.GetLong();
// unwrap our key
// remove our timestamp keypart
// TODO: THIS IS A SUPER HACK AND STOP DOING IT!!!
row.Key.key_parts.RemoveAt(row.Key.key_parts.Count - 1);
RecordKey clean_key = row.Key;
// unwrap our data
var clean_update = RecordUpdate.FromEncodedData(row.Value.data);
if (last_key == null) {
last_key = clean_key;
} else if (clean_key.CompareTo(last_key) != 0) {
if (max_valid_record.Key != null) {
if (max_valid_record.Value.State != RecordDataState.DELETED) {
yield return max_valid_record;
}
max_valid_record = new KeyValuePair<RecordKey, RecordData>(null, null);
max_valid_timestamp = 0;
last_key = clean_key;
}
}
// record the current record
if (cur_timestamp > max_valid_timestamp) {
if (this.is_frozen && (cur_timestamp > this.frozen_at_snapshotnumber)) {
continue;
}
max_valid_timestamp = cur_timestamp;
RecordData rec_data = new RecordData(RecordDataState.NOT_PROVIDED, clean_key);
rec_data.applyUpdate(clean_update);
max_valid_record = new KeyValuePair<RecordKey, RecordData>(clean_key, rec_data);
}
}
if (max_valid_record.Key != null) {
if (max_valid_record.Value.State != RecordDataState.DELETED) {
yield return max_valid_record;
}
max_valid_record = new KeyValuePair<RecordKey, RecordData>(null, null);
max_valid_timestamp = 0;
}
}