Skip to content

Commit

Permalink
Avoid Storage use Transaction and OpenWrite delete in chunks #484
Browse files Browse the repository at this point in the history
  • Loading branch information
mbdavid committed Feb 15, 2017
1 parent 1afb0b1 commit 69ae228
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 3 deletions.
5 changes: 5 additions & 0 deletions LiteDB/Engine/Engine/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ public partial class LiteEngine : IDisposable
{
private Stack<LockControl> _transactions = new Stack<LockControl>();

/// <summary>
/// Get transaction stack count. If returns 0, there is no transaction.
/// </summary>
internal int TransactionCount { get { return _transactions.Count; } }

/// <summary>
/// Starts a new transaction keeping all changed from now in memory only until Commit() be executed.
/// Lock thread in write mode to not accept other transaction
Expand Down
13 changes: 11 additions & 2 deletions LiteDB/Storage/LiteFileStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ internal LiteFileStream(LiteEngine engine, LiteFileInfo file, FileAccess mode)
_file = file;
_mode = mode;

if(mode == FileAccess.Read)
if (_engine.TransactionCount > 0) throw LiteException.TransactionNotSupported("LiteFileStream");

if (mode == FileAccess.Read)
{
// initialize first data block
_currentChunkData = this.GetChunkData(_currentChunkIndex);
Expand All @@ -39,7 +41,14 @@ internal LiteFileStream(LiteEngine engine, LiteFileInfo file, FileAccess mode)
// delete chunks content if needed
if (file.Length > 0)
{
_engine.Delete(LiteStorage.CHUNKS, Query.StartsWith("_id", _file.Id + "\\"));
var index = 0;
var deleted = true;

// delete one-by-one to avoid all pages files dirty in memory
while (deleted)
{
deleted = _engine.Delete(LiteStorage.CHUNKS, LiteFileStream.GetChunckId(_file.Id, index++)); // index zero based
}
}

// clear size counters
Expand Down
3 changes: 2 additions & 1 deletion LiteDB/Storage/LiteStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace LiteDB
{
/// <summary>
/// Storage is a special collection to store files/streams.
/// Storage is a special collection to store files/streams. Transactions are not supported in Upload/Download operations.
/// </summary>
public class LiteStorage
{
Expand Down Expand Up @@ -194,6 +194,7 @@ public IEnumerable<LiteFileInfo> FindAll()
/// </summary>
public bool Delete(string id)
{
if (_engine.TransactionCount > 0) throw LiteException.TransactionNotSupported("LiteStorage.Delete");
if (id.IsNullOrWhiteSpace()) throw new ArgumentNullException("id");

// remove file reference in _files
Expand Down
6 changes: 6 additions & 0 deletions LiteDB/Utils/LiteException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class LiteException : Exception
public const int ALREADY_EXISTS_COLLECTION_NAME = 122;
public const int DATABASE_WRONG_PASSWORD = 123;
public const int READ_ONLY_DATABASE = 125;
public const int TRANSACTION_NOT_SUPPORTED = 126;

public const int INVALID_FORMAT = 200;
public const int DOCUMENT_MAX_DEPTH = 201;
Expand Down Expand Up @@ -156,6 +157,11 @@ internal static LiteException InvalidDbRef(string path)
return new LiteException(INVALID_DBREF, "Invalid value for DbRef in path \"{0}\". Value must be document like {{ $ref: \"?\", $id: ? }}", path);
}

internal static LiteException TransactionNotSupported(string method)
{
return new LiteException(TRANSACTION_NOT_SUPPORTED, "Transactions are not supported here: " + method);
}

#endregion

#region Document/Mapper Errors
Expand Down

0 comments on commit 69ae228

Please sign in to comment.