public void ReadToEnd() { WithVolumeHandle( volumeHandle => { byte[] buffer = new byte[4096]; while (true) { QueryUsnJournalData journalState = QueryJournal(volumeHandle); ReadUsnJournalResult readJournalResult = FileUtilities.TryReadUsnJournal( volumeHandle, buffer, journalState.UsnJournalId, startUsn: journalState.NextUsn); XAssert.AreEqual(ReadUsnJournalStatus.Success, readJournalResult.Status); XAssert.IsFalse(readJournalResult.NextUsn.IsZero); XAssert.IsTrue(readJournalResult.NextUsn >= journalState.NextUsn); if (readJournalResult.Records.Count == 0) { break; } } }); }
public void ReadEarliestUsnRecords() { WithVolumeHandle( volumeHandle => { QueryUsnJournalData journalState = QueryJournal(volumeHandle); byte[] buffer = new byte[4096]; ReadUsnJournalResult readJournalResult = FileUtilities.TryReadUsnJournal(volumeHandle, buffer, journalState.UsnJournalId, startUsn: new Usn(0)); XAssert.AreEqual(ReadUsnJournalStatus.Success, readJournalResult.Status); XAssert.IsFalse(readJournalResult.NextUsn.IsZero); XAssert.IsTrue(readJournalResult.NextUsn >= journalState.FirstUsn); XAssert.AreNotEqual(0, readJournalResult.Records.Count, "It is unlikely that this journal should be empty, since this test's execution has written to the volume."); var firstRecord = readJournalResult.Records.First(); XAssert.IsTrue(firstRecord.Usn == journalState.FirstUsn); XAssert.IsTrue(firstRecord.Usn < readJournalResult.NextUsn); var lastUsn = firstRecord.Usn; foreach (UsnRecord record in readJournalResult.Records.Skip(1)) { XAssert.IsTrue(record.Usn > lastUsn, "Expected USNs to be monotically increasing."); lastUsn = record.Usn; XAssert.IsTrue(record.Usn >= journalState.FirstUsn); XAssert.IsTrue(record.Usn < readJournalResult.NextUsn); } }); }
private void ExpectChangesSinceUsn( UsnChangeReasons expectedChangeReasons, SafeFileHandle volumeHandle, Usn startUsn, FileId fileId, out Usn nextUsn, TimeSpan?timeLimit = default(TimeSpan?)) { const int DefaultTimeLimitForScanningInSecond = 30; // 30 sec for scanning. QueryUsnJournalData journalState = QueryJournal(volumeHandle); byte[] buffer = new byte[64 * 1024]; // 655 records per read. timeLimit = timeLimit.HasValue ? timeLimit : TimeSpan.FromSeconds(DefaultTimeLimitForScanningInSecond); var stopWatch = System.Diagnostics.Stopwatch.StartNew(); UsnChangeReasons foundChangeReasons = 0; nextUsn = startUsn; while (true) { if (stopWatch.ElapsedTicks > timeLimit.Value.Ticks) { break; } ReadUsnJournalResult result = FileUtilities.TryReadUsnJournal( volumeHandle, buffer, journalState.UsnJournalId, startUsn); nextUsn = result.NextUsn; if (!result.Succeeded) { break; } if (result.Records.Count == 0) { break; } foundChangeReasons |= UsnJournalUtilities.GetAggregateChangeReasons(fileId, result.Records); if (expectedChangeReasons == (foundChangeReasons & expectedChangeReasons)) { // Found all expected change reasons. return; } startUsn = result.NextUsn; } XAssert.AreEqual(expectedChangeReasons, foundChangeReasons & expectedChangeReasons); }
private ReadUsnJournalResult ReadChangesSinceUsn(SafeFileHandle volumeHandle, Usn startUsn) { QueryUsnJournalData journalState = QueryJournal(volumeHandle); // TODO: On a busy volume, we may need to read up to a particular expected USN - or we will fill up the single buffer before finding the expected records. byte[] buffer = new byte[32768]; ReadUsnJournalResult readJournalResult = FileUtilities.TryReadUsnJournal(volumeHandle, buffer, journalState.UsnJournalId, startUsn: startUsn); XAssert.AreEqual(ReadUsnJournalStatus.Success, readJournalResult.Status); return(readJournalResult); }
public void QueryJournal() { WithVolumeHandle( volumeHandle => { using (FileStream file = File.Create(GetFullPath("File"))) { QueryUsnJournalData journalState = QueryJournal(volumeHandle); Usn usn = FileUtilities.ReadFileUsnByHandle(file.SafeFileHandle).Value.Usn; XAssert.IsTrue(journalState.LowestValidUsn <= usn); XAssert.IsTrue(journalState.NextUsn > usn); } }); }
public static QueryUsnJournalData ReadUsnJournalData(this ChangeJournalServiceProtocolReader reader) { Contract.Requires(reader != null); var data = new QueryUsnJournalData { UsnJournalId = reader.ReadUInt64(), FirstUsn = new Usn(reader.ReadUInt64()), NextUsn = new Usn(reader.ReadUInt64()), LowestValidUsn = new Usn(reader.ReadUInt64()), MaxUsn = new Usn(reader.ReadUInt64()), MaximumSize = reader.ReadUInt64(), AllocationDelta = reader.ReadUInt64() }; return(data); }
public static QueryUsnJournalResult ReadQueryUsnJournalResult(this ChangeJournalServiceProtocolReader reader) { Contract.Requires(reader != null); var queryStatusValue = reader.ReadInt32(); QueryUsnJournalStatus queryStatus; if (!EnumTraits <QueryUsnJournalStatus> .TryConvert(queryStatusValue, out queryStatus)) { throw new BuildXLException("Invalid QueryUsnJournalStatus"); } if (queryStatus == QueryUsnJournalStatus.Success) { QueryUsnJournalData data = reader.ReadUsnJournalData(); return(new QueryUsnJournalResult(queryStatus, data)); } return(new QueryUsnJournalResult(queryStatus, data: null)); }
public static void WriteUsnJournalData(this ChangeJournalServiceProtocolWriter writer, QueryUsnJournalData data) { Contract.Requires(writer != null); Contract.Requires(data != null); writer.Write(data.UsnJournalId); writer.Write(data.FirstUsn.Value); writer.Write(data.NextUsn.Value); writer.Write(data.LowestValidUsn.Value); writer.Write(data.MaxUsn.Value); writer.Write(data.MaximumSize); writer.Write(data.AllocationDelta); }