Free cookie consent management tool by TermsFeed Policy Generator

source: branches/PushGP/HeuristicLab.PushGP/FeatureTests/Pool/ManagedPoolProvider.cs @ 14777

Last change on this file since 14777 was 14777, checked in by pkimmesw, 7 years ago

#2665 simplifier, push solution results view, performance improvements, small bug fixes, ui fixes

File size: 3.2 KB
Line 
1namespace TestPooling.Pool {
2  using System;
3  using System.Collections.Concurrent;
4  using System.Collections.Generic;
5  using System.IO;
6  using System.Linq;
7  using System.Runtime.Serialization.Formatters.Binary;
8
9  public interface IManagedPool<T> : IDisposable where T : class, IPooledObject {
10    T Get();
11  }
12
13  public class ManagedPoolProvider<T> where T : class, IPooledObject {
14    private readonly ConcurrentStack<T[]> partitions = new ConcurrentStack<T[]>();
15    private readonly ObjectPool<IManagedPool<T>> managedPools;
16    private readonly BinaryFormatter binaryFormatter = new BinaryFormatter();
17    private byte[] dummyPartition;
18
19    public readonly int PartitionSize;
20    public readonly int MaxParitionCount;
21    public const int DefaultMaxInstanceCount = 65536;
22
23    public ManagedPoolProvider(int partitionSize, Func<T> factory, int? maxPartitionCount = null) {
24      PartitionSize = partitionSize;
25      MaxParitionCount = maxPartitionCount ?? DefaultMaxInstanceCount / PartitionSize;
26
27      managedPools = new ObjectPool<IManagedPool<T>>(() => new ManagedPool<T>(this));
28
29      InitDummyPartition(factory);
30    }
31
32    private void InitDummyPartition(Func<T> factory) {
33      var temp = new T[PartitionSize];
34
35      for (var i = 0; i < PartitionSize; i++) {
36        temp[i] = factory();
37      }
38
39      using (var memoryStream = new MemoryStream()) {
40        binaryFormatter.Serialize(memoryStream, temp);
41        dummyPartition = memoryStream.ToArray();
42      }
43    }
44
45    public int InstanceCount { get { return partitions.Count * PartitionSize; } }
46
47    public void ReleasePartitions(params T[][] partition) {
48      if (partitions.Count <= MaxParitionCount && partition.Length > 0)
49        partitions.PushRange(partition);
50    }
51
52    private T[] GetPartition() {
53      T[] partition;
54      return partitions.TryPop(out partition) ? partition : CloneDummyPartition();
55    }
56
57    private T[] CloneDummyPartition() {
58      using (var memoryStream = new MemoryStream(dummyPartition)) {
59        memoryStream.Seek(0, SeekOrigin.Begin);
60
61        return (T[])binaryFormatter.Deserialize(memoryStream);
62      }
63    }
64
65    public IManagedPool<T> CreatePool() {
66      return managedPools.Allocate();
67    }
68
69    private class ManagedPool<T> : IManagedPool<T> where T : class, IPooledObject {
70      private readonly ManagedPoolProvider<T> provider;
71      private readonly IList<T[]> partitions = new List<T[]>();
72      private T[] currentPartition;
73      private int entryIndex;
74
75      public ManagedPool(ManagedPoolProvider<T> provider) {
76        this.provider = provider;
77        entryIndex = provider.PartitionSize;
78      }
79
80      public T Get() {
81        if (entryIndex == provider.PartitionSize) {
82          currentPartition = provider.GetPartition();
83          partitions.Add(currentPartition);
84          entryIndex = 0;
85        }
86
87        var entry = currentPartition[entryIndex++];
88
89        entry.Reset();
90
91        return entry;
92      }
93
94      public void Dispose() {
95        provider.ReleasePartitions(partitions.ToArray());
96        partitions.Clear();
97        entryIndex = provider.PartitionSize;
98        provider.managedPools.Free(this);
99      }
100    }
101  }
102}
Note: See TracBrowser for help on using the repository browser.