Skip to content

Commit

Permalink
Use a Stack for VisitEntries
Browse files Browse the repository at this point in the history
Avoid recursion and multiple List allocations
  • Loading branch information
jeremy-visionaid committed Oct 6, 2024
1 parent 8fd145c commit 8960aa2
Showing 1 changed file with 13 additions and 24 deletions.
37 changes: 13 additions & 24 deletions sources/OpenMcdf/CFStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -423,34 +423,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

0 comments on commit 8960aa2

Please sign in to comment.