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
30 #include <string>
31 #include <algorithm>
32 #include <iterator>
33 #include <DataItemIndex.h>
34 #include <platform_lib_log_util.h>
35 #include <IDataItemObserver.h>
36 #include <DataItemId.h>
37
38 using namespace std;
39 using namespace loc_core;
40
41 template <typename CT, typename DIT>
DataItemIndex()42 inline DataItemIndex <CT,DIT> :: DataItemIndex () {}
43
44 template <typename CT, typename DIT>
~DataItemIndex()45 inline DataItemIndex <CT,DIT> :: ~DataItemIndex () {}
46
47 template <typename CT, typename DIT>
getListOfSubscribedClients(DIT id,list<CT> & out)48 void DataItemIndex <CT,DIT> :: getListOfSubscribedClients
49 (
50 DIT id,
51 list <CT> & out
52 )
53 {
54 typename map < DIT, list <CT> > :: iterator cdiIter =
55 mClientsPerDataItemMap.find (id);
56 if (cdiIter != mClientsPerDataItemMap.end ()) {
57 out = cdiIter->second;
58 }
59 }
60
61
62 template <typename CT, typename DIT>
remove(DIT id)63 int DataItemIndex <CT,DIT> :: remove (DIT id) {
64 int result = 0;
65 ENTRY_LOG ();
66 mClientsPerDataItemMap.erase (id);
67 EXIT_LOG_WITH_ERROR ("%d",result);
68 return result;
69 }
70
71 template <typename CT, typename DIT>
remove(const list<CT> & r,list<DIT> & out)72 void DataItemIndex <CT,DIT> :: remove (const list <CT> & r, list <DIT> & out) {
73 ENTRY_LOG ();
74 typename map < DIT, list <CT> > :: iterator cdiIter =
75 mClientsPerDataItemMap.begin ();
76 while (cdiIter != mClientsPerDataItemMap.end()) {
77 typename list <CT> :: const_iterator it = r.begin ();
78 for (; it != r.end (); ++it) {
79 typename list <CT> :: iterator iter =
80 find
81 (
82 cdiIter->second.begin (),
83 cdiIter->second.end (),
84 *it
85 );
86 if (iter != cdiIter->second.end ()) {
87 cdiIter->second.erase (iter);
88 }
89 }
90
91 if (cdiIter->second.empty ()) {
92 out.push_back (cdiIter->first);
93 // Post-increment operator increases the iterator but returns the
94 // prevous one that will be invalidated by erase()
95 mClientsPerDataItemMap.erase (cdiIter++);
96 } else {
97 ++cdiIter;
98 }
99 }
100 EXIT_LOG_WITH_ERROR ("%d",0);
101 }
102
103 template <typename CT, typename DIT>
remove(DIT id,const list<CT> & r,list<CT> & out)104 void DataItemIndex <CT,DIT> :: remove
105 (
106 DIT id,
107 const list <CT> & r,
108 list <CT> & out
109 )
110 {
111 ENTRY_LOG ();
112
113 typename map < DIT, list <CT> > :: iterator cdiIter =
114 mClientsPerDataItemMap.find (id);
115 if (cdiIter != mClientsPerDataItemMap.end ()) {
116 set_intersection (cdiIter->second.begin (), cdiIter->second.end (),
117 r.begin (), r.end (),
118 inserter (out, out.begin ()));
119 if (!out.empty ()) {
120 typename list <CT> :: iterator it = out.begin ();
121 for (; it != out.end (); ++it) {
122 cdiIter->second.erase (find (cdiIter->second.begin (),
123 cdiIter->second.end (),
124 *it));
125 }
126 }
127 if (cdiIter->second.empty ()) {
128 mClientsPerDataItemMap.erase (cdiIter);
129 EXIT_LOG_WITH_ERROR ("%d",0);
130 }
131 }
132 EXIT_LOG_WITH_ERROR ("%d",0);
133 }
134
135 template <typename CT, typename DIT>
add(DIT id,const list<CT> & l,list<CT> & out)136 void DataItemIndex <CT,DIT> :: add
137 (
138 DIT id,
139 const list <CT> & l,
140 list <CT> & out
141 )
142 {
143 ENTRY_LOG ();
144 list <CT> difference;
145 typename map < DIT, list <CT> > :: iterator cdiIter =
146 mClientsPerDataItemMap.find (id);
147 if (cdiIter != mClientsPerDataItemMap.end ()) {
148 set_difference (l.begin (), l.end (),
149 cdiIter->second.begin (), cdiIter->second.end (),
150 inserter (difference, difference.begin ()));
151 if (!difference.empty ()) {
152 difference.sort ();
153 out = difference;
154 cdiIter->second.merge (difference);
155 }
156 } else {
157 out = l;
158 pair < DIT, list <CT> > cndipair (id, out);
159 mClientsPerDataItemMap.insert (cndipair);
160 }
161 EXIT_LOG_WITH_ERROR ("%d",0);
162 }
163
164 template <typename CT, typename DIT>
add(CT client,const list<DIT> & l,list<DIT> & out)165 void DataItemIndex <CT,DIT> :: add
166 (
167 CT client,
168 const list <DIT> & l,
169 list <DIT> & out
170 )
171 {
172 ENTRY_LOG ();
173 typename map < DIT, list <CT> > :: iterator cdiIter;
174 typename list <DIT> :: const_iterator it = l.begin ();
175 for (; it != l.end (); ++it) {
176 cdiIter = mClientsPerDataItemMap.find (*it);
177 if (cdiIter == mClientsPerDataItemMap.end ()) {
178 out.push_back (*it);
179 pair < DIT, list <CT> > cndiPair (*it, list <CT> (1, client));
180 mClientsPerDataItemMap.insert (cndiPair);
181 } else {
182 typename list<CT> :: iterator clientIter =
183 find
184 (
185 cdiIter->second.begin (),
186 cdiIter->second.end (),
187 client
188 );
189 if (clientIter == cdiIter->second.end()) {
190 cdiIter->second.push_back (client);
191 }
192 }
193 }
194 EXIT_LOG_WITH_ERROR ("%d",0);
195 }
196
197 // Explicit instantiation must occur in same namespace where class is defined
198 namespace loc_core
199 {
200 template class DataItemIndex <IDataItemObserver *, DataItemId>;
201 template class DataItemIndex <string, DataItemId>;
202 }
203