sai_status_t Syncd::processBulkEntry()

in syncd/Syncd.cpp [1893:2066]


sai_status_t Syncd::processBulkEntry(
        _In_ sai_object_type_t objectType,
        _In_ const std::vector<std::string>& objectIds,
        _In_ sai_common_api_t api,
        _In_ const std::vector<std::shared_ptr<SaiAttributeList>>& attributes,
        _In_ const std::vector<std::vector<swss::FieldValueTuple>>& strAttributes)
{
    SWSS_LOG_ENTER();

    auto info = sai_metadata_get_object_type_info(objectType);

    if (info->isobjectid)
    {
        SWSS_LOG_THROW("passing oid object to bulk non object id operation");
    }

    std::vector<sai_status_t> statuses(objectIds.size());

    sai_status_t all = SAI_STATUS_SUCCESS;

    if (m_commandLineOptions->m_enableSaiBulkSupport)
    {
        switch (api)
        {
            case SAI_COMMON_API_BULK_CREATE:
                all = processBulkCreateEntry(objectType, objectIds, attributes, statuses);
                break;

            case SAI_COMMON_API_BULK_REMOVE:
                all = processBulkRemoveEntry(objectType, objectIds, statuses);
                break;

            case SAI_COMMON_API_BULK_SET:
                all = processBulkSetEntry(objectType, objectIds, attributes, statuses);
                break;

            default:
                SWSS_LOG_ERROR("api %s is not supported in bulk", sai_serialize_common_api(api).c_str());
                all = SAI_STATUS_NOT_SUPPORTED;
        }

        if (all != SAI_STATUS_NOT_SUPPORTED && all != SAI_STATUS_NOT_IMPLEMENTED)
        {
            sendApiResponse(api, all, (uint32_t)objectIds.size(), statuses.data());
            syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes);

            return all;
        }
    }

    // vendor SAI don't bulk API yet, so execute one by one

    all = SAI_STATUS_SUCCESS;

    for (size_t idx = 0; idx < objectIds.size(); ++idx)
    {
        sai_object_meta_key_t metaKey;

        metaKey.objecttype = objectType;

        switch ((int)objectType)
        {
            case SAI_OBJECT_TYPE_ROUTE_ENTRY:
                sai_deserialize_route_entry(objectIds[idx], metaKey.objectkey.key.route_entry);
                break;

            case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY:
                sai_deserialize_neighbor_entry(objectIds[idx], metaKey.objectkey.key.neighbor_entry);
                break;

            case SAI_OBJECT_TYPE_NAT_ENTRY:
                sai_deserialize_nat_entry(objectIds[idx], metaKey.objectkey.key.nat_entry);
                break;

            case SAI_OBJECT_TYPE_FDB_ENTRY:
                sai_deserialize_fdb_entry(objectIds[idx], metaKey.objectkey.key.fdb_entry);
                break;

            case SAI_OBJECT_TYPE_INSEG_ENTRY:
                sai_deserialize_inseg_entry(objectIds[idx], metaKey.objectkey.key.inseg_entry);
                break;

            case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:
                sai_deserialize_direction_lookup_entry(objectIds[idx], metaKey.objectkey.key.direction_lookup_entry);
                break;

            case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:
                sai_deserialize_eni_ether_address_map_entry(objectIds[idx], metaKey.objectkey.key.eni_ether_address_map_entry);
                break;

            case SAI_OBJECT_TYPE_VIP_ENTRY:
                sai_deserialize_vip_entry(objectIds[idx], metaKey.objectkey.key.vip_entry);
                break;

            case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:
                sai_deserialize_inbound_routing_entry(objectIds[idx], metaKey.objectkey.key.inbound_routing_entry);
                break;

            case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:
                sai_deserialize_pa_validation_entry(objectIds[idx], metaKey.objectkey.key.pa_validation_entry);
                break;

            case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:
                sai_deserialize_outbound_routing_entry(objectIds[idx], metaKey.objectkey.key.outbound_routing_entry);
                break;

            case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:
                sai_deserialize_outbound_ca_to_pa_entry(objectIds[idx], metaKey.objectkey.key.outbound_ca_to_pa_entry);
                break;

            default:
                SWSS_LOG_THROW("object %s not implemented, FIXME", sai_serialize_object_type(objectType).c_str());
        }

        sai_status_t status = SAI_STATUS_FAILURE;

        auto& list = attributes[idx];

        sai_attribute_t *attr_list = list->get_attr_list();
        uint32_t attr_count = list->get_attr_count();

        if (api == SAI_COMMON_API_BULK_CREATE)
        {
            if (objectType == SAI_OBJECT_TYPE_ROUTE_ENTRY)
            {
                static PerformanceIntervalTimer timer("Syncd::processBulkEntry::processEntry(route_entry) CREATE");

                timer.start();

                status = processEntry(metaKey, SAI_COMMON_API_CREATE, attr_count, attr_list);

                timer.stop();

                timer.inc();
            }
            else
            {
                status = processEntry(metaKey, SAI_COMMON_API_CREATE, attr_count, attr_list);
            }
        }
        else if (api == SAI_COMMON_API_BULK_REMOVE)
        {
            status = processEntry(metaKey, SAI_COMMON_API_REMOVE, attr_count, attr_list);
        }
        else if (api == SAI_COMMON_API_BULK_SET)
        {
            status = processEntry(metaKey, SAI_COMMON_API_SET, attr_count, attr_list);
        }
        else
        {
            SWSS_LOG_THROW("api %d is not supported in bulk mode", api);
        }

        if (api != SAI_COMMON_API_BULK_GET && status != SAI_STATUS_SUCCESS)
        {
            if (!m_enableSyncMode)
            {
                SWSS_LOG_THROW("operation %s for %s failed in async mode!",
                        sai_serialize_common_api(api).c_str(),
                        sai_serialize_object_type(objectType).c_str());
            }

            all = SAI_STATUS_FAILURE; // all can be success if all has been success
        }

        statuses[idx] = status;
    }

    sendApiResponse(api, all, (uint32_t)objectIds.size(), statuses.data());

    syncUpdateRedisBulkQuadEvent(api, statuses, objectType, objectIds, strAttributes);

    return all;
}