add logic related Topic List.
[platform/upstream/iotivity.git] / service / notification / src / provider / NSProviderMemoryCache.c
1 //******************************************************************\r
2 //\r
3 // Copyright 2016 Samsung Electronics All Rights Reserved.\r
4 //\r
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
6 //\r
7 // Licensed under the Apache License, Version 2.0 (the "License");\r
8 // you may not use this file except in compliance with the License.\r
9 // You may obtain a copy of the License at\r
10 //\r
11 //      http://www.apache.org/licenses/LICENSE-2.0\r
12 //\r
13 // Unless required by applicable law or agreed to in writing, software\r
14 // distributed under the License is distributed on an "AS IS" BASIS,\r
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16 // See the License for the specific language governing permissions and\r
17 // limitations under the License.\r
18 //\r
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
20 \r
21 #include "NSProviderMemoryCache.h"\r
22 #include <string.h>\r
23 \r
24 NSCacheList * NSStorageCreate()\r
25 {\r
26     pthread_mutex_lock(&NSCacheMutex);\r
27     NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));\r
28     if (!newList)\r
29     {\r
30         pthread_mutex_unlock(&NSCacheMutex);\r
31         return NULL;\r
32     }\r
33 \r
34     newList->head = newList->tail = NULL;\r
35 \r
36     pthread_mutex_unlock(&NSCacheMutex);\r
37     NS_LOG(DEBUG, "NSCacheCreate");\r
38 \r
39     return newList;\r
40 }\r
41 \r
42 NSCacheElement * NSStorageRead(NSCacheList * list, const char * findId)\r
43 {\r
44     pthread_mutex_lock(&NSCacheMutex);\r
45 \r
46     NS_LOG(DEBUG, "NSCacheRead - IN");\r
47 \r
48     NSCacheElement * iter = list->head;\r
49     NSCacheElement * next = NULL;\r
50     NSCacheType type = list->cacheType;\r
51 \r
52     NS_LOG_V(DEBUG, "Find ID - %s", findId);\r
53 \r
54     while (iter)\r
55     {\r
56         next = iter->next;\r
57 \r
58         if (NSProviderCompareIdCacheData(type, iter->data, findId))\r
59         {\r
60             NS_LOG(DEBUG, "Found in Cache");\r
61             pthread_mutex_unlock(&NSCacheMutex);\r
62             return iter;\r
63         }\r
64 \r
65         iter = next;\r
66     }\r
67 \r
68     NS_LOG(DEBUG, "Not found in Cache");\r
69     NS_LOG(DEBUG, "NSCacheRead - OUT");\r
70     pthread_mutex_unlock(&NSCacheMutex);\r
71 \r
72     return NULL;\r
73 }\r
74 \r
75 NSResult NSCacheUpdateSubScriptionState(NSCacheList * list, char * id, bool state)\r
76 {\r
77     pthread_mutex_lock(&NSCacheMutex);\r
78 \r
79     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - IN");\r
80 \r
81     if (id == NULL)\r
82     {\r
83         NS_LOG(DEBUG, "id is NULL");\r
84         pthread_mutex_unlock(&NSCacheMutex);\r
85         return NS_ERROR;\r
86     }\r
87 \r
88     NSCacheElement * it = NSStorageRead(list, id);\r
89 \r
90     if (it)\r
91     {\r
92         NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
93         if (strcmp(itData->id, id) == 0)\r
94         {\r
95             NS_LOG(DEBUG, "Update Data - IN");\r
96 \r
97             NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
98             NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
99             NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
100             NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
101             NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
102             NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
103 \r
104             NS_LOG_V(DEBUG, "update state = %d", state);\r
105 \r
106             itData->isWhite = state;\r
107 \r
108             NS_LOG(DEBUG, "Update Data - OUT");\r
109             pthread_mutex_unlock(&NSCacheMutex);\r
110             return NS_OK;\r
111         }\r
112     }\r
113     else\r
114     {\r
115         NS_LOG(DEBUG, "Not Found Data");\r
116     }\r
117 \r
118     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - OUT");\r
119     pthread_mutex_unlock(&NSCacheMutex);\r
120     return NS_ERROR;\r
121 }\r
122 \r
123 NSResult NSCacheUpdateSubScriptionState(NSCacheList * list, char * id, bool state)\r
124 {\r
125     pthread_mutex_lock(&NSCacheMutex);\r
126 \r
127     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - IN");\r
128 \r
129     if (id == NULL)\r
130     {\r
131         NS_LOG(DEBUG, "id is NULL");\r
132         pthread_mutex_unlock(&NSCacheMutex);\r
133         return NS_ERROR;\r
134     }\r
135 \r
136     NSCacheElement * it = NSStorageRead(list, id);\r
137 \r
138     if (it)\r
139     {\r
140         NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
141         if (strcmp(itData->id, id) == 0)\r
142         {\r
143             NS_LOG(DEBUG, "Update Data - IN");\r
144 \r
145             NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
146             NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
147             NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
148             NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
149             NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
150             NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
151 \r
152             NS_LOG_V(DEBUG, "update state = %d", state);\r
153 \r
154             itData->isWhite = state;\r
155 \r
156             NS_LOG(DEBUG, "Update Data - OUT");\r
157             pthread_mutex_unlock(&NSCacheMutex);\r
158             return NS_OK;\r
159         }\r
160     }\r
161     else\r
162     {\r
163         NS_LOG(DEBUG, "Not Found Data");\r
164     }\r
165 \r
166     NS_LOG(DEBUG, "NSCacheUpdateSubScriptionState - OUT");\r
167     pthread_mutex_unlock(&NSCacheMutex);\r
168     return NS_ERROR;\r
169 }\r
170 \r
171 NSResult NSStorageWrite(NSCacheList * list, NSCacheElement * newObj)\r
172 {\r
173     pthread_mutex_lock(&NSCacheMutex);\r
174 \r
175     NSCacheType type = list->cacheType;\r
176 \r
177     NS_LOG(DEBUG, "NSCacheWrite - IN");\r
178 \r
179     if (newObj == NULL)\r
180     {\r
181         NS_LOG(DEBUG, "newObj is NULL - IN");\r
182         pthread_mutex_unlock(&NSCacheMutex);\r
183         return NS_ERROR;\r
184     }\r
185 \r
186     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
187     {\r
188         NS_LOG(DEBUG, "Type is SUBSCRIBER");\r
189 \r
190         NSCacheSubData * subData = (NSCacheSubData *) newObj->data;\r
191         NSCacheElement * it = NSStorageRead(list, subData->id);\r
192 \r
193         if (it)\r
194         {\r
195             NSCacheSubData * itData = (NSCacheSubData *) it->data;\r
196 \r
197             if (strcmp(itData->id, subData->id) == 0)\r
198             {\r
199                 NS_LOG(DEBUG, "Update Data - IN");\r
200 \r
201                 NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
202                 NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
203                 NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
204                 NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
205                 NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
206                 NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
207 \r
208                 NS_LOG_V(DEBUG, "subData_ID = %s", subData->id);\r
209                 NS_LOG_V(DEBUG, "subData_MsgObID = %d", subData->messageObId);\r
210                 NS_LOG_V(DEBUG, "subData_SyncObID = %d", subData->syncObId);\r
211                 NS_LOG_V(DEBUG, "subData_Cloud_MsgObID = %d", subData->remote_messageObId);\r
212                 NS_LOG_V(DEBUG, "subData_Cloud_SyncObID = %d", subData->remote_syncObId);\r
213                 NS_LOG_V(DEBUG, "subData_IsWhite = %d", subData->isWhite);\r
214 \r
215                 if (subData->messageObId != 0)\r
216                 {\r
217                     itData->messageObId = subData->messageObId;\r
218                 }\r
219 \r
220                 if (subData->syncObId != 0)\r
221                 {\r
222                     itData->syncObId = subData->syncObId;\r
223                 }\r
224 \r
225                 if (subData->remote_messageObId != 0)\r
226                 {\r
227                     itData->remote_messageObId = subData->remote_messageObId;\r
228                 }\r
229 \r
230                 if (subData->remote_syncObId != 0)\r
231                 {\r
232                     itData->remote_syncObId = subData->remote_syncObId;\r
233                     NS_LOG_V(DEBUG, "sync id cached: %d", itData->remote_syncObId);\r
234                 }\r
235 \r
236                 NS_LOG(DEBUG, "Update Data - OUT");\r
237 \r
238                 pthread_mutex_unlock(&NSCacheMutex);\r
239                 return NS_OK;\r
240             }\r
241         }\r
242 \r
243     }\r
244     else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
245     {\r
246         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
247 \r
248         NSCacheTopicData * topicData = (NSCacheTopicData *) newObj->data;\r
249         NSCacheElement * it = NSStorageRead(list, topicData->topicName);\r
250 \r
251         if (it)\r
252         {\r
253             NS_LOG(DEBUG, "already registered for topic name");\r
254             pthread_mutex_unlock(&NSCacheMutex);\r
255             return NS_FAIL;\r
256         }\r
257     }\r
258 \r
259     if (list->head == NULL)\r
260     {\r
261         NS_LOG(DEBUG, "list->head is NULL, Insert First Data");\r
262         list->head = list->tail = newObj;\r
263         pthread_mutex_unlock(&NSCacheMutex);\r
264         return NS_OK;\r
265     }\r
266 \r
267     list->tail = list->tail->next = newObj;\r
268     NS_LOG(DEBUG, "list->head is not NULL");\r
269     pthread_mutex_unlock(&NSCacheMutex);\r
270     return NS_OK;\r
271 }\r
272 \r
273 NSResult NSStorageDestroy(NSCacheList * list)\r
274 {\r
275     NSCacheElement * iter = list->head;\r
276     NSCacheElement * next = NULL;\r
277 \r
278     NSCacheType type = list->cacheType;\r
279 \r
280     while (iter)\r
281     {\r
282         next = (NSCacheElement *) iter->next;\r
283 \r
284         NSProviderDeleteCacheData(type, iter->data);\r
285         OICFree(iter);\r
286 \r
287         iter = next;\r
288     }\r
289 \r
290     OICFree(list);\r
291 \r
292     return NS_OK;\r
293 }\r
294 \r
295 bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id)\r
296 {\r
297     NS_LOG(DEBUG, "NSProviderCompareIdCacheData - IN");\r
298 \r
299     if (data == NULL)\r
300     {\r
301         return false;\r
302     }\r
303 \r
304     NS_LOG_V(DEBUG, "Data(compData) = [%s]", id);\r
305 \r
306     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
307     {\r
308         NSCacheSubData * subData = (NSCacheSubData *) data;\r
309 \r
310         NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
311 \r
312         if (strcmp(subData->id, id) == 0)\r
313         {\r
314             NS_LOG(DEBUG, "SubData is Same");\r
315             return true;\r
316         }\r
317 \r
318         NS_LOG(DEBUG, "Message Data is Not Same");\r
319         return false;\r
320     }\r
321     else if (type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
322     {\r
323         NSCacheTopicData * topicData = (NSCacheTopicData *) data;\r
324 \r
325         NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->topicName);\r
326 \r
327         if (strcmp(topicData->topicName, id) == 0)\r
328         {\r
329             NS_LOG(DEBUG, "SubData is Same");\r
330             return true;\r
331         }\r
332 \r
333         NS_LOG(DEBUG, "Message Data is Not Same");\r
334         return false;\r
335     }\r
336     else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC)\r
337     {\r
338         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
339 \r
340         NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->topicName);\r
341 \r
342         if (strcmp(topicData->topicName, id) == 0)\r
343         {\r
344             NS_LOG(DEBUG, "SubData is Same");\r
345             return true;\r
346         }\r
347 \r
348         NS_LOG(DEBUG, "Message Data is Not Same");\r
349         return false;\r
350     }\r
351 \r
352     NS_LOG(DEBUG, "NSProviderCompareIdCacheData - OUT");\r
353     return false;\r
354 }\r
355 \r
356 NSResult NSProviderDeleteCacheData(NSCacheType type, void * data)\r
357 {\r
358     if (data == NULL)\r
359     {\r
360         return NS_OK;\r
361     }\r
362 \r
363     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
364     {\r
365         NSCacheSubData * subData = (NSCacheSubData *) data;\r
366 \r
367         (subData->id)[0] = '\0';\r
368         OICFree(subData);\r
369 \r
370         return NS_OK;\r
371     }\r
372     else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
373     {\r
374         NSCacheTopicData * data = (NSCacheTopicData *) data;\r
375         OICFree(data->topicName);\r
376     }\r
377     else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC)\r
378     {\r
379         NSCacheTopicSubData * data = (NSCacheTopicSubData *) data;\r
380         OICFree(data->topicName);\r
381     }\r
382 \r
383     return NS_OK;\r
384 }\r
385 \r
386 bool NSIsSameObId(NSCacheSubData * data, OCObservationId id)\r
387 {\r
388     if (id == data->messageObId || id == data->syncObId || id == data->remote_messageObId ||\r
389                 id == data->remote_syncObId)\r
390     {\r
391         return true;\r
392     }\r
393 \r
394     return false;\r
395 }\r
396 \r
397 NSResult NSProviderDeleteSubDataFromObId(NSCacheList * list, OCObservationId id)\r
398 {\r
399     if(!list || !list->head)\r
400     {\r
401         NS_LOG(INFO, "list is NULL");\r
402         return NS_FAIL;\r
403     }\r
404 \r
405     pthread_mutex_lock(&NSCacheMutex);\r
406     NSCacheElement * prev = list->head;\r
407     NSCacheElement * del = list->head;\r
408 \r
409     NSCacheType type = list->cacheType;\r
410 \r
411     bool isDelete = true;\r
412 \r
413     while(isDelete)\r
414     {\r
415         NSCacheSubData * curr = (NSCacheSubData *)del->data;\r
416 \r
417         isDelete = false;\r
418 \r
419         if (NSIsSameObId(curr, id))\r
420         {\r
421             if (del == list->head) // first object\r
422             {\r
423                 if (del == list->tail) // first object (one object)\r
424                 {\r
425                     list->tail = del->next;\r
426                 }\r
427 \r
428                 list->head = del->next;\r
429 \r
430                 NSProviderDeleteCacheData(type, del->data);\r
431                 OICFree(del);\r
432                 isDelete = true;\r
433             }\r
434         }\r
435         else\r
436         {\r
437             del = del->next;\r
438             while (del)\r
439             {\r
440                 if (NSIsSameObId(curr, id))\r
441                 {\r
442                     if (del == list->tail) // delete object same to last object\r
443                     {\r
444                         list->tail = prev;\r
445                     }\r
446 \r
447                     prev->next = del->next;\r
448                     NSProviderDeleteCacheData(type, del->data);\r
449                     OICFree(del);\r
450                     isDelete = true;\r
451                     break;\r
452                 }\r
453 \r
454                 prev = del;\r
455                 del = del->next;\r
456             }\r
457         }\r
458     }\r
459     pthread_mutex_unlock(&NSCacheMutex);\r
460     return NS_OK;\r
461 }\r
462 \r
463 NSResult NSStorageDelete(NSCacheList * list, const char * delId)\r
464 {\r
465     pthread_mutex_lock(&NSCacheMutex);\r
466     NSCacheElement * prev = list->head;\r
467     NSCacheElement * del = list->head;\r
468 \r
469     NSCacheType type = list->cacheType;\r
470 \r
471     if (NSProviderCompareIdCacheData(type, del->data, delId))\r
472     {\r
473         if (del == list->head) // first object\r
474         {\r
475             if (del == list->tail) // first object (one object)\r
476             {\r
477                 list->tail = del->next;\r
478             }\r
479 \r
480             list->head = del->next;\r
481 \r
482             NSProviderDeleteCacheData(type, del->data);\r
483             OICFree(del);\r
484             pthread_mutex_unlock(&NSCacheMutex);\r
485             return NS_OK;\r
486         }\r
487     }\r
488 \r
489     del = del->next;\r
490     while (del)\r
491     {\r
492         if (NSProviderCompareIdCacheData(type, del->data, delId))\r
493         {\r
494             if (del == list->tail) // delete object same to last object\r
495             {\r
496                 list->tail = prev;\r
497             }\r
498 \r
499             prev->next = del->next;\r
500             NSProviderDeleteCacheData(type, del->data);\r
501             OICFree(del);\r
502             pthread_mutex_unlock(&NSCacheMutex);\r
503             return NS_OK;\r
504         }\r
505 \r
506         prev = del;\r
507         del = del->next;\r
508     }\r
509     pthread_mutex_unlock(&NSCacheMutex);\r
510     return NS_FAIL;\r
511 }\r