Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.3.1/SimSharp-3.3.1/Core/Resources/Store.cs @ 17487

Last change on this file since 17487 was 17487, checked in by abeham, 4 years ago

#3065: update Sim# to 3.3.1

File size: 6.9 KB
Line 
1#region License Information
2/*
3 * This file is part of SimSharp which is licensed under the MIT license.
4 * See the LICENSE file in the project root for more information.
5 */
6#endregion
7
8using System;
9using System.Collections.Generic;
10using System.Linq;
11
12namespace SimSharp {
13  /// <summary>
14  /// The store holds a variable number of individual items.
15  /// The items are removed from the store in FIFO order.
16  ///
17  /// Put are processed in FIFO order.
18  /// Get are processed in FIFO order.
19  /// </summary>
20  public class Store {
21
22    public int Capacity { get; protected set; }
23
24    public int Count { get { return Items.Count; } }
25
26    protected Simulation Environment { get; private set; }
27
28    protected Queue<StorePut> PutQueue { get; private set; }
29    protected Queue<StoreGet> GetQueue { get; private set; }
30    protected Queue<StoreItem> Items { get; private set; }
31    protected List<Event> WhenNewQueue { get; private set; }
32    protected List<Event> WhenAnyQueue { get; private set; }
33    protected List<Event> WhenFullQueue { get; private set; }
34    protected List<Event> WhenEmptyQueue { get; private set; }
35    protected List<Event> WhenChangeQueue { get; private set; }
36
37    public ITimeSeriesMonitor Utilization { get; set; }
38    public ITimeSeriesMonitor WIP { get; set; }
39    public ISampleMonitor LeadTime { get; set; }
40    public ITimeSeriesMonitor PutQueueLength { get; set; }
41    public ISampleMonitor PutWaitingTime { get; set; }
42    public ITimeSeriesMonitor GetQueueLength { get; set; }
43    public ISampleMonitor GetWaitingTime { get; set; }
44
45    public Store(Simulation environment, int capacity = int.MaxValue) {
46      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
47      Environment = environment;
48      Capacity = capacity;
49      PutQueue = new Queue<StorePut>();
50      GetQueue = new Queue<StoreGet>();
51      Items = new Queue<StoreItem>();
52      WhenNewQueue = new List<Event>();
53      WhenAnyQueue = new List<Event>();
54      WhenFullQueue = new List<Event>();
55      WhenEmptyQueue = new List<Event>();
56      WhenChangeQueue = new List<Event>();
57    }
58    public Store(Simulation environment, IEnumerable<object> items, int capacity = int.MaxValue) {
59      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
60      Environment = environment;
61      Capacity = capacity;
62      PutQueue = new Queue<StorePut>();
63      GetQueue = new Queue<StoreGet>();
64      Items = new Queue<StoreItem>(items.Select(x => new StoreItem() { AdmissionDate = environment.Now, Item = x }));
65      WhenNewQueue = new List<Event>();
66      WhenAnyQueue = new List<Event>();
67      WhenFullQueue = new List<Event>();
68      WhenEmptyQueue = new List<Event>();
69      WhenChangeQueue = new List<Event>();
70      if (capacity < Items.Count) throw new ArgumentException("There are more initial items than there is capacity.", "items");
71    }
72
73    public virtual StorePut Put(object item) {
74      var put = new StorePut(Environment, TriggerGet, item);
75      PutQueue.Enqueue(put);
76      TriggerPut();
77      return put;
78    }
79
80    public virtual StoreGet Get() {
81      var get = new StoreGet(Environment, TriggerPut);
82      GetQueue.Enqueue(get);
83      TriggerGet();
84      return get;
85    }
86
87    public virtual Event WhenNew() {
88      var whenNew = new Event(Environment);
89      WhenNewQueue.Add(whenNew);
90      return whenNew;
91    }
92
93    public virtual Event WhenAny() {
94      var whenAny = new Event(Environment);
95      WhenAnyQueue.Add(whenAny);
96      TriggerWhenAny();
97      return whenAny;
98    }
99
100    public virtual Event WhenFull() {
101      var whenFull = new Event(Environment);
102      WhenFullQueue.Add(whenFull);
103      TriggerWhenFull();
104      return whenFull;
105    }
106
107    public virtual Event WhenEmpty() {
108      var whenEmpty = new Event(Environment);
109      WhenEmptyQueue.Add(whenEmpty);
110      TriggerWhenEmpty();
111      return whenEmpty;
112    }
113
114    public virtual Event WhenChange() {
115      var whenChange = new Event(Environment);
116      WhenChangeQueue.Add(whenChange);
117      return whenChange;
118    }
119
120    protected virtual void DoPut(StorePut put) {
121      if (Items.Count < Capacity) {
122        PutWaitingTime?.Add(Environment.ToDouble(Environment.Now - put.Time));
123        Items.Enqueue(new StoreItem() { AdmissionDate = Environment.Now, Item = put.Value });
124        put.Succeed();
125      }
126    }
127
128    protected virtual void DoGet(StoreGet get) {
129      if (Items.Count > 0) {
130        var item = Items.Dequeue();
131        GetWaitingTime?.Add(Environment.ToDouble(Environment.Now - get.Time));
132        LeadTime?.Add(Environment.ToDouble(Environment.Now - item.AdmissionDate));
133        get.Succeed(item.Item);
134      }
135    }
136
137    protected virtual void TriggerPut(Event @event = null) {
138      while (PutQueue.Count > 0) {
139        var put = PutQueue.Peek();
140        DoPut(put);
141        if (put.IsTriggered) {
142          PutQueue.Dequeue();
143          TriggerWhenNew();
144          TriggerWhenAny();
145          TriggerWhenFull();
146          TriggerWhenChange();
147        } else break;
148      }
149      Utilization?.UpdateTo(Count / (double)Capacity);
150      WIP?.UpdateTo(Count + PutQueue.Count + GetQueue.Count);
151      PutQueueLength?.UpdateTo(PutQueue.Count);
152    }
153
154    protected virtual void TriggerGet(Event @event = null) {
155      while (GetQueue.Count > 0) {
156        var get = GetQueue.Peek();
157        DoGet(get);
158        if (get.IsTriggered) {
159          GetQueue.Dequeue();
160          TriggerWhenEmpty();
161          TriggerWhenChange();
162        } else break;
163      }
164      Utilization?.UpdateTo(Count / (double)Capacity);
165      WIP?.UpdateTo(Count + PutQueue.Count + GetQueue.Count);
166      GetQueueLength?.UpdateTo(GetQueue.Count);
167    }
168
169    protected virtual void TriggerWhenNew() {
170      if (WhenNewQueue.Count == 0) return;
171      foreach (var evt in WhenNewQueue)
172        evt.Succeed();
173      WhenNewQueue.Clear();
174    }
175
176    protected virtual void TriggerWhenAny() {
177      if (Count > 0) {
178        if (WhenAnyQueue.Count == 0) return;
179        foreach (var evt in WhenAnyQueue)
180          evt.Succeed();
181        WhenAnyQueue.Clear();
182      }
183    }
184
185    protected virtual void TriggerWhenFull() {
186      if (Count == Capacity) {
187        if (WhenFullQueue.Count == 0) return;
188        foreach (var evt in WhenFullQueue)
189          evt.Succeed();
190        WhenFullQueue.Clear();
191      }
192    }
193
194    protected virtual void TriggerWhenEmpty() {
195      if (Count == 0) {
196        if (WhenEmptyQueue.Count == 0) return;
197        foreach (var evt in WhenEmptyQueue)
198          evt.Succeed();
199        WhenEmptyQueue.Clear();
200      }
201    }
202
203    protected virtual void TriggerWhenChange() {
204      if (WhenChangeQueue.Count == 0) return;
205      foreach (var evt in WhenChangeQueue)
206        evt.Succeed();
207      WhenChangeQueue.Clear();
208    }
209  }
210
211  public struct StoreItem {
212    public DateTime AdmissionDate;
213    public object Item;
214  }
215}
Note: See TracBrowser for help on using the repository browser.