diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Communications/Cache/AssetCache.cs | 117 | ||||
-rw-r--r-- | OpenSim/Framework/Communications/Cache/AssetServerBase.cs | 4 |
2 files changed, 73 insertions, 48 deletions
diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index d94af44..0d85345 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs | |||
@@ -41,38 +41,60 @@ namespace OpenSim.Framework.Communications.Cache | |||
41 | 41 | ||
42 | /// <summary> | 42 | /// <summary> |
43 | /// Manages local cache of assets and their sending to viewers. | 43 | /// Manages local cache of assets and their sending to viewers. |
44 | /// | ||
45 | /// This class actually encapsulates two largely separate mechanisms. One mechanism fetches assets either | ||
46 | /// synchronously or async and passes the data back to the requester. The second mechanism fetches assets and | ||
47 | /// sends packetised data directly back to the client. The only point where they meets is AssetReceived() and | ||
48 | /// AssetNotFound(). | ||
49 | /// | ||
50 | /// TODO Assets in this cache are effectively immortal (they are never disposed off through old age). | ||
51 | /// This is not a huge problem at the moment since other memory use usually dwarfs that used by assets | ||
52 | /// but it's something to bear in mind. | ||
44 | /// </summary> | 53 | /// </summary> |
45 | public class AssetCache : IAssetReceiver | 54 | public class AssetCache : IAssetReceiver |
46 | { | 55 | { |
47 | private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 56 | private static readonly log4net.ILog m_log |
57 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | 58 | ||
49 | public Dictionary<LLUUID, AssetInfo> Assets; | 59 | /// <summary> |
50 | public Dictionary<LLUUID, TextureImage> Textures; | 60 | /// The cache of assets. This does not include textures. |
51 | 61 | /// </summary> | |
52 | public List<AssetRequest> AssetRequests; //assets ready to be sent to viewers | 62 | private Dictionary<LLUUID, AssetInfo> Assets; |
53 | public List<AssetRequest> TextureRequests; //textures ready to be sent | 63 | |
54 | 64 | /// <summary> | |
55 | public Dictionary<LLUUID, AssetRequest> RequestedAssets; | 65 | /// The cache of textures. |
56 | //Assets requested from the asset server | 66 | /// </summary> |
67 | private Dictionary<LLUUID, TextureImage> Textures; | ||
57 | 68 | ||
58 | public Dictionary<LLUUID, AssetRequest> RequestedTextures; | 69 | /// <summary> |
59 | //Textures requested from the asset server | 70 | /// Assets requests which are waiting for asset server data. This includes texture requests |
71 | /// </summary> | ||
72 | private Dictionary<LLUUID, AssetRequest> RequestedAssets; | ||
73 | |||
74 | /// <summary> | ||
75 | /// Asset requests with data which are ready to be sent back to requesters. This includes textures. | ||
76 | /// </summary> | ||
77 | private List<AssetRequest> AssetRequests; | ||
60 | 78 | ||
61 | public Dictionary<LLUUID, AssetRequestsList> RequestLists; | 79 | /// <summary> |
80 | /// Until the asset request is fulfilled, each asset request is associated with a list of requesters | ||
81 | /// </summary> | ||
82 | private Dictionary<LLUUID, AssetRequestsList> RequestLists; | ||
62 | 83 | ||
63 | private readonly IAssetServer m_assetServer; | 84 | private readonly IAssetServer m_assetServer; |
64 | 85 | ||
65 | private readonly Thread m_assetCacheThread; | 86 | private readonly Thread m_assetCacheThread; |
66 | 87 | ||
88 | /// <summary> | ||
89 | /// Report statistical data. | ||
90 | /// </summary> | ||
67 | public void ShowState() | 91 | public void ShowState() |
68 | { | 92 | { |
69 | m_log.InfoFormat("Assets:{0} Textures:{1} AssetRequests:{2} TextureRequests:{3} RequestedAssets:{4} RequestedTextures:{5} RequestLists:{6}", | 93 | m_log.InfoFormat("Assets:{0} Textures:{1} AssetRequests:{2} RequestedAssets:{3} RequestLists:{4}", |
70 | Assets.Count, | 94 | Assets.Count, |
71 | Textures.Count, | 95 | Textures.Count, |
72 | AssetRequests.Count, | 96 | AssetRequests.Count, |
73 | TextureRequests.Count, | ||
74 | RequestedAssets.Count, | 97 | RequestedAssets.Count, |
75 | RequestedTextures.Count, | ||
76 | RequestLists.Count); | 98 | RequestLists.Count); |
77 | 99 | ||
78 | int temporaryImages = 0; | 100 | int temporaryImages = 0; |
@@ -81,9 +103,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
81 | long imageBytes = 0; | 103 | long imageBytes = 0; |
82 | long assetBytes = 0; | 104 | long assetBytes = 0; |
83 | 105 | ||
84 | |||
85 | |||
86 | |||
87 | foreach (TextureImage texture in Textures.Values) | 106 | foreach (TextureImage texture in Textures.Values) |
88 | { | 107 | { |
89 | if (texture.Temporary) | 108 | if (texture.Temporary) |
@@ -109,30 +128,37 @@ namespace OpenSim.Framework.Communications.Cache | |||
109 | temporaryAssets); | 128 | temporaryAssets); |
110 | 129 | ||
111 | m_log.InfoFormat("Image data: {0}kb Asset data: {1}kb", | 130 | m_log.InfoFormat("Image data: {0}kb Asset data: {1}kb", |
112 | imageBytes / 1024, | 131 | imageBytes / 1024, |
113 | assetBytes / 1024); | 132 | assetBytes / 1024); |
114 | 133 | ||
115 | } | 134 | } |
116 | 135 | ||
136 | /// <summary> | ||
137 | /// Clear the asset cache. | ||
138 | /// </summary> | ||
117 | public void Clear() | 139 | public void Clear() |
118 | { | 140 | { |
119 | m_log.Info("[ASSET CACHE]: Clearing Asset cache"); | 141 | m_log.Info("[ASSET CACHE]: Clearing Asset cache"); |
120 | Initialize(); | 142 | Initialize(); |
121 | } | 143 | } |
122 | 144 | ||
145 | /// <summary> | ||
146 | /// Initialize the cache. | ||
147 | /// </summary> | ||
123 | private void Initialize() | 148 | private void Initialize() |
124 | { | 149 | { |
125 | Assets = new Dictionary<LLUUID, AssetInfo>(); | 150 | Assets = new Dictionary<LLUUID, AssetInfo>(); |
126 | Textures = new Dictionary<LLUUID, TextureImage>(); | 151 | Textures = new Dictionary<LLUUID, TextureImage>(); |
127 | AssetRequests = new List<AssetRequest>(); //assets ready to be sent to viewers | 152 | AssetRequests = new List<AssetRequest>(); |
128 | TextureRequests = new List<AssetRequest>(); //textures ready to be sent | 153 | |
129 | |||
130 | RequestedAssets = new Dictionary<LLUUID, AssetRequest>(); | 154 | RequestedAssets = new Dictionary<LLUUID, AssetRequest>(); |
131 | RequestedTextures = new Dictionary<LLUUID, AssetRequest>(); | ||
132 | RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); | 155 | RequestLists = new Dictionary<LLUUID, AssetRequestsList>(); |
133 | } | 156 | } |
134 | 157 | ||
135 | 158 | /// <summary> | |
159 | /// Constructor. Initialize will need to be called separately. | ||
160 | /// </summary> | ||
161 | /// <param name="assetServer"></param> | ||
136 | public AssetCache(IAssetServer assetServer) | 162 | public AssetCache(IAssetServer assetServer) |
137 | { | 163 | { |
138 | m_log.Info("[ASSET CACHE]: Creating Asset cache"); | 164 | m_log.Info("[ASSET CACHE]: Creating Asset cache"); |
@@ -148,7 +174,8 @@ namespace OpenSim.Framework.Communications.Cache | |||
148 | } | 174 | } |
149 | 175 | ||
150 | /// <summary> | 176 | /// <summary> |
151 | /// | 177 | /// Process the asset queue which holds data which is packeted up and sent |
178 | /// directly back to the client. | ||
152 | /// </summary> | 179 | /// </summary> |
153 | public void RunAssetManager() | 180 | public void RunAssetManager() |
154 | { | 181 | { |
@@ -359,6 +386,12 @@ namespace OpenSim.Framework.Communications.Cache | |||
359 | m_log.InfoFormat("[ASSET CACHE]: Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); | 386 | m_log.InfoFormat("[ASSET CACHE]: Adding {0} {1} [{2}]: {3}.", temporary, type, asset.FullID, result); |
360 | } | 387 | } |
361 | 388 | ||
389 | /// <summary> | ||
390 | /// Copy an asset and add it to the cache with a new assetID. | ||
391 | /// XXX We shouldn't actually ever need to do this! | ||
392 | /// </summary> | ||
393 | /// <param name="assetID"></param> | ||
394 | /// <returns></returns> | ||
362 | public AssetBase CopyAsset(LLUUID assetID) | 395 | public AssetBase CopyAsset(LLUUID assetID) |
363 | { | 396 | { |
364 | AssetBase asset; | 397 | AssetBase asset; |
@@ -402,19 +435,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
402 | { | 435 | { |
403 | StatsManager.SimExtraStats.AddTexture(image); | 436 | StatsManager.SimExtraStats.AddTexture(image); |
404 | } | 437 | } |
405 | |||
406 | if (RequestedTextures.ContainsKey(image.FullID)) | ||
407 | { | ||
408 | m_log.InfoFormat("[ASSET CACHE]: Moving {0} from RequestedTextures to TextureRequests", asset.FullID); | ||
409 | |||
410 | AssetRequest req = RequestedTextures[image.FullID]; | ||
411 | req.ImageInfo = image; | ||
412 | |||
413 | req.NumPackets = CalculateNumPackets(image.Data); | ||
414 | |||
415 | RequestedTextures.Remove(image.FullID); | ||
416 | TextureRequests.Add(req); | ||
417 | } | ||
418 | } | 438 | } |
419 | } | 439 | } |
420 | else | 440 | else |
@@ -422,7 +442,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
422 | AssetInfo assetInf = new AssetInfo(asset); | 442 | AssetInfo assetInf = new AssetInfo(asset); |
423 | if (Assets.ContainsKey(assetInf.FullID)) | 443 | if (Assets.ContainsKey(assetInf.FullID)) |
424 | { | 444 | { |
425 | m_log.InfoFormat("[ASSET CACHE]: There's already an asset {0} in memory. Skipping.", asset.FullID); | 445 | m_log.DebugFormat("[ASSET CACHE]: There's already an asset {0} in memory. Skipping.", asset.FullID); |
426 | } | 446 | } |
427 | else | 447 | else |
428 | { | 448 | { |
@@ -435,7 +455,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
435 | 455 | ||
436 | if (RequestedAssets.ContainsKey(assetInf.FullID)) | 456 | if (RequestedAssets.ContainsKey(assetInf.FullID)) |
437 | { | 457 | { |
438 | m_log.InfoFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID); | 458 | m_log.DebugFormat("[ASSET CACHE]: Moving {0} from RequestedAssets to AssetRequests", asset.FullID); |
439 | 459 | ||
440 | AssetRequest req = RequestedAssets[assetInf.FullID]; | 460 | AssetRequest req = RequestedAssets[assetInf.FullID]; |
441 | req.AssetInf = assetInf; | 461 | req.AssetInf = assetInf; |
@@ -447,6 +467,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
447 | } | 467 | } |
448 | } | 468 | } |
449 | 469 | ||
470 | // Notify requesters for this asset | ||
450 | if (RequestLists.ContainsKey(asset.FullID)) | 471 | if (RequestLists.ContainsKey(asset.FullID)) |
451 | { | 472 | { |
452 | lock (RequestLists) | 473 | lock (RequestLists) |
@@ -503,6 +524,11 @@ namespace OpenSim.Framework.Communications.Cache | |||
503 | } | 524 | } |
504 | } | 525 | } |
505 | 526 | ||
527 | /// <summary> | ||
528 | /// Calculate the number of packets required to send the asset to the client. | ||
529 | /// </summary> | ||
530 | /// <param name="data"></param> | ||
531 | /// <returns></returns> | ||
506 | private int CalculateNumPackets(byte[] data) | 532 | private int CalculateNumPackets(byte[] data) |
507 | { | 533 | { |
508 | const uint m_maxPacketSize = 600; | 534 | const uint m_maxPacketSize = 600; |
@@ -519,10 +545,8 @@ namespace OpenSim.Framework.Communications.Cache | |||
519 | return numPackets; | 545 | return numPackets; |
520 | } | 546 | } |
521 | 547 | ||
522 | #region Assets | ||
523 | |||
524 | /// <summary> | 548 | /// <summary> |
525 | /// | 549 | /// Make an asset request the result of which will be packeted up and sent directly back to the client. |
526 | /// </summary> | 550 | /// </summary> |
527 | /// <param name="userInfo"></param> | 551 | /// <param name="userInfo"></param> |
528 | /// <param name="transferRequest"></param> | 552 | /// <param name="transferRequest"></param> |
@@ -577,7 +601,7 @@ namespace OpenSim.Framework.Communications.Cache | |||
577 | } | 601 | } |
578 | 602 | ||
579 | /// <summary> | 603 | /// <summary> |
580 | /// | 604 | /// Process the asset queue which sends packets directly back to the client. |
581 | /// </summary> | 605 | /// </summary> |
582 | private void ProcessAssetQueue() | 606 | private void ProcessAssetQueue() |
583 | { | 607 | { |
@@ -672,8 +696,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
672 | } | 696 | } |
673 | } | 697 | } |
674 | 698 | ||
675 | #endregion | ||
676 | |||
677 | public class AssetRequest | 699 | public class AssetRequest |
678 | { | 700 | { |
679 | public IClientAPI RequestUser; | 701 | public IClientAPI RequestUser; |
@@ -730,7 +752,6 @@ namespace OpenSim.Framework.Communications.Cache | |||
730 | } | 752 | } |
731 | } | 753 | } |
732 | 754 | ||
733 | |||
734 | public class AssetRequestsList | 755 | public class AssetRequestsList |
735 | { | 756 | { |
736 | public LLUUID AssetID; | 757 | public LLUUID AssetID; |
diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs index 8e670b5..b6ec898 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs | |||
@@ -120,6 +120,10 @@ namespace OpenSim.Framework.Communications.Cache | |||
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | /// <summary> | ||
124 | /// The receiver will be called back with asset data once it comes in. | ||
125 | /// </summary> | ||
126 | /// <param name="receiver"></param> | ||
123 | public void SetReceiver(IAssetReceiver receiver) | 127 | public void SetReceiver(IAssetReceiver receiver) |
124 | { | 128 | { |
125 | m_receiver = receiver; | 129 | m_receiver = receiver; |