Modify resourceCache to handle datacache releasing exception
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceCache / src / ResourceCacheManager.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "ResourceCacheManager.h"
22
23 namespace OIC
24 {
25     namespace Service
26     {
27         ResourceCacheManager *ResourceCacheManager::s_instance = NULL;
28         std::mutex ResourceCacheManager::s_mutexForCreation;
29         std::unique_ptr<std::list<DataCachePtr>> ResourceCacheManager::s_cacheDataList(nullptr);
30
31         ResourceCacheManager::~ResourceCacheManager()
32         {
33             if (s_cacheDataList != nullptr)
34             {
35                 s_cacheDataList->clear();
36             }
37         }
38
39         ResourceCacheManager *ResourceCacheManager::getInstance()
40         {
41             if (s_instance == nullptr)
42             {
43                 s_mutexForCreation.lock();
44                 if (s_instance == nullptr)
45                 {
46                     s_instance = new ResourceCacheManager();
47                     s_instance->initializeResourceCacheManager();
48                 }
49                 s_mutexForCreation.unlock();
50             }
51             return s_instance;
52         }
53
54         CacheID ResourceCacheManager::requestResourceCache(
55             PrimitiveResourcePtr pResource, CacheCB func,
56             REPORT_FREQUENCY rf, long reportTime)
57         {
58             if (pResource == nullptr)
59             {
60                 throw InvalidParameterException {"[requestResourceCache] Primitive Resource is invaild"};
61             }
62
63             CacheID retID = 0;
64
65             if (rf != REPORT_FREQUENCY::NONE)
66             {
67                 if (func == NULL || func == nullptr)
68                 {
69                     throw InvalidParameterException {"[requestResourceCache] CacheCB is invaild"};
70                 }
71                 if (!reportTime)
72                 {
73                     // default setting
74                     reportTime = CACHE_DEFAULT_REPORT_MILLITIME;
75                 }
76             }
77
78             DataCachePtr newHandler = findDataCache(pResource);
79             if (newHandler == nullptr)
80             {
81                 newHandler.reset(new DataCache());
82                 newHandler->initializeDataCache(pResource);
83                 s_cacheDataList->push_back(newHandler);
84             }
85             retID = newHandler->addSubscriber(func, rf, reportTime);
86
87             cacheIDmap.insert(std::make_pair(retID, newHandler));
88
89             return retID;
90         }
91
92         void ResourceCacheManager::cancelResourceCache(CacheID id)
93         {
94             if (id == 0 || cacheIDmap.find(id) == cacheIDmap.end())
95             {
96                 throw InvalidParameterException {"[cancelResourceCache] CacheID is invaild"};
97             }
98
99             DataCachePtr foundCacheHandler = findDataCache(id);
100             if (foundCacheHandler != nullptr)
101             {
102                 CacheID retID = foundCacheHandler->deleteSubscriber(id);
103                 if (retID == id)
104                 {
105                     cacheIDmap.erase(id);
106                 }
107                 if (foundCacheHandler->isEmptySubscriber())
108                 {
109                     s_cacheDataList->remove(foundCacheHandler);
110                 }
111             }
112         }
113
114         void ResourceCacheManager::updateResourceCache(PrimitiveResourcePtr pResource) const
115         {
116             if (pResource == nullptr)
117             {
118                 throw InvalidParameterException
119                 {"[updateResourceCache] Primitive Resource is invaild"};
120             }
121
122             DataCachePtr foundCache = findDataCache(pResource);
123             if (foundCache == nullptr)
124             {
125                 throw InvalidParameterException
126                 {"[updateResourceCache] Primitive Resource is invaild"};
127             }
128             foundCache->requestGet();
129         }
130         void ResourceCacheManager::updateResourceCache(CacheID updateId) const
131         {
132             if (updateId == 0)
133             {
134                 throw InvalidParameterException {"[getCachedData] CacheID is NULL"};
135             }
136
137             DataCachePtr foundCache = findDataCache(updateId);
138             if (foundCache == nullptr)
139             {
140                 throw InvalidParameterException {"[getCachedData] CacheID is invaild"};
141             }
142             foundCache->requestGet();
143         }
144
145         const RCSResourceAttributes ResourceCacheManager::getCachedData(
146             PrimitiveResourcePtr pResource) const
147         {
148             if (pResource == nullptr)
149             {
150                 throw InvalidParameterException {"[getCachedData] Primitive Resource is nullptr"};
151             }
152
153             DataCachePtr handler = findDataCache(pResource);
154             if (handler == nullptr)
155             {
156                 throw InvalidParameterException {"[getCachedData] Primitive Resource is invaild"};
157             }
158             return handler->getCachedData();
159         }
160
161         const RCSResourceAttributes ResourceCacheManager::getCachedData(CacheID id) const
162         {
163             if (id == 0)
164             {
165                 throw InvalidParameterException {"[getCachedData] CacheID is NULL"};
166             }
167
168             DataCachePtr handler = findDataCache(id);
169             if (handler == nullptr)
170             {
171                 throw InvalidParameterException {"[getCachedData] CacheID is invaild"};
172             }
173             return handler->getCachedData();
174         }
175
176         CACHE_STATE ResourceCacheManager::getResourceCacheState(
177             PrimitiveResourcePtr pResource) const
178         {
179             if (pResource == nullptr)
180             {
181                 throw InvalidParameterException {"[getResourceCacheState] Primitive Resource is nullptr"};
182             }
183
184             DataCachePtr handler = findDataCache(pResource);
185             if (handler == nullptr)
186             {
187                 return CACHE_STATE::NONE;
188             }
189             return handler->getCacheState();
190         }
191
192         CACHE_STATE ResourceCacheManager::getResourceCacheState(CacheID id) const
193         {
194             if (id == 0)
195             {
196                 throw InvalidParameterException {"[getResourceCacheState] CacheID is NULL"};
197             }
198
199             DataCachePtr handler = findDataCache(id);
200             if (handler == nullptr)
201             {
202                 return CACHE_STATE::NONE;
203             }
204             return handler->getCacheState();
205         }
206
207         void ResourceCacheManager::initializeResourceCacheManager()
208         {
209             if (s_cacheDataList == nullptr)
210             {
211                 s_cacheDataList
212                     = std::unique_ptr<std::list<DataCachePtr>>(new std::list<DataCachePtr>);
213             }
214         }
215
216         DataCachePtr ResourceCacheManager::findDataCache(PrimitiveResourcePtr pResource) const
217         {
218             DataCachePtr retHandler = nullptr;
219             for (auto &i : * s_cacheDataList)
220             {
221                 if (i->getPrimitiveResource()->getUri() == pResource->getUri() &&
222                     i->getPrimitiveResource()->getHost() == pResource->getHost())
223                 {
224                     retHandler = i;
225                     break;
226                 }
227             }
228             return retHandler;
229         }
230
231         DataCachePtr ResourceCacheManager::findDataCache(CacheID id) const
232         {
233             DataCachePtr retHandler = nullptr;
234             for (auto it : cacheIDmap)
235             {
236                 if (it.first == id)
237                 {
238                     retHandler = it.second;
239                     break;
240                 }
241             }
242
243             return retHandler;
244         }
245     } // namespace Service
246 } // namespace OIC