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

Generated by: LCOV version 2.0-1