aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/MinHeap.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/MinHeap.cs150
1 files changed, 80 insertions, 70 deletions
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs
index 99ac25d..68f6668 100644
--- a/OpenSim/Framework/MinHeap.cs
+++ b/OpenSim/Framework/MinHeap.cs
@@ -45,8 +45,8 @@ namespace OpenSim.Framework
45 45
46 internal void Clear() 46 internal void Clear()
47 { 47 {
48 this.index = -1; 48 index = -1;
49 this.heap = null; 49 heap = null;
50 } 50 }
51 } 51 }
52 52
@@ -55,23 +55,26 @@ namespace OpenSim.Framework
55 internal T value; 55 internal T value;
56 internal Handle handle; 56 internal Handle handle;
57 57
58 internal HeapItem(T value, Handle handle) 58 internal HeapItem(T _value, Handle _handle)
59 { 59 {
60 this.value = value; 60 value = _value;
61 this.handle = handle; 61 handle = _handle;
62 } 62 }
63 63
64 internal void Clear() 64 internal void Clear()
65 { 65 {
66 if (this.handle != null) 66 if (handle != null)
67 this.handle.Clear(); 67 {
68 ClearRef(); 68 handle.Clear();
69 handle = null;
70 }
71 value = default(T);
69 } 72 }
70 73
71 internal void ClearRef() 74 internal void ClearRef()
72 { 75 {
73 this.value = default(T); 76 value = default(T);
74 this.handle = null; 77 handle = null;
75 } 78 }
76 } 79 }
77 80
@@ -81,6 +84,7 @@ namespace OpenSim.Framework
81 private int size; 84 private int size;
82 private object sync_root; 85 private object sync_root;
83 private int version; 86 private int version;
87 private int capacity;
84 88
85 private Comparison<T> comparison; 89 private Comparison<T> comparison;
86 90
@@ -90,14 +94,15 @@ namespace OpenSim.Framework
90 public MinHeap(int capacity, IComparer<T> comparer) : 94 public MinHeap(int capacity, IComparer<T> comparer) :
91 this(capacity, new Comparison<T>(comparer.Compare)) { } 95 this(capacity, new Comparison<T>(comparer.Compare)) { }
92 public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { } 96 public MinHeap(Comparison<T> comparison) : this(DEFAULT_CAPACITY, comparison) { }
93 public MinHeap(int capacity, Comparison<T> comparison) 97 public MinHeap(int _capacity, Comparison<T> _comparison)
94 { 98 {
95 this.items = new HeapItem[capacity]; 99 capacity = _capacity;
96 this.comparison = comparison; 100 items = new HeapItem[capacity];
97 this.size = this.version = 0; 101 comparison = _comparison;
102 size = version = 0;
98 } 103 }
99 104
100 public int Count { get { return this.size; } } 105 public int Count { get { return size; } }
101 106
102 public bool IsReadOnly { get { return false; } } 107 public bool IsReadOnly { get { return false; } }
103 108
@@ -108,15 +113,16 @@ namespace OpenSim.Framework
108 get 113 get
109 { 114 {
110 Handle handle = ValidateThisHandle(key); 115 Handle handle = ValidateThisHandle(key);
111 return this.items[handle.index].value; 116 return items[handle.index].value;
112 } 117 }
113 118
114 set 119 set
115 { 120 {
116 Handle handle = ValidateThisHandle(key); 121 Handle handle = ValidateThisHandle(key);
117 this.items[handle.index].value = value; 122 int indx = handle.index;
118 if (!BubbleUp(handle.index)) 123 items[indx].value = value;
119 BubbleDown(handle.index); 124 if (!BubbleUp(indx))
125 BubbleDown(indx);
120 } 126 }
121 } 127 }
122 128
@@ -124,9 +130,9 @@ namespace OpenSim.Framework
124 { 130 {
125 get 131 get
126 { 132 {
127 if (this.sync_root == null) 133 if (sync_root == null)
128 Interlocked.CompareExchange<object>(ref this.sync_root, new object(), null); 134 Interlocked.CompareExchange<object>(ref sync_root, new object(), null);
129 return this.sync_root; 135 return sync_root;
130 } 136 }
131 } 137 }
132 138
@@ -152,27 +158,27 @@ namespace OpenSim.Framework
152 158
153 private void Set(HeapItem item, int index) 159 private void Set(HeapItem item, int index)
154 { 160 {
155 this.items[index] = item; 161 items[index] = item;
156 if (item.handle != null) 162 if (item.handle != null)
157 item.handle.index = index; 163 item.handle.index = index;
158 } 164 }
159 165
160 private bool BubbleUp(int index) 166 private bool BubbleUp(int index)
161 { 167 {
162 HeapItem item = this.items[index]; 168 HeapItem item = items[index];
163 int current, parent; 169 int current, parent;
164 170
165 for (current = index, parent = (current - 1) / 2; 171 for (current = index, parent = (current - 1) / 2;
166 (current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0; 172 (current > 0) && (comparison(items[parent].value, item.value)) > 0;
167 current = parent, parent = (current - 1) / 2) 173 current = parent, parent = (current - 1) / 2)
168 { 174 {
169 Set(this.items[parent], current); 175 Set(items[parent], current);
170 } 176 }
171 177
172 if (current != index) 178 if (current != index)
173 { 179 {
174 Set(item, current); 180 Set(item, current);
175 ++this.version; 181 ++version;
176 return true; 182 return true;
177 } 183 }
178 return false; 184 return false;
@@ -180,24 +186,24 @@ namespace OpenSim.Framework
180 186
181 private void BubbleDown(int index) 187 private void BubbleDown(int index)
182 { 188 {
183 HeapItem item = this.items[index]; 189 HeapItem item = items[index];
184 int current, child; 190 int current, child;
185 191
186 for (current = index, child = (2 * current) + 1; 192 for (current = index, child = (2 * current) + 1;
187 current < this.size / 2; 193 current < size / 2;
188 current = child, child = (2 * current) + 1) 194 current = child, child = (2 * current) + 1)
189 { 195 {
190 if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0) 196 if ((child < size - 1) && comparison(items[child].value, items[child + 1].value) > 0)
191 ++child; 197 ++child;
192 if (this.comparison(this.items[child].value, item.value) >= 0) 198 if (comparison(items[child].value, item.value) >= 0)
193 break; 199 break;
194 Set(this.items[child], current); 200 Set(items[child], current);
195 } 201 }
196 202
197 if (current != index) 203 if (current != index)
198 { 204 {
199 Set(item, current); 205 Set(item, current);
200 ++this.version; 206 ++version;
201 } 207 }
202 } 208 }
203 209
@@ -206,7 +212,7 @@ namespace OpenSim.Framework
206 Handle handle = ValidateHandle(key); 212 Handle handle = ValidateHandle(key);
207 if (handle.index > -1) 213 if (handle.index > -1)
208 { 214 {
209 value = this.items[handle.index].value; 215 value = items[handle.index].value;
210 return true; 216 return true;
211 } 217 }
212 value = default(T); 218 value = default(T);
@@ -228,12 +234,12 @@ namespace OpenSim.Framework
228 234
229 public void Add(T value, IHandle ihandle) 235 public void Add(T value, IHandle ihandle)
230 { 236 {
231 if (this.size == this.items.Length) 237 if (size == items.Length)
232 { 238 {
233 int capacity = (int)((this.items.Length * 200L) / 100L); 239 int capacity = (int)((items.Length * 200L) / 100L);
234 if (capacity < (this.items.Length + DEFAULT_CAPACITY)) 240 if (capacity < (items.Length + DEFAULT_CAPACITY))
235 capacity = this.items.Length + DEFAULT_CAPACITY; 241 capacity = items.Length + DEFAULT_CAPACITY;
236 Array.Resize<HeapItem>(ref this.items, capacity); 242 Array.Resize<HeapItem>(ref items, capacity);
237 } 243 }
238 244
239 Handle handle = null; 245 Handle handle = null;
@@ -245,8 +251,8 @@ namespace OpenSim.Framework
245 251
246 HeapItem item = new MinHeap<T>.HeapItem(value, handle); 252 HeapItem item = new MinHeap<T>.HeapItem(value, handle);
247 253
248 Set(item, this.size); 254 Set(item, size);
249 BubbleUp(this.size++); 255 BubbleUp(size++);
250 } 256 }
251 257
252 public void Add(T value) 258 public void Add(T value)
@@ -256,50 +262,54 @@ namespace OpenSim.Framework
256 262
257 public T Min() 263 public T Min()
258 { 264 {
259 if (this.size == 0) 265 if (size == 0)
260 throw new InvalidOperationException("Heap is empty"); 266 throw new InvalidOperationException("Heap is empty");
261 267
262 return this.items[0].value; 268 return items[0].value;
263 } 269 }
264 270
265 public void Clear() 271 public void Clear()
266 { 272 {
267 for (int index = 0; index < this.size; ++index) 273 for (int index = 0; index < size; ++index)
268 this.items[index].Clear(); 274 items[index].Clear();
269 this.size = 0; 275 size = 0;
270 ++this.version; 276 if(items.Length > capacity)
277 items = new HeapItem[capacity];
278 ++version;
271 } 279 }
272 280
273 public void TrimExcess() 281 public void TrimExcess()
274 { 282 {
275 int length = (int)(this.items.Length * 0.9); 283 int length = (int)(items.Length * 0.9);
276 if (this.size < length) 284 if (size < length)
277 Array.Resize<HeapItem>(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY)); 285 Array.Resize<HeapItem>(ref items, Math.Min(size, capacity));
278 } 286 }
279 287
280 private void RemoveAt(int index) 288 private void RemoveAt(int index)
281 { 289 {
282 if (this.size == 0) 290 if (size == 0)
283 throw new InvalidOperationException("Heap is empty"); 291 throw new InvalidOperationException("Heap is empty");
284 if (index >= this.size) 292 if (index >= size)
285 throw new ArgumentOutOfRangeException("index"); 293 throw new ArgumentOutOfRangeException("index");
286 294
287 this.items[index].Clear(); 295 items[index].Clear();
288 if (--this.size > 0 && index != this.size) 296 if (--size > 0 && index != size)
289 { 297 {
290 Set(this.items[this.size], index); 298 Set(items[size], index);
291 this.items[this.size].ClearRef(); 299 items[size].ClearRef();
292 if (!BubbleUp(index)) 300 if (!BubbleUp(index))
293 BubbleDown(index); 301 BubbleDown(index);
294 } 302 }
303 if(size == 0 && items.Length > 4 * capacity)
304 items = new HeapItem[capacity];
295 } 305 }
296 306
297 public T RemoveMin() 307 public T RemoveMin()
298 { 308 {
299 if (this.size == 0) 309 if (size == 0)
300 throw new InvalidOperationException("Heap is empty"); 310 throw new InvalidOperationException("Heap is empty");
301 311
302 HeapItem item = this.items[0]; 312 HeapItem item = items[0];
303 RemoveAt(0); 313 RemoveAt(0);
304 return item.value; 314 return item.value;
305 } 315 }
@@ -307,7 +317,7 @@ namespace OpenSim.Framework
307 public T Remove(IHandle ihandle) 317 public T Remove(IHandle ihandle)
308 { 318 {
309 Handle handle = ValidateThisHandle(ihandle); 319 Handle handle = ValidateThisHandle(ihandle);
310 HeapItem item = this.items[handle.index]; 320 HeapItem item = items[handle.index];
311 RemoveAt(handle.index); 321 RemoveAt(handle.index);
312 return item.value; 322 return item.value;
313 } 323 }
@@ -317,9 +327,9 @@ namespace OpenSim.Framework
317 EqualityComparer<T> comparer = EqualityComparer<T>.Default; 327 EqualityComparer<T> comparer = EqualityComparer<T>.Default;
318 int index; 328 int index;
319 329
320 for (index = 0; index < this.size; ++index) 330 for (index = 0; index < size; ++index)
321 { 331 {
322 if (comparer.Equals(this.items[index].value, value)) 332 if (comparer.Equals(items[index].value, value))
323 return index; 333 return index;
324 } 334 }
325 return -1; 335 return -1;
@@ -356,8 +366,8 @@ namespace OpenSim.Framework
356 if ((length - index) < this.size) 366 if ((length - index) < this.size)
357 throw new ArgumentException("Not enough space available in array starting at index"); 367 throw new ArgumentException("Not enough space available in array starting at index");
358 368
359 for (int i = 0; i < this.size; ++i) 369 for (int i = 0; i < size; ++i)
360 array[index + i] = this.items[i].value; 370 array[index + i] = items[i].value;
361 } 371 }
362 372
363 public void CopyTo(Array array, int index) 373 public void CopyTo(Array array, int index)
@@ -372,13 +382,13 @@ namespace OpenSim.Framework
372 int length = array.Length; 382 int length = array.Length;
373 if ((index < 0) || (index > length)) 383 if ((index < 0) || (index > length))
374 throw new ArgumentOutOfRangeException("index"); 384 throw new ArgumentOutOfRangeException("index");
375 if ((length - index) < this.size) 385 if ((length - index) < size)
376 throw new ArgumentException("Not enough space available in array starting at index"); 386 throw new ArgumentException("Not enough space available in array starting at index");
377 387
378 try 388 try
379 { 389 {
380 for (int i = 0; i < this.size; ++i) 390 for (int i = 0; i < size; ++i)
381 array.SetValue(this.items[i].value, index + i); 391 array.SetValue(items[i].value, index + i);
382 } 392 }
383 catch (ArrayTypeMismatchException) 393 catch (ArrayTypeMismatchException)
384 { 394 {
@@ -388,13 +398,13 @@ namespace OpenSim.Framework
388 398
389 public IEnumerator<T> GetEnumerator() 399 public IEnumerator<T> GetEnumerator()
390 { 400 {
391 int version = this.version; 401 int cversion = version;
392 402
393 for (int index = 0; index < this.size; ++index) 403 for (int index = 0; index < size; ++index)
394 { 404 {
395 if (version != this.version) 405 if (cversion != version)
396 throw new InvalidOperationException("Heap was modified while enumerating"); 406 throw new InvalidOperationException("Heap was modified while enumerating");
397 yield return this.items[index].value; 407 yield return items[index].value;
398 } 408 }
399 } 409 }
400 410