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