Changeset 17053 for stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/PriorityResource.cs
- Timestamp:
- 07/04/19 12:55:52 (5 years ago)
- Location:
- stable
- Files:
-
- 3 edited
- 1 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
stable
-
stable/HeuristicLab.ExtLibs
- Property svn:mergeinfo changed
/trunk/HeuristicLab.ExtLibs merged: 16779
- Property svn:mergeinfo changed
-
stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/PriorityResource.cs
r15972 r17053 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 22 22 namespace SimSharp { 23 /// <summary> 24 /// A PriorityResource is similar to a <see cref="Resource"/>. 25 /// However, it enables prioritizing requests. 26 /// 27 /// PriorityResource holds a fixed number of anonymous entities. 28 /// Requests are processed in order priority first, FIFO second. 29 /// Releases are processed in FIFO order (usually no simulation time passes for a Release). 30 /// </summary> 23 31 public class PriorityResource { 24 32 … … 29 37 public int Remaining { get { return Capacity - InUse; } } 30 38 31 protected EnvironmentEnvironment { get; private set; }39 protected Simulation Environment { get; private set; } 32 40 33 protected S ortedList<int, LinkedList<PriorityRequest>> RequestQueue { get; private set; }41 protected SimplePriorityQueue<Request, double> RequestQueue { get; private set; } 34 42 protected Queue<Release> ReleaseQueue { get; private set; } 35 43 protected HashSet<Request> Users { get; private set; } 44 protected List<Event> WhenAnyQueue { get; private set; } 45 protected List<Event> WhenFullQueue { get; private set; } 46 protected List<Event> WhenEmptyQueue { get; private set; } 47 protected List<Event> WhenChangeQueue { get; private set; } 36 48 37 public PriorityResource( Environmentenvironment, int capacity = 1) {49 public PriorityResource(Simulation environment, int capacity = 1) { 38 50 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0.", "capacity"); 39 51 Environment = environment; 40 52 Capacity = capacity; 41 RequestQueue = new S ortedList<int, LinkedList<PriorityRequest>>();53 RequestQueue = new SimplePriorityQueue<Request, double>(); 42 54 ReleaseQueue = new Queue<Release>(); 43 55 Users = new HashSet<Request>(); 56 WhenAnyQueue = new List<Event>(); 57 WhenFullQueue = new List<Event>(); 58 WhenEmptyQueue = new List<Event>(); 59 WhenChangeQueue = new List<Event>(); 44 60 } 45 61 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); 62 public virtual Request Request(double priority = 1) { 63 var request = new Request(Environment, TriggerRelease, DisposeCallback); 64 RequestQueue.Enqueue(request, priority); 51 65 TriggerRequest(); 52 66 return request; 53 67 } 54 68 55 public virtual Release Release( PriorityRequest request) {69 public virtual Release Release(Request request) { 56 70 var release = new Release(Environment, request, TriggerRequest); 57 71 ReleaseQueue.Enqueue(release); … … 60 74 } 61 75 76 public virtual Event WhenAny() { 77 var whenAny = new Event(Environment); 78 WhenAnyQueue.Add(whenAny); 79 TriggerWhenAny(); 80 return whenAny; 81 } 82 83 public virtual Event WhenFull() { 84 var whenFull = new Event(Environment); 85 WhenFullQueue.Add(whenFull); 86 TriggerWhenFull(); 87 return whenFull; 88 } 89 90 public virtual Event WhenEmpty() { 91 var whenEmpty = new Event(Environment); 92 WhenEmptyQueue.Add(whenEmpty); 93 TriggerWhenEmpty(); 94 return whenEmpty; 95 } 96 97 public virtual Event WhenChange() { 98 var whenChange = new Event(Environment); 99 WhenChangeQueue.Add(whenChange); 100 return whenChange; 101 } 102 62 103 protected void DisposeCallback(Event @event) { 63 var request = @event as PriorityRequest;104 var request = @event as Request; 64 105 if (request != null) Release(request); 65 106 } … … 73 114 74 115 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 } 116 if (!Users.Remove(release.Request)) 117 throw new InvalidOperationException("Released request does not have a user."); 84 118 release.Succeed(); 85 119 } 86 120 87 121 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; 122 while (RequestQueue.Count > 0) { 123 var request = RequestQueue.First; 124 DoRequest(request); 125 if (request.IsTriggered) { 126 RequestQueue.Dequeue(); 127 TriggerWhenEmpty(); 128 TriggerWhenChange(); 129 } else break; 102 130 } 103 131 } … … 106 134 while (ReleaseQueue.Count > 0) { 107 135 var release = ReleaseQueue.Peek(); 136 if (release.Request.IsAlive) { 137 if (!RequestQueue.TryRemove(release.Request)) 138 throw new InvalidOperationException("Failed to cancel a request."); 139 release.Succeed(); 140 ReleaseQueue.Dequeue(); 141 } 108 142 DoRelease(release); 109 143 if (release.IsTriggered) { 110 144 ReleaseQueue.Dequeue(); 145 TriggerWhenAny(); 146 TriggerWhenFull(); 147 TriggerWhenChange(); 111 148 } else break; 112 149 } 113 150 } 151 152 protected virtual void TriggerWhenAny() { 153 if (Remaining > 0) { 154 if (WhenAnyQueue.Count == 0) return; 155 foreach (var evt in WhenAnyQueue) 156 evt.Succeed(); 157 WhenAnyQueue.Clear(); 158 } 159 } 160 161 protected virtual void TriggerWhenFull() { 162 if (InUse == 0) { 163 if (WhenFullQueue.Count == 0) return; 164 foreach (var evt in WhenFullQueue) 165 evt.Succeed(); 166 WhenFullQueue.Clear(); 167 } 168 } 169 170 protected virtual void TriggerWhenEmpty() { 171 if (Remaining == 0) { 172 if (WhenEmptyQueue.Count == 0) return; 173 foreach (var evt in WhenEmptyQueue) 174 evt.Succeed(); 175 WhenEmptyQueue.Clear(); 176 } 177 } 178 179 protected virtual void TriggerWhenChange() { 180 if (WhenChangeQueue.Count == 0) return; 181 foreach (var evt in WhenChangeQueue) 182 evt.Succeed(); 183 WhenChangeQueue.Clear(); 184 } 114 185 } 115 186 }
Note: See TracChangeset
for help on using the changeset viewer.