/// <summary> /// Enqueue an item into the specified priority queue /// </summary> public bool Enqueue(uint pqueue, EntityUpdate value) { LookupItem lookup; IHandle lookupH; UInt64 entry; uint localid = value.Entity.LocalId; if (m_lookupTable.TryGetValue(localid, out lookup)) { lookupH = lookup.Handle; entry = lookup.Heap[lookupH].EntryOrder; value.Update(lookup.Heap[lookupH].Value); lookup.Heap.Remove(lookupH); } else { entry = m_nextRequest++; ++m_added; } pqueue = Util.Clamp <uint>(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); }
/// <summary> /// Reapply the prioritization function to each of the updates currently /// stored in the priority queues. /// </summary public void Reprioritize(UpdatePriorityHandler handler) { MinHeapItem item; foreach (LookupItem lookup in new List <LookupItem>(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 // the entry pqueue = Util.Clamp <uint>(pqueue, 0, NumberOfQueues - 1); if (pqueue != item.PriorityQueue) { lookup.Heap.Remove(lookup.Handle); LookupItem litem = lookup; litem.Heap = m_heaps[pqueue]; litem.Heap.Add(new MinHeapItem(pqueue, item), ref litem.Handle); m_lookupTable[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); } } } }
// Make sure user specified region sizes are sane. // Must be multiples of legacy region size (256). private void DoRegionSizeSanityChecks() { if (RegionSizeX != Constants.RegionSize || RegionSizeY != Constants.RegionSize) { // Doing non-legacy region sizes. // Enforce region size to be multiples of the legacy region size (256) uint partial = RegionSizeX % Constants.RegionSize; if (partial != 0) { RegionSizeX -= partial; if (RegionSizeX == 0) { RegionSizeX = Constants.RegionSize; } m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeX={3} instead of specified {4}", LogHeader, Constants.RegionSize, m_regionName, RegionSizeX, RegionSizeX + partial); } partial = RegionSizeY % Constants.RegionSize; if (partial != 0) { RegionSizeY -= partial; if (RegionSizeY == 0) { RegionSizeY = Constants.RegionSize; } m_log.ErrorFormat("{0} Region size must be multiple of {1}. Enforcing {2}.RegionSizeY={3} instead of specified {4}", LogHeader, Constants.RegionSize, m_regionName, RegionSizeY, RegionSizeY + partial); } // Because of things in the viewer, regions MUST be square. // Remove this check when viewers have been updated. if (RegionSizeX != RegionSizeY) { uint minSize = Math.Min(RegionSizeX, RegionSizeY); RegionSizeX = minSize; RegionSizeY = minSize; m_log.ErrorFormat("{0} Regions must be square until viewers are updated. Forcing region {1} size to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY); } // There is a practical limit to region size. if (RegionSizeX > Constants.MaximumRegionSize || RegionSizeY > Constants.MaximumRegionSize) { RegionSizeX = Util.Clamp <uint>(RegionSizeX, Constants.RegionSize, Constants.MaximumRegionSize); RegionSizeY = Util.Clamp <uint>(RegionSizeY, Constants.RegionSize, Constants.MaximumRegionSize); m_log.ErrorFormat("{0} Region dimensions must be less than {1}. Clamping {2}'s size to <{3},{4}>", LogHeader, Constants.MaximumRegionSize, m_regionName, RegionSizeX, RegionSizeY); } m_log.InfoFormat("{0} Region {1} size set to <{2},{3}>", LogHeader, m_regionName, RegionSizeX, RegionSizeY); } }