You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/FASTER/Index/FasterLog/FasterLogRecoveryInfo.cs

161 lines
4.6 KiB

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
#pragma warning disable 0162
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace FASTER.core
{
/// <summary>
/// Recovery info for FASTER Log
/// </summary>
internal struct FasterLogRecoveryInfo
{
/// <summary>
/// Begin address
/// </summary>
public long BeginAddress;
/// <summary>
/// Flushed logical address
/// </summary>
public long FlushedUntilAddress;
/// <summary>
/// Persisted iterators
/// </summary>
public Dictionary<string, long> Iterators;
/// <summary>
/// Initialize
/// </summary>
public void Initialize()
{
BeginAddress = 0;
FlushedUntilAddress = 0;
}
/// <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();
FlushedUntilAddress = reader.ReadInt64();
}
catch (Exception e)
{
throw new Exception("Unable to recover from previous commit. Inner exception: " + e.ToString());
}
if (version != 0)
throw new Exception("Invalid version found during commit recovery");
if (checkSum != (BeginAddress ^ FlushedUntilAddress))
throw new Exception("Invalid checksum found during commit recovery");
var count = 0;
try
{
count = reader.ReadInt32();
}
catch { }
if (count > 0)
{
Iterators = new Dictionary<string, long>();
for (int i = 0; i < count; i++)
{
Iterators.Add(reader.ReadString(), reader.ReadInt64());
}
}
}
/// <summary>
/// Recover info from token
/// </summary>
/// <param name="logCommitManager"></param>
/// <returns></returns>
internal void Recover(ILogCommitManager logCommitManager)
{
var metadata = logCommitManager.GetCommitMetadata();
if (metadata == null)
throw new Exception("Invalid log commit metadata during recovery");
Initialize(new BinaryReader(new MemoryStream(metadata)));
}
/// <summary>
/// Reset
/// </summary>
public void Reset()
{
Initialize();
}
/// <summary>
/// Write info to byte array
/// </summary>
public byte[] ToByteArray()
{
using (var ms = new MemoryStream())
{
using (var writer = new BinaryWriter(ms))
{
writer.Write(0); // version
writer.Write(BeginAddress ^ FlushedUntilAddress); // checksum
writer.Write(BeginAddress);
writer.Write(FlushedUntilAddress);
if (Iterators?.Count > 0)
{
writer.Write(Iterators.Count);
foreach (var kvp in Iterators)
{
writer.Write(kvp.Key);
writer.Write(kvp.Value);
}
}
}
return ms.ToArray();
}
}
/// <summary>
/// Take snapshot of persisted iterators
/// </summary>
public void PopulateIterators()
{
if (FasterLogScanIterator.PersistedIterators.Count > 0)
{
Iterators = new Dictionary<string, long>();
foreach (var kvp in FasterLogScanIterator.PersistedIterators)
{
Iterators.Add(kvp.Key, kvp.Value.CurrentAddress);
}
}
}
/// <summary>
/// Print checkpoint info for debugging purposes
/// </summary>
public void DebugPrint()
{
Debug.WriteLine("******** Log Commit Info ********");
Debug.WriteLine("BeginAddress: {0}", BeginAddress);
Debug.WriteLine("FlushedUntilAddress: {0}", FlushedUntilAddress);
}
}
}

Powered by TurnKey Linux.