1 /* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation, nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29 #include <algorithm>
30 #include <iterator>
31 #include <string>
32 #include <platform_lib_log_util.h>
33 #include <ClientIndex.h>
34 #include <IDataItemObserver.h>
35 #include <DataItemId.h>
36
37 using namespace std;
38 using namespace loc_core;
39
40 template <typename CT, typename DIT>
ClientIndex()41 inline ClientIndex <CT,DIT> :: ClientIndex () {}
42
43 template <typename CT, typename DIT>
~ClientIndex()44 inline ClientIndex <CT,DIT> :: ~ClientIndex () {}
45
46 template <typename CT, typename DIT>
isSubscribedClient(CT client)47 bool ClientIndex <CT,DIT> :: isSubscribedClient (CT client) {
48 bool result = false;
49 ENTRY_LOG ();
50 typename map < CT, list <DIT> > :: iterator it =
51 mDataItemsPerClientMap.find (client);
52 if (it != mDataItemsPerClientMap.end ()) {
53 result = true;
54 }
55 EXIT_LOG_WITH_ERROR ("%d",result);
56 return result;
57 }
58
59 template <typename CT, typename DIT>
getSubscribedList(CT client,list<DIT> & out)60 void ClientIndex <CT,DIT> :: getSubscribedList (CT client, list <DIT> & out) {
61 ENTRY_LOG ();
62 typename map < CT, list <DIT> > :: iterator it =
63 mDataItemsPerClientMap.find (client);
64 if (it != mDataItemsPerClientMap.end ()) {
65 out = it->second;
66 }
67 EXIT_LOG_WITH_ERROR ("%d",0);
68 }
69
70 template <typename CT, typename DIT>
remove(CT client)71 int ClientIndex <CT,DIT> :: remove (CT client) {
72 int result = 0;
73 ENTRY_LOG ();
74 mDataItemsPerClientMap.erase (client);
75 EXIT_LOG_WITH_ERROR ("%d",result);
76 return result;
77 }
78
79 template <typename CT, typename DIT>
remove(const list<DIT> & r,list<CT> & out)80 void ClientIndex <CT,DIT> :: remove (const list <DIT> & r, list <CT> & out) {
81 ENTRY_LOG ();
82 typename map < CT, list <DIT> > :: iterator dicIter =
83 mDataItemsPerClientMap.begin ();
84 while (dicIter != mDataItemsPerClientMap.end()) {
85 typename list <DIT> :: const_iterator it = r.begin ();
86 for (; it != r.end (); ++it) {
87 typename list <DIT> :: iterator iter =
88 find (dicIter->second.begin (), dicIter->second.end (), *it);
89 if (iter != dicIter->second.end ()) {
90 dicIter->second.erase (iter);
91 }
92 }
93 if (dicIter->second.empty ()) {
94 out.push_back (dicIter->first);
95 // Post-increment operator increases the iterator but returns the
96 // prevous one that will be invalidated by erase()
97 mDataItemsPerClientMap.erase (dicIter++);
98 } else {
99 ++dicIter;
100 }
101 }
102 EXIT_LOG_WITH_ERROR ("%d",0);
103 }
104
105 template <typename CT, typename DIT>
remove(CT client,const list<DIT> & r,list<DIT> & out)106 void ClientIndex <CT,DIT> :: remove
107 (
108 CT client,
109 const list <DIT> & r,
110 list <DIT> & out
111 )
112 {
113 ENTRY_LOG ();
114 typename map < CT, list <DIT> > :: iterator dicIter =
115 mDataItemsPerClientMap.find (client);
116 if (dicIter != mDataItemsPerClientMap.end ()) {
117 set_intersection (dicIter->second.begin (), dicIter->second.end (),
118 r.begin (), r.end (),
119 inserter (out,out.begin ()));
120 if (!out.empty ()) {
121 typename list <DIT> :: iterator it = out.begin ();
122 for (; it != out.end (); ++it) {
123 dicIter->second.erase (find (dicIter->second.begin (),
124 dicIter->second.end (),
125 *it));
126 }
127 }
128 if (dicIter->second.empty ()) {
129 mDataItemsPerClientMap.erase (dicIter);
130 EXIT_LOG_WITH_ERROR ("%d",0);
131 }
132 }
133 EXIT_LOG_WITH_ERROR ("%d",0);
134 }
135
136 template <typename CT, typename DIT>
add(CT client,const list<DIT> & l,list<DIT> & out)137 void ClientIndex <CT,DIT> :: add
138 (
139 CT client,
140 const list <DIT> & l,
141 list <DIT> & out
142 )
143 {
144 ENTRY_LOG ();
145 list <DIT> difference;
146 typename map < CT, list <DIT> > :: iterator dicIter =
147 mDataItemsPerClientMap.find (client);
148 if (dicIter != mDataItemsPerClientMap.end ()) {
149 set_difference (l.begin (), l.end (),
150 dicIter->second.begin (), dicIter->second.end (),
151 inserter (difference,difference.begin ()));
152 if (!difference.empty ()) {
153 difference.sort ();
154 out = difference;
155 dicIter->second.merge (difference);
156 dicIter->second.unique ();
157 }
158 } else {
159 out = l;
160 pair < CT, list <DIT> > dicnpair (client, out);
161 mDataItemsPerClientMap.insert (dicnpair);
162 }
163 EXIT_LOG_WITH_ERROR ("%d",0);
164 }
165
166 // Explicit instantiation must occur in same namespace where class is defined
167 namespace loc_core
168 {
169 template class ClientIndex <IDataItemObserver *, DataItemId>;
170 template class ClientIndex <string, DataItemId>;
171 }
172