29 using System.Collections;
30 using System.Collections.Generic;
31 using System.Reflection;
33 using OpenSim.Framework;
34 using OpenSim.Framework.Client;
37 namespace OpenSim.Framework
43 public delegate
bool UpdatePriorityHandler(ref uint priority,
ISceneEntity entity);
49 public const uint NumberOfQueues = 12;
54 public const uint NumberOfImmediateQueues = 2;
56 private MinHeap<MinHeapItem>[] m_heaps =
new MinHeap<MinHeapItem>[NumberOfQueues];
57 private Dictionary<uint, LookupItem> m_lookupTable;
62 private uint m_nextQueue = 0;
63 private uint m_countFromQueue = 0;
66 private uint[] m_queueCounts = {0, 0, 8, 8, 5, 4, 3, 2, 1, 1, 1, 1};
72 private UInt64 m_nextRequest = 0;
77 private object m_syncRoot =
new object();
78 public object SyncRoot {
79 get {
return this.m_syncRoot; }
83 public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
87 m_lookupTable =
new Dictionary<uint, LookupItem>(capacity);
89 for (
int i = 0; i < m_heaps.Length; ++i)
90 m_heaps[i] =
new MinHeap<MinHeapItem>(capacity);
92 m_nextQueue = NumberOfImmediateQueues;
93 m_countFromQueue = m_queueCounts[m_nextQueue];
95 #endregion Constructor
106 for (
int i = 0; i < m_heaps.Length; ++i)
107 count += m_heaps[i].Count;
120 uint localid = value.Entity.LocalId;
121 UInt64 entry = m_nextRequest++;
122 if (m_lookupTable.TryGetValue(localid, out lookup))
124 entry = lookup.Heap[lookup.Handle].EntryOrder;
125 value.Update(lookup.Heap[lookup.Handle].Value);
126 lookup.Heap.Remove(lookup.Handle);
129 pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1);
130 lookup.Heap = m_heaps[pqueue];
131 lookup.Heap.Add(
new MinHeapItem(pqueue, entry, value), ref lookup.Handle);
132 m_lookupTable[localid] = lookup;
142 foreach (uint localid
in ids)
144 if (m_lookupTable.TryGetValue(localid, out lookup))
146 lookup.Heap.Remove(lookup.Handle);
147 m_lookupTable.Remove(localid);
161 for (
int iq = 0; iq < NumberOfImmediateQueues; iq++)
163 if (m_heaps[iq].Count > 0)
165 MinHeapItem item = m_heaps[iq].RemoveMin();
166 m_lookupTable.Remove(item.Value.Entity.LocalId);
167 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
181 if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0)
185 MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
186 m_lookupTable.Remove(item.Value.Entity.LocalId);
187 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
194 for (uint i = NumberOfImmediateQueues; i < NumberOfQueues; ++i)
197 if(m_nextQueue >= NumberOfQueues)
198 m_nextQueue = NumberOfImmediateQueues;
200 m_countFromQueue = m_queueCounts[m_nextQueue];
202 if (m_heaps[m_nextQueue].Count > 0)
206 MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
207 m_lookupTable.Remove(item.Value.Entity.LocalId);
208 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
226 foreach (LookupItem lookup
in new List<LookupItem>(this.m_lookupTable.Values))
228 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
230 uint pqueue = item.PriorityQueue;
231 uint localid = item.Value.Entity.LocalId;
233 if (handler(ref pqueue, item.Value.Entity))
237 pqueue = Util.Clamp<uint>(pqueue, 0, NumberOfQueues - 1);
238 if (pqueue != item.PriorityQueue)
240 lookup.Heap.Remove(lookup.Handle);
242 LookupItem litem = lookup;
243 litem.Heap = m_heaps[pqueue];
244 litem.Heap.Add(
new MinHeapItem(pqueue, item), ref litem.Handle);
245 m_lookupTable[localid] = litem;
251 lookup.Heap.Remove(lookup.Handle);
252 this.m_lookupTable.Remove(localid);
263 for (
int i = 0; i < NumberOfQueues; i++)
264 s += String.Format(
"{0,7} ",m_heaps[i].Count);
268 #endregion PublicMethods
271 private struct MinHeapItem : IComparable<MinHeapItem>
287 private Int32 entrytime;
288 internal Int32 EntryTime {
290 return this.entrytime;
294 private UInt64 entryorder;
295 internal UInt64 EntryOrder
298 return this.entryorder;
302 internal MinHeapItem(uint pqueue, MinHeapItem other)
304 this.entrytime = other.entrytime;
305 this.entryorder = other.entryorder;
306 this.value = other.value;
307 this.pqueue = pqueue;
310 internal MinHeapItem(uint pqueue, UInt64 entryorder,
IEntityUpdate value)
312 this.entrytime = Util.EnvironmentTickCount();
313 this.entryorder = entryorder;
315 this.pqueue = pqueue;
318 public override string ToString()
320 return String.Format(
"[{0},{1},{2}]",pqueue,entryorder,value.Entity.LocalId);
323 public int CompareTo(MinHeapItem other)
327 return Comparer<UInt64>.Default.Compare(this.EntryOrder, other.EntryOrder);
333 private struct LookupItem
335 internal MinHeap<MinHeapItem> Heap;
bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
Remove an item from one of the queues. Specifically, it removes the oldest item from the next queue i...
void Reprioritize(UpdatePriorityHandler handler)
Reapply the prioritization function to each of the updates currently stored in the priority queues...
PriorityQueue(int capacity)
override string ToString()
bool Enqueue(uint pqueue, IEntityUpdate value)
Enqueue an item into the specified priority queue
void Remove(List< uint > ids)