Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.0.7/SimSharp-3.0.7/Core/Resources/FilterStore.cs @ 14186

Last change on this file since 14186 was 14186, checked in by swagner, 8 years ago

#2526: Updated year of copyrights in license headers

File size: 3.8 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;
21using System.Linq;
22
23namespace SimSharp {
24  public class FilterStore {
25    public int Count { get { return Items.Count; } }
26    public int Capacity { get; protected set; }
27    protected Environment Environment { get; private set; }
28
29    protected Queue<StorePut> PutQueue { get; private set; }
30    protected LinkedList<FilterStoreGet> GetQueue { get; private set; }
31    protected List<object> Items { get; private set; }
32
33    public FilterStore(Environment environment, int capacity = int.MaxValue) {
34      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
35      Environment = environment;
36      Capacity = capacity;
37      PutQueue = new Queue<StorePut>();
38      GetQueue = new LinkedList<FilterStoreGet>();
39      Items = new List<object>();
40    }
41    public FilterStore(Environment environment, IEnumerable<object> items, int capacity = int.MaxValue) {
42      if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity");
43      Environment = environment;
44      Capacity = capacity;
45      PutQueue = new Queue<StorePut>();
46      GetQueue = new LinkedList<FilterStoreGet>();
47      Items = new List<object>(items);
48      if (capacity < Items.Count) throw new ArgumentException("There are more initial items than there is capacity.", "items");
49    }
50
51    public virtual bool IsAvailable(Func<object, bool> filter) {
52      return Items.Any(filter);
53    }
54
55    public virtual StorePut Put(object item) {
56      var put = new StorePut(Environment, TriggerGet, item);
57      PutQueue.Enqueue(put);
58      TriggerPut();
59      return put;
60    }
61
62    public virtual FilterStoreGet Get(Func<object, bool> filter = null) {
63      if (filter == null) filter = _ => true;
64      var get = new FilterStoreGet(Environment, TriggerPut, filter);
65      GetQueue.AddLast(get);
66      TriggerGet();
67      return get;
68    }
69
70    protected virtual void DoPut(StorePut put) {
71      if (Items.Count < Capacity) {
72        Items.Add(put.Value);
73        put.Succeed();
74      }
75    }
76
77    protected virtual void DoGet(FilterStoreGet get) {
78      for (int i = 0; i < Items.Count; i++) {
79        var item = Items[i];
80        if (!get.Filter(item)) continue;
81        Items.RemoveAt(i);
82        get.Succeed(item);
83        return;
84      }
85    }
86
87    protected virtual void TriggerPut(Event @event = null) {
88      while (PutQueue.Count > 0) {
89        var put = PutQueue.Peek();
90        DoPut(put);
91        if (put.IsTriggered) {
92          PutQueue.Dequeue();
93        } else break;
94      }
95    }
96
97    protected virtual void TriggerGet(Event @event = null) {
98      var current = GetQueue.First;
99      while (current != null) {
100        var get = current.Value;
101        DoGet(get);
102        if (get.IsTriggered) {
103          var next = current.Next;
104          GetQueue.Remove(current);
105          current = next;
106        } else current = current.Next;
107        if (Items.Count == 0) break;
108      }
109    }
110  }
111}
Note: See TracBrowser for help on using the repository browser.