Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
                    }
                }
            }
        }
Пример #3
0
        // 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);
            }
        }