##// END OF EJS Templates
added object pool
cin -
r82:0363407ee75c v2
parent child
Show More
@@ -0,0 +1,85
1 using System;
2 using Implab.Parallels;
3 using System.Threading;
4
5 namespace Implab {
6 public class ObjectPool<T> : IDisposable {
7 readonly Func<T> m_factory;
8 readonly Action<T> m_cleanup;
9 readonly int m_size;
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
11
12 volatile bool m_disposed;
13
14 volatile int m_count;
15
16 public ObjectPool(Func<T> factory, Action<T> cleanup, int size) {
17 Safe.ArgumentNotNull(factory, "factory");
18 Safe.ArgumentInRange(size, 1, size, "size");
19
20 m_factory = factory;
21 m_cleanup = cleanup;
22 m_size = size;
23 }
24
25 public ObjectPool(Func<T> factory, Action<T> cleanup) : this(factory,cleanup,Environment.ProcessorCount+1) {
26 }
27
28 public ObjectPool(Func<T> factory) : this(factory,null,Environment.ProcessorCount+1) {
29 }
30
31 public ObjectPoolWrapper<T> Allocate() {
32 if (m_disposed)
33 throw new ObjectDisposedException(this.ToString());
34
35 T instance;
36 if (m_queue.TryDequeue(out instance)) {
37 Interlocked.Decrement(ref m_count);
38 return instance;
39 } else {
40 instance = m_factory();
41 }
42 return new ObjectPoolWrapper<T>(instance, this);
43 }
44
45 public void Release(T instance) {
46 if (m_count < m_size && !m_disposed) {
47 Interlocked.Increment(ref m_count);
48
49 if (m_cleanup != null)
50 m_cleanup(instance);
51
52 m_queue.Enqueue(instance);
53
54 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
55 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
56 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
57 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
58 if (m_disposed && m_queue.TryDequeue(out instance))
59 Safe.Dispose(instance);
60
61 } else {
62 Safe.Dispose(instance);
63 }
64 }
65
66 protected virtual void Dispose(bool disposing) {
67 if (disposing) {
68 m_disposed = true;
69 T instance;
70 while (m_queue.TryDequeue(out instance))
71 Safe.Dispose(instance);
72 }
73 }
74
75 #region IDisposable implementation
76
77 public void Dispose() {
78 Dispose(true);
79 GC.SuppressFinalize(this);
80 }
81
82 #endregion
83 }
84 }
85
@@ -0,0 +1,24
1 using System;
2
3 namespace Implab {
4 public struct ObjectPoolWrapper<T> : IDisposable {
5 readonly T m_value;
6 readonly ObjectPool<T> m_pool;
7
8 internal ObjectPoolWrapper(T value, ObjectPool<T> pool) {
9 m_value = value;
10 m_pool = pool;
11 }
12
13 public T Value {
14 get { return m_value; }
15 }
16
17 #region IDisposable implementation
18 public void Dispose() {
19 m_pool.Release(m_value);
20 }
21 #endregion
22 }
23 }
24
@@ -7,8 +7,6
7 7 <OutputType>Library</OutputType>
8 8 <RootNamespace>Implab</RootNamespace>
9 9 <AssemblyName>Implab</AssemblyName>
10 <ProductVersion>8.0.30703</ProductVersion>
11 <SchemaVersion>2.0</SchemaVersion>
12 10 </PropertyGroup>
13 11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14 12 <DebugSymbols>true</DebugSymbols>
@@ -123,8 +121,8
123 121 <Compile Include="PromiseExtensions.cs" />
124 122 <Compile Include="TransientPromiseException.cs" />
125 123 <Compile Include="SyncContextPromise.cs" />
126 <Compile Include="SyncPool.cs" />
127 <Compile Include="SyncPoolWrapper.cs" />
124 <Compile Include="ObjectPool.cs" />
125 <Compile Include="ObjectPoolWrapper.cs" />
128 126 </ItemGroup>
129 127 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
130 128 <ItemGroup />
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now