Skip to content

Commit

Permalink
Merge pull request #182 from Visionaid-International-Ltd/stack
Browse files Browse the repository at this point in the history
Use Stack for VisitEntries and enumerating RBTree
  • Loading branch information
ironfede authored Oct 7, 2024
2 parents d9fbc1f + 8960aa2 commit 634ba16
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 32 deletions.
37 changes: 13 additions & 24 deletions sources/OpenMcdf/CFStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,34 +409,23 @@ public void VisitEntries(Action<CFItem> action, bool recursive)
{
CheckDisposed();

if (action != null)
{
List<IRBNode> subStorages
= new List<IRBNode>();

Action<IRBNode> internalAction =
delegate (IRBNode targetNode)
{
IDirectoryEntry d = targetNode as IDirectoryEntry;
if (d.StgType == StgType.StgStream)
action(new CFStream(CompoundFile, d));
else
action(new CFStorage(CompoundFile, d));
if (action is null)
return; // TODO: Reorder and throw ArgumentNullException in v3

if (d.Child != DirectoryEntry.NOSTREAM)
subStorages.Add(targetNode);
Stack<CFItem> stack = new();
stack.Push(this);

return;
};

Children.VisitTree(internalAction);

if (recursive && subStorages.Count > 0)
while (stack.Count > 0)
{
CFItem current = stack.Pop();
if (current is CFStorage storage)
{
foreach (IRBNode n in subStorages)
foreach (IDirectoryEntry de in storage.Children.Cast<IDirectoryEntry>())
{
IDirectoryEntry d = n as IDirectoryEntry;
new CFStorage(CompoundFile, d).VisitEntries(action, recursive);
CFItem item = de.StgType == StgType.StgStream ? new CFStream(CompoundFile, de) : new CFStorage(CompoundFile, de);
action(item);
if (recursive)
stack.Push(item);
}
}
}
Expand Down
32 changes: 24 additions & 8 deletions sources/OpenMcdf/RBTree/RBTreeEnumerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,47 @@ public partial class RBTree
// TODO: Make internal in v3 (can seal in v2 since constructor is internal)
public sealed class RBTreeEnumerator : IEnumerator<IRBNode>
{
private readonly List<IRBNode> list = new();
int position = -1;
private readonly IRBNode root;
private readonly Stack<IRBNode> stack = new();

internal RBTreeEnumerator(RBTree tree)
{
tree.VisitTree(item => list.Add(item));
root = tree.Root;
PushLeft(root);
}

public void Dispose()
{
}

public IRBNode Current => list[position];
public IRBNode Current { get; private set; }

object IEnumerator.Current => list[position];
object IEnumerator.Current => Current;

public bool MoveNext()
{
position++;
return position < list.Count;
if (stack.Count == 0)
return false;

Current = stack.Pop();
PushLeft(Current.Right);
return true;
}

public void Reset()
{
position = -1;
Current = null;
stack.Clear();
PushLeft(root);
}

private void PushLeft(IRBNode node)
{
while (node is not null)
{
stack.Push(node);
node = node.Left;
}
}
}
}
Expand Down

0 comments on commit 634ba16

Please sign in to comment.