annotate Implab/Components/ObjectPool.cs @ 166:b84cdbe82e7f ref20160224

sync
author cin
date Mon, 29 Feb 2016 18:41:01 +0300
parents 2dcdee4c0810
children 7c7e9ad6fe4a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
1 using Implab.Parallels;
240aa6994018 component model refactoring
cin
parents:
diff changeset
2 using System;
240aa6994018 component model refactoring
cin
parents:
diff changeset
3 using System.Threading;
240aa6994018 component model refactoring
cin
parents:
diff changeset
4
240aa6994018 component model refactoring
cin
parents:
diff changeset
5 namespace Implab.Components {
240aa6994018 component model refactoring
cin
parents:
diff changeset
6 /// <summary>
154
cin
parents: 152
diff changeset
7 /// The base class for creating object pools.
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
8 /// </summary>
240aa6994018 component model refactoring
cin
parents:
diff changeset
9 /// <remarks>
154
cin
parents: 152
diff changeset
10 /// <para>The objects pool is offers frequently requested objects to be reused, this gives
cin
parents: 152
diff changeset
11 /// a gool speed improvement for the 'heavy' objects. To avoid memory overhead the pool uses
cin
parents: 152
diff changeset
12 /// weak references allowing CG to do it's work. If there are no free objects in the pool
cin
parents: 152
diff changeset
13 /// they are created on demand. </para>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
14 /// <para>
154
cin
parents: 152
diff changeset
15 /// Implementors need to defined a <see cref="CreateInstance()"/> method
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
16 /// </para>
154
cin
parents: 152
diff changeset
17 /// <para>The instances of this class are thred-safe.</para>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
18 /// </remarks>
240aa6994018 component model refactoring
cin
parents:
diff changeset
19 public abstract class ObjectPool<T> where T : class {
240aa6994018 component model refactoring
cin
parents:
diff changeset
20 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
240aa6994018 component model refactoring
cin
parents:
diff changeset
21 readonly int m_size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
22 int m_count = 0;
240aa6994018 component model refactoring
cin
parents:
diff changeset
23
240aa6994018 component model refactoring
cin
parents:
diff changeset
24 protected ObjectPool() : this(Environment.ProcessorCount+1) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
25
240aa6994018 component model refactoring
cin
parents:
diff changeset
26 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
27
240aa6994018 component model refactoring
cin
parents:
diff changeset
28 protected ObjectPool(int size) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
29 Safe.ArgumentInRange(size,1,size,"size");
240aa6994018 component model refactoring
cin
parents:
diff changeset
30
240aa6994018 component model refactoring
cin
parents:
diff changeset
31 m_size = size;
240aa6994018 component model refactoring
cin
parents:
diff changeset
32 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
33
154
cin
parents: 152
diff changeset
34 /// <summary>
cin
parents: 152
diff changeset
35 /// Creates the instance if there are no free ones in the pool.
cin
parents: 152
diff changeset
36 /// </summary>
cin
parents: 152
diff changeset
37 /// <returns>The new instance.</returns>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
38 protected abstract T CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
39
154
cin
parents: 152
diff changeset
40 /// <summary>
cin
parents: 152
diff changeset
41 /// Cleanups the instance.
cin
parents: 152
diff changeset
42 /// </summary>
cin
parents: 152
diff changeset
43 /// <param name="instance">The instance to cleanup and prepare it for the next use.</param>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
44 protected virtual void CleanupInstance(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
45 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
46
154
cin
parents: 152
diff changeset
47 /// <summary>
cin
parents: 152
diff changeset
48 /// Allocate free instance from the pool or reates a new one.
cin
parents: 152
diff changeset
49 /// </summary>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
50 public T Allocate() {
240aa6994018 component model refactoring
cin
parents:
diff changeset
51 WeakReference reference;
240aa6994018 component model refactoring
cin
parents:
diff changeset
52 while (m_queue.TryDequeue(out reference)) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
53 Interlocked.Decrement(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
54 object instance = reference.Target;
240aa6994018 component model refactoring
cin
parents:
diff changeset
55 if (instance == null)
240aa6994018 component model refactoring
cin
parents:
diff changeset
56 continue;
240aa6994018 component model refactoring
cin
parents:
diff changeset
57 return (T)instance;
240aa6994018 component model refactoring
cin
parents:
diff changeset
58 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
59 return CreateInstance();
240aa6994018 component model refactoring
cin
parents:
diff changeset
60 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
61
154
cin
parents: 152
diff changeset
62 /// <summary>
cin
parents: 152
diff changeset
63 /// Release the specified instance and returns it to the pool of free instances.
cin
parents: 152
diff changeset
64 /// </summary>
cin
parents: 152
diff changeset
65 /// <param name="instance">The instance to return to the pool.</param>
cin
parents: 152
diff changeset
66 /// <remarks>Before the instance is returned to the pool the <see cref="CleanupInstance(T)"/> is called.</remarks>
152
240aa6994018 component model refactoring
cin
parents:
diff changeset
67 public void Release(T instance) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
68 if (m_count < m_size && instance != null) {
240aa6994018 component model refactoring
cin
parents:
diff changeset
69 Interlocked.Increment(ref m_count);
240aa6994018 component model refactoring
cin
parents:
diff changeset
70 CleanupInstance(instance);
240aa6994018 component model refactoring
cin
parents:
diff changeset
71 m_queue.Enqueue(new WeakReference(instance));
240aa6994018 component model refactoring
cin
parents:
diff changeset
72 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
73 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
74 }
240aa6994018 component model refactoring
cin
parents:
diff changeset
75 }