parent
bd525d4da0
commit
10b2a4597a
|
@ -84,12 +84,6 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
public InventoryFolderImpl RootFolder { get { return m_rootFolder; } }
|
public InventoryFolderImpl RootFolder { get { return m_rootFolder; } }
|
||||||
private InventoryFolderImpl m_rootFolder;
|
private InventoryFolderImpl m_rootFolder;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// FIXME: This could be contained within a local variable - it doesn't need to be a field
|
|
||||||
/// </summary>
|
|
||||||
private IDictionary<LLUUID, IList<InventoryFolderImpl>> pendingCategorizationFolders
|
|
||||||
= new Dictionary<LLUUID, IList<InventoryFolderImpl>>();
|
|
||||||
|
|
||||||
public LLUUID SessionID
|
public LLUUID SessionID
|
||||||
{
|
{
|
||||||
get { return m_session_id; }
|
get { return m_session_id; }
|
||||||
|
@ -130,55 +124,58 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Store a folder pending arrival of its parent
|
/// Helper function for InventoryReceive() - Store a folder temporarily until we've received entire folder list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folder"></param>
|
/// <param name="folder"></param>
|
||||||
private void AddPendingFolder(InventoryFolderImpl folder)
|
private void AddFolderToDictionary(InventoryFolderImpl folder, IDictionary<LLUUID, IList<InventoryFolderImpl>> dictionary)
|
||||||
{
|
{
|
||||||
LLUUID parentFolderId = folder.ParentID;
|
LLUUID parentFolderId = folder.ParentID;
|
||||||
|
|
||||||
if (pendingCategorizationFolders.ContainsKey(parentFolderId))
|
if (dictionary.ContainsKey(parentFolderId))
|
||||||
{
|
dictionary[parentFolderId].Add(folder);
|
||||||
pendingCategorizationFolders[parentFolderId].Add(folder);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IList<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
IList<InventoryFolderImpl> folders = new List<InventoryFolderImpl>();
|
||||||
folders.Add(folder);
|
folders.Add(folder);
|
||||||
|
dictionary[parentFolderId] = folders;
|
||||||
pendingCategorizationFolders[parentFolderId] = folders;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add any pending folders which were received before the given folder
|
/// Recursively, in depth-first order, add all the folders we've received (stored
|
||||||
|
/// in a dictionary indexed by parent ID) into the tree that describes user folder
|
||||||
|
/// heirarchy
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parentId">
|
/// <param name="parentId">
|
||||||
/// A <see cref="LLUUID"/>
|
/// A <see cref="LLUUID"/>
|
||||||
/// </param>
|
/// </param>
|
||||||
private void ResolvePendingFolders(InventoryFolderImpl newFolder)
|
private void ResolveReceivedFolders(InventoryFolderImpl parentFolder, IDictionary<LLUUID, IList<InventoryFolderImpl>> folderDictionary)
|
||||||
{
|
{
|
||||||
if (pendingCategorizationFolders.ContainsKey(newFolder.ID))
|
if (folderDictionary.ContainsKey(parentFolder.ID))
|
||||||
{
|
{
|
||||||
List<InventoryFolderImpl> resolvedFolders = new List<InventoryFolderImpl>(); // Folders we've resolved with this invocation
|
List<InventoryFolderImpl> resolvedFolders = new List<InventoryFolderImpl>(); // Folders we've resolved with this invocation
|
||||||
foreach (InventoryFolderImpl folder in pendingCategorizationFolders[newFolder.ID])
|
foreach (InventoryFolderImpl folder in folderDictionary[parentFolder.ID])
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
lock (parentFolder.SubFolders)
|
||||||
// "[INVENTORY CACHE]: Resolving pending received folder {0} {1} into {2} {3}",
|
|
||||||
// folder.name, folder.folderID, parent.name, parent.folderID);
|
|
||||||
lock (newFolder.SubFolders)
|
|
||||||
{
|
{
|
||||||
if (!newFolder.SubFolders.ContainsKey(folder.ID))
|
if (parentFolder.SubFolders.ContainsKey(folder.ID))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[INVENTORY CACHE]: Received folder {0} {1} from inventory service which has already been received",
|
||||||
|
folder.Name, folder.ID);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
resolvedFolders.Add(folder);
|
resolvedFolders.Add(folder);
|
||||||
newFolder.SubFolders.Add(folder.ID, folder);
|
parentFolder.SubFolders.Add(folder.ID, folder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // foreach (folder in pendingCategorizationFolders[parentFolder.ID])
|
||||||
pendingCategorizationFolders.Remove(newFolder.ID);
|
|
||||||
|
folderDictionary.Remove(parentFolder.ID);
|
||||||
foreach (InventoryFolderImpl folder in resolvedFolders)
|
foreach (InventoryFolderImpl folder in resolvedFolders)
|
||||||
ResolvePendingFolders(folder);
|
ResolveReceivedFolders(folder, folderDictionary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,26 +201,57 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
/// <param name="inventoryCollection"></param>
|
/// <param name="inventoryCollection"></param>
|
||||||
public void InventoryReceive(ICollection<InventoryFolderImpl> folders, ICollection<InventoryItemBase> items)
|
public void InventoryReceive(ICollection<InventoryFolderImpl> folders, ICollection<InventoryItemBase> items)
|
||||||
{
|
{
|
||||||
|
|
||||||
// FIXME: Exceptions thrown upwards never appear on the console. Could fix further up if these
|
// FIXME: Exceptions thrown upwards never appear on the console. Could fix further up if these
|
||||||
// are simply being swallowed
|
// are simply being swallowed
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// collection of all received folders, indexed by their parent ID
|
||||||
|
IDictionary<LLUUID, IList<InventoryFolderImpl>> receivedFolders =
|
||||||
|
new Dictionary<LLUUID, IList<InventoryFolderImpl>>();
|
||||||
|
|
||||||
|
// Take all received folders, find the root folder, and put ther rest into
|
||||||
|
// the pendingCategorizationFolders collection
|
||||||
foreach (InventoryFolderImpl folder in folders)
|
foreach (InventoryFolderImpl folder in folders)
|
||||||
|
AddFolderToDictionary(folder, receivedFolders);
|
||||||
|
|
||||||
|
if (!receivedFolders.ContainsKey(LLUUID.Zero))
|
||||||
|
throw new Exception("Database did not return a root inventory folder");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
FolderReceive(folder);
|
IList<InventoryFolderImpl> rootFolderList = receivedFolders[LLUUID.Zero];
|
||||||
|
m_rootFolder = rootFolderList[0];
|
||||||
|
if (rootFolderList.Count > 1)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < rootFolderList.Count; i++)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[INVENTORY CACHE]: Discarding extra root folder {0}. Using previously received root folder {1}",
|
||||||
|
rootFolderList[i].ID, RootFolder.ID);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
receivedFolders.Remove(LLUUID.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now take the pendingCategorizationFolders collection, and turn that into a tree,
|
||||||
|
// with the root being RootFolder
|
||||||
|
if (RootFolder != null)
|
||||||
|
ResolveReceivedFolders(RootFolder, receivedFolders);
|
||||||
|
|
||||||
// Generate a warning for folders that are not part of the heirarchy
|
// Generate a warning for folders that are not part of the heirarchy
|
||||||
foreach ( KeyValuePair<LLUUID, IList<InventoryFolderImpl>> folderList in pendingCategorizationFolders)
|
foreach (KeyValuePair<LLUUID, IList<InventoryFolderImpl>> folderList in receivedFolders)
|
||||||
{
|
{
|
||||||
foreach (InventoryFolderImpl folder in folderList.Value)
|
foreach (InventoryFolderImpl folder in folderList.Value)
|
||||||
m_log.WarnFormat("[INVENTORY CACHE]: Malformed Database: Unresolved Pending Folder {0}", folder.Name);
|
m_log.WarnFormat("[INVENTORY CACHE]: Malformed Database: Unresolved Pending Folder {0}", folder.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Take all ther received items and put them into the folder tree heirarchy
|
||||||
|
// TBD: This operation is O(n^2), if we made a dictionary of all folders indexed by their ID, we could make
|
||||||
|
// this O(n)
|
||||||
foreach (InventoryItemBase item in items)
|
foreach (InventoryItemBase item in items)
|
||||||
{
|
|
||||||
ItemReceive(item);
|
ItemReceive(item);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e);
|
m_log.ErrorFormat("[INVENTORY CACHE]: Error processing inventory received from inventory service, {0}", e);
|
||||||
|
@ -243,56 +271,6 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Callback invoked when a folder is received from an async request to the inventory service.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="userID"></param>
|
|
||||||
/// <param name="folderInfo"></param>
|
|
||||||
private void FolderReceive(InventoryFolderImpl newFolder)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[INVENTORY CACHE]: Received folder {0} {1} for user {2}",
|
|
||||||
// folderInfo.Name, folderInfo.ID, userID);
|
|
||||||
|
|
||||||
if (RootFolder == null)
|
|
||||||
{
|
|
||||||
if (newFolder.ParentID == LLUUID.Zero)
|
|
||||||
{
|
|
||||||
m_rootFolder = newFolder;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddPendingFolder(newFolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InventoryFolderImpl parentFolder = RootFolder.FindFolder(newFolder.ParentID);
|
|
||||||
|
|
||||||
if (parentFolder == null)
|
|
||||||
{
|
|
||||||
AddPendingFolder(newFolder);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lock (parentFolder.SubFolders)
|
|
||||||
{
|
|
||||||
if (!parentFolder.SubFolders.ContainsKey(newFolder.ID))
|
|
||||||
{
|
|
||||||
parentFolder.SubFolders.Add(newFolder.ID, newFolder);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[INVENTORY CACHE]: Received folder {0} {1} from inventory service which has already been received",
|
|
||||||
newFolder.Name, newFolder.ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ResolvePendingFolders(newFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback invoked when an item is received from an async request to the inventory service.
|
/// Callback invoked when an item is received from an async request to the inventory service.
|
||||||
///
|
///
|
||||||
|
|
|
@ -65,6 +65,7 @@ namespace OpenSim.Region.Communications.Local
|
||||||
rootFolder = new InventoryFolderImpl(folder);
|
rootFolder = new InventoryFolderImpl(folder);
|
||||||
folders.Add(rootFolder);
|
folders.Add(rootFolder);
|
||||||
items.AddRange(RequestFolderItems(rootFolder.ID));
|
items.AddRange(RequestFolderItems(rootFolder.ID));
|
||||||
|
break; // Only 1 root folder per user
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue