annotate Implab/ObjectPool.cs @ 121:62d2f1e98c4e v2

working version of AsyncQueue and batch operations tests
author cin
date Mon, 12 Jan 2015 18:19:41 +0300
parents 2573b562e328
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
117
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
1 using Implab.Parallels;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
2 using System;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
3 using System.Threading;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
4
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
5 namespace Implab {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
6 /// <summary>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
7 /// Базовый класс для создания пулов объектов.
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
8 /// </summary>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
9 /// <remarks>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект,
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
11 /// что актуально для объектов, создание которых требует существенных ресурсов.
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
13 /// ресурсов и создает новые объекты при необходимости.</para>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
14 /// <para>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
16 /// новых экземпляров.
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
17 /// </para>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
19 /// </remarks>
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
20 public abstract class ObjectPool<T> where T : class {
119
2573b562e328 Promises rewritten, added improved version of AsyncQueue
cin
parents: 117
diff changeset
21 readonly AsyncQueue<WeakReference> m_queue = new AsyncQueue<WeakReference>();
117
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
22 readonly int m_size;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
23 int m_count = 0;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
24
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
25 protected ObjectPool() : this(Environment.ProcessorCount+1) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
26
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
27 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
28
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
29 protected ObjectPool(int size) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
30 Safe.ArgumentInRange(size,1,size,"size");
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
31
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
32 m_size = size;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
33 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
34
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
35 protected abstract T CreateInstance();
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
36
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
37 protected virtual void CleanupInstance(T instance) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
38 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
39
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
40 public T Allocate() {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
41 WeakReference reference;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
42 while (m_queue.TryDequeue(out reference)) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
43 Interlocked.Decrement(ref m_count);
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
44 object instance = reference.Target;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
45 if (instance == null)
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
46 continue;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
47 return (T)instance;
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
48 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
49 return CreateInstance();
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
50 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
51
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
52 public void Release(T instance) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
53 if (m_count < m_size && instance != null) {
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
54 Interlocked.Increment(ref m_count);
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
55 CleanupInstance(instance);
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
56 m_queue.Enqueue(new WeakReference(instance));
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
57 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
58 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
59 }
8beee0d11de6 pool refactoring
cin
parents: 91
diff changeset
60 }