wasSharp – Diff between revs 27 and 34
?pathlinks?
Rev 27 | Rev 34 | |||
---|---|---|---|---|
1 | /////////////////////////////////////////////////////////////////////////// |
1 | /////////////////////////////////////////////////////////////////////////// |
|
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
2 | // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // |
|
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
3 | // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // |
|
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
4 | // rights of fair usage, the disclaimer and warranty conditions. // |
|
5 | /////////////////////////////////////////////////////////////////////////// |
5 | /////////////////////////////////////////////////////////////////////////// |
|
6 | |
6 | |
|
7 | using System.Collections.Generic; |
7 | using System.Collections.Generic; |
|
8 | |
8 | |
|
9 | namespace wasSharp.Collections.Generic |
9 | namespace wasSharp.Collections.Generic |
|
10 | { |
10 | { |
|
11 | /////////////////////////////////////////////////////////////////////////// |
11 | /////////////////////////////////////////////////////////////////////////// |
|
12 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
12 | // Copyright (C) 2016 Wizardry and Steamworks - License: GNU GPLv3 // |
|
13 | /////////////////////////////////////////////////////////////////////////// |
13 | /////////////////////////////////////////////////////////////////////////// |
|
14 | /// <summary> |
14 | /// <summary> |
|
15 | /// A circular queue implementation based on linked lists. |
15 | /// A circular queue implementation based on linked lists. |
|
16 | /// </summary> |
16 | /// </summary> |
|
17 | /// <typeparam name="T">the type of value to store</typeparam> |
17 | /// <typeparam name="T">the type of value to store</typeparam> |
|
18 | public class CircularQueue<T> |
18 | public class CircularQueue<T> |
|
19 | { |
19 | { |
|
20 | private readonly LinkedList<T> Store = new LinkedList<T>(); |
20 | private readonly LinkedList<T> Store = new LinkedList<T>(); |
|
21 | |
21 | |
|
22 | private readonly object SyncRoot = new object(); |
22 | private readonly object SyncRoot = new object(); |
|
23 | private LinkedListNode<T> CurrentNode; |
23 | private LinkedListNode<T> CurrentNode; |
|
24 | |
24 | |
|
25 | public CircularQueue() |
25 | public CircularQueue() |
|
26 | { |
26 | { |
|
27 | } |
27 | } |
|
28 | |
28 | |
|
29 | public CircularQueue(IEnumerable<T> items) |
29 | public CircularQueue(IEnumerable<T> items) |
|
30 | { |
30 | { |
|
31 | Enqueue(items); |
31 | Enqueue(items); |
|
32 | } |
32 | } |
|
33 | |
33 | |
|
34 | public CircularQueue(CircularQueue<T> queue) |
34 | public CircularQueue(CircularQueue<T> queue) |
|
35 | { |
35 | { |
|
36 | lock (SyncRoot) |
36 | lock (SyncRoot) |
|
37 | { |
37 | { |
|
38 | lock (queue.SyncRoot) |
38 | lock (queue.SyncRoot) |
|
39 | { |
39 | { |
|
40 | foreach (var item in queue.Items) |
40 | foreach (var item in queue.Items) |
|
41 | { |
41 | { |
|
42 | Store.AddLast(item); |
42 | Store.AddLast(item); |
|
43 | } |
43 | } |
|
44 | |
44 | |
|
45 | if (CurrentNode == null) |
45 | if (CurrentNode == null) |
|
46 | CurrentNode = Store.First; |
46 | CurrentNode = Store.First; |
|
47 | } |
47 | } |
|
48 | } |
48 | } |
|
49 | } |
49 | } |
|
50 | |
50 | |
|
51 | public int Count |
51 | public int Count |
|
52 | { |
52 | { |
|
53 | get |
53 | get |
|
54 | { |
54 | { |
|
55 | lock (SyncRoot) |
55 | lock (SyncRoot) |
|
56 | { |
56 | { |
|
57 | return Store.Count; |
57 | return Store.Count; |
|
58 | } |
58 | } |
|
59 | } |
59 | } |
|
60 | } |
60 | } |
|
- | 61 | |
||
- | 62 | public bool IsEmpty |
||
- | 63 | { |
||
- | 64 | get |
||
- | 65 | { |
||
- | 66 | lock (SyncRoot) |
||
- | 67 | { |
||
- | 68 | return Store.Count.Equals(0); |
||
- | 69 | } |
||
- | 70 | } |
||
- | 71 | } |
||
61 | |
72 | |
|
62 | private T GetNext |
73 | private T GetNext |
|
63 | { |
74 | { |
|
64 | get |
75 | get |
|
65 | { |
76 | { |
|
66 | lock (SyncRoot) |
77 | lock (SyncRoot) |
|
67 | { |
78 | { |
|
68 | if (CurrentNode == null) |
79 | if (CurrentNode == null) |
|
69 | return default(T); |
80 | return default(T); |
|
70 | |
81 | |
|
71 | var value = CurrentNode.Value; |
82 | var value = CurrentNode.Value; |
|
72 | |
83 | |
|
73 | switch (CurrentNode.Next != null) |
84 | switch (CurrentNode.Next != null) |
|
74 | { |
85 | { |
|
75 | case true: |
86 | case true: |
|
76 | CurrentNode = CurrentNode.Next; |
87 | CurrentNode = CurrentNode.Next; |
|
77 | break; |
88 | break; |
|
78 | |
89 | |
|
79 | default: |
90 | default: |
|
80 | CurrentNode = Store.First; |
91 | CurrentNode = Store.First; |
|
81 | break; |
92 | break; |
|
82 | } |
93 | } |
|
83 | |
94 | |
|
84 | return value; |
95 | return value; |
|
85 | } |
96 | } |
|
86 | } |
97 | } |
|
87 | } |
98 | } |
|
88 | |
99 | |
|
89 | public IEnumerable<T> Items |
100 | public IEnumerable<T> Items |
|
90 | { |
101 | { |
|
91 | get |
102 | get |
|
92 | { |
103 | { |
|
93 | lock (SyncRoot) |
104 | lock (SyncRoot) |
|
94 | { |
105 | { |
|
95 | if (CurrentNode == null) |
106 | if (CurrentNode == null) |
|
96 | yield break; |
107 | yield break; |
|
97 | |
108 | |
|
98 | var node = CurrentNode; |
109 | var node = CurrentNode; |
|
99 | do |
110 | do |
|
100 | { |
111 | { |
|
101 | yield return node.Value; |
112 | yield return node.Value; |
|
102 | node = node.Next; |
113 | node = node.Next; |
|
103 | } while (node != null); |
114 | } while (node != null); |
|
104 | } |
115 | } |
|
105 | } |
116 | } |
|
106 | } |
117 | } |
|
107 | |
118 | |
|
108 | public void Enqueue(IEnumerable<T> items) |
119 | public void Enqueue(IEnumerable<T> items) |
|
109 | { |
120 | { |
|
110 | lock (SyncRoot) |
121 | lock (SyncRoot) |
|
111 | { |
122 | { |
|
112 | foreach (var i in items) |
123 | foreach (var i in items) |
|
113 | Store.AddLast(i); |
124 | Store.AddLast(i); |
|
114 | |
125 | |
|
115 | if (CurrentNode == null) |
126 | if (CurrentNode == null) |
|
116 | CurrentNode = Store.First; |
127 | CurrentNode = Store.First; |
|
117 | } |
128 | } |
|
118 | } |
129 | } |
|
119 | |
130 | |
|
120 | public void Enqueue(T item) |
131 | public void Enqueue(T item) |
|
121 | { |
132 | { |
|
122 | lock (SyncRoot) |
133 | lock (SyncRoot) |
|
123 | { |
134 | { |
|
124 | Store.AddLast(item); |
135 | Store.AddLast(item); |
|
125 | |
136 | |
|
126 | if (CurrentNode == null) |
137 | if (CurrentNode == null) |
|
127 | CurrentNode = Store.First; |
138 | CurrentNode = Store.First; |
|
128 | } |
139 | } |
|
129 | } |
140 | } |
|
130 | |
141 | |
|
131 | public T Dequeue() |
142 | public T Dequeue() |
|
132 | { |
143 | { |
|
133 | lock (SyncRoot) |
144 | lock (SyncRoot) |
|
134 | { |
145 | { |
|
135 | return GetNext; |
146 | return GetNext; |
|
136 | } |
147 | } |
|
137 | } |
148 | } |
|
138 | |
149 | |
|
139 | public IEnumerable<T> Dequeue(int count = 1) |
150 | public IEnumerable<T> Dequeue(int count = 1) |
|
140 | { |
151 | { |
|
141 | if (count <= 0) |
152 | if (count <= 0) |
|
142 | yield break; |
153 | yield break; |
|
143 | |
154 | |
|
144 | lock (SyncRoot) |
155 | lock (SyncRoot) |
|
145 | { |
156 | { |
|
146 | if (CurrentNode == null) |
157 | if (CurrentNode == null) |
|
147 | yield break; |
158 | yield break; |
|
148 | |
159 | |
|
149 | do |
160 | do |
|
150 | { |
161 | { |
|
151 | yield return GetNext; |
162 | yield return GetNext; |
|
152 | } while (--count != 0); |
163 | } while (--count != 0); |
|
153 | } |
164 | } |
|
154 | } |
165 | } |
|
155 | |
166 | |
|
156 | public void Clear() |
167 | public void Clear() |
|
157 | { |
168 | { |
|
158 | lock (SyncRoot) |
169 | lock (SyncRoot) |
|
159 | { |
170 | { |
|
160 | Store.Clear(); |
171 | Store.Clear(); |
|
161 | |
172 | |
|
162 | CurrentNode = null; |
173 | CurrentNode = null; |
|
163 | } |
174 | } |
|
164 | } |
175 | } |
|
165 | |
176 | |
|
166 | public bool Contains(T item) |
177 | public bool Contains(T item) |
|
167 | { |
178 | { |
|
168 | lock (SyncRoot) |
179 | lock (SyncRoot) |
|
169 | { |
180 | { |
|
170 | return Store.Contains(item); |
181 | return Store.Contains(item); |
|
171 | } |
182 | } |
|
172 | } |
183 | } |
|
173 | |
184 | |
|
174 | public void CopyTo(T[] array, int arrayIndex) |
185 | public void CopyTo(T[] array, int arrayIndex) |
|
175 | { |
186 | { |
|
176 | lock (SyncRoot) |
187 | lock (SyncRoot) |
|
177 | { |
188 | { |
|
178 | Store.CopyTo(array, arrayIndex); |
189 | Store.CopyTo(array, arrayIndex); |
|
179 | } |
190 | } |
|
180 | } |
191 | } |
|
181 | |
192 | |
|
182 | public bool Remove(T item) |
193 | public bool Remove(T item) |
|
183 | { |
194 | { |
|
184 | lock (SyncRoot) |
195 | lock (SyncRoot) |
|
185 | { |
196 | { |
|
186 | var node = Store.Find(item); |
197 | var node = Store.Find(item); |
|
187 | if (node == null) |
198 | if (node == null) |
|
188 | return false; |
199 | return false; |
|
189 | if (CurrentNode.Equals(node)) |
200 | if (CurrentNode.Equals(node)) |
|
190 | { |
201 | { |
|
191 | switch (node.Next != null) |
202 | switch (node.Next != null) |
|
192 | { |
203 | { |
|
193 | case true: |
204 | case true: |
|
194 | CurrentNode = node.Next; |
205 | CurrentNode = node.Next; |
|
195 | break; |
206 | break; |
|
196 | |
207 | |
|
197 | default: |
208 | default: |
|
198 | CurrentNode = Store.First; |
209 | CurrentNode = Store.First; |
|
199 | break; |
210 | break; |
|
200 | } |
211 | } |
|
201 | } |
212 | } |
|
202 | Store.Remove(node); |
213 | Store.Remove(node); |
|
203 | return true; |
214 | return true; |
|
204 | } |
215 | } |
|
205 | } |
216 | } |
|
206 | |
217 | |
|
207 | public void RemoveAll(IEnumerable<T> items) |
218 | public void RemoveAll(IEnumerable<T> items) |
|
208 | { |
219 | { |
|
209 | var itemSet = new HashSet<T>(items); |
220 | var itemSet = new HashSet<T>(items); |
|
210 | lock (SyncRoot) |
221 | lock (SyncRoot) |
|
211 | { |
222 | { |
|
212 | var node = CurrentNode; |
223 | var node = CurrentNode; |
|
213 | do |
224 | do |
|
214 | { |
225 | { |
|
215 | var next = node.Next; |
226 | var next = node.Next; |
|
216 | if (itemSet.Contains(node.Value)) |
227 | if (itemSet.Contains(node.Value)) |
|
217 | { |
228 | { |
|
218 | switch (next != null) |
229 | switch (next != null) |
|
219 | { |
230 | { |
|
220 | case true: |
231 | case true: |
|
221 | CurrentNode = next; |
232 | CurrentNode = next; |
|
222 | break; |
233 | break; |
|
223 | |
234 | |
|
224 | default: |
235 | default: |
|
225 | CurrentNode = Store.First; |
236 | CurrentNode = Store.First; |
|
226 | break; |
237 | break; |
|
227 | } |
238 | } |
|
228 | Store.Remove(node); |
239 | Store.Remove(node); |
|
229 | } |
240 | } |
|
230 | node = next; |
241 | node = next; |
|
231 | } while (node != null); |
242 | } while (node != null); |
|
232 | } |
243 | } |
|
233 | } |
244 | } |
|
234 | } |
245 | } |
|
235 | } |
246 | } |
|
236 | |
247 | |