aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs69
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs57
-rw-r--r--OpenSim/Framework/ClientInfo.cs3
-rw-r--r--OpenSim/Framework/PriorityQueue.cs105
-rw-r--r--OpenSim/Framework/Tests/MundaneFrameworkTests.cs2
5 files changed, 139 insertions, 97 deletions
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index 3dbc215..dbd47d3 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -152,27 +152,6 @@ namespace OpenSim.Framework
152 } 152 }
153 153
154 /// <summary> 154 /// <summary>
155 /// Create AgentCircuitData from a Serializable AgentCircuitData
156 /// </summary>
157 /// <param name="cAgent"></param>
158 public AgentCircuitData(sAgentCircuitData cAgent)
159 {
160 AgentID = new UUID(cAgent.AgentID);
161 SessionID = new UUID(cAgent.SessionID);
162 SecureSessionID = new UUID(cAgent.SecureSessionID);
163 startpos = new Vector3(cAgent.startposx, cAgent.startposy, cAgent.startposz);
164 firstname = cAgent.firstname;
165 lastname = cAgent.lastname;
166 circuitcode = cAgent.circuitcode;
167 child = cAgent.child;
168 InventoryFolder = new UUID(cAgent.InventoryFolder);
169 BaseFolder = new UUID(cAgent.BaseFolder);
170 CapsPath = cAgent.CapsPath;
171 ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
172 Viewer = cAgent.Viewer;
173 }
174
175 /// <summary>
176 /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json 155 /// Pack AgentCircuitData into an OSDMap for transmission over LLSD XML or LLSD json
177 /// </summary> 156 /// </summary>
178 /// <returns>map of the agent circuit data</returns> 157 /// <returns>map of the agent circuit data</returns>
@@ -369,52 +348,4 @@ namespace OpenSim.Framework
369 } 348 }
370 349
371 350
372 /// <summary>
373 /// Serializable Agent Circuit Data
374 /// </summary>
375 [Serializable]
376 public class sAgentCircuitData
377 {
378 public Guid AgentID;
379 public Guid BaseFolder;
380 public string CapsPath = String.Empty;
381 public Dictionary<ulong, string> ChildrenCapSeeds;
382 public bool child;
383 public uint circuitcode;
384 public string firstname;
385 public Guid InventoryFolder;
386 public string lastname;
387 public Guid SecureSessionID;
388 public Guid SessionID;
389 public float startposx;
390 public float startposy;
391 public float startposz;
392 public string Viewer;
393 public string Channel;
394 public string Mac;
395 public string Id0;
396
397 public sAgentCircuitData()
398 {
399 }
400
401 public sAgentCircuitData(AgentCircuitData cAgent)
402 {
403 AgentID = cAgent.AgentID.Guid;
404 SessionID = cAgent.SessionID.Guid;
405 SecureSessionID = cAgent.SecureSessionID.Guid;
406 startposx = cAgent.startpos.X;
407 startposy = cAgent.startpos.Y;
408 startposz = cAgent.startpos.Z;
409 firstname = cAgent.firstname;
410 lastname = cAgent.lastname;
411 circuitcode = cAgent.circuitcode;
412 child = cAgent.child;
413 InventoryFolder = cAgent.InventoryFolder.Guid;
414 BaseFolder = cAgent.BaseFolder.Guid;
415 CapsPath = cAgent.CapsPath;
416 ChildrenCapSeeds = cAgent.ChildrenCapSeeds;
417 Viewer = cAgent.Viewer;
418 }
419 }
420} 351}
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs
index ce0b2fb..a626b82 100644
--- a/OpenSim/Framework/ChildAgentDataUpdate.cs
+++ b/OpenSim/Framework/ChildAgentDataUpdate.cs
@@ -62,7 +62,7 @@ namespace OpenSim.Framework
62 UUID AgentID { get; set; } 62 UUID AgentID { get; set; }
63 63
64 OSDMap Pack(); 64 OSDMap Pack();
65 void Unpack(OSDMap map); 65 void Unpack(OSDMap map, IScene scene);
66 } 66 }
67 67
68 /// <summary> 68 /// <summary>
@@ -122,7 +122,7 @@ namespace OpenSim.Framework
122 return args; 122 return args;
123 } 123 }
124 124
125 public void Unpack(OSDMap args) 125 public void Unpack(OSDMap args, IScene scene)
126 { 126 {
127 if (args.ContainsKey("region_handle")) 127 if (args.ContainsKey("region_handle"))
128 UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle); 128 UInt64.TryParse(args["region_handle"].AsString(), out RegionHandle);
@@ -329,6 +329,10 @@ namespace OpenSim.Framework
329 329
330 public string CallbackURI; 330 public string CallbackURI;
331 331
332 // These two must have the same Count
333 public List<ISceneObject> AttachmentObjects;
334 public List<string> AttachmentObjectStates;
335
332 public virtual OSDMap Pack() 336 public virtual OSDMap Pack()
333 { 337 {
334 m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); 338 m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
@@ -441,7 +445,30 @@ namespace OpenSim.Framework
441 if ((CallbackURI != null) && (!CallbackURI.Equals(""))) 445 if ((CallbackURI != null) && (!CallbackURI.Equals("")))
442 args["callback_uri"] = OSD.FromString(CallbackURI); 446 args["callback_uri"] = OSD.FromString(CallbackURI);
443 447
448 // Attachment objects for fatpack messages
449 if (AttachmentObjects != null)
450 {
451 int i = 0;
452 OSDArray attObjs = new OSDArray(AttachmentObjects.Count);
453 foreach (ISceneObject so in AttachmentObjects)
454 {
455 OSDMap info = new OSDMap(4);
456 info["sog"] = OSD.FromString(so.ToXml2());
457 info["extra"] = OSD.FromString(so.ExtraToXmlString());
458 info["modified"] = OSD.FromBoolean(so.HasGroupChanged);
459 try
460 {
461 info["state"] = OSD.FromString(AttachmentObjectStates[i++]);
462 }
463 catch (IndexOutOfRangeException e)
464 {
465 m_log.WarnFormat("[CHILD AGENT DATA]: scrtips list is shorter than object list.");
466 }
444 467
468 attObjs.Add(info);
469 }
470 args["attach_objects"] = attObjs;
471 }
445 return args; 472 return args;
446 } 473 }
447 474
@@ -450,7 +477,7 @@ namespace OpenSim.Framework
450 /// Avoiding reflection makes it painful to write, but that's the price! 477 /// Avoiding reflection makes it painful to write, but that's the price!
451 /// </summary> 478 /// </summary>
452 /// <param name="hash"></param> 479 /// <param name="hash"></param>
453 public virtual void Unpack(OSDMap args) 480 public virtual void Unpack(OSDMap args, IScene scene)
454 { 481 {
455 m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); 482 m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data");
456 483
@@ -628,6 +655,26 @@ namespace OpenSim.Framework
628 655
629 if (args["callback_uri"] != null) 656 if (args["callback_uri"] != null)
630 CallbackURI = args["callback_uri"].AsString(); 657 CallbackURI = args["callback_uri"].AsString();
658
659 // Attachment objects
660 if (args["attach_objects"] != null && args["attach_objects"].Type == OSDType.Array)
661 {
662 OSDArray attObjs = (OSDArray)(args["attach_objects"]);
663 AttachmentObjects = new List<ISceneObject>();
664 AttachmentObjectStates = new List<string>();
665 foreach (OSD o in attObjs)
666 {
667 if (o.Type == OSDType.Map)
668 {
669 OSDMap info = (OSDMap)o;
670 ISceneObject so = scene.DeserializeObject(info["sog"].AsString());
671 so.ExtraFromXmlString(info["extra"].AsString());
672 so.HasGroupChanged = info["modified"].AsBoolean();
673 AttachmentObjects.Add(so);
674 AttachmentObjectStates.Add(info["state"].AsString());
675 }
676 }
677 }
631 } 678 }
632 679
633 public AgentData() 680 public AgentData()
@@ -655,9 +702,9 @@ namespace OpenSim.Framework
655 return base.Pack(); 702 return base.Pack();
656 } 703 }
657 704
658 public override void Unpack(OSDMap map) 705 public override void Unpack(OSDMap map, IScene scene)
659 { 706 {
660 base.Unpack(map); 707 base.Unpack(map, scene);
661 } 708 }
662 } 709 }
663} 710}
diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs
index fbd18b5..62acb70 100644
--- a/OpenSim/Framework/ClientInfo.cs
+++ b/OpenSim/Framework/ClientInfo.cs
@@ -31,10 +31,9 @@ using System.Net;
31 31
32namespace OpenSim.Framework 32namespace OpenSim.Framework
33{ 33{
34 [Serializable]
35 public class ClientInfo 34 public class ClientInfo
36 { 35 {
37 public sAgentCircuitData agentcircuit; 36 public AgentCircuitData agentcircuit;
38 37
39 public Dictionary<uint, byte[]> needAck; 38 public Dictionary<uint, byte[]> needAck;
40 39
diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs
index eec2a92..3e6fdaa 100644
--- a/OpenSim/Framework/PriorityQueue.cs
+++ b/OpenSim/Framework/PriorityQueue.cs
@@ -42,22 +42,40 @@ namespace OpenSim.Framework
42 42
43 public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity); 43 public delegate bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity);
44 44
45 // Heap[0] for self updates 45 /// <summary>
46 // Heap[1..12] for entity updates 46 /// Total number of queues (priorities) available
47 47 /// </summary>
48 public const uint NumberOfQueues = 12; 48 public const uint NumberOfQueues = 12;
49 public const uint ImmediateQueue = 0; 49
50 /// <summary>
51 /// Number of queuest (priorities) that are processed immediately
52 /// </summary.
53 public const uint NumberOfImmediateQueues = 2;
50 54
51 private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues]; 55 private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[NumberOfQueues];
52 private Dictionary<uint, LookupItem> m_lookupTable; 56 private Dictionary<uint, LookupItem> m_lookupTable;
57
58 // internal state used to ensure the deqeues are spread across the priority
59 // queues "fairly". queuecounts is the amount to pull from each queue in
60 // each pass. weighted towards the higher priority queues
53 private uint m_nextQueue = 0; 61 private uint m_nextQueue = 0;
62 private uint m_countFromQueue = 0;
63 private uint[] m_queueCounts = { 8, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1 };
64
65 // next request is a counter of the number of updates queued, it provides
66 // a total ordering on the updates coming through the queue and is more
67 // lightweight (and more discriminating) than tick count
54 private UInt64 m_nextRequest = 0; 68 private UInt64 m_nextRequest = 0;
55 69
70 /// <summary>
71 /// Lock for enqueue and dequeue operations on the priority queue
72 /// </summary>
56 private object m_syncRoot = new object(); 73 private object m_syncRoot = new object();
57 public object SyncRoot { 74 public object SyncRoot {
58 get { return this.m_syncRoot; } 75 get { return this.m_syncRoot; }
59 } 76 }
60 77
78#region constructor
61 public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { } 79 public PriorityQueue() : this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY) { }
62 80
63 public PriorityQueue(int capacity) 81 public PriorityQueue(int capacity)
@@ -66,8 +84,16 @@ namespace OpenSim.Framework
66 84
67 for (int i = 0; i < m_heaps.Length; ++i) 85 for (int i = 0; i < m_heaps.Length; ++i)
68 m_heaps[i] = new MinHeap<MinHeapItem>(capacity); 86 m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
87
88 m_nextQueue = NumberOfImmediateQueues;
89 m_countFromQueue = m_queueCounts[m_nextQueue];
69 } 90 }
91#endregion Constructor
70 92
93#region PublicMethods
94 /// <summary>
95 /// Return the number of items in the queues
96 /// </summary>
71 public int Count 97 public int Count
72 { 98 {
73 get 99 get
@@ -75,10 +101,14 @@ namespace OpenSim.Framework
75 int count = 0; 101 int count = 0;
76 for (int i = 0; i < m_heaps.Length; ++i) 102 for (int i = 0; i < m_heaps.Length; ++i)
77 count += m_heaps[i].Count; 103 count += m_heaps[i].Count;
104
78 return count; 105 return count;
79 } 106 }
80 } 107 }
81 108
109 /// <summary>
110 /// Enqueue an item into the specified priority queue
111 /// </summary>
82 public bool Enqueue(uint pqueue, IEntityUpdate value) 112 public bool Enqueue(uint pqueue, IEntityUpdate value)
83 { 113 {
84 LookupItem lookup; 114 LookupItem lookup;
@@ -100,32 +130,62 @@ namespace OpenSim.Framework
100 return true; 130 return true;
101 } 131 }
102 132
133 /// <summary>
134 /// Remove an item from one of the queues. Specifically, it removes the
135 /// oldest item from the next queue in order to provide fair access to
136 /// all of the queues
137 /// </summary>
103 public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue) 138 public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
104 { 139 {
105 // If there is anything in priority queue 0, return it first no 140 // If there is anything in priority queue 0, return it first no
106 // matter what else. Breaks fairness. But very useful. 141 // matter what else. Breaks fairness. But very useful.
107 if (m_heaps[ImmediateQueue].Count > 0) 142 for (int iq = 0; iq < NumberOfImmediateQueues; iq++)
108 { 143 {
109 MinHeapItem item = m_heaps[ImmediateQueue].RemoveMin(); 144 if (m_heaps[iq].Count > 0)
145 {
146 MinHeapItem item = m_heaps[iq].RemoveMin();
147 m_lookupTable.Remove(item.Value.Entity.LocalId);
148 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
149 value = item.Value;
150
151 return true;
152 }
153 }
154
155 // To get the fair queing, we cycle through each of the
156 // queues when finding an element to dequeue.
157 // We pull (NumberOfQueues - QueueIndex) items from each queue in order
158 // to give lower numbered queues a higher priority and higher percentage
159 // of the bandwidth.
160
161 // Check for more items to be pulled from the current queue
162 if (m_heaps[m_nextQueue].Count > 0 && m_countFromQueue > 0)
163 {
164 m_countFromQueue--;
165
166 MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
110 m_lookupTable.Remove(item.Value.Entity.LocalId); 167 m_lookupTable.Remove(item.Value.Entity.LocalId);
111 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); 168 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
112 value = item.Value; 169 value = item.Value;
113 170
114 return true; 171 return true;
115 } 172 }
116 173
174 // Find the next non-immediate queue with updates in it
117 for (int i = 0; i < NumberOfQueues; ++i) 175 for (int i = 0; i < NumberOfQueues; ++i)
118 { 176 {
119 // To get the fair queing, we cycle through each of the 177 m_nextQueue = (uint)((m_nextQueue + 1) % NumberOfQueues);
120 // queues when finding an element to dequeue, this code 178 m_countFromQueue = m_queueCounts[m_nextQueue];
121 // assumes that the distribution of updates in the queues 179
122 // is polynomial, probably quadractic (eg distance of PI * R^2) 180 // if this is one of the immediate queues, just skip it
123 uint h = (uint)((m_nextQueue + i) % NumberOfQueues); 181 if (m_nextQueue < NumberOfImmediateQueues)
124 if (m_heaps[h].Count > 0) 182 continue;
183
184 if (m_heaps[m_nextQueue].Count > 0)
125 { 185 {
126 m_nextQueue = (uint)((h + 1) % NumberOfQueues); 186 m_countFromQueue--;
127 187
128 MinHeapItem item = m_heaps[h].RemoveMin(); 188 MinHeapItem item = m_heaps[m_nextQueue].RemoveMin();
129 m_lookupTable.Remove(item.Value.Entity.LocalId); 189 m_lookupTable.Remove(item.Value.Entity.LocalId);
130 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); 190 timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime);
131 value = item.Value; 191 value = item.Value;
@@ -139,6 +199,10 @@ namespace OpenSim.Framework
139 return false; 199 return false;
140 } 200 }
141 201
202 /// <summary>
203 /// Reapply the prioritization function to each of the updates currently
204 /// stored in the priority queues.
205 /// </summary
142 public void Reprioritize(UpdatePriorityHandler handler) 206 public void Reprioritize(UpdatePriorityHandler handler)
143 { 207 {
144 MinHeapItem item; 208 MinHeapItem item;
@@ -174,17 +238,18 @@ namespace OpenSim.Framework
174 } 238 }
175 } 239 }
176 240
241 /// <summary>
242 /// </summary>
177 public override string ToString() 243 public override string ToString()
178 { 244 {
179 string s = ""; 245 string s = "";
180 for (int i = 0; i < NumberOfQueues; i++) 246 for (int i = 0; i < NumberOfQueues; i++)
181 { 247 s += String.Format("{0,7} ",m_heaps[i].Count);
182 if (s != "") s += ",";
183 s += m_heaps[i].Count.ToString();
184 }
185 return s; 248 return s;
186 } 249 }
187 250
251#endregion PublicMethods
252
188#region MinHeapItem 253#region MinHeapItem
189 private struct MinHeapItem : IComparable<MinHeapItem> 254 private struct MinHeapItem : IComparable<MinHeapItem>
190 { 255 {
diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
index e131260..34a3f15 100644
--- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
+++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs
@@ -115,7 +115,7 @@ namespace OpenSim.Framework.Tests
115 position2 = new AgentPosition(); 115 position2 = new AgentPosition();
116 116
117 Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition"); 117 Assert.IsFalse(position2.AgentID == position1.AgentID, "Test Error, position2 should be a blank uninitialized AgentPosition");
118 position2.Unpack(position1.Pack()); 118 position2.Unpack(position1.Pack(), null);
119 119
120 Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed"); 120 Assert.IsTrue(position2.AgentID == position1.AgentID, "Agent ID didn't unpack the same way it packed");
121 Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed"); 121 Assert.IsTrue(position2.Position == position1.Position, "Position didn't unpack the same way it packed");