Free cookie consent management tool by TermsFeed Policy Generator

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