aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs
blob: dcf33a119d91e9339b1d70ff0395f4ef91cb0fc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
using System.Collections.Generic;
using System.Threading;
using OpenSim.Framework;
using OpenMetaverse;

namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
{
    /// <summary>
    /// Cache root and system inventory folders to reduce number of potentially remote inventory calls and associated holdups.
    /// </summary>
    public class InventoryCache
    {
        private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour

        private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
        private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
        private static ExpiringCache<UUID, InventoryCollection> m_Inventories = new ExpiringCache<UUID, InventoryCollection>();

        public void Cache(UUID userID, InventoryFolderBase root)
        {
            m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS);
        }

        public InventoryFolderBase GetRootFolder(UUID userID)
        {
            InventoryFolderBase root = null;
            if (m_RootFolders.TryGetValue(userID, out root))
                return root;

            return null;
        }

        public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
        {
            Dictionary<AssetType, InventoryFolderBase> ff = null;
            if (!m_FolderTypes.TryGetValue(userID, out ff))
            {
                ff = new Dictionary<AssetType, InventoryFolderBase>();
                m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
            }

            // We need to lock here since two threads could potentially retrieve the same dictionary
            // and try to add a folder for that type simultaneously.  Dictionary<>.Add() is not described as thread-safe in the SDK
            // even if the folders are identical.
            lock (ff)
            {
                if (!ff.ContainsKey(type))
                    ff.Add(type, folder);
            }
        }

        public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
        {
            Dictionary<AssetType, InventoryFolderBase> ff = null;
            if (m_FolderTypes.TryGetValue(userID, out ff))
            {
                InventoryFolderBase f = null;

                lock (ff)
                {
                    if (ff.TryGetValue(type, out f))
                        return f;
                }
            }

            return null;
        }

        public void Cache(UUID userID, InventoryCollection inv)
        {
            m_Inventories.AddOrUpdate(userID, inv, 120);
        }

        public InventoryCollection GetUserInventory(UUID userID)
        {
            InventoryCollection inv = null;
            if (m_Inventories.TryGetValue(userID, out inv))
                return inv;
            return null;
        }

        public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
        {
            InventoryCollection inv = null;
            InventoryCollection c;
            if (m_Inventories.TryGetValue(userID, out inv))
            {
                c = new InventoryCollection();
                c.UserID = userID;

                c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
                {
                    return f.ParentID == folderID;
                });
                c.Items = inv.Items.FindAll(delegate(InventoryItemBase i)
                {
                    return i.Folder == folderID;
                });
                return c;
            }
            return null;
        }

        public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
        {
            InventoryCollection inv = null;
            if (m_Inventories.TryGetValue(userID, out inv))
            {
                List<InventoryItemBase> items = inv.Items.FindAll(delegate(InventoryItemBase i)
                {
                    return i.Folder == folderID;
                });
                return items;
            }
            return null;
        }
    }
}