Skip to content

Commit

Permalink
Small refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
z4kn4fein committed Mar 11, 2017
1 parent 05ade00 commit a0f26b3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
artifact: /.*\.nupkg/

environment:
build_version: 2.2.1
build_version: 2.2.2
COVERALLS_REPO_TOKEN:
secure: Q9gcbZnzJ5a0YYF6mkr4QoQylIzeQmVytMnIe4WL7aPtb30SdNes7brLkvnXOirt

Expand Down Expand Up @@ -79,7 +79,7 @@
secure: 2bITagXOj2s3bTJaGXh8/iyWtST8OQOFaMM+0GAKgZts9OjCVCiV7C+E/0SYsM6M

environment:
build_version: 2.2.1
build_version: 2.2.2
COVERALLS_REPO_TOKEN:
secure: Q9gcbZnzJ5a0YYF6mkr4QoQylIzeQmVytMnIe4WL7aPtb30SdNes7brLkvnXOirt

Expand Down
2 changes: 1 addition & 1 deletion src/stashbox/BuildUp/Expressions/Compile/DelegateTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal static class DelegateTargetSelector
{
private static int TypeCounter;

private static readonly ConcurrentTree<int, Type> TargetTypes = new ConcurrentTree<int, Type>();
private static readonly ConcurrentTree<Type> TargetTypes = new ConcurrentTree<Type>();

private static Type GetOrAddTargetType(Constants constants)
{
Expand Down
66 changes: 62 additions & 4 deletions src/stashbox/Utils/ConcurrentTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ConcurrentTree<TKey, TValue> : IEnumerable<TValue>
/// <returns>A new tree instance</returns>
public static ConcurrentTree<TKey, TValue> Create() => new ConcurrentTree<TKey, TValue>();

private AvlTree<TValue> repository;
private ConcurrentTree<TValue> repository;

/// <summary>
/// The current root value of the tree,
Expand All @@ -35,7 +35,7 @@ public class ConcurrentTree<TKey, TValue> : IEnumerable<TValue>
/// </summary>
public ConcurrentTree()
{
this.repository = new AvlTree<TValue>();
this.repository = ConcurrentTree<TValue>.Create();
}

/// <summary>
Expand All @@ -59,12 +59,70 @@ public TValue GetOrDefault(TKey key)
public ConcurrentTree<TKey, TValue> AddOrUpdate(TKey key, TValue value, Func<TValue, TValue, TValue> updateDelegate = null)
{
var hash = key.GetHashCode();
this.repository.AddOrUpdate(hash, value, updateDelegate);
return this;
}

/// <inheritdoc />
public IEnumerator<TValue> GetEnumerator() => this.repository.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => this.repository.GetEnumerator();
}

/// <summary>
/// Represents an immutable AVL tree
/// </summary>
/// <typeparam name="TValue">The type of the value.</typeparam>
public class ConcurrentTree<TValue> : IEnumerable<TValue>
{
/// <summary>
/// Static factory method.
/// </summary>
/// <returns>A new tree instance</returns>
public static ConcurrentTree<TValue> Create() => new ConcurrentTree<TValue>();

private AvlTree<TValue> repository;

/// <summary>
/// The current root value of the tree,
/// </summary>
public TValue Value => this.repository.Value;

/// <summary>
/// Inidicates that the tree has more nodes than the root one.
/// </summary>
public bool HasMultipleItems => this.repository.HasMultipleItems;

/// <summary>
/// Constructs the <see cref="ConcurrentTree{TKey, TValue}"/>
/// </summary>
public ConcurrentTree()
{
this.repository = new AvlTree<TValue>();
}

/// <summary>
/// Returns with the value specified by the given key if it's exist, otherwise it's default value will be returned.
/// </summary>
/// <param name="key">The key of the entry.</param>
/// <returns>The found or the default value.</returns>
public TValue GetOrDefault(int key) =>
this.repository.GetOrDefault(key);

/// <summary>
/// Inserts an item into the tree if it doesn't exist, otherwise the existing item will be replaced if the update delegate is set.
/// </summary>
/// <param name="key">The key of the entry.</param>
/// <param name="value">The value which will be inserted if it doesn't exist yet.</param>
/// <param name="updateDelegate">The update delegate which will be invoked when the value is already stored on the tree.</param>
/// <returns>The modified tree.</returns>
public ConcurrentTree<TValue> AddOrUpdate(int key, TValue value, Func<TValue, TValue, TValue> updateDelegate = null)
{
var currentRepo = this.repository;
var newRepo = this.repository.AddOrUpdate(hash, value, updateDelegate);
var newRepo = this.repository.AddOrUpdate(key, value, updateDelegate);

if (!this.TrySwapCurrentRepository(currentRepo, newRepo))
this.SwapCurrentRepository(repo => repo.AddOrUpdate(hash, value, updateDelegate));
this.SwapCurrentRepository(repo => repo.AddOrUpdate(key, value, updateDelegate));

return this;
}
Expand Down

0 comments on commit a0f26b3

Please sign in to comment.