Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/04/19 12:55:52 (5 years ago)
Author:
abeham
Message:

#2975: merged to stable

Location:
stable
Files:
3 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.ExtLibs

  • stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/PriorityResource.cs

    r15972 r17053  
    11#region License Information
    22/* SimSharp - A .NET port of SimPy, discrete event simulation framework
    3 Copyright (C) 2016  Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3Copyright (C) 2019  Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44
    55This program is free software: you can redistribute it and/or modify
     
    2121
    2222namespace 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>
    2331  public class PriorityResource {
    2432
     
    2937    public int Remaining { get { return Capacity - InUse; } }
    3038
    31     protected Environment Environment { get; private set; }
     39    protected Simulation Environment { get; private set; }
    3240
    33     protected SortedList<int, LinkedList<PriorityRequest>> RequestQueue { get; private set; }
     41    protected SimplePriorityQueue<Request, double> RequestQueue { get; private set; }
    3442    protected Queue<Release> ReleaseQueue { get; private set; }
    3543    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; }
    3648
    37     public PriorityResource(Environment environment, int capacity = 1) {
     49    public PriorityResource(Simulation environment, int capacity = 1) {
    3850      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0.", "capacity");
    3951      Environment = environment;
    4052      Capacity = capacity;
    41       RequestQueue = new SortedList<int, LinkedList<PriorityRequest>>();
     53      RequestQueue = new SimplePriorityQueue<Request, double>();
    4254      ReleaseQueue = new Queue<Release>();
    4355      Users = new HashSet<Request>();
     56      WhenAnyQueue = new List<Event>();
     57      WhenFullQueue = new List<Event>();
     58      WhenEmptyQueue = new List<Event>();
     59      WhenChangeQueue = new List<Event>();
    4460    }
    4561
    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);
    5165      TriggerRequest();
    5266      return request;
    5367    }
    5468
    55     public virtual Release Release(PriorityRequest request) {
     69    public virtual Release Release(Request request) {
    5670      var release = new Release(Environment, request, TriggerRequest);
    5771      ReleaseQueue.Enqueue(release);
     
    6074    }
    6175
     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
    62103    protected void DisposeCallback(Event @event) {
    63       var request = @event as PriorityRequest;
     104      var request = @event as Request;
    64105      if (request != null) Release(request);
    65106    }
     
    73114
    74115    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.");
    84118      release.Succeed();
    85119    }
    86120
    87121    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;
    102130      }
    103131    }
     
    106134      while (ReleaseQueue.Count > 0) {
    107135        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        }
    108142        DoRelease(release);
    109143        if (release.IsTriggered) {
    110144          ReleaseQueue.Dequeue();
     145          TriggerWhenAny();
     146          TriggerWhenFull();
     147          TriggerWhenChange();
    111148        } else break;
    112149      }
    113150    }
     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    }
    114185  }
    115186}
Note: See TracChangeset for help on using the changeset viewer.