LCOV - code coverage report
Current view: top level - server - bind_relation.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.2 % 779 687
Test Date: 2026-07-28 10:54:05 Functions: 98.2 % 57 56

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "bind_relation.h"
      12              : #include <atomic>
      13              : #include <numeric>
      14              : #include <queue>
      15              : #include <algorithm>
      16              : #include "common/bqs_log.h"
      17              : #include "subscribe_manager.h"
      18              : #include "statistic_manager.h"
      19              : #include "entity_manager.h"
      20              : #include "schedule_config.h"
      21              : #include "hccl/comm_channel_manager.h"
      22              : 
      23              : namespace bqs {
      24              : namespace {
      25              : // RELATION_UPPER_BOUND: 64 * 1024
      26              : constexpr const uint32_t RELATION_UPPER_BOUND = 65536U;
      27              : } // namespace
      28              : 
      29          580 : BindRelation &BindRelation::GetInstance()
      30              : {
      31          580 :     static BindRelation instance;
      32          580 :     return instance;
      33              : }
      34              : 
      35          159 : BqsStatus BindRelation::CheckMultiLayerBind(const EntityInfo& srcEntity, const EntityInfo& dstEntity,
      36              :     const uint32_t index) const
      37              : {
      38          159 :     const MapEnitityInfoToInfoSet &srcToDstRelation = (index == 0) ? srcToDstRelation_ : srcToDstRelationExtra_;
      39          159 :     const MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
      40              : 
      41          159 :     const auto srcToDstIter = srcToDstRelation.find(dstEntity);
      42          159 :     if (srcToDstIter != srcToDstRelation.end()) {
      43            2 :         auto dstSets = srcToDstIter->second;
      44            4 :         for (auto itDst = dstSets.begin(); itDst != dstSets.end(); ++itDst) {
      45            3 :             if ((*itDst).GetType() == dgw::EntityType::ENTITY_TAG) {
      46            1 :                 BQS_LOG_WARN("Bind relation[%s->%s] ignore check multi layer bind.",
      47              :                     (srcToDstIter->first).ToString().c_str(), (*itDst).ToString().c_str());
      48            1 :                 return BQS_STATUS_OK;
      49              :             }
      50              :         }
      51              : 
      52            1 :         BQS_LOG_ERROR("Bind relation[%s->*] already exists, can't add relation [%s->%s], suggest to add "
      53              :             "relation[%s->*] directly.",
      54              :             (srcToDstIter->first).ToString().c_str(), srcEntity.ToString().c_str(),
      55              :             dstEntity.ToString().c_str(), srcEntity.ToString().c_str());
      56            1 :         return BQS_STATUS_PARAM_INVALID;
      57            2 :     }
      58              : 
      59          157 :     const auto dstToSrcIter = dstToSrcRelation.find(srcEntity);
      60          157 :     if (dstToSrcIter != dstToSrcRelation.end()) {
      61            1 :         BQS_LOG_ERROR("Bind relation[*->%s] already exists, can't add relation [%s->%s], suggest to add "
      62              :             "relation[*->%s] directly.",
      63              :             (dstToSrcIter->first).ToString().c_str(), srcEntity.ToString().c_str(),
      64              :             dstEntity.ToString().c_str(), dstEntity.ToString().c_str());
      65            1 :         return BQS_STATUS_PARAM_INVALID;
      66              :     }
      67          156 :     return BQS_STATUS_OK;
      68              : }
      69              : 
      70              : 
      71          160 : BqsStatus BindRelation::CheckEntityExistInGroup(const EntityInfo& src, const EntityInfo& dst,
      72              :     const uint32_t resIndex) const
      73              : {
      74          160 :     if (src.GetType() == dgw::EntityType::ENTITY_GROUP) {
      75           10 :         const auto &entitiesInGroup = GetEntitiesInGroup(src.GetId());
      76           25 :         for (auto iter = entitiesInGroup.begin(); iter != entitiesInGroup.end(); ++iter) {
      77           16 :             const auto &element = (*(*iter));
      78           16 :             if (dst == element) {
      79            0 :                 BQS_LOG_ERROR("dst entity[%s] has exist in src group entity[%s].",
      80              :                     dst.ToString().c_str(), src.ToString().c_str());
      81            1 :                 return BQS_STATUS_PARAM_INVALID;
      82              :             }
      83           16 :             const auto existSrcEntity = dgw::EntityManager::Instance(resIndex).GetEntityById(
      84              :                 element.GetQueueType(), element.GetDeviceId(), element.GetType(),
      85           16 :                 element.GetId(), dgw::EntityDirection::DIRECTION_SEND);
      86           17 :             if ((existSrcEntity != nullptr) &&
      87            1 :                 (existSrcEntity->GetHostGroupId() != static_cast<int32_t>(src.GetId()))) {
      88            1 :                 BQS_LOG_ERROR("Entity[%s] in group[%s] exists in other src side.",
      89              :                     element.ToString().c_str(), src.ToString().c_str());
      90            1 :                 return BQS_STATUS_PARAM_INVALID;
      91              :             }
      92           16 :         }
      93              :     } else {
      94          150 :         const auto srcEntityPtr = dgw::EntityManager::Instance(resIndex).
      95              :             GetEntityById(src.GetQueueType(), src.GetDeviceId(), src.GetType(),
      96          150 :                           src.GetId(), dgw::EntityDirection::DIRECTION_SEND);
      97          150 :         if (srcEntityPtr != nullptr) {
      98           57 :             const int32_t groupId = srcEntityPtr->GetHostGroupId();
      99           57 :             if (groupId != dgw::INVALID_GROUP_ID) {
     100            1 :                 BQS_LOG_ERROR("Entity[%s] has exist in group[%d].", src.ToString().c_str(), groupId);
     101            1 :                 return BQS_STATUS_PARAM_INVALID;
     102              :             }
     103           56 :             BQS_LOG_INFO("Entity[%s] has been created.", src.ToString().c_str());
     104              :         }
     105          150 :     }
     106              : 
     107          158 :     if (dst.GetType() == dgw::EntityType::ENTITY_GROUP) {
     108           12 :         const auto &entitiesInGroup = GetEntitiesInGroup(dst.GetId());
     109           32 :         for (auto iter = entitiesInGroup.begin(); iter != entitiesInGroup.end(); ++iter) {
     110           22 :             const auto &element = (*(*iter));
     111           22 :             if (src == element) {
     112            1 :                 BQS_LOG_ERROR("src entity[%s] has exist in dst group entity[%s].",
     113              :                     src.ToString().c_str(), dst.ToString().c_str());
     114            2 :                 return BQS_STATUS_PARAM_INVALID;
     115              :             }
     116           21 :             const auto existDstEntity = dgw::EntityManager::Instance(resIndex).
     117              :                 GetEntityById(element.GetQueueType(), element.GetDeviceId(), element.GetType(),
     118           21 :                               element.GetId(), dgw::EntityDirection::DIRECTION_RECV);
     119           22 :             if ((existDstEntity != nullptr) &&
     120            1 :                 (existDstEntity->GetHostGroupId() != static_cast<int32_t>(dst.GetId()))) {
     121            1 :                 BQS_LOG_ERROR("Entity[%s] in group[%s] exists in other dst side.",
     122              :                     element.ToString().c_str(), dst.ToString().c_str());
     123            1 :                 return BQS_STATUS_PARAM_INVALID;
     124              :             }
     125           21 :         }
     126              :     } else {
     127          146 :         const auto dstEntityPtr = dgw::EntityManager::Instance(resIndex).
     128              :             GetEntityById(dst.GetQueueType(), dst.GetDeviceId(), dst.GetType(),
     129          146 :                           dst.GetId(), dgw::EntityDirection::DIRECTION_RECV);
     130          146 :         if (dstEntityPtr != nullptr) {
     131            7 :             const int32_t groupId = dstEntityPtr->GetHostGroupId();
     132            7 :             if (groupId != dgw::INVALID_GROUP_ID) {
     133            1 :                 BQS_LOG_ERROR("Entity[%s] has exist in group[%d].", dst.ToString().c_str(), groupId);
     134            1 :                 return BQS_STATUS_PARAM_INVALID;
     135              :             }
     136            6 :             BQS_LOG_INFO("Entity[%s] has been created.", dst.ToString().c_str());
     137              :         }
     138          146 :     }
     139          155 :     return BQS_STATUS_OK;
     140              : }
     141              : 
     142          163 : BqsStatus BindRelation::CheckBind(const EntityInfo& srcEntity, const EntityInfo& dstEntity,
     143              :     const uint32_t resIndex, uint32_t &index) const
     144              : {
     145          163 :     if (srcEntity == dstEntity) {
     146            1 :         BQS_LOG_ERROR("Bind relation[%s->%s] failed, as can't bind to self.", srcEntity.ToString().c_str(),
     147              :             dstEntity.ToString().c_str());
     148            1 :         return BQS_STATUS_PARAM_INVALID;
     149              :     }
     150              : 
     151          162 :     if (GetBindRelationIndex(srcEntity, dstEntity, index) != BQS_STATUS_OK) {
     152            1 :         BQS_LOG_ERROR("GetBindRelationIndex error");
     153            1 :         return BQS_STATUS_PARAM_INVALID;
     154              :     }
     155              : 
     156          161 :     if (resIndex != index) {
     157            1 :         BQS_LOG_INFO("relation[%s->%s] should be processed by threads[%u] while current threads[%u]",
     158              :             srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), index, resIndex);
     159            1 :         return BQS_STATUS_OK;
     160              :     }
     161              : 
     162          160 :     const MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     163          160 :     if (dstToSrcRelation.size() >= RELATION_UPPER_BOUND) {
     164            0 :         BQS_LOG_ERROR("Bind relation[%u->%u] failed, as the maximum number of relation supported is %u, "
     165              :             "current number is %zu.",
     166              :             srcEntity.GetId(), dstEntity.GetId(), RELATION_UPPER_BOUND, dstToSrcRelation.size());
     167            0 :         return BQS_STATUS_INNER_ERROR;
     168              :     }
     169          160 :     const auto dstToSrcIter = dstToSrcRelation.find(dstEntity);
     170          160 :     if ((dstToSrcIter != dstToSrcRelation.end()) && (dstToSrcIter->second.count(srcEntity) != 0U)) {
     171            1 :         BQS_LOG_WARN("Bind relation[%s->%s] already exists, no need bind.", srcEntity.ToString().c_str(),
     172              :             dstEntity.ToString().c_str());
     173            1 :         (void)UpdateSubscribeEvent(srcEntity, EventType::ENQUEUE, index);
     174            1 :         (void)UpdateSubscribeEvent(dstEntity, EventType::F2NF, index);
     175            1 :         return BQS_STATUS_OK;
     176              :     }
     177              : 
     178          159 :     const auto &abnormalDstToSrcIter = abnormalDstToSrc_.find(dstEntity);
     179          159 :     if ((abnormalDstToSrcIter != abnormalDstToSrc_.end()) && (abnormalDstToSrcIter->second.count(srcEntity) != 0U)) {
     180            1 :         BQS_LOG_WARN("Bind relation[%s->%s] already exists in abnormal bind relations, cannot bind.",
     181              :                      srcEntity.ToString().c_str(), dstEntity.ToString().c_str());
     182            1 :         return BQS_STATUS_OK;
     183              :     }
     184              : 
     185          158 :     auto ret = CheckMultiLayerBind(srcEntity, dstEntity, index);
     186          158 :     if (ret != BQS_STATUS_OK) {
     187            2 :         return ret;
     188              :     }
     189              : 
     190              :     // check whether entity exist in group
     191          156 :     ret = CheckEntityExistInGroup(srcEntity, dstEntity, index);
     192          156 :     if (ret != BQS_STATUS_OK) {
     193            1 :         return ret;
     194              :     }
     195          155 :     return BQS_STATUS_OK;
     196              : }
     197              : 
     198          632 : BqsStatus BindRelation::SetEntityPtr(EntityInfo &entityInfo, const dgw::EntityDirection direction,
     199              :     const uint32_t index) const
     200              : {
     201          632 :     if (entityInfo.GetEntity() != nullptr) {
     202          372 :         return BQS_STATUS_OK;
     203              :     }
     204              : 
     205          260 :     const auto entity = dgw::EntityManager::Instance(index).GetEntityById(
     206          260 :         entityInfo.GetQueueType(), entityInfo.GetDeviceId(), entityInfo.GetType(), entityInfo.GetId(), direction);
     207          260 :     if (entity == nullptr) {
     208            2 :         BQS_LOG_ERROR("Missing entity [%s].", entityInfo.ToString().c_str());
     209            2 :         return BQS_STATUS_INNER_ERROR;
     210              :     }
     211          258 :     entityInfo.SetEntity(entity);
     212          258 :     return BQS_STATUS_OK;
     213          260 : }
     214              : 
     215          159 : BqsStatus BindRelation::AddSrcToDst(EntityInfo &srcEntity, EntityInfo &dstEntity, const uint32_t index)
     216              : {
     217          159 :     BqsStatus ret = BQS_STATUS_OK;
     218          317 :     if ((SetEntityPtr(srcEntity, dgw::EntityDirection::DIRECTION_SEND, index) != BQS_STATUS_OK) ||
     219          158 :         (SetEntityPtr(dstEntity, dgw::EntityDirection::DIRECTION_RECV, index) != BQS_STATUS_OK)) {
     220            1 :         BQS_LOG_ERROR("Bind relation add [%s->%s] failed becuause of missing entity.",
     221              :                       srcEntity.ToString().c_str(), dstEntity.ToString().c_str());
     222            1 :         return BQS_STATUS_INNER_ERROR;
     223              :     }
     224              : 
     225          158 :     MapEnitityInfoToInfoSet &srcToDstRelation = (index == 0) ? srcToDstRelation_ : srcToDstRelationExtra_;
     226          158 :     const auto iter = srcToDstRelation.find(srcEntity);
     227          158 :     if (iter == srcToDstRelation.end()) {
     228          103 :         ret = SubscribeEvent(srcEntity, EventType::ENQUEUE, index);
     229          103 :         if (ret != BQS_STATUS_OK) {
     230            1 :             BQS_LOG_ERROR("Bind relation add [%s->%s] failed, as subscribe failed, ret=%d.",
     231              :                 srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), static_cast<int32_t>(ret));
     232            1 :             return ret;
     233              :         } else {
     234          102 :             (void)srcToDstRelation.emplace(
     235          408 :                 std::make_pair(srcEntity, EntityInfoSet{ dstEntity }));
     236              :         }
     237              :     } else {
     238           55 :         (void)iter->second.emplace(dstEntity);
     239              :     }
     240              : 
     241          157 :     return ret;
     242          102 : }
     243              : 
     244          158 : BqsStatus BindRelation::AddDstToSrc(EntityInfo &srcEntity, EntityInfo &dstEntity, const uint32_t index)
     245              : {
     246          158 :     BqsStatus ret = BQS_STATUS_OK;
     247              : 
     248          315 :     if ((SetEntityPtr(srcEntity, dgw::EntityDirection::DIRECTION_SEND, index) != BQS_STATUS_OK) ||
     249          157 :         (SetEntityPtr(dstEntity, dgw::EntityDirection::DIRECTION_RECV, index) != BQS_STATUS_OK)) {
     250            1 :         BQS_LOG_ERROR("Bind relation add [%s->%s] failed becuause of missing entity.",
     251              :                       srcEntity.ToString().c_str(), dstEntity.ToString().c_str());
     252            1 :         return BQS_STATUS_INNER_ERROR;
     253              :     }
     254              : 
     255          157 :     MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     256          157 :     const auto iter = dstToSrcRelation.find(dstEntity);
     257          157 :     if (iter == dstToSrcRelation.end()) {
     258          152 :         ret = SubscribeEvent(dstEntity, EventType::F2NF, index);
     259          152 :         if (ret != BQS_STATUS_OK) {
     260            0 :             BQS_LOG_ERROR("Bind relation add [%s->%s] failed, as subscribe f2nf failed, ret=%d.",
     261              :                 srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), static_cast<int32_t>(ret));
     262              :         } else {
     263          152 :             (void)dstToSrcRelation.emplace(
     264          608 :                 std::make_pair(dstEntity, EntityInfoSet{ srcEntity }));
     265              :         }
     266              :     } else {
     267            5 :         (void)iter->second.emplace(srcEntity);
     268              :     }
     269          157 :     return ret;
     270          152 : }
     271              : 
     272          149 : BqsStatus BindRelation::DelSrcToDst(const EntityInfo& srcEntity, const EntityInfo& dstEntity, const uint32_t index)
     273              : {
     274          149 :     auto ret = BQS_STATUS_OK;
     275          149 :     MapEnitityInfoToInfoSet &srcToDstRelation = (index == 0) ? srcToDstRelation_ : srcToDstRelationExtra_;
     276          149 :     const auto iter = srcToDstRelation.find(srcEntity);
     277          149 :     if (iter == srcToDstRelation.end()) {
     278            7 :         BQS_LOG_WARN("Bind relation[%s->%s] dst doesn't exist, no need unbind.", srcEntity.ToString().c_str(),
     279              :             dstEntity.ToString().c_str());
     280            7 :         return BQS_STATUS_OK;
     281              :     }
     282              : 
     283          142 :     (void)iter->second.erase(dstEntity);
     284          142 :     if (iter->second.empty()) {
     285           88 :         (void)UnsubscribeEvent(srcEntity, EventType::ENQUEUE, index);
     286           88 :         BQS_LOG_INFO("delete route [%s->*]", srcEntity.ToString().c_str());
     287           88 :         (void)srcToDstRelation.erase(iter);
     288              :     }
     289              :     
     290          142 :     return ret;
     291              : }
     292              : 
     293          148 : BqsStatus BindRelation::DelDstToSrc(const EntityInfo& srcEntity, const EntityInfo& dstEntity, const uint32_t index)
     294              : {
     295          148 :     MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     296          148 :     auto ret = BQS_STATUS_OK;
     297          148 :     const auto iter = dstToSrcRelation.find(dstEntity);
     298          148 :     if (iter == dstToSrcRelation.end()) {
     299            8 :         BQS_LOG_WARN("Bind relation[%s->%s] dst doesn't exist, no need unbind.", srcEntity.ToString().c_str(),
     300              :             dstEntity.ToString().c_str());
     301            8 :         return BQS_STATUS_OK;
     302              :     }
     303              : 
     304          140 :     (void)iter->second.erase(srcEntity);
     305          140 :     if (iter->second.empty()) {
     306          138 :         (void)UnsubscribeEvent(dstEntity, EventType::F2NF, index);
     307          138 :         (void)dstToSrcRelation.erase(iter);
     308              :     }
     309              : 
     310          140 :     return ret;
     311              : }
     312              : 
     313          164 : BqsStatus BindRelation::Bind(EntityInfo &srcEntity, EntityInfo &dstEntity, const uint32_t resIndex)
     314              : {
     315          164 :     uint32_t index = 0;
     316          164 :     auto ret = CheckBind(srcEntity, dstEntity, resIndex, index);
     317          164 :     if (ret != BQS_STATUS_OK) {
     318            4 :         return ret;
     319              :     }
     320              : 
     321          160 :     if (index != resIndex) {
     322            1 :         return BQS_STATUS_RETRY;
     323              :     }
     324              : 
     325          159 :     ret = CreateEntity(srcEntity, dstEntity, index);
     326          159 :     if (ret != BQS_STATUS_OK) {
     327            0 :         return ret;
     328              :     }
     329              : 
     330          159 :     ret = AddSrcToDst(srcEntity, dstEntity, index);
     331          159 :     if (ret != BQS_STATUS_OK) {
     332            1 :         (void) DeleteEntity(srcEntity, true, index);
     333            1 :         (void) DeleteEntity(dstEntity, false, index);
     334            1 :         return ret;
     335              :     }
     336              : 
     337          158 :     ret = AddDstToSrc(srcEntity, dstEntity, index);
     338          158 :     if (ret != BQS_STATUS_OK) {
     339              :         // roll back
     340            1 :         (void) DelSrcToDst(srcEntity, dstEntity, index);
     341            1 :         (void) DeleteEntity(srcEntity, true, index);
     342            1 :         (void) DeleteEntity(dstEntity, false, index);
     343            1 :         BQS_LOG_ERROR("Bind relation add [%s->%s] failed, as subscribe f2nf failed, ret=%d.",
     344              :             srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), static_cast<int32_t>(ret));
     345            1 :         return ret;
     346              :     }
     347              : 
     348          157 :     BQS_LOG_RUN_INFO("Bind relation add {src[%s]->dst[%s]} success on resIndex[%u].",
     349              :         srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), resIndex);
     350          157 :     return BQS_STATUS_OK;
     351              : }
     352              : 
     353          144 : BqsStatus BindRelation::UnBind(EntityInfo &srcEntity, EntityInfo &dstEntity, const uint32_t resIndex)
     354              : {
     355              :     // check unbind for src and dst entity
     356          144 :     auto ret = CheckUnBind(srcEntity);
     357          144 :     if (ret != BQS_STATUS_OK) {
     358            1 :         return ret;
     359              :     }
     360          143 :     ret = CheckUnBind(dstEntity);
     361          143 :     if (ret != BQS_STATUS_OK) {
     362            1 :         return ret;
     363              :     }
     364              : 
     365          142 :     uint32_t index = 0U;
     366          142 :     if (GetBindIndexBySrc(srcEntity, index) != BQS_STATUS_OK) {
     367            1 :         BQS_LOG_WARN("GetBindIndexBySrc failed");
     368            1 :         return BQS_STATUS_OK;
     369              :     }
     370          141 :     if (index != resIndex) {
     371            1 :         return BQS_STATUS_RETRY;
     372              :     }
     373              : 
     374          140 :     ret = DelSrcToDst(srcEntity, dstEntity, resIndex);
     375          140 :     if (ret == BQS_STATUS_OK) {
     376          139 :         ret = DelDstToSrc(srcEntity, dstEntity, resIndex);
     377          139 :         if (ret != BQS_STATUS_OK) {
     378              :             // roll back
     379            0 :             (void)AddSrcToDst(srcEntity, dstEntity, resIndex);
     380              :         }
     381              :     }
     382          140 :     if (ret != BQS_STATUS_OK) {
     383            1 :         BQS_LOG_ERROR("Bind relation del [%s->%s] failed, bqsStatus=%d.",
     384              :             srcEntity.ToString().c_str(), dstEntity.ToString().c_str(), static_cast<int32_t>(ret));
     385            1 :         return ret;
     386              :     }
     387              : 
     388              :     // no roll back if delete entity failed
     389              :     // check src entity whether exist multi bind
     390          139 :     auto &srcToDstRelation = (resIndex == 0U) ? srcToDstRelation_ : srcToDstRelationExtra_;
     391          139 :     auto &dstToSrcRelation = (resIndex == 0U) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     392          139 :     const auto srcIter = srcToDstRelation.find(srcEntity);
     393          139 :     if (srcIter == srcToDstRelation.end()) {
     394           87 :         (void)DeleteEntity(srcEntity, true, resIndex);
     395              :     }
     396              :     // check dst entity whether exist multi bind
     397          139 :     const auto dstIter = dstToSrcRelation.find(dstEntity);
     398          139 :     if (dstIter == dstToSrcRelation.end()) {
     399          137 :         (void)DeleteEntity(dstEntity, false, resIndex);
     400              :     }
     401              : 
     402              :     // delete abnormal bind relation
     403          139 :     DelAbnormalSrcToDst(srcEntity, dstEntity);
     404          139 :     DelAbnormalDstToSrc(srcEntity, dstEntity);
     405              : 
     406          139 :     return BQS_STATUS_OK;
     407              : }
     408              : 
     409            5 : BqsStatus BindRelation::UnBindBySrc(const EntityInfo& srcEntity)
     410              : {
     411            5 :     UnBindAbnormalRelationBySrc(srcEntity);
     412            5 :     return UnBindRelationBySrc(srcEntity);
     413              : }
     414              : 
     415           14 : BqsStatus BindRelation::UnBindRelationBySrc(const EntityInfo& srcEntity)
     416              : {
     417           14 :     uint32_t index = 0;
     418           14 :     if (GetBindIndexBySrc(srcEntity, index) != BQS_STATUS_OK) {
     419            0 :         BQS_LOG_WARN("GetBindIndexBySrc failed");
     420            0 :         return BQS_STATUS_OK;
     421              :     }
     422              : 
     423           14 :     MapEnitityInfoToInfoSet &srcToDstRelation = (index == 0) ? srcToDstRelation_ : srcToDstRelationExtra_;
     424           14 :     const auto srcToDstIter = srcToDstRelation.find(srcEntity);
     425           14 :     if (srcToDstIter == srcToDstRelation.end()) {
     426            5 :         BQS_LOG_WARN("No relation [%s->*] exists, no need unbind", srcEntity.ToString().c_str());
     427            5 :         return BQS_STATUS_OK;
     428              :     }
     429              : 
     430            9 :     const auto ret = UnsubscribeEvent(srcEntity, EventType::ENQUEUE, index);
     431            9 :     if (ret != BQS_STATUS_OK) {
     432            1 :         BQS_LOG_ERROR("Unsubscribe queue[%s] failed, bqsStatus=%d.", srcEntity.ToString().c_str(),
     433              :             static_cast<int32_t>(ret));
     434            1 :         return BQS_STATUS_DRIVER_ERROR;
     435              :     }
     436              : 
     437            8 :     MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     438           17 :     for (const auto &dstEntity : srcToDstIter->second) {
     439            9 :         (void)DelDstToSrc(srcEntity, dstEntity, index);
     440              :         // delete dst entity
     441            9 :         const auto dstIter = dstToSrcRelation.find(dstEntity);
     442            9 :         if (dstIter == dstToSrcRelation.end()) {
     443            9 :             (void)DeleteEntity(dstEntity, false, index);
     444              :         }
     445              :     }
     446              : 
     447            8 :     (void)srcToDstRelation.erase(srcToDstIter);
     448              :     // delete src entity
     449            8 :     (void)DeleteEntity(srcEntity, true, index);
     450            8 :     return BQS_STATUS_OK;
     451              : }
     452              : 
     453            7 : BqsStatus BindRelation::UnBindByDst(const EntityInfo& dstEntity)
     454              : {
     455            7 :     UnBindAbnormalRelationByDst(dstEntity);
     456            7 :     return UnBindRelationByDst(dstEntity);
     457              : }
     458              : 
     459           11 : BqsStatus BindRelation::UnBindRelationByDst(const EntityInfo& dstEntity)
     460              : {
     461           11 :     uint32_t index = 0;
     462           11 :     if (GetBindIndexByDst(dstEntity, index) != BQS_STATUS_OK) {
     463            2 :         BQS_LOG_WARN("GetBindIndexByDst failed");
     464            2 :         return BQS_STATUS_OK;
     465              :     }
     466              : 
     467            9 :     MapEnitityInfoToInfoSet &dstToSrcRelation = (index == 0) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     468            9 :     const auto dstToSrcIter = dstToSrcRelation.find(dstEntity);
     469            9 :     if (dstToSrcIter == dstToSrcRelation.end()) {
     470            2 :         BQS_LOG_WARN("No bind relation[*->%s] exists, no need unbind.", dstEntity.ToString().c_str());
     471            2 :         return BQS_STATUS_OK;
     472              :     }
     473              : 
     474            7 :     auto ret = UnsubscribeEvent(dstEntity, EventType::F2NF, index);
     475            7 :     if (ret != BQS_STATUS_OK) {
     476            0 :         BQS_LOG_ERROR("UnsubscribeFullToNotFull queue[%s] failed, bqsStatus=%d.", dstEntity.ToString().c_str(),
     477              :             static_cast<int32_t>(ret));
     478            0 :         return BQS_STATUS_DRIVER_ERROR;
     479              :     }
     480              : 
     481            7 :     MapEnitityInfoToInfoSet &srcToDstRelation = (index == 0) ? srcToDstRelation_ : srcToDstRelationExtra_;
     482           16 :     for (const auto &srcEntity : dstToSrcIter->second) {
     483            9 :         ret = DelSrcToDst(srcEntity, dstEntity, index);
     484            9 :         if (ret != BQS_STATUS_OK) {
     485            0 :             break;
     486              :         }
     487              :         // delete src entity
     488            9 :         const auto srcIter = srcToDstRelation.find(srcEntity);
     489            9 :         if (srcIter == srcToDstRelation.end()) {
     490            7 :             (void)DeleteEntity(srcEntity, true, index);
     491              :         }
     492              :     }
     493              : 
     494            7 :     if (ret == BQS_STATUS_OK) {
     495            7 :         (void)dstToSrcRelation.erase(dstToSrcIter);
     496              :         // delete dst entity
     497            7 :         (void)DeleteEntity(dstEntity, false, index);
     498              :     } else {
     499            0 :         BQS_LOG_ERROR("Bind relation del [*->%s] failed, bqsStatus=%d.", dstEntity.ToString().c_str(),
     500              :             static_cast<int32_t>(ret));
     501              :     }
     502              : 
     503            7 :     return ret;
     504              : }
     505              : 
     506              : // topsort
     507          136 : void BindRelation::Order(const uint32_t index)
     508              : {
     509          136 :     StatisticManager::GetInstance().BindNum(CountBinds());
     510          136 :     StatisticManager::GetInstance().AbnormalBindNum(CountAbnormalBinds());
     511          272 :     StatisticManager::GetInstance().SubscribeNum(
     512          136 :         static_cast<uint32_t>(srcToDstRelation_.size() + srcToDstRelationExtra_.size()));
     513          136 :     if (index == 0U) {
     514          134 :         OrderOneTable(orderedSubscribeQueueId_, srcToDstRelation_, dstToSrcRelation_);
     515              :     } else {
     516            2 :         OrderOneTable(orderedSubscribeQueueIdExtra_, srcToDstRelationExtra_, dstToSrcRelationExtra_);
     517              :     }
     518          136 : }
     519              : 
     520          136 : void BindRelation::OrderOneTable(std::vector<EntityInfo> &orderedSubscribeQueueId,
     521              :     const MapEnitityInfoToInfoSet &srcToDstRelation, const MapEnitityInfoToInfoSet &dstToSrcRelation)
     522              : {
     523          136 :     isHasLoop_ = false;
     524          136 :     orderedSubscribeQueueId.clear();
     525          136 :     orderedSubscribeQueueId.reserve(srcToDstRelation.size());
     526          136 :     std::unordered_map<EntityInfo, uint32_t, EntityInfoHash> inDegrees;
     527              : 
     528              :     // as queue input edge is only one, so we can use order by traverse
     529          136 :     std::queue<EntityInfo> subscribeQueue;
     530          229 :     for (auto &iter : srcToDstRelation) {
     531              :         // No input queue is head queue
     532           93 :         if (dstToSrcRelation.count(iter.first) == 0U) {
     533           92 :             (void)subscribeQueue.emplace(iter.first);
     534              :         }
     535          191 :         for (const auto &dstQ : iter.second) {
     536           98 :             const auto degIter = inDegrees.find(dstQ);
     537           98 :             if (degIter != inDegrees.end()) {
     538            2 :                 degIter->second++;
     539              :             } else {
     540           96 :                 inDegrees[dstQ] = 1U;
     541              :             }
     542              :         }
     543              :     }
     544              : 
     545              :     // protect for loop
     546          324 :     while (!subscribeQueue.empty()) {
     547          188 :         auto queueId = subscribeQueue.front();
     548          188 :         subscribeQueue.pop();
     549          188 :         const auto &dstQueueIter = srcToDstRelation.find(queueId);
     550          188 :         if (dstQueueIter == srcToDstRelation.end()) {
     551           95 :             continue;
     552              :         }
     553              : 
     554           93 :         orderedSubscribeQueueId.emplace_back(dstQueueIter->first);
     555          191 :         for (auto dstQueueId : dstQueueIter->second) {
     556           98 :             --(inDegrees[dstQueueId]);
     557           98 :             if (inDegrees[dstQueueId] == 0U) {
     558           96 :                 (void)subscribeQueue.emplace(dstQueueId);
     559              :             }
     560           98 :         }
     561          188 :     }
     562              : 
     563          136 :     if (orderedSubscribeQueueId.size() != srcToDstRelation.size()) {
     564            0 :         BQS_LOG_ERROR("orderedSubscribeQueueId.size is [%zu] is not equal to srcToDstRelation.size[%zu], "
     565              :             "may be with loop in bind relation, use unordered instead.",
     566              :             orderedSubscribeQueueId.size(), srcToDstRelation.size());
     567            0 :         isHasLoop_ = true;
     568            0 :         orderedSubscribeQueueId.clear();
     569            0 :         for (auto &srcToDstIter : srcToDstRelation) {
     570            0 :             (void)orderedSubscribeQueueId.emplace_back(srcToDstIter.first);
     571              :         }
     572              :     }
     573          136 : }
     574              : 
     575           92 : const MapEnitityInfoToInfoSet &BindRelation::GetSrcToDstRelation() const
     576              : {
     577           92 :     return srcToDstRelation_;
     578              : }
     579              : 
     580          189 : const MapEnitityInfoToInfoSet &BindRelation::GetDstToSrcRelation() const
     581              : {
     582          189 :     return dstToSrcRelation_;
     583              : }
     584              : 
     585           19 : const MapEnitityInfoToInfoSet &BindRelation::GetAbnormalSrcToDstRelation() const
     586              : {
     587           19 :     return abnormalSrcToDst_;
     588              : }
     589              : 
     590            9 : const MapEnitityInfoToInfoSet &BindRelation::GetAbnormalDstToSrcRelation() const
     591              : {
     592            9 :     return abnormalDstToSrc_;
     593              : }
     594              : 
     595           29 : const std::vector<EntityInfo> &BindRelation::GetOrderedSubscribeQueueId() const
     596              : {
     597           29 :     return orderedSubscribeQueueId_;
     598              : }
     599              : 
     600          136 : uint32_t BindRelation::CountBinds() const
     601              : {
     602          408 :     uint32_t bindCount = std::accumulate(std::begin(srcToDstRelation_), std::end(srcToDstRelation_), 0U,
     603           94 :         [](const uint32_t previous,
     604              :         const std::pair<EntityInfo, EntityInfoSet> &dstQueueId) {
     605           94 :             return previous + static_cast<uint32_t>(dstQueueId.second.size());
     606              :         });
     607          136 :     if (GlobalCfg::GetInstance().GetNumaFlag()) {
     608           30 :         bindCount += std::accumulate(std::begin(srcToDstRelationExtra_), std::end(srcToDstRelationExtra_), 0U,
     609            2 :             [](const uint32_t previous,
     610              :             const std::pair<EntityInfo, EntityInfoSet> &dstQueueId) {
     611            2 :                 return previous + static_cast<uint32_t>(dstQueueId.second.size());
     612              :             });
     613              :     }
     614          136 :     return bindCount;
     615              : }
     616              : 
     617          136 : uint32_t BindRelation::CountAbnormalBinds() const
     618              : {
     619          408 :     const uint32_t bindCount = std::accumulate(std::begin(abnormalSrcToDst_), std::end(abnormalSrcToDst_), 0U,
     620           18 :         [](const uint32_t previous,
     621              :         const std::pair<EntityInfo, EntityInfoSet> &abnormalBinds) {
     622           18 :             return previous + static_cast<uint32_t>(abnormalBinds.second.size());
     623              :         });
     624          136 :     return bindCount;
     625              : }
     626              : 
     627           26 : BqsStatus BindRelation::CreateGroup(const std::vector<EntityInfoPtr> &entities, uint32_t &groupId)
     628              : {
     629           26 :     if (entities.empty()) {
     630            0 :         BQS_LOG_ERROR("entity is empty.");
     631            0 :         return BQS_STATUS_PARAM_INVALID;
     632              :     }
     633              : 
     634              :     // generate group id
     635           26 :     groupId = GenerateGroupId();
     636              :     // save to allGroupConfig
     637           26 :     const auto ret = allGroupConfig_.emplace(std::make_pair(groupId, entities));
     638           26 :     if (!ret.second) {
     639            0 :         BQS_LOG_ERROR("create group [%u] failed.", groupId);
     640            0 :         return BQS_STATUS_GROUP_HAS_EXIST;
     641              :     }
     642           26 :     return BQS_STATUS_OK;
     643              : }
     644              : 
     645            9 : BqsStatus BindRelation::DeleteGroup(const uint32_t groupId)
     646              : {
     647            9 :     const auto indexIter = group2ResIndex_.find(groupId);
     648            9 :     if (indexIter != group2ResIndex_.end()) {
     649              :         const MapEnitityInfoToInfoSet &srcToDstRelation =
     650            4 :             (indexIter->second.first == 0U) ? srcToDstRelation_ : srcToDstRelationExtra_;
     651              :         const MapEnitityInfoToInfoSet &dstToSrcRelation =
     652            4 :             (indexIter->second.first == 0U) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
     653            4 :         OptionalArg args = {};
     654            4 :         args.eType = dgw::EntityType::ENTITY_GROUP;
     655            4 :         const EntityInfo group(groupId, indexIter->second.second, &args);
     656            8 :         if ((srcToDstRelation.find(group) != srcToDstRelation.end()) ||
     657            8 :             (dstToSrcRelation.find(group) != dstToSrcRelation.end())) {
     658            1 :             BQS_LOG_ERROR("group[%u] still exist in routes. Please delete route first.", groupId);
     659            1 :             return BQS_STATUS_GROUP_EXIST_IN_ROUTE;
     660              :         }
     661            4 :     }
     662              : 
     663            8 :     const auto iter = allGroupConfig_.find(groupId);
     664            8 :     if (iter == allGroupConfig_.end()) {
     665            1 :         BQS_LOG_RUN_INFO("group %u does not exist.", groupId);
     666            1 :         return BQS_STATUS_OK;
     667              :     }
     668           24 :     for (auto infoPtr : iter->second) {
     669           17 :         if (infoPtr->GetType() == dgw::EntityType::ENTITY_TAG) {
     670            2 :             (void)dgw::CommChannelManager::GetInstance().DeleteCommChannel(*(infoPtr->GetCommChannel()));
     671              :         }
     672           17 :     }
     673            7 :     (void)allGroupConfig_.erase(iter);
     674            7 :     if (indexIter != group2ResIndex_.end()) {
     675            3 :         (void) group2ResIndex_.erase(indexIter);
     676              :     }
     677            7 :     return BQS_STATUS_OK;
     678              : }
     679              : 
     680          161 : BqsStatus BindRelation::CreateEntity(const EntityInfo &src, const EntityInfo &dst, const uint32_t resIndex)
     681              : {
     682              :     // when one src entity bind with multi dst entities, src entity may has been created
     683          161 :     const auto srcRet = CreateEntity(src, true, resIndex);
     684          161 :     if ((srcRet != BQS_STATUS_OK) && (srcRet != BQS_STATUS_ENTITY_EXIST)) {
     685              :         // roolback
     686            0 :         (void) DeleteEntity(src, true, resIndex);
     687            0 :         return srcRet;
     688              :     }
     689          161 :     const auto dstRet = CreateEntity(dst, false, resIndex);
     690          161 :     if ((dstRet != BQS_STATUS_OK) && (dstRet != BQS_STATUS_ENTITY_EXIST)) {
     691              :         // roolback
     692            0 :         (void) DeleteEntity(dst, false, resIndex);
     693            0 :         if (srcRet == BQS_STATUS_ENTITY_EXIST) {
     694            0 :             (void) DeleteEntity(src, true, resIndex);
     695              :         }
     696            0 :         return dstRet;
     697              :     }
     698              : 
     699              :     // set needTransId for entity: no need check nullptr
     700          161 :     const auto srcEntity = dgw::EntityManager::Instance(resIndex).GetEntityById(
     701          161 :         src.GetQueueType(), src.GetDeviceId(), src.GetType(), src.GetId(), dgw::EntityDirection::DIRECTION_SEND);
     702          161 :     if (srcEntity == nullptr) {
     703            1 :         BQS_LOG_ERROR("Missing entity [%s].", src.ToString().c_str());
     704            1 :         return BQS_STATUS_INNER_ERROR;
     705              :     }
     706          160 :     if (srcEntity->IsNeedTransId()) {
     707            0 :         return BQS_STATUS_OK;
     708              :     }
     709              :     // if dst entity is group, src entity need get transId
     710          160 :     if (dst.GetType() == dgw::EntityType::ENTITY_GROUP) {
     711           10 :         srcEntity->SetNeedTransId(true);
     712           10 :         BQS_LOG_INFO("entity[%s] need get transId when scheduled because dst entity[%s].",
     713              :             src.ToString().c_str(), dst.ToString().c_str());
     714           10 :         return BQS_STATUS_OK;
     715              :     }
     716          150 :     return BQS_STATUS_OK;
     717          161 : }
     718              : 
     719          322 : BqsStatus BindRelation::CreateEntity(const EntityInfo &info, const bool isSrc, const uint32_t resIndex)
     720              : {
     721              :     // check entity exist
     722          322 :     const dgw::EntityDirection direction = isSrc ? dgw::EntityDirection::DIRECTION_SEND :
     723              :                                                    dgw::EntityDirection::DIRECTION_RECV;
     724          322 :     const auto entity = dgw::EntityManager::Instance(resIndex).GetEntityById(
     725          322 :         info.GetQueueType(), info.GetDeviceId(), info.GetType(), info.GetId(), direction);
     726          322 :     if (entity != nullptr) {
     727           66 :         BQS_LOG_INFO("Entity[%s] has been created, no need created again.", info.ToString().c_str());
     728           66 :         return BQS_STATUS_ENTITY_EXIST;
     729              :     }
     730              : 
     731              :     // create entity for [group]
     732          256 :     if (info.GetType() == dgw::EntityType::ENTITY_GROUP) {
     733           19 :         const auto ret = CreateEntityForGroup(info, isSrc, resIndex);
     734           19 :         return ret;
     735              :     }
     736              :     // create entify for [queue or channel]
     737          237 :     dgw::EntityMaterial material = {};
     738          237 :     material.eType = info.GetType();
     739          237 :     material.direction = direction;
     740          237 :     material.id = info.GetId();
     741          237 :     material.globalId = info.GetGlobalId();
     742          237 :     material.uuId = info.GetUuId();
     743          237 :     material.schedCfgKey = info.GetSchedCfgKey();
     744          237 :     material.resId = info.GetDeviceId();
     745          237 :     material.channel = info.GetCommChannel();
     746          237 :     material.queueType = info.GetQueueType();
     747          237 :     if (nullptr == dgw::EntityManager::Instance(resIndex).CreateEntity(material)) {
     748            0 :         BQS_LOG_ERROR("Create entityPtr for entity[%s] failed.", info.ToString().c_str());
     749            0 :         return BQS_STATUS_INNER_ERROR;
     750              :     }
     751          237 :     return BQS_STATUS_OK;
     752          322 : }
     753              : 
     754           20 : BqsStatus BindRelation::CreateEntityForGroup(const EntityInfo &groupEntity, const bool isSrc,
     755              :     const uint32_t resIndex)
     756              : {
     757           20 :     const uint32_t groupId = groupEntity.GetId();
     758           20 :     BQS_LOG_INFO("Begin to create entityPtr for group[%u].", groupId);
     759           20 :     const std::vector<EntityInfoPtr> &entities = GetEntitiesInGroup(groupId);
     760           20 :     if (entities.empty()) {
     761            1 :         BQS_LOG_ERROR("group %u does not exist.", groupId);
     762            1 :         return BQS_STATUS_INNER_ERROR;
     763              :     }
     764              : 
     765           19 :     const dgw::EntityDirection direction = isSrc ? dgw::EntityDirection::DIRECTION_SEND :
     766              :                                                    dgw::EntityDirection::DIRECTION_RECV;
     767           19 :     std::vector<dgw::EntityPtr> entityPtrVec;
     768              :     // create entity in group
     769           54 :     for (auto &info : entities) {
     770           35 :         dgw::EntityMaterial material = {};
     771           35 :         material.eType = info->GetType();
     772           35 :         material.direction = direction;
     773           35 :         material.id = info->GetId();
     774           35 :         material.globalId = info->GetGlobalId();
     775           35 :         material.uuId = info->GetUuId();
     776           35 :         material.schedCfgKey = info->GetSchedCfgKey();
     777           35 :         material.resId = info->GetDeviceId();
     778           35 :         material.channel = info->GetCommChannel();
     779           35 :         material.hostGroupId = static_cast<int32_t>(groupId);
     780           35 :         material.queueType = info->GetQueueType();
     781           35 :         auto entityPtr = dgw::EntityManager::Instance(resIndex).CreateEntity(material);
     782           35 :         if (entityPtr == nullptr) {
     783            0 :             BQS_LOG_ERROR("Create entityPtr for entity[%s] failed.", info->ToString().c_str());
     784            0 :             return BQS_STATUS_INNER_ERROR;
     785              :         }
     786           35 :         entityPtrVec.emplace_back(entityPtr);
     787              :         // src entity in group need transId
     788           35 :         entityPtr->SetNeedTransId(true);
     789           35 :         BQS_LOG_RUN_INFO("Entity group[%u] add element[%s] success.", groupId, info->ToString().c_str());
     790           35 :     }
     791              :     // save group
     792           19 :     const dgw::FsmStatus ret = dgw::EntityManager::Instance(resIndex).CreateGroup(groupId, entityPtrVec);
     793           19 :     if (ret != dgw::FsmStatus::FSM_SUCCESS) {
     794            0 :         BQS_LOG_ERROR("Save group[%u] failed.", groupId);
     795            0 :         return BQS_STATUS_INNER_ERROR;
     796              :     }
     797           19 :     group2ResIndex_[groupId] = std::make_pair(resIndex, groupEntity.GetDeviceId());
     798              : 
     799              :     // create group entity
     800           19 :     dgw::EntityMaterial material = {};
     801           19 :     material.eType = dgw::EntityType::ENTITY_GROUP;
     802           19 :     material.direction = direction;
     803           19 :     material.id = groupId;
     804           19 :     material.globalId = groupEntity.GetGlobalId();
     805           19 :     material.uuId = groupEntity.GetUuId();
     806           19 :     material.schedCfgKey = groupEntity.GetSchedCfgKey();
     807           19 :     material.resId = groupEntity.GetDeviceId();
     808           19 :     material.groupPolicy = groupEntity.GetGroupPolicy();
     809           19 :     material.peerInstanceNum = groupEntity.GetPeerInstanceNum();
     810           19 :     material.localInstanceIndex = groupEntity.GetLocalInstanceIndex();
     811           19 :     material.queueType = groupEntity.GetQueueType();
     812           19 :     const auto groupEntityPtr = dgw::EntityManager::Instance(resIndex).CreateEntity(material);
     813           19 :     if (groupEntityPtr == nullptr) {
     814            0 :         BQS_LOG_ERROR("Create entityPtr for group[%u] failed.", groupId);
     815            0 :         return BQS_STATUS_INNER_ERROR;
     816              :     }
     817           19 :     return BQS_STATUS_OK;
     818           19 : }
     819              : 
     820          260 : BqsStatus BindRelation::DeleteEntity(const EntityInfo &info, const bool isSrc, const uint32_t resIndex) const
     821              : {
     822          260 :     BQS_LOG_INFO("DeleteEntity: %s", info.ToString().c_str());
     823          260 :     const dgw::EntityDirection direction = isSrc ? dgw::EntityDirection::DIRECTION_SEND :
     824              :                                                    dgw::EntityDirection::DIRECTION_RECV;
     825              :     // group
     826          260 :     if (info.GetType() == dgw::EntityType::ENTITY_GROUP) {
     827           20 :         return DeleteEntityForGroup(info.GetQueueType(), info.GetDeviceId(), info.GetId(), direction, resIndex);
     828              :     }
     829              :     // queue or tag
     830          240 :     const auto ret = dgw::EntityManager::Instance(resIndex).DeleteEntity(
     831              :         info.GetQueueType(), info.GetDeviceId(), info.GetType(), info.GetId(), direction);
     832          240 :     if (ret != dgw::FsmStatus::FSM_SUCCESS) {
     833            0 :         BQS_LOG_ERROR("Delete entity[%s] failed.", info.ToString().c_str());
     834            0 :         return BQS_STATUS_INNER_ERROR;
     835              :     }
     836          240 :     return BQS_STATUS_OK;
     837              : }
     838              : 
     839           20 : BqsStatus BindRelation::DeleteEntityForGroup(
     840              :     const uint32_t queueType, const uint32_t deviceId, const uint32_t groupId, const dgw::EntityDirection direction,
     841              :     const uint32_t resIndex) const
     842              : {
     843              :     // delete group entity
     844           20 :     dgw::FsmStatus ret = dgw::EntityManager::Instance(resIndex).
     845           20 :         DeleteEntity(queueType, deviceId, dgw::EntityType::ENTITY_GROUP, groupId, direction);
     846           20 :     if (ret != dgw::FsmStatus::FSM_SUCCESS) {
     847            0 :         BQS_LOG_ERROR("Delete group entity[%u] failed.", groupId);
     848            0 :         return BQS_STATUS_INNER_ERROR;
     849              :     }
     850              :     // delete group
     851           20 :     ret = dgw::EntityManager::Instance(resIndex).DeleteGroup(groupId);
     852           20 :     if (ret != dgw::FsmStatus::FSM_SUCCESS) {
     853            0 :         BQS_LOG_ERROR("Delete group[%u] failed.", groupId);
     854            0 :         return BQS_STATUS_INNER_ERROR;
     855              :     }
     856              :     // delete entity in group
     857           20 :     const std::vector<EntityInfoPtr> &entities = GetEntitiesInGroup(groupId);
     858           55 :     for (auto &info : entities) {
     859           35 :         ret = dgw::EntityManager::Instance(resIndex).DeleteEntity(
     860              :             info->GetQueueType(), info->GetDeviceId(), info->GetType(), info->GetId(), direction);
     861           35 :         if (ret != dgw::FsmStatus::FSM_SUCCESS) {
     862            0 :             BQS_LOG_ERROR("delete entityPtr for entity[%s] failed.", info->ToString().c_str());
     863            0 :             return BQS_STATUS_INNER_ERROR;
     864              :         }
     865              :     }
     866           20 :     return BQS_STATUS_OK;
     867              : }
     868              : 
     869           26 : uint32_t BindRelation::GenerateGroupId()
     870              : {
     871              :     static uint32_t groupId = 0U;
     872              :     uint32_t currGroupId;
     873           26 :     lockForGroup_.Lock();
     874           26 :     ++groupId;
     875           26 :     currGroupId = groupId;
     876           26 :     lockForGroup_.Unlock();
     877           26 :     return currGroupId;
     878              : }
     879              : 
     880          122 : const std::vector<EntityInfoPtr> &BindRelation::GetEntitiesInGroup(const uint32_t groupId) const
     881              : {
     882          122 :     static const std::vector<EntityInfoPtr> emptyVec;
     883          122 :     const auto iter = allGroupConfig_.find(groupId);
     884          122 :     if (iter != allGroupConfig_.end()) {
     885          117 :         return iter->second;
     886              :     }
     887            5 :     return emptyVec;
     888              : }
     889              : 
     890          255 : BqsStatus BindRelation::SubscribeEvent(const EntityInfo &subscribeEntity, const EventType eventType,
     891              :     const uint32_t index) const
     892              : {
     893          255 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_QUEUE) {
     894          210 :         const uint32_t SubQueueType = subscribeEntity.GetQueueType();
     895              :         const auto subscribeManager =
     896          210 :             Subscribers::GetInstance().GetSubscribeManager(index, subscribeEntity.GetDeviceId());
     897          210 :         if (subscribeManager == nullptr) {
     898            0 :             DGW_LOG_ERROR("Failed to find subscribeManager for isHost:%d, resIndex: %u, device: %u",
     899              :                 SubQueueType == bqs::LOCAL_Q, index, subscribeEntity.GetDeviceId());
     900            0 :             return BQS_STATUS_INNER_ERROR;
     901              :         }
     902          210 :         return (eventType == EventType::ENQUEUE) ?
     903           89 :             subscribeManager->Subscribe(subscribeEntity.GetId()) :
     904          210 :             subscribeManager->SubscribeFullToNotFull(subscribeEntity.GetId());
     905              :     }
     906           45 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_GROUP) {
     907           19 :         const auto entitiesInGroup = GetEntitiesInGroup(subscribeEntity.GetId());
     908           54 :         for (const auto &entity : entitiesInGroup) {
     909           35 :             if (entity->GetType() != dgw::EntityType::ENTITY_QUEUE) {
     910            3 :                 continue;
     911              :             }
     912           32 :             const uint32_t queuType = entity->GetQueueType();
     913              :             const auto subscribeManager =
     914           32 :                 Subscribers::GetInstance().GetSubscribeManager(index, entity->GetDeviceId());
     915           32 :             if (subscribeManager == nullptr) {
     916            0 :                 DGW_LOG_ERROR("Failed to find subscribeManager for ishost: %d, resIndex: %u, device: %u",
     917              :                     queuType == bqs::LOCAL_Q, index, entity->GetDeviceId());
     918            0 :                 return BQS_STATUS_INNER_ERROR;
     919              :             }
     920           32 :             const auto ret = (eventType == EventType::ENQUEUE) ?
     921           15 :                 subscribeManager->Subscribe(entity->GetId()) :
     922           17 :                 subscribeManager->SubscribeFullToNotFull(entity->GetId());
     923           32 :             if (ret != BQS_STATUS_OK) {
     924            0 :                 BQS_LOG_ERROR("Subscribe queue[%u] in group[%u] failed.", entity->GetId(), subscribeEntity.GetId());
     925            0 :                 return ret;
     926              :             }
     927              :         }
     928           19 :         return BQS_STATUS_OK;
     929           19 :     }
     930           26 :     return BQS_STATUS_OK;
     931              : }
     932              : 
     933          242 : BqsStatus BindRelation::UnsubscribeEvent(const EntityInfo &subscribeEntity, const EventType eventType,
     934              :     const uint32_t index) const
     935              : {
     936          242 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_QUEUE) {
     937          199 :         const uint32_t SubQueueType = subscribeEntity.GetQueueType();
     938              :         const auto subscribeManager =
     939          199 :         Subscribers::GetInstance().GetSubscribeManager(index, subscribeEntity.GetDeviceId());
     940          199 :         if (subscribeManager == nullptr) {
     941            0 :             DGW_LOG_ERROR("Failed to find subscribeManager for SubQueueType: %u resIndex: %u, device: %u",
     942              :                 SubQueueType, index, subscribeEntity.GetDeviceId());
     943            0 :             return BQS_STATUS_INNER_ERROR;
     944              :         }
     945          199 :         return (eventType == EventType::ENQUEUE) ?
     946           84 :             subscribeManager->Unsubscribe(subscribeEntity.GetId()) :
     947          199 :             subscribeManager->UnsubscribeFullToNotFull(subscribeEntity.GetId());
     948              :     }
     949           43 :     auto result = BQS_STATUS_OK;
     950           43 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_GROUP) {
     951           17 :         const auto entitiesInGroup = GetEntitiesInGroup(subscribeEntity.GetId());
     952           48 :         for (const auto &entity : entitiesInGroup) {
     953           31 :             if (entity->GetType() != dgw::EntityType::ENTITY_QUEUE) {
     954            3 :                 continue;
     955              :             }
     956              :             const auto subscribeManager =
     957           28 :                 Subscribers::GetInstance().GetSubscribeManager(index, entity->GetDeviceId());
     958           28 :             if (subscribeManager == nullptr) {
     959            0 :                 DGW_LOG_ERROR("Failed to find subscribeManager for resIndex: %u, device: %u",
     960              :                     index, entity->GetDeviceId());
     961            0 :                 return BQS_STATUS_INNER_ERROR;
     962              :             }
     963           28 :             const auto ret = (eventType == EventType::ENQUEUE) ?
     964           13 :                 subscribeManager->Unsubscribe(entity->GetId()) :
     965           15 :                 subscribeManager->UnsubscribeFullToNotFull(entity->GetId());
     966           28 :             if (ret != BQS_STATUS_OK) {
     967            0 :                 result = ret;
     968            0 :                 BQS_LOG_ERROR("Unsubscribe queue[%u] in group[%u] failed.", entity->GetId(), subscribeEntity.GetId());
     969              :             }
     970              :         }
     971           17 :     }
     972           43 :     return result;
     973              : }
     974              : 
     975            4 : BqsStatus BindRelation::UpdateSubscribeEvent(const EntityInfo &subscribeEntity, const EventType eventType,
     976              :     const uint32_t index) const
     977              : {
     978            4 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_QUEUE) {
     979              :         const auto subscribeManager =
     980            2 :                 Subscribers::GetInstance().GetSubscribeManager(index, subscribeEntity.GetDeviceId());
     981            2 :         if (subscribeManager == nullptr) {
     982            0 :             DGW_LOG_ERROR("Failed to find subscribeManager for resIndex: %u, device: %u",
     983              :                 index, subscribeEntity.GetDeviceId());
     984            0 :             return BQS_STATUS_INNER_ERROR;
     985              :         }
     986            2 :         return (eventType == EventType::ENQUEUE) ?
     987            1 :             subscribeManager->UpdateSubscribe(subscribeEntity.GetId()) :
     988            2 :             subscribeManager->UpdateSubscribeFullToNotFull(subscribeEntity.GetId());
     989              :     }
     990            2 :     auto result = BQS_STATUS_OK;
     991            2 :     if (subscribeEntity.GetType() == dgw::EntityType::ENTITY_GROUP) {
     992            2 :         const auto entitiesInGroup = GetEntitiesInGroup(subscribeEntity.GetId());
     993            6 :         for (const auto &entity : entitiesInGroup) {
     994            4 :             if (entity->GetType() != dgw::EntityType::ENTITY_QUEUE) {
     995            0 :                 continue;
     996              :             }
     997              :             const auto subscribeManager =
     998            4 :                 Subscribers::GetInstance().GetSubscribeManager(index, entity->GetDeviceId());
     999            4 :             if (subscribeManager == nullptr) {
    1000            0 :                 DGW_LOG_ERROR("Failed to find subscribeManager for resIndex: %u, device: %u",
    1001              :                     index, entity->GetDeviceId());
    1002            0 :                 return BQS_STATUS_INNER_ERROR;
    1003              :             }
    1004            4 :             const auto ret = (eventType == EventType::ENQUEUE) ?
    1005            2 :                 subscribeManager->UpdateSubscribe(entity->GetId()) :
    1006            2 :                 subscribeManager->UpdateSubscribeFullToNotFull(entity->GetId());
    1007            4 :             if (ret != BQS_STATUS_OK) {
    1008            0 :                 result = ret;
    1009            0 :                 BQS_LOG_ERROR("Subscribe queue[%u] in group[%u] failed.",
    1010              :                     entity->GetId(), subscribeEntity.GetId());
    1011              :             }
    1012              :         }
    1013            2 :     }
    1014            2 :     return result;
    1015              : }
    1016              : 
    1017          278 : BqsStatus BindRelation::CheckUnBind(const EntityInfo &entity) const
    1018              : {
    1019              :     (void)entity;
    1020          278 :     return BQS_STATUS_OK;
    1021              : }
    1022              : 
    1023            9 : void BindRelation::MarkAbnormalSrc(const EntityInfo &srcEntity)
    1024              : {
    1025            9 :     const auto &iter = srcToDstRelation_.find(srcEntity);
    1026            9 :     if (iter == srcToDstRelation_.end()) {
    1027            4 :         BQS_LOG_WARN("No relation [%s->*] exists, no need mark", srcEntity.ToString().c_str());
    1028            4 :         return;
    1029              :     } else {
    1030            5 :         auto abnormalSrc = iter->first;
    1031            5 :         abnormalSrc.SetEntity(nullptr);
    1032              : 
    1033            5 :         auto &abnormalDstSet = iter->second;
    1034           10 :         for (auto abnormalDst : abnormalDstSet) {
    1035            5 :             abnormalDst.SetEntity(nullptr);
    1036            5 :             abnormalSrcToDst_[abnormalSrc].emplace(abnormalDst);
    1037            5 :             abnormalDstToSrc_[abnormalDst].emplace(abnormalSrc);
    1038            5 :         }
    1039            5 :         BQS_LOG_RUN_INFO("Mark abnormal relation [%s->*]", abnormalSrc.ToString().c_str());
    1040            5 :     }
    1041              : }
    1042              : 
    1043            4 : void BindRelation::MarkAbnormalDst(const EntityInfo &dstEntity)
    1044              : {
    1045            4 :     const auto &iter = dstToSrcRelation_.find(dstEntity);
    1046            4 :     if (iter == dstToSrcRelation_.end()) {
    1047            1 :         BQS_LOG_WARN("No relation [*->%s] exists, no need mark", dstEntity.ToString().c_str());
    1048            1 :         return;
    1049              :     } else {
    1050            3 :         auto abnormalDst = iter->first;
    1051            3 :         abnormalDst.SetEntity(nullptr);
    1052              : 
    1053            3 :         const auto &abnormalSrcSet = iter->second;
    1054            6 :         for (auto abnormalSrc : abnormalSrcSet) {
    1055            3 :             abnormalSrc.SetEntity(nullptr);
    1056            3 :             abnormalDstToSrc_[abnormalDst].emplace(abnormalSrc);
    1057            3 :             abnormalSrcToDst_[abnormalSrc].emplace(abnormalDst);
    1058            3 :         }
    1059            3 :         BQS_LOG_RUN_INFO("Mark abnormal relation [*->%s]", abnormalDst.ToString().c_str());
    1060            3 :     }
    1061              : }
    1062              : 
    1063          139 : void BindRelation::DelAbnormalSrcToDst(const EntityInfo &srcEntity, const EntityInfo &dstEntity)
    1064              : {
    1065          139 :     const auto iter = abnormalSrcToDst_.find(srcEntity);
    1066          139 :     if (iter == abnormalSrcToDst_.end()) {
    1067          133 :         BQS_LOG_WARN("Bind relation[%s->%s] dst doesn't exist in abnormal bind relations, no need unbind.",
    1068              :                      srcEntity.ToString().c_str(), dstEntity.ToString().c_str());
    1069          133 :         return;
    1070              :     }
    1071              : 
    1072            6 :     (void)iter->second.erase(dstEntity);
    1073            6 :     if (iter->second.empty()) {
    1074            6 :         (void)abnormalSrcToDst_.erase(iter);
    1075              :     }
    1076              : }
    1077              : 
    1078          139 : void BindRelation::DelAbnormalDstToSrc(const EntityInfo &srcEntity, const EntityInfo &dstEntity)
    1079              : {
    1080          139 :     const auto iter = abnormalDstToSrc_.find(dstEntity);
    1081          139 :     if (iter == abnormalDstToSrc_.end()) {
    1082          133 :         BQS_LOG_WARN("Bind relation[%s->%s] dst doesn't exist in abnormal bind relations, no need unbind.",
    1083              :                      srcEntity.ToString().c_str(), dstEntity.ToString().c_str());
    1084          133 :         return;
    1085              :     }
    1086              : 
    1087            6 :     (void)iter->second.erase(srcEntity);
    1088            6 :     if (iter->second.empty()) {
    1089            6 :         (void)abnormalDstToSrc_.erase(iter);
    1090              :     }
    1091              : }
    1092              : 
    1093            5 : void BindRelation::UnBindAbnormalRelationBySrc(const EntityInfo &srcEntity)
    1094              : {
    1095            5 :     const auto srcToDstIter = abnormalSrcToDst_.find(srcEntity);
    1096            5 :     if (srcToDstIter == abnormalSrcToDst_.end()) {
    1097            5 :         BQS_LOG_WARN("No relation [%s->*] exists in abnormal bind relation, no need unbind",
    1098              :                      srcEntity.ToString().c_str());
    1099            5 :         return;
    1100              :     }
    1101              : 
    1102            0 :     for (const auto &dstEntity : srcToDstIter->second) {
    1103            0 :         DelAbnormalDstToSrc(srcEntity, dstEntity);
    1104              :     }
    1105              : 
    1106            0 :     (void)abnormalSrcToDst_.erase(srcToDstIter);
    1107              : }
    1108              : 
    1109            7 : void BindRelation::UnBindAbnormalRelationByDst(const EntityInfo &dstEntity)
    1110              : {
    1111            7 :     const auto dstToSrcIter = abnormalDstToSrc_.find(dstEntity);
    1112            7 :     if (dstToSrcIter == abnormalDstToSrc_.end()) {
    1113            7 :         BQS_LOG_WARN("No bind relation[*->%s] exists in abnormal bind relations, no need unbind.",
    1114              :                      dstEntity.ToString().c_str());
    1115            7 :         return;
    1116              :     }
    1117              : 
    1118            0 :     for (const auto &srcEntity : dstToSrcIter->second) {
    1119            0 :         DelAbnormalSrcToDst(srcEntity, dstEntity);
    1120              :     }
    1121              : 
    1122            0 :     (void)abnormalDstToSrc_.erase(dstToSrcIter);
    1123              : }
    1124              : 
    1125            2 : BqsStatus BindRelation::ClearInputQueue(const uint32_t index, const std::unordered_set<uint32_t>& keySet)
    1126              : {
    1127            2 :     const auto &inputQueues = (index == 0U) ? orderedSubscribeQueueId_ : orderedSubscribeQueueIdExtra_;
    1128            2 :     for (const auto &info: inputQueues) {
    1129            0 :         if (keySet.count(info.GetSchedCfgKey()) == 0U) {
    1130            0 :             continue;
    1131              :         }
    1132            0 :         const auto entity = info.GetEntity();
    1133            0 :         if (entity == nullptr) {
    1134            0 :             BQS_LOG_ERROR("[%s] has no entity, this should not happen.", info.ToString().c_str());
    1135            0 :             return BQS_STATUS_INNER_ERROR;
    1136              :         }
    1137            0 :         const auto ret = entity->ClearQueue();
    1138            0 :         if (ret != dgw::FsmStatus::FSM_SUCCESS) {
    1139            0 :             return BQS_STATUS_INNER_ERROR;
    1140              :         }
    1141            0 :     }
    1142            2 :     return BQS_STATUS_OK;
    1143              : }
    1144              : 
    1145            2 : BqsStatus BindRelation::MakeSureOutputCompletion(const uint32_t index, const std::unordered_set<uint32_t>& keySet)
    1146              : {
    1147            2 :     const auto &dstToSrcRelation = (index == 0U) ? dstToSrcRelation_ : dstToSrcRelationExtra_;
    1148            2 :     for (const auto &dstItem: dstToSrcRelation) {
    1149            1 :         auto &dst = dstItem.first;
    1150            1 :         if (keySet.count(dst.GetSchedCfgKey()) == 0U) {
    1151            0 :             continue;
    1152              :         }
    1153            1 :         const auto entity = dst.GetEntity();
    1154            1 :         if (entity == nullptr) {
    1155            0 :             BQS_LOG_ERROR("[%s] has no entity, this should not happen.", dst.ToString().c_str());
    1156            0 :             return BQS_STATUS_INNER_ERROR;
    1157              :         }
    1158            1 :         const auto ret = entity->MakeSureOutputCompletion();
    1159            1 :         if (ret != dgw::FsmStatus::FSM_SUCCESS) {
    1160            1 :             return BQS_STATUS_INNER_ERROR;
    1161              :         }
    1162            1 :     }
    1163            1 :     return BQS_STATUS_OK;
    1164              : }
    1165              : 
    1166          160 : BqsStatus BindRelation::GetBindRelationIndex(const EntityInfo &srcEntity, const EntityInfo &dstEntity,
    1167              :     uint32_t &index) const
    1168              : {
    1169          160 :     if (!GlobalCfg::GetInstance().GetNumaFlag()) {
    1170          150 :         index = 0U;
    1171          150 :         return BQS_STATUS_OK;
    1172              :     }
    1173           10 :     const auto srcToDstIter = srcToDstRelation_.find(srcEntity);
    1174           10 :     const auto dstToSrcIter = dstToSrcRelation_.find(dstEntity);
    1175           10 :     const auto srcToDstIterExtra = srcToDstRelationExtra_.find(srcEntity);
    1176           10 :     const auto dstToSrcIterExtra = dstToSrcRelationExtra_.find(dstEntity);
    1177           16 :     if ((srcToDstIter != srcToDstRelation_.end() || dstToSrcIter != dstToSrcRelation_.end()) &&
    1178           16 :         (srcToDstIterExtra == srcToDstRelationExtra_.end() && dstToSrcIterExtra == dstToSrcRelationExtra_.end())) {
    1179            3 :         index = 0;
    1180            3 :         return BQS_STATUS_OK;
    1181              :     }
    1182              : 
    1183            7 :     if ((srcToDstIterExtra != srcToDstRelationExtra_.end() || dstToSrcIterExtra != dstToSrcRelationExtra_.end()) &&
    1184            7 :         (srcToDstIter == srcToDstRelation_.end() && dstToSrcIter == dstToSrcRelation_.end())) {
    1185            0 :         index = 1;
    1186            0 :         return BQS_STATUS_OK;
    1187              :     }
    1188              : 
    1189           21 :     if ((srcToDstIterExtra == srcToDstRelationExtra_.end() || dstToSrcIterExtra == dstToSrcRelationExtra_.end()) &&
    1190           21 :         (srcToDstIter == srcToDstRelation_.end() && dstToSrcIter == dstToSrcRelation_.end())) {
    1191            7 :         index = GlobalCfg::GetInstance().GetResIndexByDeviceId(srcEntity.GetDeviceId());
    1192            7 :         return BQS_STATUS_OK;
    1193              :     }
    1194              : 
    1195            0 :     return BQS_STATUS_PARAM_INVALID;
    1196              : }
    1197              : 
    1198          153 : BqsStatus BindRelation::GetBindIndexBySrc(const EntityInfo &srcEntity, uint32_t &index) const
    1199              : {
    1200          153 :     if (!GlobalCfg::GetInstance().GetNumaFlag()) {
    1201          142 :         index = 0U;
    1202          142 :         return BQS_STATUS_OK;
    1203              :     }
    1204           11 :     const auto srcToDstIter = srcToDstRelation_.find(srcEntity);
    1205           11 :     if (srcToDstIter != srcToDstRelation_.end()) {
    1206           10 :         index = 0;
    1207           10 :         return BQS_STATUS_OK;
    1208              :     }
    1209              : 
    1210            1 :     const auto srcToDstIterExtra = srcToDstRelationExtra_.find(srcEntity);
    1211            1 :     if (srcToDstIterExtra != srcToDstRelationExtra_.end()) {
    1212            1 :         index = 1;
    1213            1 :         return BQS_STATUS_OK;
    1214              :     }
    1215              : 
    1216            0 :     return BQS_STATUS_PARAM_INVALID;
    1217              : }
    1218              : 
    1219           11 : BqsStatus BindRelation::GetBindIndexByDst(const EntityInfo &srcEntity, uint32_t &index) const
    1220              : {
    1221           11 :     if (!GlobalCfg::GetInstance().GetNumaFlag()) {
    1222            9 :         index = 0U;
    1223            9 :         return BQS_STATUS_OK;
    1224              :     }
    1225            2 :     const auto dstToSrcIter = dstToSrcRelation_.find(srcEntity);
    1226            2 :     if (dstToSrcIter != dstToSrcRelation_.end()) {
    1227            0 :         index = 0;
    1228            0 :         return BQS_STATUS_OK;
    1229              :     }
    1230              : 
    1231            2 :     const auto dstToSrcIterExtra = dstToSrcRelationExtra_.find(srcEntity);
    1232            2 :     if (dstToSrcIterExtra != dstToSrcRelationExtra_.end()) {
    1233            0 :         index = 1;
    1234            0 :         return BQS_STATUS_OK;
    1235              :     }
    1236              : 
    1237            2 :     return BQS_STATUS_PARAM_INVALID;
    1238              : }
    1239              : 
    1240           12 : const MapEnitityInfoToInfoSet &BindRelation::GetSrcToDstExtraRelation() const
    1241              : {
    1242           12 :     return srcToDstRelationExtra_;
    1243              : }
    1244              : 
    1245            7 : const MapEnitityInfoToInfoSet &BindRelation::GetDstToSrcExtraRelation() const
    1246              : {
    1247            7 :     return dstToSrcRelationExtra_;
    1248              : }
    1249              : 
    1250            0 : const std::vector<EntityInfo> &BindRelation::GetOrderedSubscribeQueueIdExtra() const
    1251              : {
    1252            0 :     return orderedSubscribeQueueIdExtra_;
    1253              : }
    1254              : 
    1255           13 : void BindRelation::AppendAbnormalEntity(const EntityInfo &info, const dgw::EntityDirection direction,
    1256              :     const uint32_t index) {
    1257           13 :     if (index == 0) {
    1258           13 :         if (direction == dgw::EntityDirection::DIRECTION_SEND) {
    1259            9 :             abnormalSrc_.emplace_back(info);
    1260              :         } else {
    1261            4 :             abnormalDst_.emplace_back(info);
    1262              :         }
    1263              :     }
    1264           13 : }
    1265              : 
    1266           28 : void BindRelation::ClearAbnormalEntityInfo(const uint32_t index) {
    1267           28 :     if (index == 0) {
    1268           28 :         abnormalSrc_.clear();
    1269           28 :         abnormalDst_.clear();
    1270              :     }
    1271           28 : }
    1272              : 
    1273           34 : void BindRelation::UpdateRelation(const uint32_t index)
    1274              : {
    1275           34 :     if (index == 0) {
    1276           34 :         if (abnormalSrc_.empty() && abnormalDst_.empty()) {
    1277           26 :         return;
    1278              :         }
    1279              : 
    1280           17 :         for (const auto &abnormalSrc : abnormalSrc_) {
    1281            9 :             MarkAbnormalSrc(abnormalSrc);
    1282            9 :             UnBindRelationBySrc(abnormalSrc);
    1283              :         }
    1284              : 
    1285           12 :         for (const auto &abnormalDst : abnormalDst_) {
    1286            4 :             MarkAbnormalDst(abnormalDst);
    1287            4 :             UnBindRelationByDst(abnormalDst);
    1288              :         }
    1289              : 
    1290            8 :         Order(index);
    1291              : 
    1292            8 :         abnormalSrc_.clear();
    1293            8 :         abnormalDst_.clear();
    1294              :     }
    1295              : }
    1296              : }  // namespace bqs
        

Generated by: LCOV version 2.0-1