Skip to content

Commit

Permalink
Crop last unsaved page before open datafile.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbdavid committed Dec 23, 2022
1 parent 1d98f39 commit 43da629
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
2 changes: 1 addition & 1 deletion LiteDB/Engine/Disk/DiskService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public DiskService(EngineSettings settings, int[] memorySegmentSizes)
_dataPool = new StreamPool(_dataFactory, false);
_logPool = new StreamPool(_logFactory, true);

var isNew = !_dataFactory.Exists() || _dataFactory.GetLength() == 0L;
var isNew = _dataFactory.GetLength() == 0L;

// create lazy async writer queue for log file
_queue = new Lazy<DiskWriterQueue>(() => new DiskWriterQueue(_logPool.Writer));
Expand Down
33 changes: 25 additions & 8 deletions LiteDB/Engine/Disk/StreamFactory/FileStreamFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public Stream GetStream(bool canWrite, bool sequencial)

var isNewFile = write && this.Exists() == false;

var stream = new FileStream(_filename,
var stream = new FileStream(
_filename,
_readonly ? System.IO.FileMode.Open : System.IO.FileMode.OpenOrCreate,
write ? FileAccess.ReadWrite : FileAccess.Read,
write ? FileShare.Read : FileShare.ReadWrite,
Expand All @@ -56,7 +57,7 @@ public Stream GetStream(bool canWrite, bool sequencial)
}

/// <summary>
/// Get file length using FileInfo
/// Get file length using FileInfo. Crop file length if not length % PAGE_SIZE
/// </summary>
public long GetLength()
{
Expand All @@ -66,13 +67,29 @@ public long GetLength()
// get physical file length from OS
var length = new FileInfo(_filename).Length;

// if length < PAGE_SIZE, ignore file length (should be 0)
if (length < PAGE_SIZE) return 0;

ENSURE(length % PAGE_SIZE == 0, $"file length must be PAGE_SIZE module. length={length}, file={Path.GetFileName(_filename)}");
// if file length are not PAGE_SIZE module, maybe last save are not completed saved on disk
// crop file removing last uncompleted page saved
if (length % PAGE_SIZE != 0)
{
length = length - (length % PAGE_SIZE);

using (var fs = new FileStream(
_filename,
System.IO.FileMode.Open,
FileAccess.Write,
FileShare.None,
PAGE_SIZE,
FileOptions.SequentialScan))
{
fs.SetLength(length);
fs.FlushToDisk();
}
}

// if encrypted must remove salt first page
return length - (_password == null ? 0 : PAGE_SIZE);
// if encrypted must remove salt first page (only if page contains data)
return length > 0 ?
length - (_password == null ? 0 : PAGE_SIZE) :
0;
}

/// <summary>
Expand Down

0 comments on commit 43da629

Please sign in to comment.