Skip to content

Commit 02714c7

Browse files
author
electricessence
committed
IRecyclable
Added IRecylable interface since it's much easier to internally define what is required for recycling. Added static methods to accomodate. Redefined Recycler to only be created by an extension of IObjectPool<T>.
1 parent 0b8eb4e commit 02714c7

10 files changed

Lines changed: 197 additions & 59 deletions

source/Array/InterlockedArrayObjectPool.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,20 @@ public static InterlockedArrayObjectPool<T> Create<T>(int capacity = Constants.D
8585
{
8686
return Create(() => new T(), capacity);
8787
}
88+
89+
public static InterlockedArrayObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
90+
where T : class, IRecyclable
91+
{
92+
Action<T> recycler = null;
93+
if (autoRecycle) recycler = Recycler.Recycle;
94+
return new InterlockedArrayObjectPool<T>(factory, recycler, capacity);
95+
}
96+
97+
public static InterlockedArrayObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
98+
where T : class, IRecyclable, new()
99+
{
100+
return Create(() => new T(), autoRecycle, capacity);
101+
}
102+
88103
}
89104
}

source/Array/OptimisticArrayObjectPool.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,20 @@ public static OptimisticArrayObjectPool<T> Create<T>(int capacity = Constants.DE
6262
{
6363
return Create(() => new T(), capacity);
6464
}
65+
66+
public static OptimisticArrayObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
67+
where T : class, IRecyclable
68+
{
69+
Action<T> recycler = null;
70+
if (autoRecycle) recycler = Recycler.Recycle;
71+
return new OptimisticArrayObjectPool<T>(factory, recycler, capacity);
72+
}
73+
74+
public static OptimisticArrayObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
75+
where T : class, IRecyclable, new()
76+
{
77+
return Create(() => new T(), autoRecycle, capacity);
78+
}
79+
6580
}
6681
}

source/Collection/ConcurrentQueueObjectPool.cs

Lines changed: 65 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44
namespace Open.Disposable
55
{
66
public sealed class ConcurrentQueueObjectPool<T> : TrimmableObjectPoolBase<T>
7-
where T : class
8-
{
7+
where T : class
8+
{
99

10-
public ConcurrentQueueObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
11-
: base(factory, recycler, capacity)
12-
{
13-
Pool = new ConcurrentQueue<T>();
14-
}
10+
public ConcurrentQueueObjectPool(Func<T> factory, Action<T> recycler, int capacity = DEFAULT_CAPACITY)
11+
: base(factory, recycler, capacity)
12+
{
13+
Pool = new ConcurrentQueue<T>();
14+
}
1515

16-
public ConcurrentQueueObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
17-
: this(factory, null, capacity)
18-
{
19-
20-
}
16+
public ConcurrentQueueObjectPool(Func<T> factory, int capacity = DEFAULT_CAPACITY)
17+
: this(factory, null, capacity)
18+
{
2119

22-
ConcurrentQueue<T> Pool;
20+
}
2321

24-
public override int Count => Pool?.Count ?? 0;
22+
ConcurrentQueue<T> Pool;
23+
24+
public override int Count => Pool?.Count ?? 0;
2525

2626
// For ConcurrentQueue disable using the Pocket. It's fast enough as it is...
2727
protected override bool SaveToPocket(T item)
@@ -35,40 +35,55 @@ protected override T TakeFromPocket()
3535
}
3636

3737
protected override bool Receive(T item)
38-
{
39-
var p = Pool;
40-
if (p == null) return false;
41-
p.Enqueue(item); // It's possible that the count could exceed MaxSize here, but the risk is negligble as a few over the limit won't hurt.
42-
return true;
43-
}
44-
45-
protected override T TryRelease()
46-
{
47-
var p = Pool;
48-
if (p == null) return null;
49-
p.TryDequeue(out T item);
50-
return item;
51-
}
52-
53-
protected override void OnDispose(bool calledExplicitly)
54-
{
55-
Pool = null;
56-
}
57-
58-
}
59-
60-
public static class ConcurrentQueueObjectPool
61-
{
62-
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
63-
where T : class
64-
{
65-
return new ConcurrentQueueObjectPool<T>(factory, capacity);
66-
}
67-
68-
public static ConcurrentQueueObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
69-
where T : class, new()
70-
{
71-
return Create(() => new T(), capacity);
72-
}
73-
}
38+
{
39+
var p = Pool;
40+
if (p == null) return false;
41+
p.Enqueue(item); // It's possible that the count could exceed MaxSize here, but the risk is negligble as a few over the limit won't hurt.
42+
return true;
43+
}
44+
45+
protected override T TryRelease()
46+
{
47+
var p = Pool;
48+
if (p == null) return null;
49+
p.TryDequeue(out T item);
50+
return item;
51+
}
52+
53+
protected override void OnDispose(bool calledExplicitly)
54+
{
55+
Pool = null;
56+
}
57+
58+
}
59+
60+
public static class ConcurrentQueueObjectPool
61+
{
62+
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, int capacity = Constants.DEFAULT_CAPACITY)
63+
where T : class
64+
{
65+
return new ConcurrentQueueObjectPool<T>(factory, capacity);
66+
}
67+
68+
69+
public static ConcurrentQueueObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPACITY)
70+
where T : class, new()
71+
{
72+
return Create(() => new T(), capacity);
73+
}
74+
75+
public static ConcurrentQueueObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
76+
where T : class, IRecyclable
77+
{
78+
Action<T> recycler = null;
79+
if (autoRecycle) recycler = Recycler.Recycle;
80+
return new ConcurrentQueueObjectPool<T>(factory, recycler, capacity);
81+
}
82+
83+
public static ConcurrentQueueObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
84+
where T : class, IRecyclable, new()
85+
{
86+
return Create(() => new T(), autoRecycle, capacity);
87+
}
88+
}
7489
}

source/Collection/ConcurrentStackObjectPool.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,20 @@ public static ConcurrentStackObjectPool<T> Create<T>(int capacity = Constants.DE
6161
{
6262
return Create(() => new T(), capacity);
6363
}
64-
}
64+
65+
public static ConcurrentStackObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
66+
where T : class, IRecyclable
67+
{
68+
Action<T> recycler = null;
69+
if (autoRecycle) recycler = Recycler.Recycle;
70+
return new ConcurrentStackObjectPool<T>(factory, recycler, capacity);
71+
}
72+
73+
public static ConcurrentStackObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
74+
where T : class, IRecyclable, new()
75+
{
76+
return Create(() => new T(), autoRecycle, capacity);
77+
}
78+
79+
}
6580
}

source/Collection/QueueObjectPool.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,20 @@ public static QueueObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPA
7373
{
7474
return Create(() => new T(), capacity);
7575
}
76-
}
76+
77+
public static QueueObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
78+
where T : class, IRecyclable
79+
{
80+
Action<T> recycler = null;
81+
if (autoRecycle) recycler = Recycler.Recycle;
82+
return new QueueObjectPool<T>(factory, recycler, capacity);
83+
}
84+
85+
public static QueueObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
86+
where T : class, IRecyclable, new()
87+
{
88+
return Create(() => new T(), autoRecycle, capacity);
89+
}
90+
91+
}
7792
}

source/Collection/StackObjectPool.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,20 @@ public static StackObjectPool<T> Create<T>(int capacity = Constants.DEFAULT_CAPA
7373
{
7474
return Create(() => new T(), capacity);
7575
}
76-
}
76+
77+
public static StackObjectPool<T> Create<T>(Func<T> factory, bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
78+
where T : class, IRecyclable
79+
{
80+
Action<T> recycler = null;
81+
if (autoRecycle) recycler = Recycler.Recycle;
82+
return new StackObjectPool<T>(factory, recycler, capacity);
83+
}
84+
85+
public static StackObjectPool<T> Create<T>(bool autoRecycle, int capacity = Constants.DEFAULT_CAPACITY)
86+
where T : class, IRecyclable, new()
87+
{
88+
return Create(() => new T(), autoRecycle, capacity);
89+
}
90+
91+
}
7792
}

source/Constants.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ namespace Open.Disposable
66
{
77
internal static class Constants
88
{
9-
internal const int DEFAULT_CAPACITY = 65535;
9+
internal const int DEFAULT_CAPACITY = 128; // Should accomodate all object pools without decreasing their effectiveness.
1010
}
1111
}

source/IRecyclable.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Open.Disposable
6+
{
7+
public interface IRecyclable
8+
{
9+
void Recycle();
10+
}
11+
}

source/Open.Disposable.ObjectPools.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ Part of the "Open" set of libraries.</Description>
1616
<RepositoryType>git</RepositoryType>
1717
<PackageTags>objectpool, dotnet, dotnetcore, cs, idisposable, threadsafe, thread-safe</PackageTags>
1818
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
19-
<Version>1.1.0</Version>
19+
<Version>1.2.0</Version>
2020
<AssemblyVersion>1.1.0.0</AssemblyVersion>
2121
<FileVersion>1.1.0.0</FileVersion>
22-
<PackageReleaseNotes>Removed pools that are simply too slow for real world use and migrated to separate branch since they are simply not worth</PackageReleaseNotes>
22+
<PackageReleaseNotes>Added IRecylable interface since it's much easier to internally define what is required for recycling.
23+
Added static methods to accomodate.
24+
Redefined Recycler to only be created by an extension of IObjectPool&lt;T&gt;.</PackageReleaseNotes>
2325
</PropertyGroup>
2426

2527
<ItemGroup>

source/Recycler.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ public class Recycler<T> : DisposableBase
1414
IObjectPool<T> _target;
1515
ActionBlock<T> _bin;
1616

17-
public Recycler(
17+
internal Recycler(
1818
IObjectPool<T> target,
1919
Action<T> recycleFunction,
20-
ushort limit = ushort.MaxValue)
20+
ushort limit = Constants.DEFAULT_CAPACITY)
2121
{
2222
if(recycleFunction==null) throw new ArgumentNullException("recycleFunction");
2323
_target = target ?? throw new ArgumentNullException("target");
@@ -39,7 +39,7 @@ public Recycler(
3939
}
4040
}
4141

42-
public Recycler(
42+
internal Recycler(
4343
ushort limit,
4444
IObjectPool<T> pool,
4545
Action<T> recycleFunction) : this(pool, recycleFunction, limit)
@@ -72,4 +72,39 @@ protected override void OnDispose(bool calledExplicitly)
7272
_target = null;
7373
}
7474
}
75+
76+
public static class Recycler
77+
{
78+
public static Recycler<T> CreateRecycler<T>(
79+
this IObjectPool<T> pool,
80+
Action<T> recycleFunction,
81+
ushort limit = Constants.DEFAULT_CAPACITY)
82+
where T : class
83+
{
84+
return new Recycler<T>(pool, recycleFunction, limit);
85+
}
86+
87+
public static Recycler<T> CreateRecycler<T>(
88+
this IObjectPool<T> pool,
89+
ushort limit,
90+
Action<T> recycleFunction)
91+
where T : class
92+
{
93+
return new Recycler<T>(pool, recycleFunction, limit);
94+
}
95+
96+
public static void Recycle(IRecyclable r)
97+
{
98+
r.Recycle();
99+
}
100+
101+
public static Recycler<T> CreateRecycler<T>(
102+
this IObjectPool<T> pool,
103+
ushort limit = Constants.DEFAULT_CAPACITY)
104+
where T : class, IRecyclable
105+
{
106+
return new Recycler<T>(pool, Recycle, limit);
107+
}
108+
109+
}
75110
}

0 commit comments

Comments
 (0)