29 using System.Collections.Generic;
30 using System.Reflection;
32 using OpenMetaverse.Packets;
34 using OpenSim.Framework.Monitoring;
36 namespace OpenSim.
Region.ClientStack.LindenUDP
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 private readonly Dictionary<PacketType, Stack<Packet>> pool =
new Dictionary<PacketType, Stack<Packet>>();
49 private static Dictionary<Type, Stack<Object>> DataBlocks =
new Dictionary<Type, Stack<Object>>();
53 get {
return instance; }
56 public bool RecyclePackets {
get; set; }
58 public bool RecycleDataBlocks {
get; set; }
63 public int PacketsPooled
75 public int BlocksPooled
80 return DataBlocks.Count;
87 public long PacketsRequested {
get;
private set; }
92 public long PacketsReused {
get;
private set; }
97 public long BlocksRequested {
get;
private set; }
102 public long BlocksReused {
get;
private set; }
107 RecyclePackets =
true;
108 RecycleDataBlocks =
true;
123 return Packet.BuildPacket(type);
127 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
132 packet = Packet.BuildPacket(type);
141 packet = pool[type].Pop();
148 private static PacketType GetType(byte[] bytes)
151 PacketFrequency freq;
152 bool isZeroCoded = (bytes[0] & Helpers.MSG_ZEROCODED) != 0;
154 if (bytes[6] == 0xFF)
156 if (bytes[7] == 0xFF)
158 freq = PacketFrequency.Low;
159 if (isZeroCoded && bytes[8] == 0)
162 id = (ushort)((bytes[8] << 8) + bytes[9]);
166 freq = PacketFrequency.Medium;
172 freq = PacketFrequency.High;
176 return Packet.GetType(id, freq);
179 public Packet
GetPacket(byte[] bytes, ref
int packetEnd, byte[] zeroBuffer)
181 PacketType type = GetType(bytes);
186 Packet packet = GetPacket(type);
188 m_log.WarnFormat(
"[PACKETPOOL]: Failed to get packet of type {0}", type);
190 packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
201 if (RecycleDataBlocks)
205 case PacketType.ObjectUpdate:
206 ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
208 foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
209 ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod);
211 oup.ObjectData = null;
214 case PacketType.ImprovedTerseObjectUpdate:
215 ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
217 foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
218 ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
220 itoup.ObjectData = null;
230 case PacketType.AgentUpdate:
231 case PacketType.PacketAck:
232 case PacketType.ObjectUpdate:
233 case PacketType.ImprovedTerseObjectUpdate:
236 PacketType type = packet.Type;
238 if (!pool.ContainsKey(type))
240 pool[type] =
new Stack<Packet>();
243 if ((pool[type]).Count < 50)
247 pool[type].Push(packet);
259 public T GetDataBlock<T>() where T:
new()
267 if (DataBlocks.TryGetValue(typeof(T), out s))
277 DataBlocks[typeof(T)] =
new Stack<Object>();
284 public void ReturnDataBlock<T>(T block) where T:
new()
291 if (!DataBlocks.ContainsKey(typeof(T)))
292 DataBlocks[typeof(T)] =
new Stack<Object>();
294 if (DataBlocks[typeof(T)].Count < 50)
295 DataBlocks[typeof(T)].Push(block);
void ReturnPacket(Packet packet)
Return a packet to the packet pool
Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer)
Packet GetPacket(PacketType type)
Gets a packet of the given type.