Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.0.7/SimSharp-3.0.7/Core/Resources/ResourcePool.cs @ 12657

Last change on this file since 12657 was 12657, checked in by abeham, 9 years ago

#2420: Added Sim# as an ExtLib plugin

File size: 3.8 KB
Line 
1#region License Information
2/* SimSharp - A .NET port of SimPy, discrete event simulation framework
3Copyright (C) 2014  Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 3 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
17#endregion
18
19using System;
20using System.Collections.Generic;
21using System.Linq;
22
23namespace SimSharp {
24  public class ResourcePool {
25    protected static readonly Func<object, bool> TrueFunc = _ => true;
26
27    public int Capacity { get; protected set; }
28
29    public int InUse { get { return Capacity - Remaining; } }
30
31    public int Remaining { get { return Resources.Count; } }
32
33    protected Environment Environment { get; private set; }
34
35    protected LinkedList<ResourcePoolRequest> RequestQueue { get; private set; }
36    protected Queue<Release> ReleaseQueue { get; private set; }
37    protected List<object> Resources { get; private set; }
38
39    public ResourcePool(Environment environment, IEnumerable<object> resources) {
40      Environment = environment;
41      if (resources == null) throw new ArgumentNullException("resources");
42      Resources = new List<object>(resources);
43      Capacity = Resources.Count;
44      if (Capacity == 0) throw new ArgumentException("There must be at least one resource", "resources");
45      RequestQueue = new LinkedList<ResourcePoolRequest>();
46      ReleaseQueue = new Queue<Release>();
47    }
48
49    public virtual bool IsAvailable(Func<object, bool> filter) {
50      return Resources.Any(filter);
51    }
52
53    public virtual ResourcePoolRequest Request(Func<object, bool> filter = null) {
54      var request = new ResourcePoolRequest(Environment, TriggerRelease, DisposeCallback, filter ?? TrueFunc);
55      RequestQueue.AddLast(request);
56      TriggerRequest();
57      return request;
58    }
59
60    public virtual Release Release(Request request) {
61      var release = new Release(Environment, request, TriggerRequest);
62      ReleaseQueue.Enqueue(release);
63      TriggerRelease();
64      return release;
65    }
66
67    protected virtual void DisposeCallback(Event @event) {
68      var request = @event as Request;
69      if (request != null) Release(request);
70    }
71
72    protected virtual void DoRequest(ResourcePoolRequest request) {
73      foreach (var o in Resources) {
74        if (!request.Filter(o)) continue;
75        Resources.Remove(o);
76        request.Succeed(o);
77        return;
78      }
79    }
80
81    protected virtual void DoRelease(Release release) {
82      Resources.Add(release.Request.Value);
83      release.Succeed();
84    }
85
86    protected virtual void TriggerRequest(Event @event = null) {
87      var current = RequestQueue.First;
88      while (current != null) {
89        var request = current.Value;
90        DoRequest(request);
91        if (request.IsTriggered) {
92          var next = current.Next;
93          RequestQueue.Remove(current);
94          current = next;
95        }
96        if (Resources.Count == 0) break;
97      }
98    }
99
100    protected virtual void TriggerRelease(Event @event = null) {
101      while (ReleaseQueue.Count > 0) {
102        var release = ReleaseQueue.Peek();
103        DoRelease(release);
104        if (release.IsTriggered) {
105          ReleaseQueue.Dequeue();
106        } else break;
107      }
108    }
109  }
110}
Note: See TracBrowser for help on using the repository browser.