Skip to content

Commit

Permalink
Merge pull request #2454 from alexbereznikov/2451-lazy-string-interpo…
Browse files Browse the repository at this point in the history
…lation-in-ensure

Lazy string interpolation in ENSURE
  • Loading branch information
JKamsker authored Jun 4, 2024
2 parents 6be2e24 + 6ecf9e8 commit a08e330
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 52 deletions.
7 changes: 2 additions & 5 deletions LiteDB/Engine/Disk/DiskService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static LiteDB.Constants;

namespace LiteDB.Engine
Expand All @@ -29,7 +26,7 @@ internal class DiskService : IDisposable
private long _logLength;

public DiskService(
EngineSettings settings,
EngineSettings settings,
EngineState state,
int[] memorySegmentSizes)
{
Expand Down Expand Up @@ -261,7 +258,7 @@ public IEnumerable<PageBuffer> ReadFull(FileOrigin origin)

var bytesRead = stream.Read(buffer, 0, PAGE_SIZE);

ENSURE(bytesRead == PAGE_SIZE, $"ReadFull must read PAGE_SIZE bytes [{bytesRead}]");
ENSURE(bytesRead == PAGE_SIZE, "ReadFull must read PAGE_SIZE bytes [{0}]", bytesRead);

yield return new PageBuffer(buffer, 0, 0)
{
Expand Down
8 changes: 4 additions & 4 deletions LiteDB/Engine/Disk/Streams/AesStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class AesStream : Stream

private readonly byte[] _decryptedZeroes = new byte[16];

private static readonly byte[] _emptyContent = new byte[PAGE_SIZE - 1 - 16]; // 1 for aes indicator + 16 for salt
private static readonly byte[] _emptyContent = new byte[PAGE_SIZE - 1 - 16]; // 1 for aes indicator + 16 for salt

public byte[] Salt { get; }

Expand Down Expand Up @@ -111,7 +111,7 @@ public AesStream(string password, Stream stream)
// check whether bytes 32 to 64 is empty. This indicates LiteDb was unable to write encrypted 1s during last attempt.
_stream.Read(checkBuffer, 0, checkBuffer.Length);
isNew = checkBuffer.All(x => x == 0);

// reset checkBuffer and stream position
Array.Clear(checkBuffer, 0, checkBuffer.Length);
_stream.Position = 32;
Expand Down Expand Up @@ -160,7 +160,7 @@ public AesStream(string password, Stream stream)
/// </summary>
public override int Read(byte[] array, int offset, int count)
{
ENSURE(this.Position % PAGE_SIZE == 0, $"AesRead: position must be in PAGE_SIZE module. Position={this.Position}, File={_name}");
ENSURE(this.Position % PAGE_SIZE == 0, "AesRead: position must be in PAGE_SIZE module. Position={0}, File={1}", this.Position, _name);

var r = _reader.Read(array, offset, count);

Expand All @@ -181,7 +181,7 @@ public override int Read(byte[] array, int offset, int count)
public override void Write(byte[] array, int offset, int count)
{
ENSURE(count == PAGE_SIZE || count == 1, "buffer size must be PAGE_SIZE");
ENSURE(this.Position == HeaderPage.P_INVALID_DATAFILE_STATE || this.Position % PAGE_SIZE == 0, $"AesWrite: position must be in PAGE_SIZE module. Position={this.Position}, File={_name}");
ENSURE(this.Position == HeaderPage.P_INVALID_DATAFILE_STATE || this.Position % PAGE_SIZE == 0, "AesWrite: position must be in PAGE_SIZE module. Position={0}, File={1}", this.Position, _name);

_writer.Write(array, offset, count);
}
Expand Down
34 changes: 17 additions & 17 deletions LiteDB/Engine/FileReader/FileReaderV8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public IEnumerable<BsonDocument> GetDocuments(string collection)
var colID = _collections[collection];

if (!_collectionsDataPages.ContainsKey(colID)) yield break;

var dataPages = _collectionsDataPages[colID];
var uniqueIDs = new HashSet<BsonValue>();

Expand Down Expand Up @@ -156,8 +156,8 @@ public IEnumerable<BsonDocument> GetDocuments(string collection)
// empty slot
if (position == 0) continue;

ENSURE(position > 0 && length > 0, $"Invalid footer ref position {position} with length {length}");
ENSURE(position + length < PAGE_SIZE, $"Invalid footer ref position {position} with length {length}");
ENSURE(position > 0 && length > 0, "Invalid footer ref position {0} with length {1}", position, length);
ENSURE(position + length < PAGE_SIZE, "Invalid footer ref position {0} with length {1}", position, length);

// get segment slice
var segment = buffer.Slice(position, length);
Expand All @@ -183,8 +183,8 @@ public IEnumerable<BsonDocument> GetDocuments(string collection)
var nextBuffer = nextPage.Value.Buffer;

// make page validations
ENSURE(nextPage.Value.PageType == PageType.Data, $"Invalid PageType (excepted Data, get {nextPage.Value.PageType})");
ENSURE(nextPage.Value.ColID == colID, $"Invalid ColID in this page (expected {colID}, get {nextPage.Value.ColID})");
ENSURE(nextPage.Value.PageType == PageType.Data, "Invalid PageType (excepted Data, get {0})", nextPage.Value.PageType);
ENSURE(nextPage.Value.ColID == colID, "Invalid ColID in this page (expected {0}, get {1})", colID, nextPage.Value.ColID);
ENSURE(nextPage.Value.ItemsCount > 0, "Page with no items count");

// read slot address
Expand All @@ -196,15 +196,15 @@ public IEnumerable<BsonDocument> GetDocuments(string collection)
length = nextBuffer.ReadUInt16(lengthAddr);

// empty slot
ENSURE(length > 0, $"Last DataBlock request a next extend to {nextBlock}, but this block are empty footer");
ENSURE(length > 0, "Last DataBlock request a next extend to {0}, but this block are empty footer", nextBlock);

// get segment slice
segment = nextBuffer.Slice(position, length);
extend = segment.ReadBool(DataBlock.P_EXTEND);
nextBlock = segment.ReadPageAddress(DataBlock.P_NEXT_BLOCK);
data = segment.Slice(DataBlock.P_BUFFER, segment.Count - DataBlock.P_BUFFER);

ENSURE(extend == true, $"Next datablock always be an extend. Invalid data block {nextBlock}");
ENSURE(extend == true, "Next datablock always be an extend. Invalid data block {0}", nextBlock);

// write data on memorystream

Expand All @@ -219,8 +219,8 @@ public IEnumerable<BsonDocument> GetDocuments(string collection)
var docResult = r.ReadDocument();
var id = docResult.Value["_id"];

ENSURE(!(id == BsonValue.Null || id == BsonValue.MinValue || id == BsonValue.MaxValue), $"Invalid _id value: {id}");
ENSURE(uniqueIDs.Contains(id) == false, $"Duplicated _id value: {id}");
ENSURE(!(id == BsonValue.Null || id == BsonValue.MinValue || id == BsonValue.MaxValue), "Invalid _id value: {0}", id);
ENSURE(uniqueIDs.Contains(id) == false, "Duplicated _id value: {0}", id);

uniqueIDs.Add(id);

Expand Down Expand Up @@ -279,7 +279,7 @@ private void LoadDataPages()
var header = this.ReadPage(0, out var pageInfo).GetValue();
var lastPageID = header.Buffer.ReadUInt32(HeaderPage.P_LAST_PAGE_ID); //TOFO: tentar não usar esse valor como referencia (varrer tudo)

ENSURE(lastPageID <= _maxPageID, $"LastPageID {lastPageID} should be less or equals to maxPageID {_maxPageID}");
ENSURE(lastPageID <= _maxPageID, "LastPageID {0} should be less or equals to maxPageID {1}", lastPageID, _maxPageID);

for (uint i = 0; i <= lastPageID; i++)
{
Expand Down Expand Up @@ -398,8 +398,8 @@ private void LoadIndexes()

position += 15; // head 5 bytes, tail 5 bytes, reserved 1 byte, freeIndexPageList 4 bytes

ENSURE(!string.IsNullOrEmpty(name), $"Index name can't be empty (collection {collection.Key} - index: {i})");
ENSURE(!string.IsNullOrEmpty(expr), $"Index expression can't be empty (collection {collection.Key} - index: {i})");
ENSURE(!string.IsNullOrEmpty(name), "Index name can't be empty (collection {0} - index: {1})", collection.Key, i);
ENSURE(!string.IsNullOrEmpty(expr), "Index expression can't be empty (collection {0} - index: {1})", collection.Key, i);

var indexInfo = new IndexInfo
{
Expand Down Expand Up @@ -481,7 +481,7 @@ private void LoadIndexMap()
pageInfo.PageID = pageID;
pageInfo.ColID = buffer.ReadUInt32(BasePage.P_COL_ID);

ENSURE(read == PAGE_SIZE, $"Page position {_logStream} read only than {read} bytes (instead {PAGE_SIZE})");
ENSURE(read == PAGE_SIZE, "Page position {0} read only than {1} bytes (instead {2})", _logStream, read, PAGE_SIZE);

var position = new PagePosition(pageID, currentPosition);

Expand Down Expand Up @@ -515,7 +515,7 @@ private void LoadIndexMap()
{
var mapIndexPages = transactions[transactionID];

// update
// update
foreach (var page in mapIndexPages)
{
_logIndexMap[page.PageID] = page.Position;
Expand All @@ -532,7 +532,7 @@ private Result<BasePage> ReadPage(uint pageID, out PageInfo pageInfo)

try
{
ENSURE(pageID <= _maxPageID, $"PageID: {pageID} should be less then or equals to maxPageID: {_maxPageID}");
ENSURE(pageID <= _maxPageID, "PageID: {0} should be less then or equals to maxPageID: {1}", pageID, _maxPageID);

var pageBuffer = new PageBuffer(new byte[PAGE_SIZE], 0, PAGE_SIZE);
Stream stream;
Expand All @@ -556,13 +556,13 @@ private Result<BasePage> ReadPage(uint pageID, out PageInfo pageInfo)

read = stream.Read(pageBuffer.Array, pageBuffer.Offset, pageBuffer.Count);

ENSURE(read == PAGE_SIZE, $"Page position {stream.Position} read only than {read} bytes (instead {PAGE_SIZE})");
ENSURE(read == PAGE_SIZE, "Page position {0} read only than {1} bytes (instead {2})", stream.Position, read, PAGE_SIZE);

var page = new BasePage(pageBuffer);

pageInfo.ColID = page.ColID;

ENSURE(page.PageID == pageID, $"Expect read pageID: {pageID} but header contains pageID: {page.PageID}");
ENSURE(page.PageID == pageID, "Expect read pageID: {0} but header contains pageID: {1}", pageID, page.PageID);

return page;
}
Expand Down
12 changes: 6 additions & 6 deletions LiteDB/Engine/Pages/BasePage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ internal class BasePage
/// Get how many bytes are used in footer page at this moment
/// ((HighestIndex + 1) * 4 bytes per slot: [2 for position, 2 for length])
/// </summary>
public int FooterSize =>
(this.HighestIndex == byte.MaxValue ?
public int FooterSize =>
(this.HighestIndex == byte.MaxValue ?
0 : // no items in page
((this.HighestIndex + 1) * SLOT_SIZE)); // 4 bytes PER item (2 to position + 2 to length) - need consider HighestIndex used

Expand Down Expand Up @@ -282,8 +282,8 @@ public BufferSlice Get(byte index)
var position = _buffer.ReadUInt16(positionAddr);
var length = _buffer.ReadUInt16(lengthAddr);

ENSURE(this.IsValidPos(position), $"invalid segment position in index footer: {ToString()}/{index}");
ENSURE(this.IsValidLen(length), $"invalid segment length in index footer: {ToString()}/{index}");
ENSURE(this.IsValidPos(position), "invalid segment position in index footer: {0}/{1}", this, index);
ENSURE(this.IsValidLen(length), "invalid segment length in index footer: {0}/{1}", this, index);

// return buffer slice with content only data
return _buffer.Slice(position, length);
Expand Down Expand Up @@ -408,7 +408,7 @@ public void Delete(byte index)
this.NextFreePosition = position;
}
else
{
{
// if segment is in middle of the page, add this blocks as fragment block
this.FragmentedBytes += length;
}
Expand Down Expand Up @@ -475,7 +475,7 @@ public BufferSlice Update(byte index, ushort bytesLength)

if (isLastSegment)
{
// if is at end of page, must get back unused blocks
// if is at end of page, must get back unused blocks
this.NextFreePosition -= diff;
}
else
Expand Down
6 changes: 2 additions & 4 deletions LiteDB/Engine/Pages/DataPage.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static LiteDB.Constants;

namespace LiteDB.Engine
Expand All @@ -16,7 +14,7 @@ internal class DataPage : BasePage
public DataPage(PageBuffer buffer)
: base(buffer)
{
ENSURE(this.PageType == PageType.Data, $"Page type must be data page: {PageType}");
ENSURE(this.PageType == PageType.Data, "Page type must be data page: {0}", PageType);

if (this.PageType != PageType.Data) throw LiteException.InvalidPageType(PageType.Data, this);
}
Expand Down Expand Up @@ -108,7 +106,7 @@ public IEnumerable<PageAddress> GetBlocks()
/// <returns>A slot number between 0 and 4</returns>
public static byte FreeIndexSlot(int freeBytes)
{
ENSURE(freeBytes >= 0, $"FreeBytes must be positive: {freeBytes}");
ENSURE(freeBytes >= 0, "FreeBytes must be positive: {0}", freeBytes);

for (var i = 0; i < _freePageSlots.Length; i++)
{
Expand Down
2 changes: 1 addition & 1 deletion LiteDB/Engine/Services/DataService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public IEnumerable<BufferSlice> Read(PageAddress address)

while (address != PageAddress.Empty)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in data Read({address})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in data Read({0})", address);

var dataPage = _snapshot.GetPage<DataPage>(address.PageID);

Expand Down
24 changes: 12 additions & 12 deletions LiteDB/Engine/Services/IndexService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ public IndexNode AddNode(CollectionIndex index, BsonValue key, PageAddress dataB
/// Insert a new node index inside an collection index.
/// </summary>
private IndexNode AddNode(
CollectionIndex index,
BsonValue key,
PageAddress dataBlock,
byte insertLevels,
CollectionIndex index,
BsonValue key,
PageAddress dataBlock,
byte insertLevels,
IndexNode last)
{
// get a free index page for head note
Expand All @@ -108,7 +108,7 @@ private IndexNode AddNode(
// while: scan from left to right
while (right.IsEmpty == false && right != index.Tail)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in AddNode({node.Position})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in AddNode({0})", node.Position);

var rightNode = this.GetNode(right);

Expand Down Expand Up @@ -206,7 +206,7 @@ public IEnumerable<IndexNode> GetNodeList(PageAddress nodeAddress)

while (node != null)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in GetNodeList({nodeAddress})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in GetNodeList({0})", nodeAddress);

yield return node;

Expand All @@ -225,7 +225,7 @@ public void DeleteAll(PageAddress pkAddress)

while (node != null)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in DeleteAll({pkAddress})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in DeleteAll({0})", pkAddress);

this.DeleteSingleNode(node, indexes[node.Slot]);

Expand All @@ -246,7 +246,7 @@ public IndexNode DeleteList(PageAddress pkAddress, HashSet<PageAddress> toDelete

while (node != null)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in DeleteList({pkAddress})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in DeleteList({0})", pkAddress);

if (toDelete.Contains(node.Position))
{
Expand Down Expand Up @@ -333,7 +333,7 @@ public void DropIndex(CollectionIndex index)
}

#region Find

/// <summary>
/// Return all index nodes from an index
/// </summary>
Expand All @@ -344,7 +344,7 @@ public IEnumerable<IndexNode> FindAll(CollectionIndex index, int order)

while (!cur.GetNextPrev(0, order).IsEmpty)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in FindAll({index.Name})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in FindAll({0})", index.Name);

cur = this.GetNode(cur.GetNextPrev(0, order));

Expand All @@ -356,7 +356,7 @@ public IEnumerable<IndexNode> FindAll(CollectionIndex index, int order)
}

/// <summary>
/// Find first node that index match with value .
/// Find first node that index match with value .
/// If index are unique, return unique value - if index are not unique, return first found (can start, middle or end)
/// If not found but sibling = true and key are not found, returns next value index node (if order = Asc) or prev node (if order = Desc)
/// </summary>
Expand All @@ -371,7 +371,7 @@ public IndexNode Find(CollectionIndex index, BsonValue value, bool sibling, int

while (right.IsEmpty == false)
{
ENSURE(counter++ < _maxItemsCount, $"Detected loop in Find({index.Name}, {value})");
ENSURE(counter++ < _maxItemsCount, "Detected loop in Find({0}, {1})", index.Name, value);

var rightNode = this.GetNode(right);

Expand Down
6 changes: 3 additions & 3 deletions LiteDB/Engine/Services/TransactionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public Snapshot CreateSnapshot(LockMode mode, string collection, bool addIfNotEx
_snapshots[collection] = snapshot = create();
}

// update transaction mode to write in first write snaphost request
// update transaction mode to write in first write snaphost request
if (mode == LockMode.Write) _mode = LockMode.Write;

return snapshot;
Expand Down Expand Up @@ -250,7 +250,7 @@ IEnumerable<PageBuffer> source()
/// </summary>
public void Commit()
{
ENSURE(_state == TransactionState.Active, $"transaction must be active to commit (current state: {_state})");
ENSURE(_state == TransactionState.Active, "transaction must be active to commit (current state: {0})", _state);

LOG($"commit transaction ({_transPages.TransactionSize} pages)", "TRANSACTION");

Expand Down Expand Up @@ -281,7 +281,7 @@ public void Commit()
/// </summary>
public void Rollback()
{
ENSURE(_state == TransactionState.Active, $"transaction must be active to rollback (current state: {_state})");
ENSURE(_state == TransactionState.Active, "transaction must be active to rollback (current state: {0})", _state);

LOG($"rollback transaction ({_transPages.TransactionSize} pages with {_transPages.NewPages.Count} returns)", "TRANSACTION");

Expand Down
Loading

0 comments on commit a08e330

Please sign in to comment.