Skip to content

Commit

Permalink
Lazy evaluation of ChildrenContainer.Children
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffCyr committed Mar 11, 2016
1 parent 88e7131 commit 0103fa9
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 20 deletions.
12 changes: 6 additions & 6 deletions src/core/Akka.API.Tests/CoreAPISpec.ApproveCore.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1769,11 +1769,11 @@ namespace Akka.Actor.Internal
public abstract class ChildrenContainerBase : Akka.Actor.Internal.IChildrenContainer
{
protected ChildrenContainerBase(System.Collections.Immutable.IImmutableDictionary<string, Akka.Actor.Internal.IChildStats> children) { }
public System.Collections.Generic.IReadOnlyList<Akka.Actor.IInternalActorRef> Children { get; }
public System.Collections.Generic.IReadOnlyCollection<Akka.Actor.IInternalActorRef> Children { get; }
protected System.Collections.Immutable.IImmutableDictionary<string, Akka.Actor.Internal.IChildStats> InternalChildren { get; }
public virtual bool IsNormal { get; }
public virtual bool IsTerminating { get; }
public System.Collections.Generic.IReadOnlyList<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
public System.Collections.Generic.IReadOnlyCollection<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
public abstract Akka.Actor.Internal.IChildrenContainer Add(string name, Akka.Actor.Internal.ChildRestartStats stats);
protected void ChildStatsAppender(System.Text.StringBuilder sb, System.Collections.Generic.KeyValuePair<string, Akka.Actor.Internal.IChildStats> kvp, int index) { }
public bool Contains(Akka.Actor.IActorRef actor) { }
Expand All @@ -1796,11 +1796,11 @@ namespace Akka.Actor.Internal
public class EmptyChildrenContainer : Akka.Actor.Internal.IChildrenContainer
{
protected EmptyChildrenContainer() { }
public System.Collections.Generic.IReadOnlyList<Akka.Actor.IInternalActorRef> Children { get; }
public System.Collections.Generic.IReadOnlyCollection<Akka.Actor.IInternalActorRef> Children { get; }
public static Akka.Actor.Internal.IChildrenContainer Instance { get; }
public virtual bool IsNormal { get; }
public virtual bool IsTerminating { get; }
public System.Collections.Generic.IReadOnlyList<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
public System.Collections.Generic.IReadOnlyCollection<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
public virtual Akka.Actor.Internal.IChildrenContainer Add(string name, Akka.Actor.Internal.ChildRestartStats stats) { }
public bool Contains(Akka.Actor.IActorRef actor) { }
public Akka.Actor.Internal.IChildrenContainer Remove(Akka.Actor.IActorRef child) { }
Expand All @@ -1813,10 +1813,10 @@ namespace Akka.Actor.Internal
}
public interface IChildrenContainer
{
System.Collections.Generic.IReadOnlyList<Akka.Actor.IInternalActorRef> Children { get; }
System.Collections.Generic.IReadOnlyCollection<Akka.Actor.IInternalActorRef> Children { get; }
bool IsNormal { get; }
bool IsTerminating { get; }
System.Collections.Generic.IReadOnlyList<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
System.Collections.Generic.IReadOnlyCollection<Akka.Actor.Internal.ChildRestartStats> Stats { get; }
Akka.Actor.Internal.IChildrenContainer Add(string name, Akka.Actor.Internal.ChildRestartStats stats);
bool Contains(Akka.Actor.IActorRef actor);
Akka.Actor.Internal.IChildrenContainer Remove(Akka.Actor.IActorRef child);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ public interface IChildrenContainer
IChildrenContainer Remove(IActorRef child);
bool TryGetByName(string name, out IChildStats stats);
bool TryGetByRef(IActorRef actor, out ChildRestartStats stats);
IReadOnlyList<IInternalActorRef> Children { get; }
IReadOnlyList<ChildRestartStats> Stats { get; }
IReadOnlyCollection<IInternalActorRef> Children { get; }
IReadOnlyCollection<ChildRestartStats> Stats { get; }
IChildrenContainer ShallDie(IActorRef actor);
IChildrenContainer Reserve(string name);
IChildrenContainer Unreserve(string name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// </copyright>
//-----------------------------------------------------------------------

using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
Expand All @@ -15,6 +16,41 @@ namespace Akka.Actor.Internal
{
public abstract class ChildrenContainerBase : IChildrenContainer
{
private class LazyReadOnlyCollection<T> : IReadOnlyCollection<T>
{
private readonly IEnumerable<T> _enumerable;
private int _lazyCount;

public int Count
{
get
{
int count = _lazyCount;

if (count == -1)
_lazyCount = count = _enumerable.Count();

return count;
}
}

public LazyReadOnlyCollection(IEnumerable<T> enumerable)
{
_enumerable = enumerable;
_lazyCount = -1;
}

public IEnumerator<T> GetEnumerator()
{
return _enumerable.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}

private readonly IImmutableDictionary<string, IChildStats> _children;

protected ChildrenContainerBase(IImmutableDictionary<string, IChildStats> children)
Expand All @@ -30,25 +66,26 @@ protected ChildrenContainerBase(IImmutableDictionary<string, IChildStats> childr
public abstract IChildrenContainer ShallDie(IActorRef actor);
public abstract IChildrenContainer Unreserve(string name);

public IReadOnlyList<IInternalActorRef> Children
public IReadOnlyCollection<IInternalActorRef> Children
{
get
{
return (from stat in InternalChildren.Values
let childRestartStats = stat as ChildRestartStats
where childRestartStats != null
select childRestartStats.Child).ToList();
var children = InternalChildren.Values
.OfType<ChildRestartStats>()
.Select(item => item.Child);

// The children collection must stay lazy evaluated
return new LazyReadOnlyCollection<IInternalActorRef>(children);
}
}

public IReadOnlyList<ChildRestartStats> Stats
public IReadOnlyCollection<ChildRestartStats> Stats
{
get
{
return (from stat in InternalChildren.Values
let childRestartStats = stat as ChildRestartStats
where childRestartStats != null
select childRestartStats).ToList();
var children = InternalChildren.Values.OfType<ChildRestartStats>();

return new LazyReadOnlyCollection<ChildRestartStats>(children);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public bool Contains(IActorRef actor)
return false;
}

public IReadOnlyList<IInternalActorRef> Children { get { return ImmutableList<IInternalActorRef>.Empty; } }
public IReadOnlyCollection<IInternalActorRef> Children { get { return ImmutableList<IInternalActorRef>.Empty; } }

public IReadOnlyList<ChildRestartStats> Stats { get { return ImmutableList<ChildRestartStats>.Empty; } }
public IReadOnlyCollection<ChildRestartStats> Stats { get { return ImmutableList<ChildRestartStats>.Empty; } }

public IChildrenContainer ShallDie(IActorRef actor)
{
Expand Down

0 comments on commit 0103fa9

Please sign in to comment.