source: stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Store.cs @ 17053

Last change on this file since 17053 was 17053, checked in by abeham, 2 years ago

#2975: merged to stable

File size: 6.3 KB
Line 
1#region License Information
2/* SimSharp - A .NET port of SimPy, discrete event simulation framework
3Copyright (C) 2019  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  /// <summary>
24  /// The store holds a variable number of individual items.
25  /// The items are removed from the store in FIFO order.
26  ///
27  /// Put are processed in FIFO order.
28  /// Get are processed in FIFO order.
29  /// </summary>
30  public class Store {
31
32    public int Capacity { get; protected set; }
33
34    public int Count { get { return Items.Count; } }
35
36    protected Simulation Environment { get; private set; }
37
38    protected Queue<StorePut> PutQueue { get; private set; }
39    protected Queue<StoreGet> GetQueue { get; private set; }
40    protected Queue<object> Items { get; private set; }
41    protected List<Event> WhenNewQueue { get; private set; }
42    protected List<Event> WhenAnyQueue { get; private set; }
43    protected List<Event> WhenFullQueue { get; private set; }
44    protected List<Event> WhenEmptyQueue { get; private set; }
45    protected List<Event> WhenChangeQueue { get; private set; }
46
47    public Store(Simulation environment, int capacity = int.MaxValue) {
48      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
49      Environment = environment;
50      Capacity = capacity;
51      PutQueue = new Queue<StorePut>();
52      GetQueue = new Queue<StoreGet>();
53      Items = new Queue<object>();
54      WhenNewQueue = new List<Event>();
55      WhenAnyQueue = new List<Event>();
56      WhenFullQueue = new List<Event>();
57      WhenEmptyQueue = new List<Event>();
58      WhenChangeQueue = new List<Event>();
59    }
60    public Store(Simulation environment, IEnumerable<object> items, int capacity = int.MaxValue) {
61      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
62      Environment = environment;
63      Capacity = capacity;
64      PutQueue = new Queue<StorePut>();
65      GetQueue = new Queue<StoreGet>();
66      Items = new Queue<object>(items);
67      WhenNewQueue = new List<Event>();
68      WhenAnyQueue = new List<Event>();
69      WhenFullQueue = new List<Event>();
70      WhenEmptyQueue = new List<Event>();
71      WhenChangeQueue = new List<Event>();
72      if (capacity < Items.Count) throw new ArgumentException("There are more initial items than there is capacity.", "items");
73    }
74
75    public virtual StorePut Put(object item) {
76      var put = new StorePut(Environment, TriggerGet, item);
77      PutQueue.Enqueue(put);
78      TriggerPut();
79      return put;
80    }
81
82    public virtual StoreGet Get() {
83      var get = new StoreGet(Environment, TriggerPut);
84      GetQueue.Enqueue(get);
85      TriggerGet();
86      return get;
87    }
88
89    public virtual Event WhenNew() {
90      var whenNew = new Event(Environment);
91      WhenNewQueue.Add(whenNew);
92      return whenNew;
93    }
94
95    public virtual Event WhenAny() {
96      var whenAny = new Event(Environment);
97      WhenAnyQueue.Add(whenAny);
98      TriggerWhenAny();
99      return whenAny;
100    }
101
102    public virtual Event WhenFull() {
103      var whenFull = new Event(Environment);
104      WhenFullQueue.Add(whenFull);
105      TriggerWhenFull();
106      return whenFull;
107    }
108
109    public virtual Event WhenEmpty() {
110      var whenEmpty = new Event(Environment);
111      WhenEmptyQueue.Add(whenEmpty);
112      TriggerWhenEmpty();
113      return whenEmpty;
114    }
115
116    public virtual Event WhenChange() {
117      var whenChange = new Event(Environment);
118      WhenChangeQueue.Add(whenChange);
119      return whenChange;
120    }
121
122    protected virtual void DoPut(StorePut put) {
123      if (Items.Count < Capacity) {
124        Items.Enqueue(put.Value);
125        put.Succeed();
126      }
127    }
128
129    protected virtual void DoGet(StoreGet get) {
130      if (Items.Count > 0) {
131        var item = Items.Dequeue();
132        get.Succeed(item);
133      }
134    }
135
136    protected virtual void TriggerPut(Event @event = null) {
137      while (PutQueue.Count > 0) {
138        var put = PutQueue.Peek();
139        DoPut(put);
140        if (put.IsTriggered) {
141          PutQueue.Dequeue();
142          TriggerWhenNew();
143          TriggerWhenAny();
144          TriggerWhenFull();
145          TriggerWhenChange();
146        } else break;
147      }
148    }
149
150    protected virtual void TriggerGet(Event @event = null) {
151      while (GetQueue.Count > 0) {
152        var get = GetQueue.Peek();
153        DoGet(get);
154        if (get.IsTriggered) {
155          GetQueue.Dequeue();
156          TriggerWhenEmpty();
157          TriggerWhenChange();
158        } else break;
159      }
160    }
161
162    protected virtual void TriggerWhenNew() {
163      if (WhenNewQueue.Count == 0) return;
164      foreach (var evt in WhenNewQueue)
165        evt.Succeed();
166      WhenNewQueue.Clear();
167    }
168
169    protected virtual void TriggerWhenAny() {
170      if (Count > 0) {
171        if (WhenAnyQueue.Count == 0) return;
172        foreach (var evt in WhenAnyQueue)
173          evt.Succeed();
174        WhenAnyQueue.Clear();
175      }
176    }
177
178    protected virtual void TriggerWhenFull() {
179      if (Count == Capacity) {
180        if (WhenFullQueue.Count == 0) return;
181        foreach (var evt in WhenFullQueue)
182          evt.Succeed();
183        WhenFullQueue.Clear();
184      }
185    }
186
187    protected virtual void TriggerWhenEmpty() {
188      if (Count == 0) {
189        if (WhenEmptyQueue.Count == 0) return;
190        foreach (var evt in WhenEmptyQueue)
191          evt.Succeed();
192        WhenEmptyQueue.Clear();
193      }
194    }
195
196    protected virtual void TriggerWhenChange() {
197      if (WhenChangeQueue.Count == 0) return;
198      foreach (var evt in WhenChangeQueue)
199        evt.Succeed();
200      WhenChangeQueue.Clear();
201    }
202  }
203}
Note: See TracBrowser for help on using the repository browser.