public void Initialize() { if (!File.Exists(_storePath)) { _storeStream = new FileStream(_storePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); _firstNotAllocated = SectorIndex.First; _log?.Log(LogSeverity.Info, $"Empty file created: {_storePath}."); } else { _storeStream = new FileStream(_storePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); } // Number of sectors is inferred from the file size. var info = new FileInfo(_storePath); _firstNotAllocated = SectorIndex.OffsetInBytes(info.Length, _sectorSizeInBytes); if (!File.Exists(_hotPath)) { _hotStream = new FileStream(_hotPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); _log?.Log(LogSeverity.Info, $"Empty file created: {_hotPath}."); } else { _hotStream = new FileStream(_hotPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); TryRecovery(); } }
public void Initialize() { // recovery on edge crash if (File.Exists(TmpStorePath) && !File.Exists(_storePath)) { File.Move(TmpStorePath, _storePath); _log.Log(LogSeverity.Warning, $"File recovered: {TmpStorePath}"); } // Number of sectors is inferred from the file size. _firstNotAllocated = SectorIndex.First; if (File.Exists(_storePath)) { var info = new FileInfo(_storePath); _firstNotAllocated = SectorIndex.OffsetInBytes(info.Length, _sectorSizeInBytes); } // hot stream does not apply to volatile store if (!File.Exists(_storePath)) { _storeStream = new FileStream(_storePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); _log?.Log(LogSeverity.Info, $"Empty file created: {_storePath}."); _firstNotAllocated = SectorIndex.First; _memoryStream = new MemoryStream(); } else { _storeStream = new FileStream(_storePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); _memoryStream = new MemoryStream((int)_storeStream.Length); _storeStream.CopyTo(_memoryStream); } }
/// <summary> /// Recover a halfway written sector. /// </summary> /// <remarks> /// TODO: verify this method does what it is supposed to do, after replacing TryRead with a Read that throws exceptions, /// instead of returning a bool. /// </remarks> private void TryRecovery() { try { var offset = _sector.Read(_hotStream); // hotstream is valid var deducedIndex = SectorIndex.OffsetInBytes(offset, _sectorSizeInBytes); try { //try read last recorded sector Read(deducedIndex); // reach here means that both streams are ok } catch (SectorOperationException) { // something went wrong in storeStream _hotStream.Seek(0, SeekOrigin.Begin); _sector.Read(_hotStream, offset); // reach here means that hostream is ok // copying '_hotstream' back to '_storeStream' _storeStream.Seek(deducedIndex.ByteIndex(_sectorSizeInBytes), SeekOrigin.Begin); _sector.Write(_storeStream, deducedIndex.ByteIndex(_sectorSizeInBytes)); // TODO: add log to indicate successful recovery. } } catch (SectorOperationException) { // hotstream invalid // normally thanks to double writing, main store stream is valid _log?.Log(LogSeverity.Warning, "Hotstream error when trying to recover sector store."); throw; } }