wasSharp – Diff between revs 12 and 27
?pathlinks?
Rev 12 | Rev 27 | |||
---|---|---|---|---|
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 | |
61 | |
|
62 | private T GetNext |
62 | private T GetNext |
|
63 | { |
63 | { |
|
64 | get |
64 | get |
|
65 | { |
65 | { |
|
66 | lock (SyncRoot) |
66 | lock (SyncRoot) |
|
67 | { |
67 | { |
|
68 | if (CurrentNode == null) |
68 | if (CurrentNode == null) |
|
69 | return default(T); |
69 | return default(T); |
|
70 | |
70 | |
|
71 | var value = CurrentNode.Value; |
71 | var value = CurrentNode.Value; |
|
72 | |
72 | |
|
73 | switch (CurrentNode.Next != null) |
73 | switch (CurrentNode.Next != null) |
|
74 | { |
74 | { |
|
75 | case true: |
75 | case true: |
|
76 | CurrentNode = CurrentNode.Next; |
76 | CurrentNode = CurrentNode.Next; |
|
77 | break; |
77 | break; |
|
- | 78 | |
||
78 | default: |
79 | default: |
|
79 | CurrentNode = Store.First; |
80 | CurrentNode = Store.First; |
|
80 | break; |
81 | break; |
|
81 | } |
82 | } |
|
82 | |
83 | |
|
83 | return value; |
84 | return value; |
|
84 | } |
85 | } |
|
85 | } |
86 | } |
|
86 | } |
87 | } |
|
87 | |
88 | |
|
88 | public IEnumerable<T> Items |
89 | public IEnumerable<T> Items |
|
89 | { |
90 | { |
|
90 | get |
91 | get |
|
91 | { |
92 | { |
|
92 | lock (SyncRoot) |
93 | lock (SyncRoot) |
|
93 | { |
94 | { |
|
94 | if (CurrentNode == null) |
95 | if (CurrentNode == null) |
|
95 | yield break; |
96 | yield break; |
|
96 | |
97 | |
|
97 | var node = CurrentNode; |
98 | var node = CurrentNode; |
|
98 | do |
99 | do |
|
99 | { |
100 | { |
|
100 | yield return node.Value; |
101 | yield return node.Value; |
|
101 | node = node.Next; |
102 | node = node.Next; |
|
102 | } while (node != null); |
103 | } while (node != null); |
|
103 | } |
104 | } |
|
104 | } |
105 | } |
|
105 | } |
106 | } |
|
106 | |
107 | |
|
107 | public void Enqueue(IEnumerable<T> items) |
108 | public void Enqueue(IEnumerable<T> items) |
|
108 | { |
109 | { |
|
109 | lock (SyncRoot) |
110 | lock (SyncRoot) |
|
110 | { |
111 | { |
|
111 | foreach (var i in items) |
112 | foreach (var i in items) |
|
112 | Store.AddLast(i); |
113 | Store.AddLast(i); |
|
113 | |
114 | |
|
114 | if (CurrentNode == null) |
115 | if (CurrentNode == null) |
|
115 | CurrentNode = Store.First; |
116 | CurrentNode = Store.First; |
|
116 | } |
117 | } |
|
117 | } |
118 | } |
|
118 | |
119 | |
|
119 | public void Enqueue(T item) |
120 | public void Enqueue(T item) |
|
120 | { |
121 | { |
|
121 | lock (SyncRoot) |
122 | lock (SyncRoot) |
|
122 | { |
123 | { |
|
123 | Store.AddLast(item); |
124 | Store.AddLast(item); |
|
124 | |
125 | |
|
125 | if (CurrentNode == null) |
126 | if (CurrentNode == null) |
|
126 | CurrentNode = Store.First; |
127 | CurrentNode = Store.First; |
|
127 | } |
128 | } |
|
128 | } |
129 | } |
|
129 | |
130 | |
|
130 | public T Dequeue() |
131 | public T Dequeue() |
|
131 | { |
132 | { |
|
132 | lock (SyncRoot) |
133 | lock (SyncRoot) |
|
133 | { |
134 | { |
|
134 | return GetNext; |
135 | return GetNext; |
|
135 | } |
136 | } |
|
136 | } |
137 | } |
|
137 | |
138 | |
|
138 | public IEnumerable<T> Dequeue(int count = 1) |
139 | public IEnumerable<T> Dequeue(int count = 1) |
|
139 | { |
140 | { |
|
140 | if (count <= 0) |
141 | if (count <= 0) |
|
141 | yield break; |
142 | yield break; |
|
142 | |
143 | |
|
143 | lock (SyncRoot) |
144 | lock (SyncRoot) |
|
144 | { |
145 | { |
|
145 | if (CurrentNode == null) |
146 | if (CurrentNode == null) |
|
146 | yield break; |
147 | yield break; |
|
147 | |
148 | |
|
148 | do |
149 | do |
|
149 | { |
150 | { |
|
150 | yield return GetNext; |
151 | yield return GetNext; |
|
151 | } while (--count != 0); |
152 | } while (--count != 0); |
|
152 | } |
153 | } |
|
153 | } |
154 | } |
|
154 | |
155 | |
|
155 | public void Clear() |
156 | public void Clear() |
|
156 | { |
157 | { |
|
157 | lock (SyncRoot) |
158 | lock (SyncRoot) |
|
158 | { |
159 | { |
|
159 | Store.Clear(); |
160 | Store.Clear(); |
|
160 | |
161 | |
|
161 | CurrentNode = null; |
162 | CurrentNode = null; |
|
162 | } |
163 | } |
|
163 | } |
164 | } |
|
164 | |
165 | |
|
165 | public bool Contains(T item) |
166 | public bool Contains(T item) |
|
166 | { |
167 | { |
|
167 | lock (SyncRoot) |
168 | lock (SyncRoot) |
|
168 | { |
169 | { |
|
169 | return Store.Contains(item); |
170 | return Store.Contains(item); |
|
170 | } |
171 | } |
|
171 | } |
172 | } |
|
172 | |
173 | |
|
173 | public void CopyTo(T[] array, int arrayIndex) |
174 | public void CopyTo(T[] array, int arrayIndex) |
|
174 | { |
175 | { |
|
175 | lock (SyncRoot) |
176 | lock (SyncRoot) |
|
176 | { |
177 | { |
|
177 | Store.CopyTo(array, arrayIndex); |
178 | Store.CopyTo(array, arrayIndex); |
|
178 | } |
179 | } |
|
179 | } |
180 | } |
|
180 | |
181 | |
|
181 | public bool Remove(T item) |
182 | public bool Remove(T item) |
|
182 | { |
183 | { |
|
183 | lock (SyncRoot) |
184 | lock (SyncRoot) |
|
184 | { |
185 | { |
|
185 | var node = Store.Find(item); |
186 | var node = Store.Find(item); |
|
186 | if (node == null) |
187 | if (node == null) |
|
187 | return false; |
188 | return false; |
|
188 | if (CurrentNode.Equals(node)) |
189 | if (CurrentNode.Equals(node)) |
|
189 | { |
190 | { |
|
190 | switch (node.Next != null) |
191 | switch (node.Next != null) |
|
191 | { |
192 | { |
|
192 | case true: |
193 | case true: |
|
193 | CurrentNode = node.Next; |
194 | CurrentNode = node.Next; |
|
194 | break; |
195 | break; |
|
- | 196 | |
||
195 | default: |
197 | default: |
|
196 | CurrentNode = Store.First; |
198 | CurrentNode = Store.First; |
|
197 | break; |
199 | break; |
|
198 | } |
200 | } |
|
199 | } |
201 | } |
|
200 | Store.Remove(node); |
202 | Store.Remove(node); |
|
201 | return true; |
203 | return true; |
|
202 | } |
204 | } |
|
203 | } |
205 | } |
|
204 | |
206 | |
|
205 | public void RemoveAll(IEnumerable<T> items) |
207 | public void RemoveAll(IEnumerable<T> items) |
|
206 | { |
208 | { |
|
207 | var itemSet = new HashSet<T>(items); |
209 | var itemSet = new HashSet<T>(items); |
|
208 | lock (SyncRoot) |
210 | lock (SyncRoot) |
|
209 | { |
211 | { |
|
210 | var node = CurrentNode; |
212 | var node = CurrentNode; |
|
211 | do |
213 | do |
|
212 | { |
214 | { |
|
213 | var next = node.Next; |
215 | var next = node.Next; |
|
214 | if (itemSet.Contains(node.Value)) |
216 | if (itemSet.Contains(node.Value)) |
|
215 | { |
217 | { |
|
216 | switch (next != null) |
218 | switch (next != null) |
|
217 | { |
219 | { |
|
218 | case true: |
220 | case true: |
|
219 | CurrentNode = next; |
221 | CurrentNode = next; |
|
220 | break; |
222 | break; |
|
- | 223 | |
||
221 | default: |
224 | default: |
|
222 | CurrentNode = Store.First; |
225 | CurrentNode = Store.First; |
|
223 | break; |
226 | break; |
|
224 | } |
227 | } |
|
225 | Store.Remove(node); |
228 | Store.Remove(node); |
|
226 | } |
229 | } |
|
227 | node = next; |
230 | node = next; |
|
228 | } while (node != null); |
231 | } while (node != null); |
|
229 | } |
232 | } |
|
230 | } |
233 | } |
|
231 | } |
234 | } |
|
232 | } |
- | ||
233 | |
235 | } |
|
- | 236 | |
||
234 |
|
- | ||
235 | |
- | ||
236 | |
- | ||
237 | |
- |