Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.0.9/SimSharp-3.0.9/Core/Resources/PriorityResource.cs @ 14196

Last change on this file since 14196 was 14196, checked in by abeham, 8 years ago

#2644: upgraded Sim# version from 3.0.7 to 3.0.9

File size: 3.9 KB
Line 
1#region License Information
2/* SimSharp - A .NET port of SimPy, discrete event simulation framework
3Copyright (C) 2002-2016 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;
21
22namespace SimSharp {
23  public class PriorityResource {
24
25    public int Capacity { get; protected set; }
26
27    public int InUse { get { return Users.Count; } }
28
29    public int Remaining { get { return Capacity - InUse; } }
30
31    protected Environment Environment { get; private set; }
32
33    protected SortedList<int, LinkedList<PriorityRequest>> RequestQueue { get; private set; }
34    protected Queue<Release> ReleaseQueue { get; private set; }
35    protected HashSet<Request> Users { get; private set; }
36
37    public PriorityResource(Environment environment, int capacity = 1) {
38      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0.", "capacity");
39      Environment = environment;
40      Capacity = capacity;
41      RequestQueue = new SortedList<int, LinkedList<PriorityRequest>>();
42      ReleaseQueue = new Queue<Release>();
43      Users = new HashSet<Request>();
44    }
45
46    public virtual PriorityRequest Request(int priority = 1) {
47      var request = new PriorityRequest(Environment, TriggerRelease, DisposeCallback, priority);
48      if (!RequestQueue.ContainsKey(priority))
49        RequestQueue.Add(priority, new LinkedList<PriorityRequest>());
50      RequestQueue[priority].AddLast(request);
51      TriggerRequest();
52      return request;
53    }
54
55    public virtual Release Release(PriorityRequest request) {
56      var release = new Release(Environment, request, TriggerRequest);
57      ReleaseQueue.Enqueue(release);
58      TriggerRelease();
59      return release;
60    }
61
62    protected void DisposeCallback(Event @event) {
63      var request = @event as PriorityRequest;
64      if (request != null) Release(request);
65    }
66
67    protected virtual void DoRequest(Request request) {
68      if (Users.Count < Capacity) {
69        Users.Add(request);
70        request.Succeed();
71      }
72    }
73
74    protected virtual void DoRelease(Release release) {
75      if (!Users.Remove(release.Request)) {
76        var prioRequest = release.Request as PriorityRequest;
77        if (prioRequest != null) {
78          var current = RequestQueue[prioRequest.Priority].First;
79          while (current != null && current.Value != release.Request)
80            current = current.Next;
81          if (current != null) RequestQueue[prioRequest.Priority].Remove(current);
82        }
83      }
84      release.Succeed();
85    }
86
87    protected virtual void TriggerRequest(Event @event = null) {
88      foreach (var entry in RequestQueue) {
89        var cascade = false;
90        var requests = entry.Value;
91        while (requests.Count > 0) {
92          var req = requests.First.Value;
93          DoRequest(req);
94          if (req.IsTriggered) {
95            requests.RemoveFirst();
96          } else {
97            cascade = true;
98            break;
99          }
100        }
101        if (cascade) break;
102      }
103    }
104
105    protected virtual void TriggerRelease(Event @event = null) {
106      while (ReleaseQueue.Count > 0) {
107        var release = ReleaseQueue.Peek();
108        DoRelease(release);
109        if (release.IsTriggered) {
110          ReleaseQueue.Dequeue();
111        } else break;
112      }
113    }
114  }
115}
Note: See TracBrowser for help on using the repository browser.