private unsafe static bool VerifyBlockChecksum(byte *ptr, int length) { var cs = Utility.XorBytes(ptr + 8, length + HeaderSize - 8); if (cs != GetHeader((long)ptr).Checksum) { return(false); } return(true); }
/// <summary> /// Write info to byte array /// </summary> public readonly byte[] ToByteArray() { using MemoryStream ms = new(); using (BinaryWriter writer = new(ms)) { writer.Write(FasterLogRecoveryVersion); // version int iteratorCount = 0; if (Iterators != null) { iteratorCount = Iterators.Count; } int cookieLength = -1; long cookieChecksum = 0; if (Cookie != null) { cookieLength = Cookie.Length; if (cookieLength > 0) { unsafe { fixed(byte *ptr = Cookie) cookieChecksum = (long)Utility.XorBytes(ptr, cookieLength); } } } writer.Write(BeginAddress ^ UntilAddress ^ CommitNum ^ iteratorCount ^ cookieLength ^ cookieChecksum); // checksum writer.Write(BeginAddress); writer.Write(UntilAddress); writer.Write(CommitNum); writer.Write(iteratorCount); if (iteratorCount > 0) { foreach (var kvp in Iterators) { writer.Write(kvp.Key); writer.Write(kvp.Value); } } writer.Write(cookieLength); if (cookieLength > 0) { writer.Write(Cookie); } } return(ms.ToArray()); }
/// <summary> /// Initialize from stream /// </summary> /// <param name="reader"></param> public void Initialize(BinaryReader reader) { int version; long checkSum; try { version = reader.ReadInt32(); checkSum = reader.ReadInt64(); BeginAddress = reader.ReadInt64(); UntilAddress = reader.ReadInt64(); if (version > 0) { CommitNum = reader.ReadInt64(); } else { CommitNum = -1; } } catch (Exception e) { throw new FasterException("Unable to recover from previous commit. Inner exception: " + e.ToString()); } if (version < 0 || version > FasterLogRecoveryVersion) { throw new FasterException("Invalid version found during commit recovery"); } var iteratorCount = 0; try { iteratorCount = reader.ReadInt32(); } catch { } if (iteratorCount > 0) { Iterators = new Dictionary <string, long>(); for (int i = 0; i < iteratorCount; i++) { Iterators.Add(reader.ReadString(), reader.ReadInt64()); } } int cookieLength = -1; long cookieChecksum = 0; if (version >= FasterLogRecoveryVersion) { try { cookieLength = reader.ReadInt32(); } catch { } if (cookieLength >= 0) { Cookie = reader.ReadBytes(cookieLength); unsafe { fixed(byte *ptr = Cookie) cookieChecksum = (long)Utility.XorBytes(ptr, cookieLength); } } } long computedChecksum = BeginAddress ^ UntilAddress; if (version >= FasterLogRecoveryVersion) { computedChecksum ^= CommitNum ^ iteratorCount ^ cookieLength ^ cookieChecksum; } // Handle case where all fields are zero if (version == 0 && BeginAddress == 0 && UntilAddress == 0 && iteratorCount == 0) { throw new FasterException("Invalid checksum found during commit recovery"); } if (checkSum != computedChecksum) { throw new FasterException("Invalid checksum found during commit recovery"); } }