public void T04_RecordTombstones() { RecordData data = new RecordData(RecordDataState.NOT_PROVIDED, new RecordKey()); Assert.AreEqual(RecordDataState.NOT_PROVIDED, data.State, "empty rec 1"); RecordDataUpdateResult result = data.applyUpdate(RecordUpdate.DeletionTombstone()); Assert.AreEqual(RecordDataUpdateResult.FINAL,result, "tomb result 1"); Assert.AreEqual(RecordDataState.DELETED, data.State, "tomb state 1"); /* NOT ANYMORE bool err = false; try { data.applyUpdate(RecordUpdate.WithPayload("2")); data.applyUpdate(RecordUpdate.DeletionTombstone()); } catch { err = true; } * Assert.AreEqual(err, true); */ // data after a tombstone should be ignored Assert.AreEqual(RecordDataUpdateResult.FINAL, data.applyUpdate(RecordUpdate.WithPayload("1"))); Assert.AreEqual(RecordDataState.DELETED, data.State, "still empty 1"); }
// TODO: properly implement applyUpdate by getting qualifying records and performing // applyUpdate to build the record 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; } }
public void T03_RecordDataAssembly() { RecordData data = new RecordData(RecordDataState.NOT_PROVIDED, new RecordKey()); Assert.AreEqual(RecordDataState.NOT_PROVIDED, data.State, "empty rec 1"); RecordDataUpdateResult result; result = data.applyUpdate(RecordUpdate.NoUpdate()); Assert.AreEqual(RecordDataState.NOT_PROVIDED, data.State, "empty rec 2"); Assert.AreEqual(result, RecordDataUpdateResult.SUCCESS, "apply result 2"); Assert.AreEqual(RecordDataState.NOT_PROVIDED, data.State, "apply state 2"); byte[] payload1 = new byte[] { 1 }; result = data.applyUpdate(RecordUpdate.WithPayload(payload1)); Assert.AreEqual(payload1, data.data, "apply 3"); Assert.AreEqual(result, RecordDataUpdateResult.FINAL, "apply result 3"); Assert.AreEqual(RecordDataState.FULL, data.State, "apply state 3"); // if we already have a full update, it should be an error /* NOT ANYMORE { bool err = false; try { data.applyUpdate(RecordUpdate.WithPayload("2")); } catch { err = true; } Assert.AreEqual(true, err); } { bool err = false; try { data.applyUpdate(RecordUpdate.DeletionTombstone()); } catch { err = true; } Assert.AreEqual(true, err); } Assert.AreEqual("1", data.ToString()); */ // if we already have a full update, our update should not change it { byte[] payload2 = new byte[] { 2 }; data.applyUpdate(RecordUpdate.WithPayload(payload2)); Assert.AreEqual(payload1, data.data); data.applyUpdate(RecordUpdate.DeletionTombstone()); Assert.AreEqual(payload1, data.data); } }