diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs index 2149b8ad9f..2731e9956f 100644 --- a/OpenSim/Framework/MinHeap.cs +++ b/OpenSim/Framework/MinHeap.cs @@ -65,7 +65,7 @@ namespace OpenSim.Framework { if (handle != null) { - handle.Clear(); + handle.heap = null; handle = null; } value = default(T); @@ -96,8 +96,8 @@ namespace OpenSim.Framework public MinHeap(Comparison comparison) : this(DEFAULT_CAPACITY, comparison) { } public MinHeap(int _capacity, Comparison _comparison) { - minCapacity = _capacity; - items = new HeapItem[minCapacity]; + minCapacity = 16; + items = new HeapItem[_capacity]; comparison = _comparison; size = version = 0; } @@ -169,8 +169,8 @@ namespace OpenSim.Framework int current, parent; for (current = index, parent = (current - 1) / 2; - (current > 0) && (comparison(items[parent].value, item.value)) > 0; - current = parent, parent = (current - 1) / 2) + (current > 0) && (comparison(items[parent].value, item.value)) > 0; + current = parent, parent = (current - 1) / 2) { Set(items[parent], current); } @@ -187,11 +187,12 @@ namespace OpenSim.Framework private void BubbleDown(int index) { HeapItem item = items[index]; - int current, child; + int current; + int child; - for (current = index, child = (2 * current) + 1; - current < size / 2; - current = child, child = (2 * current) + 1) + for(current = index , child = (2 * current) + 1; + current < size / 2; + current = child, child = (2 * current) + 1) { if ((child < size - 1) && comparison(items[child].value, items[child + 1].value) > 0) ++child; @@ -293,14 +294,17 @@ namespace OpenSim.Framework throw new ArgumentOutOfRangeException("index"); items[index].Clear(); - if (--size > 0 && index != size) - { - Set(items[size], index); - items[size].ClearRef(); - if (!BubbleUp(index)) - BubbleDown(index); + --size; + if (size > 0) + { if(index != size) + { + Set(items[size], index); + items[size].ClearRef(); + if (!BubbleUp(index)) + BubbleDown(index); + } } - if(size == 0 && items.Length > 4 * minCapacity) + else if(items.Length > 4 * minCapacity) items = new HeapItem[minCapacity]; } diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index 20d2049608..53b4f8c738 100644 --- a/OpenSim/Framework/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs @@ -46,14 +46,14 @@ namespace OpenSim.Framework /// Total number of queues (priorities) available /// - public const uint NumberOfQueues = 12; // includes immediate queues, m_queueCounts need to be set acording + public const uint NumberOfQueues = 13; // includes immediate queues, m_queueCounts need to be set acording /// /// Number of queuest (priorities) that are processed immediately /// [] m_heaps = new MinHeap[NumberOfQueues]; @@ -85,7 +85,7 @@ namespace OpenSim.Framework public PriorityQueue(int capacity) { - m_capacity = capacity; + m_capacity = 16; capacity /= 4; for (int i = 0; i < m_heaps.Length; ++i) @@ -137,14 +137,24 @@ namespace OpenSim.Framework { lookupH = lookup.Handle; entry = lookup.Heap[lookupH].EntryOrder; + EntityUpdate up = lookup.Heap[lookupH].Value; value.Update(lookup.Heap[lookupH].Value); lookup.Heap.Remove(lookupH); + + if((up.Flags & PrimUpdateFlags.CancelKill) != 0) + entry = m_nextRequest++; + + pqueue = Util.Clamp(pqueue, 0, NumberOfQueues - 1); + lookup.Heap = m_heaps[pqueue]; + lookup.Heap.Add(new MinHeapItem(pqueue, entry, value), ref lookup.Handle); + m_lookupTable[localid] = lookup; + return true; } - else - { - entry = m_nextRequest++; - ++m_added; - } + + value.Update(); + + entry = m_nextRequest++; + ++m_added; pqueue = Util.Clamp(pqueue, 0, NumberOfQueues - 1); lookup.Heap = m_heaps[pqueue]; @@ -178,7 +188,7 @@ namespace OpenSim.Framework /// oldest item from the next queue in order to provide fair access to /// all of the queues /// - public bool TryDequeue(out EntityUpdate value, out Int32 timeinqueue) + public bool TryDequeue(out EntityUpdate value) { // If there is anything in immediate queues, return it first no // matter what else. Breaks fairness. But very useful. @@ -189,7 +199,6 @@ namespace OpenSim.Framework { MinHeapItem item = m_heaps[iq].RemoveMin(); m_lookupTable.Remove(item.Value.Entity.LocalId); - timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; return true; @@ -210,9 +219,7 @@ namespace OpenSim.Framework MinHeapItem item = curheap.RemoveMin(); m_lookupTable.Remove(item.Value.Entity.LocalId); - timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; - return true; } @@ -232,12 +239,10 @@ namespace OpenSim.Framework MinHeapItem item = curheap.RemoveMin(); m_lookupTable.Remove(item.Value.Entity.LocalId); - timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; return true; } - timeinqueue = 0; value = default(EntityUpdate); if(m_lookupTable.Count == 0 && m_added > 8 * m_capacity) { @@ -247,23 +252,20 @@ namespace OpenSim.Framework return false; } - public bool TryOrderedDequeue(out EntityUpdate value, out Int32 timeinqueue) + public bool TryOrderedDequeue(out EntityUpdate value) { - MinHeap curheap; for (int iq = 0; iq < NumberOfQueues; ++iq) { - curheap = m_heaps[iq]; + MinHeap curheap = m_heaps[iq]; if (curheap.Count > 0) { MinHeapItem item = curheap.RemoveMin(); m_lookupTable.Remove(item.Value.Entity.LocalId); - timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); value = item.Value; return true; } } - timeinqueue = 0; value = default(EntityUpdate); if(m_lookupTable.Count == 0 && m_added > 8 * m_capacity) { @@ -280,13 +282,11 @@ namespace OpenSim.Framework public void Reprioritize(UpdatePriorityHandler handler) { MinHeapItem item; + uint pqueue = 0; foreach (LookupItem lookup in new List(m_lookupTable.Values)) { if (lookup.Heap.TryGetValue(lookup.Handle, out item)) { - uint pqueue = item.PriorityQueue; - uint localid = item.Value.Entity.LocalId; - if (handler(ref pqueue, item.Value.Entity)) { // unless the priority queue has changed, there is no need to modify @@ -299,14 +299,14 @@ namespace OpenSim.Framework LookupItem litem = lookup; litem.Heap = m_heaps[pqueue]; litem.Heap.Add(new MinHeapItem(pqueue, item), ref litem.Handle); - m_lookupTable[localid] = litem; + m_lookupTable[item.Value.Entity.LocalId] = litem; } } else { // m_log.WarnFormat("[PQUEUE]: UpdatePriorityHandler returned false for {0}",item.Value.Entity.UUID); lookup.Heap.Remove(lookup.Handle); - m_lookupTable.Remove(localid); + m_lookupTable.Remove(item.Value.Entity.LocalId); } } } @@ -318,7 +318,7 @@ namespace OpenSim.Framework { string s = ""; for (int i = 0; i < NumberOfQueues; i++) - s += String.Format("{0,7} ",m_heaps[i].Count); + s += String.Format("{0,7} ", m_heaps[i].Count); return s; } @@ -345,15 +345,6 @@ namespace OpenSim.Framework } } - private Int32 entrytime; - internal Int32 EntryTime - { - get - { - return entrytime; - } - } - private UInt64 entryorder; internal UInt64 EntryOrder { @@ -365,7 +356,6 @@ namespace OpenSim.Framework internal MinHeapItem(uint _pqueue, MinHeapItem other) { - entrytime = other.entrytime; entryorder = other.entryorder; value = other.value; pqueue = _pqueue; @@ -373,7 +363,6 @@ namespace OpenSim.Framework internal MinHeapItem(uint _pqueue, UInt64 _entryorder, EntityUpdate _value) { - entrytime = Util.EnvironmentTickCount(); entryorder = _entryorder; value = _value; pqueue = _pqueue;