Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 17 additions & 24 deletions LiteDB/Engine/Engine/Rebuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,52 +46,45 @@ public long Rebuild()
return this.Rebuild(new RebuildOptions { Password = password, Collation = collation });
}

/// <summary>
/// Fill current database with data inside file reader - run inside a transacion
/// </summary>
internal void RebuildContent(IFileReader reader)
{
// begin transaction and get TransactionID
var transaction = _monitor.GetTransaction(true, false, out _);
RebuildContent(reader, _disk.MAX_ITEMS_COUNT);
}

internal void RebuildContent(IFileReader reader, uint maxItemsCount)
{
var transaction = _monitor.GetTransaction(create: true, queryOnly: false, out _);

try
{
foreach (var collection in reader.GetCollections())
{
// get snapshot, indexer and data services
var snapshot = transaction.CreateSnapshot(LockMode.Write, collection, true);
var indexer = new IndexService(snapshot, _header.Pragmas.Collation, _disk.MAX_ITEMS_COUNT);
var data = new DataService(snapshot, _disk.MAX_ITEMS_COUNT);
var snapshot = transaction.CreateSnapshot(LockMode.Write, collection, addIfNotExists: true);

// get all documents from current collection
var docs = reader.GetDocuments(collection);
var indexer = new IndexService(snapshot, _header.Pragmas.Collation, maxItemsCount);
var data = new DataService(snapshot, maxItemsCount);

// insert one-by-one
foreach (var doc in docs)
foreach (var doc in reader.GetDocuments(collection))
{
transaction.Safepoint();

this.InsertDocument(snapshot, doc, BsonAutoId.ObjectId, indexer, data);
InsertDocument(snapshot, doc, BsonAutoId.ObjectId, indexer, data);
}

// first create all user indexes (exclude _id index)
foreach (var index in reader.GetIndexes(collection))
foreach (var idx in reader.GetIndexes(collection))
{
this.EnsureIndex(collection,
index.Name,
BsonExpression.Create(index.Expression),
index.Unique);
EnsureIndex(collection,
idx.Name,
BsonExpression.Create(idx.Expression),
idx.Unique);
}
}

transaction.Commit();

_monitor.ReleaseTransaction(transaction);
}
catch (Exception ex)
{
this.Close(ex);

Close(ex);
throw;
}
}
Expand Down
18 changes: 16 additions & 2 deletions LiteDB/Engine/Services/RebuildService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using static LiteDB.Constants;

namespace LiteDB.Engine
Expand Down Expand Up @@ -37,6 +38,16 @@ public RebuildService(EngineSettings settings)
_fileVersion = FileReaderV8.IsVersion(buffer) ? 8 : throw LiteException.InvalidDatabase();
}

private static uint GetSourceMaxItemsCount(EngineSettings settings)
{
long dataBytes = new FileInfo(settings.Filename).Length;

var logFile = FileHelper.GetLogFile(settings.Filename);
long logBytes = File.Exists(logFile) ? new FileInfo(logFile).Length : 0;
// ((pages in data+log) + 10) * 255
return (uint)((((dataBytes + logBytes) / PAGE_SIZE) + 10) * byte.MaxValue);
}

public long Rebuild(RebuildOptions options)
{
var backupFilename = FileHelper.GetSuffixFile(_settings.Filename, "-backup", true);
Expand All @@ -62,8 +73,11 @@ public long Rebuild(RebuildOptions options)
// copy all database to new Log file with NO checkpoint during all rebuild
engine.Pragma(Pragmas.CHECKPOINT, 0);

// compute the correct MAX_ITEMS_COUNT from the *source* file
uint maxItemsCount = GetSourceMaxItemsCount(_settings);

// rebuild all content from reader into new engine
engine.RebuildContent(reader);
engine.RebuildContent(reader, maxItemsCount);

// insert error report
if (options.IncludeErrorReport && options.Errors.Count > 0)
Expand Down Expand Up @@ -106,7 +120,7 @@ public long Rebuild(RebuildOptions options)


// get difference size
return
return
new FileInfo(backupFilename).Length -
new FileInfo(_settings.Filename).Length;
}
Expand Down