void ComparisonLogic::removeCurrentObjectDependencyTree()

in syncd/ComparisonLogic.cpp [2027:2154]


void ComparisonLogic::removeCurrentObjectDependencyTree(
        _In_ AsicView &currentView,
        _In_ AsicView &temporaryView,
        _In_ const std::shared_ptr<SaiObj>& currentObj)
{
    SWSS_LOG_ENTER();

    if (!currentObj->isOidObject())
    {
        // we should be able to remove non object right away since it's leaf

        removeExistingObjectFromCurrentView(currentView, temporaryView, currentObj);

        return;
    }

    // check reference count and remove other objects if necessary

    const int count = currentView.getVidReferenceCount(currentObj->getVid());

    if (count)
    {
        SWSS_LOG_INFO("similar best match has reference count: %d, will need to remove other objects", count);

        auto* info = sai_metadata_get_object_type_info(currentObj->getObjectType());

        // use reverse dependency graph to locate objects where current object can be used
        // need to lookout on loops on some objects

        for (size_t i = 0; i < info->revgraphmemberscount; i++)
        {
            auto *revgraph = info->revgraphmembers[i];

            if (revgraph->structmember)
            {
                SWSS_LOG_THROW("struct fields not supported yet, FIXME");
            }

            SWSS_LOG_INFO("used on %s:%s",
                    sai_serialize_object_type(revgraph->depobjecttype).c_str(),
                    revgraph->attrmetadata->attridname);

            // TODO it could be not processed, or matched, since on matched we
            // can still break the link

            auto objs = currentView.getObjectsByObjectType(revgraph->depobjecttype);

            for (auto& obj: objs)
            {
                // NOTE: current object can have multiple OID attributes that
                // they can have the same value, but they can have different
                // attributes (like set/create_only)

                auto status = obj->getObjectStatus();

                if (status != SAI_OBJECT_STATUS_NOT_PROCESSED &&
                         status != SAI_OBJECT_STATUS_MATCHED)
                {
                    continue;
                }

                auto attr = obj->tryGetSaiAttr(revgraph->attrmetadata->attrid);

                if (attr == nullptr)
                {
                    // no such attribute
                    continue;
                }

                if (revgraph->attrmetadata->attrvaluetype != SAI_ATTR_VALUE_TYPE_OBJECT_ID &&
                        revgraph->attrmetadata->attrvaluetype != SAI_ATTR_VALUE_TYPE_ACL_ACTION_DATA_OBJECT_ID)
                {
                    // currently we only support reference on OID, not list
                    SWSS_LOG_THROW("attr value type %d, not supported yet, FIXME",
                            revgraph->attrmetadata->attrvaluetype);
                }

                if (attr->getOid() != currentObj->getVid())
                {
                    // VID is not matching, skip this attribute
                    continue;
                }

                // we found object and attribute that is using current VID,
                // it's possible this VID is used on multiple attributes on the
                // same object

                SWSS_LOG_INFO("found reference object: %s", obj->m_str_object_id.c_str());

                if (revgraph->attrmetadata->iscreateonly && status == SAI_OBJECT_STATUS_NOT_PROCESSED)
                {
                    // attribute is create only, and object was not processed
                    // yet this means that we need to remove object, since we
                    // can't break the link

                    removeCurrentObjectDependencyTree(currentView, temporaryView, obj); // recursion
                }
                else if (revgraph->attrmetadata->iscreateandset && status == SAI_OBJECT_STATUS_NOT_PROCESSED)
                {
                    if (revgraph->attrmetadata->allownullobjectid)
                    {
                        // we can also remove entire object here too

                        SWSS_LOG_THROW("break the link is not implemented yet, FIXME");
                    }
                    else
                    {
                        // attribute is create and set, but not allow null object id
                        // so probably attribute is mandatory on create, we can't break
                        // the link, but we can remove entire object

                        removeCurrentObjectDependencyTree(currentView, temporaryView, obj); // recursion
                    }
                }
                else if (revgraph->attrmetadata->iscreateandset && status == SAI_OBJECT_STATUS_MATCHED)
                {
                    SWSS_LOG_THROW("matched break the link is not implemented yet, FIXME");
                }
                else
                {
                    SWSS_LOG_THROW("remove on %s, obj status: %d, not supported, FIXME", revgraph->attrmetadata->attridname, status);
                }
            }
        }
    }

    removeExistingObjectFromCurrentView(currentView, temporaryView, currentObj);
}