Skip to content
Merged
Changes from all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -119,31 +119,30 @@ internal int GetPropertyCount(Cursor current)

internal CompactPath CreateCompactPath(Cursor current)
{
var firstRow = _metaDb.Get(current);

// Stop at root via IsRoot flag.
if ((_metaDb.GetFlags(current) & ElementFlags.IsRoot) == ElementFlags.IsRoot)
if ((firstRow.Flags & ElementFlags.IsRoot) == ElementFlags.IsRoot)
{
return CompactPath.Root;
}

Span<Cursor> chain = stackalloc Cursor[64];
Span<DbRow> rows = stackalloc DbRow[64];
var c = current;
var written = 0;
chain[0] = current;
rows[0] = firstRow;
var written = 1;

while (true)
var parentIndex = firstRow.ParentRow;
while (parentIndex > 0)
{
var row = _metaDb.Get(c);
chain[written] = c;
var cursor = Cursor.FromIndex(parentIndex);
var row = _metaDb.Get(cursor);
chain[written] = cursor;
rows[written] = row;
written++;

var parentIndex = row.ParentRow;
if (parentIndex <= 0)
{
break;
}

c = Cursor.FromIndex(parentIndex);
parentIndex = row.ParentRow;

if (written >= 64)
{
Expand All @@ -157,7 +156,7 @@ internal CompactPath CreateCompactPath(Cursor current)

for (var i = written - 1; i >= 0; i--)
{
c = chain[i];
var cursor = chain[i];
var tokenType = rows[i].TokenType;

if (tokenType == ElementTokenType.PropertyName)
Expand All @@ -173,8 +172,8 @@ internal CompactPath CreateCompactPath(Cursor current)
if (parentTokenType is ElementTokenType.StartArray)
{
// arrayIndex = abs(child) - (abs(parent) + 1)
var absChild = (c.Chunk * Cursor.RowsPerChunk) + c.Row;
var absParent = parentCursor.Chunk * Cursor.RowsPerChunk + parentCursor.Row;
var absChild = (cursor.Chunk * Cursor.RowsPerChunk) + cursor.Row;
var absParent = (parentCursor.Chunk * Cursor.RowsPerChunk) + parentCursor.Row;
var arrayIndex = absChild - (absParent + 1);
path.AppendIndex(arrayIndex);
}
Expand All @@ -199,25 +198,27 @@ internal CompositeResultElement GetParent(Cursor current)
}

var parent = _metaDb.GetParentCursor(current);
var parentRow = _metaDb.Get(parent);

// if the parent element is a property name then we must get the parent of that,
// as property name and value represent the same element.
if (_metaDb.GetElementTokenType(parent) is ElementTokenType.PropertyName)
if (parentRow.TokenType is ElementTokenType.PropertyName)
{
parent = _metaDb.GetParentCursor(parent);
parent = Cursor.FromIndex(parentRow.ParentRow);
parentRow = _metaDb.Get(parent);
}

// if we have not yet reached the root and the element type of the parent is an object or an array
// then we need to get still the parent of this row as we want to get the logical parent
// which is the value level of the property or the element in an array.
if (parent != Cursor.Zero
&& _metaDb.GetElementTokenType(parent) is ElementTokenType.StartObject or ElementTokenType.StartArray)
&& parentRow.TokenType is ElementTokenType.StartObject or ElementTokenType.StartArray)
{
parent = _metaDb.GetParentCursor(parent);
parent = Cursor.FromIndex(parentRow.ParentRow);

// in this case the parent must be a reference, otherwise we would have
// found an inconsistency in the database.
Debug.Assert(_metaDb.GetElementTokenType(parent, resolveReferences: false) == ElementTokenType.Reference);
Debug.Assert(_metaDb.Get(parent).TokenType == ElementTokenType.Reference);
}

return new CompositeResultElement(this, parent);
Expand All @@ -227,23 +228,20 @@ internal bool IsInvalidated(Cursor current)
{
ObjectDisposedException.ThrowIf(_disposed, this);

var tokenType = _metaDb.GetElementTokenType(current, resolveReferences: false);
var row = _metaDb.Get(current);

if (tokenType is ElementTokenType.StartObject)
if (row.TokenType is ElementTokenType.StartObject)
{
var flags = _metaDb.GetFlags(current);
return (flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
return (row.Flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
}

if (tokenType is ElementTokenType.Reference)
if (row.TokenType is ElementTokenType.Reference)
{
current = _metaDb.GetLocationCursor(current);
tokenType = _metaDb.GetElementTokenType(current);
row = _metaDb.Get(Cursor.FromIndex(row.Location));

if (tokenType is ElementTokenType.StartObject)
if (row.TokenType is ElementTokenType.StartObject)
{
var flags = _metaDb.GetFlags(current);
return (flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
return (row.Flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
}
}

Expand All @@ -254,29 +252,21 @@ internal bool IsNullOrInvalidated(Cursor current)
{
ObjectDisposedException.ThrowIf(_disposed, this);

var tokenType = _metaDb.GetElementTokenType(current);
var row = _metaDb.Get(current);

if (tokenType is ElementTokenType.Null)
if (row.TokenType is ElementTokenType.Null)
{
return true;
}

if (tokenType is ElementTokenType.StartObject)
if (row.TokenType is ElementTokenType.Reference)
{
var flags = _metaDb.GetFlags(current);
return (flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
row = _metaDb.Get(Cursor.FromIndex(row.Location));
}

if (tokenType is ElementTokenType.Reference)
if (row.TokenType is ElementTokenType.StartObject)
{
current = _metaDb.GetLocationCursor(current);
tokenType = _metaDb.GetElementTokenType(current);

if (tokenType is ElementTokenType.StartObject)
{
var flags = _metaDb.GetFlags(current);
return (flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
}
return (row.Flags & ElementFlags.Invalidated) == ElementFlags.Invalidated;
}

return false;
Expand All @@ -296,36 +286,22 @@ internal void Invalidate(Cursor current)
{
ObjectDisposedException.ThrowIf(_disposed, this);

var tokenType = _metaDb.GetElementTokenType(current, resolveReferences: false);

if (tokenType is ElementTokenType.None)
{
return;
}
var row = _metaDb.Get(current);

if (tokenType is ElementTokenType.StartArray)
if (row.TokenType is ElementTokenType.Reference)
{
return;
current = Cursor.FromIndex(row.Location);
row = _metaDb.Get(current);
}

if (tokenType is ElementTokenType.StartObject)
if (row.TokenType is ElementTokenType.None or ElementTokenType.StartArray)
{
var flags = _metaDb.GetFlags(current);
_metaDb.SetFlags(current, flags | ElementFlags.Invalidated);
return;
}

if (tokenType is ElementTokenType.Reference)
if (row.TokenType is ElementTokenType.StartObject)
{
current = _metaDb.GetLocationCursor(current);
tokenType = _metaDb.GetElementTokenType(current);

if (tokenType is ElementTokenType.StartObject)
{
var flags = _metaDb.GetFlags(current);
_metaDb.SetFlags(current, flags | ElementFlags.Invalidated);
}

_metaDb.SetFlags(current, row.Flags | ElementFlags.Invalidated);
return;
}

Expand Down
Loading