summaryrefslogtreecommitdiff
path: root/core/SystemStatusOsObserver.cpp
diff options
context:
space:
mode:
authorKevin Tang <zhikait@codeaurora.org>2018-03-23 22:57:51 -0700
committerKevin Tang <zhikait@codeaurora.org>2018-05-14 12:20:31 -0700
commit36da980fea8cd9e95b26a113e7d2634bf25b3522 (patch)
treea30871c447d10dbd360c3d79616ffdba394f539d /core/SystemStatusOsObserver.cpp
parent86e1b52c812f5d9680ec1ad755d80644d0736a07 (diff)
downloadgps-36da980fea8cd9e95b26a113e7d2634bf25b3522.tar.gz
changed SystemStatusOsObserver
to allow clients to subscribe before subscription obj arrives, and also simplified ClientIndex and DataItemIndex implementation significantly. Change-Id: I092f344e688fa698aa98795b8a8f0c1ba8fcd9e4 CRs-Fixed: 2218519
Diffstat (limited to 'core/SystemStatusOsObserver.cpp')
-rw-r--r--core/SystemStatusOsObserver.cpp635
1 files changed, 275 insertions, 360 deletions
diff --git a/core/SystemStatusOsObserver.cpp b/core/SystemStatusOsObserver.cpp
index 2fdd19f..0f6d228 100644
--- a/core/SystemStatusOsObserver.cpp
+++ b/core/SystemStatusOsObserver.cpp
@@ -32,28 +32,20 @@
#include <SystemStatus.h>
#include <SystemStatusOsObserver.h>
#include <IDataItemCore.h>
-#include <IClientIndex.h>
-#include <IDataItemIndex.h>
-#include <IndexFactory.h>
#include <DataItemsFactoryProxy.h>
namespace loc_core
{
-SystemStatusOsObserver::SystemStatusOsObserver(
- SystemStatus* systemstatus, const MsgTask* msgTask) :
- mSystemStatus(systemstatus),
- mAddress("SystemStatusOsObserver"),
-#ifdef USE_GLIB
- mBackHaulConnectReqCount(0),
-#endif
- mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()),
- mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex())
-{
- mContext.mMsgTask = msgTask;
+template <typename CINT, typename COUT>
+COUT SystemStatusOsObserver::containerTransfer(CINT& inContainer) {
+ COUT outContainer(0);
+ for (auto item : inContainer) {
+ outContainer.insert(outContainer.begin(), item);
+ }
+ return outContainer;
}
-SystemStatusOsObserver::~SystemStatusOsObserver()
-{
+SystemStatusOsObserver::~SystemStatusOsObserver() {
// Close data-item library handle
DataItemsFactoryProxy::closeDataItemLibraryHandle();
@@ -65,290 +57,238 @@ SystemStatusOsObserver::~SystemStatusOsObserver()
}
mDataItemCache.clear();
- delete mClientIndex;
- delete mDataItemIndex;
}
void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj)
{
- mContext.mSubscriptionObj = subscriptionObj;
-
- LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu",
- mSubscribeReqCache.size(), mReqDataCache.size());
-
- // we have received the subscription object. process cached requests
- // process - subscribe request cache
- for (auto each : mSubscribeReqCache) {
- subscribe(each.second, each.first);
- }
- // process - requestData request cache
- for (auto each : mReqDataCache) {
- requestData(each.second, each.first);
- }
-}
-
-// Helper to cache requests subscribe and requestData till subscription obj is obtained
-void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache,
- const list<DataItemId>& l, IDataItemObserver* client)
-{
- ObserverReqCache::iterator dicIter = reqCache.find(client);
- if (dicIter != reqCache.end()) {
- // found
- list<DataItemId> difference(0);
- set_difference(l.begin(), l.end(),
- dicIter->second.begin(), dicIter->second.end(),
- inserter(difference, difference.begin()));
- if (!difference.empty()) {
- difference.sort();
- dicIter->second.merge(difference);
- dicIter->second.unique();
+ struct SetSubsObj : public LocMsg {
+ ObserverContext& mContext;
+ IDataItemSubscription* mSubsObj;
+ inline SetSubsObj(ObserverContext& context, IDataItemSubscription* subscriptionObj) :
+ mContext(context), mSubsObj(subscriptionObj) {}
+ void proc() const {
+ mContext.mSubscriptionObj = mSubsObj;
+
+ if (!mContext.mSSObserver->mDataItemToClients.empty()) {
+ list<DataItemId> dis(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ mContext.mSSObserver->mDataItemToClients.getKeys()));
+ mContext.mSubscriptionObj->subscribe(dis, mContext.mSSObserver);
+ mContext.mSubscriptionObj->requestData(dis, mContext.mSSObserver);
+ }
}
- }
- else {
- // not found
- reqCache[client] = l;
+ };
+
+ if (nullptr == subscriptionObj) {
+ LOC_LOGw("subscriptionObj is NULL");
+ } else {
+ mContext.mMsgTask->sendMsg(new SetSubsObj(mContext, subscriptionObj));
}
}
/******************************************************************************
IDataItemSubscription Overrides
******************************************************************************/
-void SystemStatusOsObserver::subscribe(
- const list<DataItemId>& l, IDataItemObserver* client)
+void SystemStatusOsObserver::subscribe(const list<DataItemId>& l, IDataItemObserver* client,
+ bool toRequestData)
{
- if (nullptr == mContext.mSubscriptionObj) {
- LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
- cacheObserverRequest(mSubscribeReqCache, l, client);
- return;
- }
-
struct HandleSubscribeReq : public LocMsg {
- HandleSubscribeReq(SystemStatusOsObserver* parent,
- const list<DataItemId>& l, IDataItemObserver* client) :
- mParent(parent), mClient(client), mDataItemList(l) {}
- virtual ~HandleSubscribeReq() {}
- void proc() const {
+ inline HandleSubscribeReq(SystemStatusOsObserver* parent,
+ list<DataItemId>& l, IDataItemObserver* client, bool requestData) :
+ mParent(parent), mClient(client),
+ mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)),
+ mToRequestData(requestData) {}
- if (mDataItemList.empty()) {
- LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
- return;
- }
-
- // Handle First Response
- list<DataItemId> pendingFirstResponseList(0);
- mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
-
- // Do not send first response for only pendingFirstResponseList,
- // instead send for all the data items (present in the cache) that
- // have been subscribed for each time.
- mParent->sendFirstResponse(mDataItemList, mClient);
+ void proc() const {
+ unordered_set<DataItemId> dataItemsToSubscribe(0);
+ mParent->mDataItemToClients.add(mDataItemSet, {mClient}, &dataItemsToSubscribe);
+ mParent->mClientToDataItems.add(mClient, mDataItemSet);
- list<DataItemId> yetToSubscribeDataItemsList(0);
- mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList);
+ mParent->sendCachedDataItems(mDataItemSet, mClient);
- // Send subscription list to framework
- if (!yetToSubscribeDataItemsList.empty()) {
- mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent);
+ // Send subscription set to framework
+ if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToSubscribe.empty()) {
LOC_LOGD("Subscribe Request sent to framework for the following");
- mParent->logMe(yetToSubscribeDataItemsList);
+ mParent->logMe(dataItemsToSubscribe);
+
+ if (mToRequestData) {
+ mParent->mContext.mSubscriptionObj->requestData(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToSubscribe)),
+ mParent);
+ } else {
+ mParent->mContext.mSubscriptionObj->subscribe(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToSubscribe)),
+ mParent);
+ }
}
}
- SystemStatusOsObserver* mParent;
+ mutable SystemStatusOsObserver* mParent;
IDataItemObserver* mClient;
- const list<DataItemId> mDataItemList;
+ const unordered_set<DataItemId> mDataItemSet;
+ bool mToRequestData;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client));
+
+ if (l.empty() || nullptr == client) {
+ LOC_LOGw("Data item set is empty or client is nullptr");
+ } else {
+ mContext.mMsgTask->sendMsg(
+ new HandleSubscribeReq(this, (list<DataItemId>&)l, client, toRequestData));
+ }
}
void SystemStatusOsObserver::updateSubscription(
const list<DataItemId>& l, IDataItemObserver* client)
{
- if (nullptr == mContext.mSubscriptionObj) {
- LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
- return;
- }
-
struct HandleUpdateSubscriptionReq : public LocMsg {
HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent,
- const list<DataItemId>& l, IDataItemObserver* client) :
- mParent(parent), mClient(client), mDataItemList(l) {}
- virtual ~HandleUpdateSubscriptionReq() {}
- void proc() const {
- if (mDataItemList.empty()) {
- LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
- return;
- }
+ list<DataItemId>& l, IDataItemObserver* client) :
+ mParent(parent), mClient(client),
+ mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}
- list<DataItemId> currentlySubscribedList(0);
- mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList);
-
- list<DataItemId> removeDataItemList(0);
- set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(),
- mDataItemList.begin(), mDataItemList.end(),
- inserter(removeDataItemList,removeDataItemList.begin()));
-
- // Handle First Response
- list<DataItemId> pendingFirstResponseList(0);
- mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList);
+ void proc() const {
+ unordered_set<DataItemId> dataItemsToSubscribe(0);
+ unordered_set<DataItemId> dataItemsToUnsubscribe(0);
+ unordered_set<IDataItemObserver*> clients({mClient});
+ // below removes clients from all entries keyed with the return of the
+ // mClientToDataItems.update() call. If leaving an empty set of clients as the
+ // result, the entire entry will be removed. dataItemsToUnsubscribe will be
+ // populated to keep the keys of the removed entries.
+ mParent->mDataItemToClients.trimOrRemove(
+ // this call updates <IDataItemObserver*, DataItemId> map; removes
+ // the DataItemId's that are not new to the clietn from mDataItemSet;
+ // and returns a set of mDataItemSet's that are no longer used by client.
+ // This unused set of mDataItemSet's is passed to trimOrRemove method of
+ // <DataItemId, IDataItemObserver*> map to remove the client from the
+ // corresponding entries, and gets a set of the entries that are
+ // removed from the <DataItemId, IDataItemObserver*> map as a result.
+ mParent->mClientToDataItems.update(mClient,
+ (unordered_set<DataItemId>&)mDataItemSet),
+ clients, &dataItemsToUnsubscribe, nullptr);
+ // below adds mClient to <DataItemId, IDataItemObserver*> map, and populates
+ // new keys added to that map, which are DataItemIds to be subscribed.
+ mParent->mDataItemToClients.add(mDataItemSet, clients, &dataItemsToSubscribe);
// Send First Response
- mParent->sendFirstResponse(pendingFirstResponseList, mClient);
-
- list<DataItemId> yetToSubscribeDataItemsList(0);
- mParent->mDataItemIndex->add(
- mClient, mDataItemList, yetToSubscribeDataItemsList);
-
- // Send subscription list to framework
- if (!yetToSubscribeDataItemsList.empty()) {
- mParent->mContext.mSubscriptionObj->subscribe(
- yetToSubscribeDataItemsList, mParent);
- LOC_LOGD("Subscribe Request sent to framework for the following");
- mParent->logMe(yetToSubscribeDataItemsList);
- }
-
- list<DataItemId> unsubscribeList(0);
- list<DataItemId> unused(0);
- mParent->mClientIndex->remove(mClient, removeDataItemList, unused);
+ mParent->sendCachedDataItems(mDataItemSet, mClient);
+
+ if (nullptr != mParent->mContext.mSubscriptionObj) {
+ // Send subscription set to framework
+ if (!dataItemsToSubscribe.empty()) {
+ LOC_LOGD("Subscribe Request sent to framework for the following");
+ mParent->logMe(dataItemsToSubscribe);
+
+ mParent->mContext.mSubscriptionObj->subscribe(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToSubscribe)),
+ mParent);
+ }
- if (!mParent->mClientIndex->isSubscribedClient(mClient)) {
- mParent->mDataItemIndex->remove(
- list<IDataItemObserver*> (1,mClient), unsubscribeList);
- }
- if (!unsubscribeList.empty()) {
// Send unsubscribe to framework
- mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
- LOC_LOGD("Unsubscribe Request sent to framework for the following");
- mParent->logMe(unsubscribeList);
+ if (!dataItemsToUnsubscribe.empty()) {
+ LOC_LOGD("Unsubscribe Request sent to framework for the following");
+ mParent->logMe(dataItemsToUnsubscribe);
+
+ mParent->mContext.mSubscriptionObj->unsubscribe(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToUnsubscribe)),
+ mParent);
+ }
}
}
SystemStatusOsObserver* mParent;
IDataItemObserver* mClient;
- const list<DataItemId> mDataItemList;
+ unordered_set<DataItemId> mDataItemSet;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client));
-}
-void SystemStatusOsObserver::requestData(
- const list<DataItemId>& l, IDataItemObserver* client)
-{
- if (nullptr == mContext.mSubscriptionObj) {
- LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__);
- cacheObserverRequest(mReqDataCache, l, client);
- return;
+ if (l.empty() || nullptr == client) {
+ LOC_LOGw("Data item set is empty or client is nullptr");
+ } else {
+ mContext.mMsgTask->sendMsg(
+ new HandleUpdateSubscriptionReq(this, (list<DataItemId>&)l, client));
}
-
- struct HandleRequestData : public LocMsg {
- HandleRequestData(SystemStatusOsObserver* parent,
- const list<DataItemId>& l, IDataItemObserver* client) :
- mParent(parent), mClient(client), mDataItemList(l) {}
- virtual ~HandleRequestData() {}
- void proc() const {
- if (mDataItemList.empty()) {
- LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
- return;
- }
-
- list<DataItemId> yetToSubscribeDataItemsList(0);
- mParent->mClientIndex->add(
- mClient, mDataItemList, yetToSubscribeDataItemsList);
- mParent->mDataItemIndex->add(
- mClient, mDataItemList, yetToSubscribeDataItemsList);
-
- // Send subscription list to framework
- if (!mDataItemList.empty()) {
- mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent);
- LOC_LOGD("Subscribe Request sent to framework for the following");
- mParent->logMe(yetToSubscribeDataItemsList);
- }
- }
- SystemStatusOsObserver* mParent;
- IDataItemObserver* mClient;
- const list<DataItemId> mDataItemList;
- };
- mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client));
}
void SystemStatusOsObserver::unsubscribe(
const list<DataItemId>& l, IDataItemObserver* client)
{
- if (nullptr == mContext.mSubscriptionObj) {
- LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
- return;
- }
struct HandleUnsubscribeReq : public LocMsg {
HandleUnsubscribeReq(SystemStatusOsObserver* parent,
- const list<DataItemId>& l, IDataItemObserver* client) :
- mParent(parent), mClient(client), mDataItemList(l) {}
- virtual ~HandleUnsubscribeReq() {}
- void proc() const {
- if (mDataItemList.empty()) {
- LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting");
- return;
- }
+ list<DataItemId>& l, IDataItemObserver* client) :
+ mParent(parent), mClient(client),
+ mDataItemSet(containerTransfer<list<DataItemId>, unordered_set<DataItemId>>(l)) {}
- list<DataItemId> unsubscribeList(0);
- list<DataItemId> unused(0);
- mParent->mClientIndex->remove(mClient, mDataItemList, unused);
-
- for (auto each : mDataItemList) {
- list<IDataItemObserver*> clientListSubs(0);
- list<IDataItemObserver*> clientListOut(0);
- mParent->mDataItemIndex->remove(
- each, list<IDataItemObserver*> (1,mClient), clientListOut);
- // check if there are any other subscribed client for this data item id
- mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs);
- if (clientListSubs.empty())
- {
- LOC_LOGD("Client list subscribed is empty for dataitem - %d", each);
- unsubscribeList.push_back(each);
- }
- }
+ void proc() const {
+ unordered_set<DataItemId> dataItemsUnusedByClient(0);
+ unordered_set<IDataItemObserver*> clientToRemove(0);
+ mParent->mClientToDataItems.trimOrRemove({mClient}, mDataItemSet, &clientToRemove,
+ &dataItemsUnusedByClient);
+ unordered_set<DataItemId> dataItemsToUnsubscribe(0);
+ mParent->mDataItemToClients.trimOrRemove(dataItemsUnusedByClient, {mClient},
+ &dataItemsToUnsubscribe, nullptr);
+
+ if (nullptr != mParent->mContext.mSubscriptionObj && !dataItemsToUnsubscribe.empty()) {
+ LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
+ mParent->logMe(dataItemsToUnsubscribe);
- if (!unsubscribeList.empty()) {
// Send unsubscribe to framework
- mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
- LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
- mParent->logMe(unsubscribeList);
+ mParent->mContext.mSubscriptionObj->unsubscribe(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToUnsubscribe)),
+ mParent);
}
}
SystemStatusOsObserver* mParent;
IDataItemObserver* mClient;
- const list<DataItemId> mDataItemList;
+ unordered_set<DataItemId> mDataItemSet;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client));
+
+ if (l.empty() || nullptr == client) {
+ LOC_LOGw("Data item set is empty or client is nullptr");
+ } else {
+ mContext.mMsgTask->sendMsg(new HandleUnsubscribeReq(this, (list<DataItemId>&)l, client));
+ }
}
void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
{
- if (nullptr == mContext.mSubscriptionObj) {
- LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__);
- return;
- }
-
struct HandleUnsubscribeAllReq : public LocMsg {
HandleUnsubscribeAllReq(SystemStatusOsObserver* parent,
IDataItemObserver* client) :
mParent(parent), mClient(client) {}
- virtual ~HandleUnsubscribeAllReq() {}
- void proc() const {
- list<IDataItemObserver*> clients(1, mClient);
- list<DataItemId> unsubscribeList(0);
- if(0 == mParent->mClientIndex->remove(mClient)) {
- return;
- }
- mParent->mDataItemIndex->remove(clients, unsubscribeList);
- if (!unsubscribeList.empty()) {
- // Send unsubscribe to framework
- mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent);
- LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
- mParent->logMe(unsubscribeList);
+ void proc() const {
+ unordered_set<DataItemId> diByClient = mParent->mClientToDataItems.getValSet(mClient);
+ if (!diByClient.empty()) {
+ unordered_set<DataItemId> dataItemsToUnsubscribe;
+ mParent->mClientToDataItems.remove(mClient);
+ mParent->mDataItemToClients.trimOrRemove(diByClient, {mClient},
+ &dataItemsToUnsubscribe, nullptr);
+
+ if (!dataItemsToUnsubscribe.empty() &&
+ nullptr != mParent->mContext.mSubscriptionObj) {
+
+ LOC_LOGD("Unsubscribe Request sent to framework for the following data items");
+ mParent->logMe(dataItemsToUnsubscribe);
+
+ // Send unsubscribe to framework
+ mParent->mContext.mSubscriptionObj->unsubscribe(
+ containerTransfer<unordered_set<DataItemId>, list<DataItemId>>(
+ std::move(dataItemsToUnsubscribe)),
+ mParent);
+ }
}
}
SystemStatusOsObserver* mParent;
IDataItemObserver* mClient;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client));
+
+ if (nullptr == client) {
+ LOC_LOGw("Data item set is empty or client is nullptr");
+ } else {
+ mContext.mMsgTask->sendMsg(new HandleUnsubscribeAllReq(this, client));
+ }
}
/******************************************************************************
@@ -356,84 +296,78 @@ void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client)
******************************************************************************/
void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist)
{
- list<IDataItemCore*> dataItemList(0);
-
- for (auto each : dlist) {
- string dv;
- each->stringify(dv);
- LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
-
- IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
- if (nullptr == di) {
- LOC_LOGE("Unable to create dataitem:%d", each->getId());
- return;
- }
-
- // Copy contents into the newly created data item
- di->copy(each);
-
- // Request systemstatus to record this dataitem in its cache
- if (mSystemStatus->eventDataItemNotify(di)) {
- // add this dataitem if updated from last one
- dataItemList.push_back(di);
- }
- }
-
struct HandleNotify : public LocMsg {
- HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) :
- mParent(parent), mDList(l) {}
- virtual ~HandleNotify() {
- for (auto each : mDList) {
- delete each;
+ HandleNotify(SystemStatusOsObserver* parent, vector<IDataItemCore*>& v) :
+ mParent(parent), mDiVec(std::move(v)) {}
+
+ inline virtual ~HandleNotify() {
+ for (auto item : mDiVec) {
+ delete item;
}
}
+
void proc() const {
// Update Cache with received data items and prepare
// list of data items to be sent.
- list<DataItemId> dataItemIdsToBeSent(0);
- for (auto item : mDList) {
- bool dataItemUpdated = false;
- mParent->updateCache(item, dataItemUpdated);
- if (dataItemUpdated) {
- dataItemIdsToBeSent.push_back(item->getId());
+ unordered_set<DataItemId> dataItemIdsToBeSent(0);
+ for (auto item : mDiVec) {
+ if (mParent->updateCache(item)) {
+ dataItemIdsToBeSent.insert(item->getId());
}
}
// Send data item to all subscribed clients
- list<IDataItemObserver*> clientList(0);
+ unordered_set<IDataItemObserver*> clientSet(0);
for (auto each : dataItemIdsToBeSent) {
- list<IDataItemObserver*> clients(0);
- mParent->mDataItemIndex->getListOfSubscribedClients(each, clients);
- for (auto each_cient: clients) {
- clientList.push_back(each_cient);
+ auto clients = mParent->mDataItemToClients.getValSetPtr(each);
+ if (nullptr != clients) {
+ clientSet.insert(clients->begin(), clients->end());
}
}
- clientList.unique();
-
- for (auto client : clientList) {
- list<DataItemId> dataItemIdsSubscribedByThisClient(0);
- list<DataItemId> dataItemIdsToBeSentForThisClient(0);
- mParent->mClientIndex->getSubscribedList(
- client, dataItemIdsSubscribedByThisClient);
- dataItemIdsSubscribedByThisClient.sort();
- dataItemIdsToBeSent.sort();
-
- set_intersection(dataItemIdsToBeSent.begin(),
- dataItemIdsToBeSent.end(),
- dataItemIdsSubscribedByThisClient.begin(),
- dataItemIdsSubscribedByThisClient.end(),
- inserter(dataItemIdsToBeSentForThisClient,
- dataItemIdsToBeSentForThisClient.begin()));
-
- mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client);
- dataItemIdsSubscribedByThisClient.clear();
- dataItemIdsToBeSentForThisClient.clear();
+
+ for (auto client : clientSet) {
+ unordered_set<DataItemId> dataItemIdsForThisClient(
+ mParent->mClientToDataItems.getValSet(client));
+ for (auto id : dataItemIdsForThisClient) {
+ if (dataItemIdsToBeSent.find(id) == dataItemIdsToBeSent.end()) {
+ dataItemIdsForThisClient.erase(id);
+ }
+ }
+
+ mParent->sendCachedDataItems(dataItemIdsForThisClient, client);
}
}
SystemStatusOsObserver* mParent;
- const list<IDataItemCore*> mDList;
+ const vector<IDataItemCore*> mDiVec;
};
- mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList));
+
+ if (!dlist.empty()) {
+ vector<IDataItemCore*> dataItemVec(dlist.size());
+
+ for (auto each : dlist) {
+ IF_LOC_LOGD {
+ string dv;
+ each->stringify(dv);
+ LOC_LOGD("notify: DataItem In Value:%s", dv.c_str());
+ }
+
+ IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId());
+ if (nullptr == di) {
+ LOC_LOGw("Unable to create dataitem:%d", each->getId());
+ continue;
+ }
+
+ // Copy contents into the newly created data item
+ di->copy(each);
+
+ // add this dataitem if updated from last one
+ dataItemVec.push_back(di);
+ }
+
+ if (!dataItemVec.empty()) {
+ mContext.mMsgTask->sendMsg(new HandleNotify(this, dataItemVec));
+ }
+ }
}
/******************************************************************************
@@ -447,7 +381,7 @@ void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut)
}
// Check if data item exists in mActiveRequestCount
- map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
+ DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit);
if (citer == mActiveRequestCount.end()) {
// Data item not found in map
// Add reference count as 1 and add dataitem to map
@@ -485,7 +419,7 @@ void SystemStatusOsObserver::turnOff(DataItemId dit)
}
// Check if data item exists in mActiveRequestCount
- map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit);
+ DataItemIdToInt::iterator citer = mActiveRequestCount.find(dit);
if (citer != mActiveRequestCount.end()) {
// found
citer->second--;
@@ -573,84 +507,65 @@ bool SystemStatusOsObserver::disconnectBackhaul()
/******************************************************************************
Helpers
******************************************************************************/
-void SystemStatusOsObserver::sendFirstResponse(
- const list<DataItemId>& l, IDataItemObserver* to)
+void SystemStatusOsObserver::sendCachedDataItems(
+ const unordered_set<DataItemId>& s, IDataItemObserver* to)
{
- if (l.empty()) {
- LOC_LOGV("list is empty. Nothing to do. Exiting");
- return;
- }
-
- string clientName;
- to->getName(clientName);
- list<IDataItemCore*> dataItems(0);
-
- for (auto each : l) {
- map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each);
- if (citer != mDataItemCache.end()) {
- string dv;
- citer->second->stringify(dv);
- LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
- dataItems.push_back(citer->second);
+ if (nullptr == to) {
+ LOC_LOGv("client pointer is NULL.");
+ } else {
+ string clientName;
+ to->getName(clientName);
+ list<IDataItemCore*> dataItems(0);
+
+ for (auto each : s) {
+ auto citer = mDataItemCache.find(each);
+ if (citer != mDataItemCache.end()) {
+ string dv;
+ citer->second->stringify(dv);
+ LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
+ dataItems.push_front(citer->second);
+ }
}
- }
- if (dataItems.empty()) {
- LOC_LOGV("No items to notify. Nothing to do. Exiting");
- return;
- }
- to->notify(dataItems);
-}
-void SystemStatusOsObserver::sendCachedDataItems(
- const list<DataItemId>& l, IDataItemObserver* to)
-{
- string clientName;
- to->getName(clientName);
- list<IDataItemCore*> dataItems(0);
-
- for (auto each : l) {
- string dv;
- IDataItemCore* di = mDataItemCache[each];
- di->stringify(dv);
- LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str());
- dataItems.push_back(di);
+ if (dataItems.empty()) {
+ LOC_LOGv("No items to notify.");
+ } else {
+ to->notify(dataItems);
+ }
}
- to->notify(dataItems);
}
-void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated)
+bool SystemStatusOsObserver::updateCache(IDataItemCore* d)
{
- if (nullptr == d) {
- return;
- }
-
- // Check if data item exists in cache
- map<DataItemId, IDataItemCore*>::iterator citer =
- mDataItemCache.find(d->getId());
- if (citer == mDataItemCache.end()) {
- // New data item; not found in cache
- IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
- if (nullptr == dataitem) {
- return;
+ bool dataItemUpdated = false;
+
+ // Request systemstatus to record this dataitem in its cache
+ // if the return is false, it means that SystemStatus is not
+ // handling it, so SystemStatusOsObserver also doesn't.
+ // So it has to be true to proceed.
+ if (nullptr != d && mSystemStatus->eventDataItemNotify(d)) {
+ auto citer = mDataItemCache.find(d->getId());
+ if (citer == mDataItemCache.end()) {
+ // New data item; not found in cache
+ IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId());
+ if (nullptr != dataitem) {
+ // Copy the contents of the data item
+ dataitem->copy(d);
+ // Insert in mDataItemCache
+ mDataItemCache.insert(std::make_pair(d->getId(), dataitem));
+ dataItemUpdated = true;
+ }
+ } else {
+ // Found in cache; Update cache if necessary
+ citer->second->copy(d, &dataItemUpdated);
}
- // Copy the contents of the data item
- dataitem->copy(d);
- pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem);
- // Insert in mDataItemCache
- mDataItemCache.insert(cpair);
- dataItemUpdated = true;
- }
- else {
- // Found in cache; Update cache if necessary
- if(0 == citer->second->copy(d, &dataItemUpdated)) {
- return;
+ if (dataItemUpdated) {
+ LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
}
}
- if (dataItemUpdated) {
- LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated);
- }
+ return dataItemUpdated;
}
} // namespace loc_core