wasSharp – Blame information for rev 38

Subversion Repositories:
Rev:
Rev Author Line No. Line
38 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. //
5 ///////////////////////////////////////////////////////////////////////////
6  
7 using System;
8 using System.Collections.Generic;
9 using System.Linq;
10 using System.Threading;
11  
12 // http://www.fallingcanbedeadly.com/posts/crazy-extention-methods-tolazylist/
13  
14 namespace wasSharp.Collections.Specialized
15 {
16 public class ConcurrentLazyList<T> : IList<T>, IDisposable
17 {
18 public ConcurrentLazyList(IEnumerable<T> list)
19 {
20 syncRoot.EnterReadLock();
21 _enumerator = list.GetEnumerator();
22 syncRoot.ExitReadLock();
23 _isFinished = false;
24 _cached = new List<T>();
25 }
26  
27 public T this[int index]
28 {
29 get
30 {
31 if (index < 0)
32 throw new ArgumentOutOfRangeException("index");
33  
34 while (_cached.Count <= index && !_isFinished)
35 {
36 syncRoot.EnterReadLock();
37 GetNext();
38 syncRoot.ExitReadLock();
39 }
40 var cached = _cached[index];
41 return cached;
42 }
43 set
44 {
45 throw new NotSupportedException();
46 }
47 }
48  
49 public int Count
50 {
51 get
52 {
53 syncRoot.EnterWriteLock();
54 Finish();
55 syncRoot.ExitWriteLock();
56 return _cached.Count;
57 }
58 }
59  
60 public IEnumerator<T> GetEnumerator()
61 {
62 int current = 0;
63  
64 while (current < _cached.Count || !_isFinished)
65 {
66 if (current == _cached.Count)
67 {
68 syncRoot.EnterReadLock();
69 GetNext();
70 syncRoot.ExitReadLock();
71 }
72 if (current != _cached.Count)
73 yield return _cached[current];
74 current++;
75 }
76 }
77  
78 public void Dispose()
79 {
80 syncRoot.EnterWriteLock();
81 _enumerator.Dispose();
82 syncRoot.ExitWriteLock();
83 _isFinished = true;
84 }
85  
86 public int IndexOf(T item)
87 {
88 int result = _cached.IndexOf(item);
89 while (result == -1 && !_isFinished)
90 {
91 syncRoot.EnterReadLock();
92 GetNext();
93 syncRoot.ExitReadLock();
94 if (_cached.Last().Equals(item))
95 result = _cached.Count - 1;
96 }
97  
98 return result;
99 }
100  
101 public void Insert(int index, T item)
102 {
103 throw new NotSupportedException();
104 }
105  
106 public void RemoveAt(int index)
107 {
108 throw new NotSupportedException();
109 }
110  
111 public void Add(T item)
112 {
113 throw new NotSupportedException();
114 }
115  
116 public void Clear()
117 {
118 throw new NotSupportedException();
119 }
120  
121 public bool Contains(T item)
122 {
123 syncRoot.EnterReadLock();
124 var contains = IndexOf(item) != -1;
125 syncRoot.ExitReadLock();
126 return contains;
127 }
128  
129 public void CopyTo(T[] array, int arrayIndex)
130 {
131 syncRoot.EnterReadLock();
132 foreach (var item in this)
133 array[arrayIndex++] = item;
134 syncRoot.ExitReadLock();
135 }
136  
137 public bool IsReadOnly => true;
138  
139 public bool Remove(T item)
140 {
141 throw new NotSupportedException();
142 }
143  
144 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
145 {
146 return GetEnumerator();
147 }
148  
149 private void GetNext()
150 {
151 if (!_isFinished)
152 {
153 if (_enumerator.MoveNext())
154 {
155 _cached.Add(_enumerator.Current);
156 }
157 else
158 {
159 _isFinished = true;
160 _enumerator.Dispose();
161 }
162 }
163 }
164  
165 private void Finish()
166 {
167 while (!_isFinished)
168 GetNext();
169 }
170  
171 private readonly List<T> _cached;
172 private readonly IEnumerator<T> _enumerator;
173 private bool _isFinished;
174 private ReaderWriterLockSlim syncRoot = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
175 }
176 }