<commit_before>#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;

std::mutex mut;
std::condition_variable cond;
bool go = false;

typedef char buffer[4096*2];
using atom = std::atomic<size_t>;
typedef void (*fnc_type)(size_t, size_t);

atom lock_instr_test;

struct {
    atom v1;
    atom v2;
} __attribute__((aligned(64))) test_same_line;

struct test_different_line {
    buffer back;
    atom value;
    buffer front;
};

test_different_line *lines;

void test_single_add(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        lock_instr_test.fetch_add(1, std::memory_order_relaxed);
    }
}

void test_single_cas(size_t id, size_t nrun) {
    size_t dummy;
    for (size_t i = 0; i < nrun; i++) {
        while (!lock_instr_test.compare_exchange_weak(dummy,
                                                      dummy+1,
                                                      std::memory_order_relaxed,
                                                      std::memory_order_relaxed))
        {}
    }
}

void test_mfence(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        std::atomic_thread_fence(std::memory_order_seq_cst);
    }
}

void test_same_line_f(size_t id, size_t nrun) {
    atom *a;
    if (id % 2) {
        a = &test_same_line.v1;
    }
    else {
        a = &test_same_line.v2;
    }

    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void test_different_line_f(size_t id, size_t nrun) {
    atom *a = &lines[id].value;
    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void time_threads(size_t ntesters, size_t nrun, fnc_type op, std::string name) {
    std::thread *ths = new std::thread[ntesters];
    for (size_t i = 0; i < ntesters; i++) {
        ths[i] = std::thread([&]() {
            {
                std::unique_lock<std::mutex> lck(mut);
                cond.wait(lck, [&]() {return go; });
            }
            op(i, nrun);
        });
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    auto cclock = std::chrono::steady_clock::now();
    go = true;
    cond.notify_all();
    for (size_t i = 0; i < ntesters; i++) {
        ths[i].join();
    }
    auto diff = std::chrono::steady_clock::now() - cclock;
    auto td = chrono::duration_cast<chrono::milliseconds>(diff).count();
    double tdiff = ((double)td / 1000.0);
    auto nthread = ntesters;
    auto total_elem = (nthread * nrun); //* 2 since popping them all
    auto elempt = total_elem / tdiff;
    auto elemptpt = elempt / nthread;
    auto ns_per_elem = 1e9 * tdiff / nrun;
    cout << "Took " << tdiff
         << " seconds for " << nthread << " threads and "
         << nrun << " elements per thread" << endl
         << "This amounts to " << ns_per_elem
         << " nanoseconds per operation "
         << "for " << name << endl << endl;
    delete[] ths;
}

int main() {
    size_t num_test = 1e8;
    for (size_t i = 1; i <= 10; i++) {
        time_threads(i, num_test, test_single_add, "same add");
        time_threads(i, num_test, test_single_cas, "same cas");
        time_threads(i, num_test, test_mfence, "mfence");
        time_threads(i, num_test, test_same_line_f, "same line");
        lines = new test_different_line[i+1];
        time_threads(i, num_test, test_different_line_f, "different_lines");
        delete[] lines;
        cout << endl << endl;
    }

    return 0;
}
<commit_msg>Added different cas tests<commit_after>#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;

std::mutex mut;
std::condition_variable cond;
bool go = false;

typedef char buffer[4096*2];
using atom = std::atomic<size_t>;
typedef void (*fnc_type)(size_t, size_t);

atom lock_instr_test;

struct {
    atom v1;
    atom v2;
} __attribute__((aligned(64))) test_same_line;

struct test_different_line {
    buffer back;
    atom value;
    buffer front;
};

test_different_line *lines;

void test_single_add(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        lock_instr_test.fetch_add(1, std::memory_order_relaxed);
    }
}

void test_single_cas(size_t id, size_t nrun) {
    size_t dummy;
    for (size_t i = 0; i < nrun; i++) {
        lock_instr_test.compare_exchange_weak(dummy,
                                              dummy+1,
					      std::memory_order_relaxed,
                                              std::memory_order_relaxed);
    }
}

void test_many_cas(size_t id, size_t nrun) {
    size_t dummy;
    for (size_t i = 0; i < nrun; i++) {
        while (!lock_instr_test.compare_exchange_weak(dummy,
                                                      dummy+1,
                                                      std::memory_order_relaxed,
                                                      std::memory_order_relaxed))
        {}
    }
}

void test_mfence(size_t id, size_t nrun) {
    for (size_t i = 0; i < nrun; i++) {
        std::atomic_thread_fence(std::memory_order_seq_cst);
    }
}

void test_same_line_f(size_t id, size_t nrun) {
    atom *a;
    if (id % 2) {
        a = &test_same_line.v1;
    }
    else {
        a = &test_same_line.v2;
    }

    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void test_different_line_f(size_t id, size_t nrun) {
    atom *a = &lines[id].value;
    for (size_t i = 0; i < nrun; i++) {
        a->fetch_add(1, std::memory_order_relaxed);
    }
}

void time_threads(size_t ntesters, size_t nrun, fnc_type op, std::string name) {
    std::thread *ths = new std::thread[ntesters];
    for (size_t i = 0; i < ntesters; i++) {
        ths[i] = std::thread([&]() {
            {
                std::unique_lock<std::mutex> lck(mut);
                cond.wait(lck, [&]() {return go; });
            }
            op(i, nrun);
        });
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(5));
    auto cclock = std::chrono::steady_clock::now();
    go = true;
    cond.notify_all();
    for (size_t i = 0; i < ntesters; i++) {
        ths[i].join();
    }
    auto diff = std::chrono::steady_clock::now() - cclock;
    auto td = chrono::duration_cast<chrono::milliseconds>(diff).count();
    double tdiff = ((double)td / 1000.0);
    auto nthread = ntesters;
    auto total_elem = (nthread * nrun); //* 2 since popping them all
    auto elempt = total_elem / tdiff;
    auto elemptpt = elempt / nthread;
    auto ns_per_elem = 1e9 * tdiff / nrun;
    cout << "Took " << tdiff
         << " seconds for " << nthread << " threads and "
         << nrun << " elements per thread" << endl
         << "This amounts to " << ns_per_elem
         << " nanoseconds per operation "
         << "for " << name << endl << endl;
    delete[] ths;
}

int main() {
    size_t num_test = 1e7;
    for (size_t i = 1; i <= 10; i++) {
        time_threads(i, num_test, test_single_add, "same add");
        time_threads(i, num_test, test_single_cas, "same single cas");
        time_threads(i, num_test, test_many_cas, "same many cas");
        time_threads(i, num_test, test_mfence, "mfence");
        time_threads(i, num_test, test_same_line_f, "same line");
        lines = new test_different_line[i+1];
        time_threads(i, num_test, test_different_line_f, "different_lines");
        delete[] lines;
        cout << endl << endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>#pragma once

#include <depthai-shared/common/EepromData.hpp>
#include <depthai-shared/common/optional.hpp>
#include <nlohmann/json.hpp>

#include "depthai-shared/common/CameraBoardSocket.hpp"
#include "depthai-shared/datatype/RawStereoDepthConfig.hpp"

namespace dai {

/**
 * Specify properties for StereoDepth
 */
struct StereoDepthProperties {
    struct RectificationMesh {
        /**
         * Uri which points to the mesh array for 'left' input rectification
         */
        std::string meshLeftUri;
        /**
         * Uri which points to the mesh array for 'right' input rectification
         */
        std::string meshRightUri;
        /**
         * Mesh array size in bytes, for each of 'left' and 'right' (need to match)
         */
        tl::optional<std::uint32_t> meshSize;
        /**
         * Distance between mesh points, in the horizontal direction
         */
        uint16_t stepWidth = 16;
        /**
         * Distance between mesh points, in the vertical direction
         */
        uint16_t stepHeight = 16;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(RectificationMesh, meshLeftUri, meshRightUri, meshSize, stepWidth, stepHeight);
    };

    /// Initial stereo config
    RawStereoDepthConfig initialConfig;

    /// Whether to wait for config at 'inputConfig' IO
    bool inputConfigSync = false;

    using MedianFilter = dai::MedianFilter;

    using DepthAlign = dai::RawStereoDepthConfig::AlgorithmControl::DepthAlign;

    /**
     * Which camera to align disparity/depth to.
     * When configured (not AUTO), takes precedence over 'depthAlign'
     */
    CameraBoardSocket depthAlignCamera = CameraBoardSocket::AUTO;

    bool enableRectification = true;

    /**
     * Fill color for missing data at frame edges: grayscale 0..255, or -1 to replicate pixels
     */
    std::int32_t rectifyEdgeFillColor = -1;
    /**
     * Input frame width. Optional (taken from MonoCamera nodes if they exist)
     */
    tl::optional<std::int32_t> width;
    /**
     * Input frame height. Optional (taken from MonoCamera nodes if they exist)
     */
    tl::optional<std::int32_t> height;
    /**
     * Output disparity/depth width. Currently only used when aligning to RGB
     */
    tl::optional<std::int32_t> outWidth;
    /**
     * Output disparity/depth height. Currently only used when aligning to RGB
     */
    tl::optional<std::int32_t> outHeight;
    /**
     * Whether to keep aspect ratio of the input (rectified) or not
     */
    bool outKeepAspectRatio = true;

    /**
     * Specify a direct warp mesh to be used for rectification,
     * instead of intrinsics + extrinsic matrices
     */
    RectificationMesh mesh;

    /**
     * Whether to enable switching stereo modes at runtime or not.
     * E.g. standard to subpixel, standard+LR-check to subpixel + LR-check.
     * Note: It will allocate resources for worst cases scenario,
     * should be enabled only if dynamic mode switch is required.
     * Default value: false.
     */
    bool enableRuntimeStereoModeSwitch = false;

    /// Num frames in output pool
    int numFramesPool = 3;

    /**
     * Number of shaves reserved for stereo depth post processing.
     * Post processing can use multiple shaves to increase performance.
     * 0 means auto.
     */
    std::int32_t numPostProcessingShaves = 0;

    /**
     * Number of memory slices reserved for stereo depth post processing.
     * 0 means auto, memory will be allocated based on initial stereo settings and number of shaves.
     */
    std::int32_t numPostProcessingMemorySlices = 0;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(StereoDepthProperties,
                                   initialConfig,
                                   inputConfigSync,
                                   depthAlignCamera,
                                   enableRectification,
                                   rectifyEdgeFillColor,
                                   width,
                                   height,
                                   outWidth,
                                   outHeight,
                                   outKeepAspectRatio,
                                   mesh,
                                   enableRuntimeStereoModeSwitch,
                                   numFramesPool,
                                   numPostProcessingShaves,
                                   numPostProcessingMemorySlices);

}  // namespace dai
<commit_msg>Change default AUTO values for stereo post processing resources<commit_after>#pragma once

#include <depthai-shared/common/EepromData.hpp>
#include <depthai-shared/common/optional.hpp>
#include <nlohmann/json.hpp>

#include "depthai-shared/common/CameraBoardSocket.hpp"
#include "depthai-shared/datatype/RawStereoDepthConfig.hpp"

namespace dai {

/**
 * Specify properties for StereoDepth
 */
struct StereoDepthProperties {
    static constexpr const std::int32_t AUTO = -1;

    struct RectificationMesh {
        /**
         * Uri which points to the mesh array for 'left' input rectification
         */
        std::string meshLeftUri;
        /**
         * Uri which points to the mesh array for 'right' input rectification
         */
        std::string meshRightUri;
        /**
         * Mesh array size in bytes, for each of 'left' and 'right' (need to match)
         */
        tl::optional<std::uint32_t> meshSize;
        /**
         * Distance between mesh points, in the horizontal direction
         */
        uint16_t stepWidth = 16;
        /**
         * Distance between mesh points, in the vertical direction
         */
        uint16_t stepHeight = 16;

        NLOHMANN_DEFINE_TYPE_INTRUSIVE(RectificationMesh, meshLeftUri, meshRightUri, meshSize, stepWidth, stepHeight);
    };

    /// Initial stereo config
    RawStereoDepthConfig initialConfig;

    /// Whether to wait for config at 'inputConfig' IO
    bool inputConfigSync = false;

    using MedianFilter = dai::MedianFilter;

    using DepthAlign = dai::RawStereoDepthConfig::AlgorithmControl::DepthAlign;

    /**
     * Which camera to align disparity/depth to.
     * When configured (not AUTO), takes precedence over 'depthAlign'
     */
    CameraBoardSocket depthAlignCamera = CameraBoardSocket::AUTO;

    bool enableRectification = true;

    /**
     * Fill color for missing data at frame edges: grayscale 0..255, or -1 to replicate pixels
     */
    std::int32_t rectifyEdgeFillColor = -1;
    /**
     * Input frame width. Optional (taken from MonoCamera nodes if they exist)
     */
    tl::optional<std::int32_t> width;
    /**
     * Input frame height. Optional (taken from MonoCamera nodes if they exist)
     */
    tl::optional<std::int32_t> height;
    /**
     * Output disparity/depth width. Currently only used when aligning to RGB
     */
    tl::optional<std::int32_t> outWidth;
    /**
     * Output disparity/depth height. Currently only used when aligning to RGB
     */
    tl::optional<std::int32_t> outHeight;
    /**
     * Whether to keep aspect ratio of the input (rectified) or not
     */
    bool outKeepAspectRatio = true;

    /**
     * Specify a direct warp mesh to be used for rectification,
     * instead of intrinsics + extrinsic matrices
     */
    RectificationMesh mesh;

    /**
     * Whether to enable switching stereo modes at runtime or not.
     * E.g. standard to subpixel, standard+LR-check to subpixel + LR-check.
     * Note: It will allocate resources for worst cases scenario,
     * should be enabled only if dynamic mode switch is required.
     * Default value: false.
     */
    bool enableRuntimeStereoModeSwitch = false;

    /// Num frames in output pool
    int numFramesPool = 3;

    /**
     * Number of shaves reserved for stereo depth post processing.
     * Post processing can use multiple shaves to increase performance.
     * -1 means auto, resources will be allocated based on enabled filters.
     * 0 means that it will reuse the shave assigned for main stereo algorithm.
     * For optimal performance it's recommended to allocate more than 0,
     * so post processing will run in parallel with main stereo algorithm.
     */
    std::int32_t numPostProcessingShaves = AUTO;

    /**
     * Number of memory slices reserved for stereo depth post processing.
     * -1 means auto, memory will be allocated based on initial stereo settings and number of shaves.
     * 0 means that it will reuse the memory slices assigned for main stereo algorithm.
     * For optimal performance it's recommended to allocate more than 0,
     * so post processing will run in parallel with main stereo algorithm.
     */
    std::int32_t numPostProcessingMemorySlices = AUTO;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(StereoDepthProperties,
                                   initialConfig,
                                   inputConfigSync,
                                   depthAlignCamera,
                                   enableRectification,
                                   rectifyEdgeFillColor,
                                   width,
                                   height,
                                   outWidth,
                                   outHeight,
                                   outKeepAspectRatio,
                                   mesh,
                                   enableRuntimeStereoModeSwitch,
                                   numFramesPool,
                                   numPostProcessingShaves,
                                   numPostProcessingMemorySlices);

}  // namespace dai
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "precompiled_xmlsecurity.hxx"
#include <certificatecontainer.hxx>

#include <sal/config.h>

using namespace ::com::sun::star::uno;

sal_Bool
CertificateContainer::searchMap( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name, Map &_certMap )
{
    Map::iterator p = _certMap.find(url);

    ::sal_Bool ret = sal_False;

    while( p != _certMap.end() )
    {
        ret = (sal_Bool) (*p).second.equals(certificate_name);
        if( ret )
                    break;
        p++;
    }

    return ret;
}
// -------------------------------------------------------------------

sal_Bool
CertificateContainer::isTemporaryCertificate ( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name )
    throw(::com::sun::star::uno::RuntimeException)
{
    return searchMap( url, certificate_name, certMap);
}

// -------------------------------------------------------------------

sal_Bool
CertificateContainer::isCertificateTrust ( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name )
    throw(::com::sun::star::uno::RuntimeException)
{
    return searchMap( url, certificate_name, certTrustMap);
}

// -------------------------------------------------------------------
sal_Bool
CertificateContainer::addCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name, ::sal_Bool trust )
    throw(::com::sun::star::uno::RuntimeException)
{
    certMap.insert( Map::value_type( url, certificate_name ) );

        //remember that the cert is trusted
        if (trust)
            certTrustMap.insert( Map::value_type( url, certificate_name ) );

        return true;
}

//-------------------------------------------------------------------------
::security::CertificateContainerStatus
CertificateContainer::hasCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name ) throw(::com::sun::star::uno::RuntimeException)
{
    if ( isTemporaryCertificate( url, certificate_name ) )
    {
        if ( isCertificateTrust( url, certificate_name ) )
            return security::CertificateContainerStatus( security::CertificateContainerStatus_TRUSTED );
        else
            return security::CertificateContainerStatus_UNTRUSTED;
    } else
    {
        return security::CertificateContainerStatus_NOCERT;
    }
}
//-------------------------------------------------------------------------

::rtl::OUString SAL_CALL
CertificateContainer::getImplementationName( )
    throw(::com::sun::star::uno::RuntimeException)
{
    return impl_getStaticImplementationName();
}

//-------------------------------------------------------------------------

sal_Bool SAL_CALL
CertificateContainer::supportsService( const ::rtl::OUString& ServiceName )
    throw(::com::sun::star::uno::RuntimeException)
{
    if ( ServiceName.compareToAscii("com.sun.star.security.CertificateContainer") == 0 )
        return sal_True;
    else
        return sal_False;
}

//-------------------------------------------------------------------------

Sequence< ::rtl::OUString > SAL_CALL
CertificateContainer::getSupportedServiceNames(  )
    throw(::com::sun::star::uno::RuntimeException)
{
    return impl_getStaticSupportedServiceNames();
}

//-------------------------------------------------------------------------

Sequence< ::rtl::OUString > SAL_CALL
CertificateContainer::impl_getStaticSupportedServiceNames(  )
    throw(::com::sun::star::uno::RuntimeException)
{
    Sequence< ::rtl::OUString > aRet(1);
    *aRet.getArray() = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.security.CertificateContainer"));
    return aRet;
}

//-------------------------------------------------------------------------

::rtl::OUString SAL_CALL
CertificateContainer::impl_getStaticImplementationName()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.security.CertificateContainer"));
}

//-------------------------------------------------------------------------

Reference< XInterface > SAL_CALL CertificateContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager )
    throw( RuntimeException )
{
    return Reference< XInterface >( *new CertificateContainer( xServiceManager ) );
}

//-------------------------------------------------------------------------

Reference< XSingleServiceFactory > SAL_CALL
CertificateContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager )
    throw(RuntimeException)
{
    Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
        CertificateContainer::impl_getStaticImplementationName(),
        CertificateContainer::impl_createInstance,
        CertificateContainer::impl_getStaticSupportedServiceNames()));

    return xReturn;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cppcheck: prefer prefix variant<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "precompiled_xmlsecurity.hxx"
#include <certificatecontainer.hxx>

#include <sal/config.h>

using namespace ::com::sun::star::uno;

sal_Bool
CertificateContainer::searchMap( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name, Map &_certMap )
{
    Map::iterator p = _certMap.find(url);

    ::sal_Bool ret = sal_False;

    while( p != _certMap.end() )
    {
        ret = (sal_Bool) (*p).second.equals(certificate_name);
        if( ret )
                    break;
        ++p;
    }

    return ret;
}
// -------------------------------------------------------------------

sal_Bool
CertificateContainer::isTemporaryCertificate ( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name )
    throw(::com::sun::star::uno::RuntimeException)
{
    return searchMap( url, certificate_name, certMap);
}

// -------------------------------------------------------------------

sal_Bool
CertificateContainer::isCertificateTrust ( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name )
    throw(::com::sun::star::uno::RuntimeException)
{
    return searchMap( url, certificate_name, certTrustMap);
}

// -------------------------------------------------------------------
sal_Bool
CertificateContainer::addCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name, ::sal_Bool trust )
    throw(::com::sun::star::uno::RuntimeException)
{
    certMap.insert( Map::value_type( url, certificate_name ) );

        //remember that the cert is trusted
        if (trust)
            certTrustMap.insert( Map::value_type( url, certificate_name ) );

        return true;
}

//-------------------------------------------------------------------------
::security::CertificateContainerStatus
CertificateContainer::hasCertificate( const ::rtl::OUString & url, const ::rtl::OUString & certificate_name ) throw(::com::sun::star::uno::RuntimeException)
{
    if ( isTemporaryCertificate( url, certificate_name ) )
    {
        if ( isCertificateTrust( url, certificate_name ) )
            return security::CertificateContainerStatus( security::CertificateContainerStatus_TRUSTED );
        else
            return security::CertificateContainerStatus_UNTRUSTED;
    } else
    {
        return security::CertificateContainerStatus_NOCERT;
    }
}
//-------------------------------------------------------------------------

::rtl::OUString SAL_CALL
CertificateContainer::getImplementationName( )
    throw(::com::sun::star::uno::RuntimeException)
{
    return impl_getStaticImplementationName();
}

//-------------------------------------------------------------------------

sal_Bool SAL_CALL
CertificateContainer::supportsService( const ::rtl::OUString& ServiceName )
    throw(::com::sun::star::uno::RuntimeException)
{
    if ( ServiceName.compareToAscii("com.sun.star.security.CertificateContainer") == 0 )
        return sal_True;
    else
        return sal_False;
}

//-------------------------------------------------------------------------

Sequence< ::rtl::OUString > SAL_CALL
CertificateContainer::getSupportedServiceNames(  )
    throw(::com::sun::star::uno::RuntimeException)
{
    return impl_getStaticSupportedServiceNames();
}

//-------------------------------------------------------------------------

Sequence< ::rtl::OUString > SAL_CALL
CertificateContainer::impl_getStaticSupportedServiceNames(  )
    throw(::com::sun::star::uno::RuntimeException)
{
    Sequence< ::rtl::OUString > aRet(1);
    *aRet.getArray() = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.security.CertificateContainer"));
    return aRet;
}

//-------------------------------------------------------------------------

::rtl::OUString SAL_CALL
CertificateContainer::impl_getStaticImplementationName()
    throw(::com::sun::star::uno::RuntimeException)
{
    return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.security.CertificateContainer"));
}

//-------------------------------------------------------------------------

Reference< XInterface > SAL_CALL CertificateContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager )
    throw( RuntimeException )
{
    return Reference< XInterface >( *new CertificateContainer( xServiceManager ) );
}

//-------------------------------------------------------------------------

Reference< XSingleServiceFactory > SAL_CALL
CertificateContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager )
    throw(RuntimeException)
{
    Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
        CertificateContainer::impl_getStaticImplementationName(),
        CertificateContainer::impl_createInstance,
        CertificateContainer::impl_getStaticSupportedServiceNames()));

    return xReturn;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Session management.
 */

#pragma once

#include "Id.hxx"
#include "http/CookieJar.hxx"
#include "http/CookieSameSite.hxx"
#include "pool/Ptr.hxx"
#include "util/AllocatedArray.hxx"
#include "util/AllocatedString.hxx"
#include "util/Expiry.hxx"

#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set_hook.hpp>

#include <chrono>

#include <string.h>

struct RealmSession;
struct HttpAddress;

/**
 * Session data associated with a widget instance (struct widget).
 */
struct WidgetSession
	: boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

	struct Compare {
		[[gnu::pure]]
		bool operator()(const WidgetSession &a, const WidgetSession &b) const noexcept {
			return strcmp(a.id.c_str(), b.id.c_str()) < 0;
		}

		[[gnu::pure]]
		bool operator()(const WidgetSession &a, const char *b) const noexcept {
			return strcmp(a.id.c_str(), b) < 0;
		}

		[[gnu::pure]]
		bool operator()(const char *a, const WidgetSession &b) const noexcept {
			return strcmp(a, b.id.c_str()) < 0;
		}
	};

	using Set = boost::intrusive::set<WidgetSession,
					  boost::intrusive::compare<Compare>,
					  boost::intrusive::constant_time_size<false>>;

	/** local id of this widget; must not be nullptr since widgets
	    without an id cannot have a session */
	const AllocatedString id;

	Set children;

	/** last relative URI */
	AllocatedString path_info;

	/** last query string */
	AllocatedString query_string;

	template<typename I>
	explicit WidgetSession(I &&_id) noexcept
		:id(std::forward<I>(_id)) {}

	~WidgetSession() noexcept;

	static void Attach(Set &dest, Set &&src) noexcept;
	void Attach(WidgetSession &&other) noexcept;

	[[gnu::pure]]
	WidgetSession *GetChild(const char *child_id, bool create) noexcept;
};

struct Session;

/**
 * A session associated with a user.
 */
struct RealmSession
	: boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

	static constexpr auto link_mode = boost::intrusive::normal_link;
	using LinkMode = boost::intrusive::link_mode<link_mode>;
	using SetHook = boost::intrusive::unordered_set_member_hook<LinkMode>;
	SetHook set_hook;

	SetHook by_attach_hook;

	Session &parent;

	struct Compare {
		[[gnu::pure]]
		bool operator()(const RealmSession &a, const RealmSession &b) const noexcept {
			return strcmp(a.realm.c_str(), b.realm.c_str()) < 0;
		}

		[[gnu::pure]]
		bool operator()(const RealmSession &a, const char *b) const noexcept {
			return strcmp(a.realm.c_str(), b) < 0;
		}

		[[gnu::pure]]
		bool operator()(const char *a, const RealmSession &b) const noexcept {
			return strcmp(a, b.realm.c_str()) < 0;
		}
	};

	/**
	 * The name of this session's realm.  It is always non-nullptr.
	 */
	const AllocatedString realm;

	/**
	 * The site name as provided by the translation server in the
	 * packet #TRANSLATE_SESSION_SITE.
	 */
	AllocatedString site;

	/** the user name which is logged in (nullptr if anonymous), provided
	    by the translation server */
	AllocatedString user;

	/** when will the #user attribute expire? */
	Expiry user_expires = Expiry::Never();

	/** a map of widget path to WidgetSession */
	WidgetSession::Set widgets;

	/** all cookies received by widget servers */
	CookieJar cookies;

	/**
	 * The "SameSite" attribute of the session cookie which was
	 * most recently sent to the client.
	 */
	CookieSameSite session_cookie_same_site = CookieSameSite::DEFAULT;

	template<typename R>
	RealmSession(Session &_parent, R &&_realm) noexcept
		:parent(_parent),
		 realm(std::forward<R>(_realm))
	{
	}

	RealmSession(Session &_parent, RealmSession &&src) noexcept
		:parent(_parent),
		 realm(std::move(src.realm)),
		 site(std::move(src.site)),
		 user(std::move(src.user)),
		 user_expires(src.user_expires),
		 widgets(std::move(src.widgets)),
		 cookies(std::move(src.cookies))
	{
	}

	~RealmSession() noexcept;

	void Attach(RealmSession &&other) noexcept;

	void ClearSite() noexcept {
		site = nullptr;
	}

	void SetSite(const char *_site) noexcept {
		site = _site;
	}

	/**
	 * @param max_age 0 = expires immediately; negative = never
	 * expires.
	 */
	void SetUser(const char *user, std::chrono::seconds max_age) noexcept;
	void ClearUser() noexcept {
		user = nullptr;
	}

	void Expire(Expiry now) noexcept;

	[[gnu::pure]]
	WidgetSession *GetWidget(const char *widget_id, bool create) noexcept;
};

struct Session {
	static constexpr auto link_mode = boost::intrusive::normal_link;
	using LinkMode = boost::intrusive::link_mode<link_mode>;
	using SetHook = boost::intrusive::unordered_set_member_hook<LinkMode>;
	SetHook set_hook;

	using ByAttachHook = boost::intrusive::unordered_set_member_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>;
	ByAttachHook by_attach_hook;

	/** identification number of this session */
	const SessionId id;

	/** a secret used to generate CSRF tokens */
	const SessionId csrf_salt;

	/** when will this session expire? */
	Expiry expires;

	/**
	 * Counts how often this session has been used.
	 */
	unsigned counter = 1;

	/** has a HTTP cookie with this session id already been received? */
	bool cookie_received = false;

	/** an opaque string for the translation server */
	AllocatedArray<std::byte> translate;

	AllocatedString recover;

	/** an opaque string for attaching sessions; if this is set,
	    then the session is in
	    SessionContainer::sessions_by_attach */
	AllocatedArray<std::byte> attach;

	/** optional  for the "Accept-Language" header, provided
	    by the translation server */
	AllocatedString language;

	PoolPtr external_manager_pool;

	/** @see #TRANSLATE_EXTERNAL_SESSION_MANAGER */
	HttpAddress *external_manager = nullptr;

	/** @see #TRANSLATE_EXTERNAL_SESSION_KEEPALIVE */
	std::chrono::duration<uint16_t> external_keepalive;

	std::chrono::steady_clock::time_point next_external_keepalive;

	using RealmSessionSet =
		boost::intrusive::set<RealmSession,
				      boost::intrusive::compare<RealmSession::Compare>,
				      boost::intrusive::constant_time_size<false>>;

	RealmSessionSet realms;

	Session(SessionId _id, SessionId _csrf_salt) noexcept;
	~Session() noexcept;

	/**
	 * Calculates the score for purging the session: higher score
	 * means more likely to be purged.
	 */
	[[gnu::pure]]
	unsigned GetPurgeScore() const noexcept;

	[[gnu::pure]]
	bool HasUser() const noexcept {
		for (auto &realm : realms)
			if (realm.user != nullptr)
				return true;

		return false;
	}

	void SetTranslate(std::span<const std::byte> translate) noexcept;
	void ClearTranslate() noexcept;

	/**
	 * @return true if the value modified
	 */
	bool SetRecover(const char *_recover) noexcept;

	/**
	 * Does this session have the specified "attach" value?
	 */
	[[gnu::pure]]
	bool IsAttach(std::span<const std::byte> other) const noexcept;

	void Attach(Session &&other) noexcept;

	void SetLanguage(const char *_language) noexcept {
		language = _language;
	}

	void ClearLanguage() noexcept {
		language = nullptr;
	}

	void SetExternalManager(const HttpAddress &address,
				std::chrono::steady_clock::time_point now,
				std::chrono::duration<uint16_t> keepalive) noexcept;

	void Expire(Expiry now) noexcept;

	[[gnu::pure]]
	RealmSession *GetRealm(const char *realm) noexcept;
};

/**
 * Deletes the session with the specified id.  The current process
 * must not hold a sssion lock.
 */
void
session_delete(SessionId id) noexcept;
<commit_msg>bp/session/Session: improve API docs<commit_after>/*
 * Copyright 2007-2022 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Session management.
 */

#pragma once

#include "Id.hxx"
#include "http/CookieJar.hxx"
#include "http/CookieSameSite.hxx"
#include "pool/Ptr.hxx"
#include "util/AllocatedArray.hxx"
#include "util/AllocatedString.hxx"
#include "util/Expiry.hxx"

#include <boost/intrusive/set.hpp>
#include <boost/intrusive/unordered_set_hook.hpp>

#include <chrono>

#include <string.h>

struct RealmSession;
struct HttpAddress;

/**
 * Session data associated with a widget instance (struct widget).
 */
struct WidgetSession
	: boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

	struct Compare {
		[[gnu::pure]]
		bool operator()(const WidgetSession &a, const WidgetSession &b) const noexcept {
			return strcmp(a.id.c_str(), b.id.c_str()) < 0;
		}

		[[gnu::pure]]
		bool operator()(const WidgetSession &a, const char *b) const noexcept {
			return strcmp(a.id.c_str(), b) < 0;
		}

		[[gnu::pure]]
		bool operator()(const char *a, const WidgetSession &b) const noexcept {
			return strcmp(a, b.id.c_str()) < 0;
		}
	};

	using Set = boost::intrusive::set<WidgetSession,
					  boost::intrusive::compare<Compare>,
					  boost::intrusive::constant_time_size<false>>;

	/** local id of this widget; must not be nullptr since widgets
	    without an id cannot have a session */
	const AllocatedString id;

	Set children;

	/** last relative URI */
	AllocatedString path_info;

	/** last query string */
	AllocatedString query_string;

	template<typename I>
	explicit WidgetSession(I &&_id) noexcept
		:id(std::forward<I>(_id)) {}

	~WidgetSession() noexcept;

	static void Attach(Set &dest, Set &&src) noexcept;
	void Attach(WidgetSession &&other) noexcept;

	[[gnu::pure]]
	WidgetSession *GetChild(const char *child_id, bool create) noexcept;
};

struct Session;

/**
 * A session associated with a user.
 */
struct RealmSession
	: boost::intrusive::set_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {

	static constexpr auto link_mode = boost::intrusive::normal_link;
	using LinkMode = boost::intrusive::link_mode<link_mode>;
	using SetHook = boost::intrusive::unordered_set_member_hook<LinkMode>;
	SetHook set_hook;

	SetHook by_attach_hook;

	Session &parent;

	struct Compare {
		[[gnu::pure]]
		bool operator()(const RealmSession &a, const RealmSession &b) const noexcept {
			return strcmp(a.realm.c_str(), b.realm.c_str()) < 0;
		}

		[[gnu::pure]]
		bool operator()(const RealmSession &a, const char *b) const noexcept {
			return strcmp(a.realm.c_str(), b) < 0;
		}

		[[gnu::pure]]
		bool operator()(const char *a, const RealmSession &b) const noexcept {
			return strcmp(a, b.realm.c_str()) < 0;
		}
	};

	/**
	 * The name of this session's realm.  It is always non-nullptr.
	 */
	const AllocatedString realm;

	/**
	 * The site name as provided by the translation server in the
	 * packet #TRANSLATE_SESSION_SITE.
	 */
	AllocatedString site;

	/** the user name which is logged in (nullptr if anonymous), provided
	    by the translation server */
	AllocatedString user;

	/** when will the #user attribute expire? */
	Expiry user_expires = Expiry::Never();

	/** a map of widget path to WidgetSession */
	WidgetSession::Set widgets;

	/** all cookies received by widget servers */
	CookieJar cookies;

	/**
	 * The "SameSite" attribute of the session cookie which was
	 * most recently sent to the client.
	 */
	CookieSameSite session_cookie_same_site = CookieSameSite::DEFAULT;

	template<typename R>
	RealmSession(Session &_parent, R &&_realm) noexcept
		:parent(_parent),
		 realm(std::forward<R>(_realm))
	{
	}

	RealmSession(Session &_parent, RealmSession &&src) noexcept
		:parent(_parent),
		 realm(std::move(src.realm)),
		 site(std::move(src.site)),
		 user(std::move(src.user)),
		 user_expires(src.user_expires),
		 widgets(std::move(src.widgets)),
		 cookies(std::move(src.cookies))
	{
	}

	~RealmSession() noexcept;

	void Attach(RealmSession &&other) noexcept;

	void ClearSite() noexcept {
		site = nullptr;
	}

	void SetSite(const char *_site) noexcept {
		site = _site;
	}

	/**
	 * @param max_age 0 = expires immediately; negative = never
	 * expires.
	 */
	void SetUser(const char *user, std::chrono::seconds max_age) noexcept;
	void ClearUser() noexcept {
		user = nullptr;
	}

	void Expire(Expiry now) noexcept;

	[[gnu::pure]]
	WidgetSession *GetWidget(const char *widget_id, bool create) noexcept;
};

struct Session {
	static constexpr auto link_mode = boost::intrusive::normal_link;
	using LinkMode = boost::intrusive::link_mode<link_mode>;
	using SetHook = boost::intrusive::unordered_set_member_hook<LinkMode>;
	SetHook set_hook;

	using ByAttachHook = boost::intrusive::unordered_set_member_hook<boost::intrusive::link_mode<boost::intrusive::auto_unlink>>;
	ByAttachHook by_attach_hook;

	/** identification number of this session */
	const SessionId id;

	/** a secret used to generate CSRF tokens */
	const SessionId csrf_salt;

	/** when will this session expire? */
	Expiry expires;

	/**
	 * Counts how often this session has been used.
	 */
	unsigned counter = 1;

	/** has a HTTP cookie with this session id already been received? */
	bool cookie_received = false;

	/**
	 * An opaque string for the translation server obtained from
	 * TranslationCommand::SESSION.
	 */
	AllocatedArray<std::byte> translate;

	AllocatedString recover;

	/** an opaque string for attaching sessions; if this is set,
	    then the session is in
	    SessionContainer::sessions_by_attach */
	AllocatedArray<std::byte> attach;

	/** optional  for the "Accept-Language" header, provided
	    by the translation server */
	AllocatedString language;

	PoolPtr external_manager_pool;

	/** @see #TRANSLATE_EXTERNAL_SESSION_MANAGER */
	HttpAddress *external_manager = nullptr;

	/** @see #TRANSLATE_EXTERNAL_SESSION_KEEPALIVE */
	std::chrono::duration<uint16_t> external_keepalive;

	std::chrono::steady_clock::time_point next_external_keepalive;

	using RealmSessionSet =
		boost::intrusive::set<RealmSession,
				      boost::intrusive::compare<RealmSession::Compare>,
				      boost::intrusive::constant_time_size<false>>;

	RealmSessionSet realms;

	Session(SessionId _id, SessionId _csrf_salt) noexcept;
	~Session() noexcept;

	/**
	 * Calculates the score for purging the session: higher score
	 * means more likely to be purged.
	 */
	[[gnu::pure]]
	unsigned GetPurgeScore() const noexcept;

	[[gnu::pure]]
	bool HasUser() const noexcept {
		for (auto &realm : realms)
			if (realm.user != nullptr)
				return true;

		return false;
	}

	void SetTranslate(std::span<const std::byte> translate) noexcept;
	void ClearTranslate() noexcept;

	/**
	 * @return true if the value modified
	 */
	bool SetRecover(const char *_recover) noexcept;

	/**
	 * Does this session have the specified "attach" value?
	 */
	[[gnu::pure]]
	bool IsAttach(std::span<const std::byte> other) const noexcept;

	void Attach(Session &&other) noexcept;

	void SetLanguage(const char *_language) noexcept {
		language = _language;
	}

	void ClearLanguage() noexcept {
		language = nullptr;
	}

	void SetExternalManager(const HttpAddress &address,
				std::chrono::steady_clock::time_point now,
				std::chrono::duration<uint16_t> keepalive) noexcept;

	void Expire(Expiry now) noexcept;

	[[gnu::pure]]
	RealmSession *GetRealm(const char *realm) noexcept;
};

/**
 * Deletes the session with the specified id.  The current process
 * must not hold a sssion lock.
 */
void
session_delete(SessionId id) noexcept;
<|endoftext|>


<commit_before>#pragma once

#include "physics/barycentric_rotating_dynamic_frame.hpp"

#include "geometry/barycentre_calculator.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {

using geometry::Barycentre;
using geometry::Displacement;
using geometry::R3x3Matrix;
using geometry::Velocity;
using geometry::Wedge;
using quantities::Length;
using quantities::Pow;
using quantities::Product;
using quantities::Speed;

namespace physics {

template<typename InertialFrame, typename ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
BarycentricRotatingDynamicFrame(
    not_null<Ephemeris<InertialFrame> const*> const ephemeris,
    not_null<MassiveBody const*> const primary,
    not_null<MassiveBody const*> const secondary)
    : ephemeris_(ephemeris),
      primary_(primary),
      secondary_(secondary),
      primary_trajectory_(ephemeris_->trajectory(primary_)),
      secondary_trajectory_(ephemeris_->trajectory(secondary_)) {}

template<typename InertialFrame, typename ThisFrame>
RigidMotion<InertialFrame, ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::ToThisFrameAtTime(
    Instant const& t) const {
  DegreesOfFreedom<InertialFrame> const primary_degrees_of_freedom =
      primary_trajectory_->EvaluateDegreesOfFreedom(t, &primary_hint_);
  DegreesOfFreedom<InertialFrame> const secondary_degrees_of_freedom =
      secondary_trajectory_->EvaluateDegreesOfFreedom(t, &secondary_hint_);
  DegreesOfFreedom<InertialFrame> const barycentre_degrees_of_freedom =
      Barycentre<DegreesOfFreedom<InertialFrame>, GravitationalParameter>(
          {primary_degrees_of_freedom,
           secondary_degrees_of_freedom},
          {primary_->gravitational_parameter(),
           secondary_->gravitational_parameter()});

  Rotation<InertialFrame, ThisFrame> rotation =
          Rotation<InertialFrame, ThisFrame>::Identity();
  AngularVelocity<InertialFrame> angular_velocity;
  ComputeAngularDegreesOfFreedom(primary_degrees_of_freedom,
                                 secondary_degrees_of_freedom,
                                 &rotation,
                                 &angular_velocity);

  RigidTransformation<InertialFrame, ThisFrame> const
      rigid_transformation(barycentre_degrees_of_freedom.position(),
                           ThisFrame::origin,
                           rotation.Forget());
  return RigidMotion<InertialFrame, ThisFrame>(
             rigid_transformation,
             angular_velocity,
             barycentre_degrees_of_freedom.velocity());
}

template<typename InertialFrame, typename ThisFrame>
RigidMotion<ThisFrame, InertialFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
FromThisFrameAtTime(Instant const& t) const {
  return ToThisFrameAtTime(t).Inverse();
}

template<typename InertialFrame, typename ThisFrame>
Vector<Acceleration, ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
GeometricAcceleration(
    Instant const& t,
    DegreesOfFreedom<ThisFrame> const& degrees_of_freedom) const {
  auto const to_this_frame = ToThisFrameAtTime(t);
  auto const from_this_frame = to_this_frame.Inverse();

  DegreesOfFreedom<InertialFrame> const primary_degrees_of_freedom =
      primary_trajectory_->EvaluateDegreesOfFreedom(t, &primary_hint_);
  DegreesOfFreedom<InertialFrame> const secondary_degrees_of_freedom =
      secondary_trajectory_->EvaluateDegreesOfFreedom(t, &secondary_hint_);

  // Beware, we want the angular velocity of ThisFrame as seen in the
  // InertialFrame, but pushed to ThisFrame.  Otherwise the sign is wrong.
  AngularVelocity<InertialFrame> const Ω_inertial =
      to_this_frame.angular_velocity_of_to_frame();
  AngularVelocity<ThisFrame> const Ω =
      to_this_frame.orthogonal_map()(Ω_inertial);

  Vector<Acceleration, InertialFrame> const primary_acceleration =
      ephemeris_->ComputeGravitationalAccelerationOnMassiveBody(
          primary_, t);
  Vector<Acceleration, InertialFrame> const secondary_acceleration =
      ephemeris_->ComputeGravitationalAccelerationOnMassiveBody(
          secondary_, t);

  // TODO(egg): TeX and reference.
  RelativeDegreesOfFreedom<InertialFrame> const primary_secondary =
      primary_degrees_of_freedom - secondary_degrees_of_freedom;
  Variation<AngularVelocity<ThisFrame>> const dΩ_over_dt =
      to_this_frame.orthogonal_map()
          (Wedge(primary_secondary.displacement(),
                 (primary_acceleration - secondary_acceleration)) * Radian -
           2 * Ω_inertial * InnerProduct(primary_secondary.displacement(),
                                         primary_secondary.velocity())) /
               InnerProduct(primary_secondary.displacement(),
                            primary_secondary.displacement());

  Displacement<ThisFrame> const r =
      degrees_of_freedom.position() - ThisFrame::origin;
  Vector<Acceleration, ThisFrame> const gravitational_acceleration_at_point =
      to_this_frame.orthogonal_map()(
          ephemeris_->ComputeGravitationalAccelerationOnMasslessBody(
              from_this_frame.rigid_transformation()(
                  degrees_of_freedom.position()), t));
  Vector<Acceleration, ThisFrame> const linear_acceleration =
      to_this_frame.orthogonal_map()(
          -Barycentre<Vector<Acceleration, InertialFrame>,
                      GravitationalParameter>(
              {primary_acceleration,
               secondary_acceleration},
              {primary_->gravitational_parameter(),
               secondary_->gravitational_parameter()}));
  Vector<Acceleration, ThisFrame> const coriolis_acceleration_at_point =
      -2 * Ω * degrees_of_freedom.velocity() / Radian;
  Vector<Acceleration, ThisFrame> const centrifugal_acceleration_at_point =
      -Ω * (Ω * r) / Pow<2>(Radian);
  Vector<Acceleration, ThisFrame> const euler_acceleration_at_point =
      -dΩ_over_dt * r / Radian;

  Vector<Acceleration, ThisFrame> const fictitious_acceleration =
      linear_acceleration +
      coriolis_acceleration_at_point +
      centrifugal_acceleration_at_point +
      euler_acceleration_at_point;
  return gravitational_acceleration_at_point + fictitious_acceleration;
}

template<typename InertialFrame, typename ThisFrame>
void BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
WriteToMessage(not_null<serialization::DynamicFrame*> const message) const {
  auto* const extension =
      message->MutableExtension(
          serialization::BarycentricRotatingDynamicFrame::
              barycentric_rotating_dynamic_frame);
  extension->set_primary(ephemeris_->serialization_index_for_body(primary_));
  extension->set_secondary(
      ephemeris_->serialization_index_for_body(secondary_));
}

template<typename InertialFrame, typename ThisFrame>
not_null<std::unique_ptr<
    BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>>>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::ReadFromMessage(
    not_null<Ephemeris<InertialFrame> const*> const ephemeris,
    serialization::BarycentricRotatingDynamicFrame const & message) {
  return std::make_unique<BarycentricRotatingDynamicFrame>(
      ephemeris,
      ephemeris->body_for_serialization_index(message.primary()),
      ephemeris->body_for_serialization_index(message.secondary()));
}

template<typename InertialFrame, typename ThisFrame>
void BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
ComputeAngularDegreesOfFreedom(
    DegreesOfFreedom<InertialFrame> const& primary_degrees_of_freedom,
    DegreesOfFreedom<InertialFrame> const& secondary_degrees_of_freedom,
    not_null<Rotation<InertialFrame, ThisFrame>*> const rotation,
    not_null<AngularVelocity<InertialFrame>*> const angular_velocity) {
  RelativeDegreesOfFreedom<InertialFrame> const reference =
      primary_degrees_of_freedom - secondary_degrees_of_freedom;
  Displacement<InertialFrame> const& reference_direction =
      reference.displacement();
  Velocity<InertialFrame> reference_normal = reference.velocity();
  reference_direction.template Orthogonalize<Speed>(&reference_normal);
  Bivector<Product<Length, Speed>, InertialFrame> const reference_binormal =
      Wedge(reference_direction, reference_normal);
  *rotation = Rotation<InertialFrame, ThisFrame>(
                  R3x3Matrix(Normalize(reference_direction).coordinates(),
                             Normalize(reference_normal).coordinates(),
                             Normalize(reference_binormal).coordinates()));
  *angular_velocity = reference_binormal * Radian /
                      InnerProduct(reference_direction, reference_direction);
}

}  // namespace physics
}  // namespace principia
<commit_msg>Add missing using for geometry::Bivector<commit_after>#pragma once

#include "physics/barycentric_rotating_dynamic_frame.hpp"

#include "geometry/barycentre_calculator.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"

namespace principia {

using geometry::Barycentre;
using geometry::Bivector;
using geometry::Displacement;
using geometry::R3x3Matrix;
using geometry::Velocity;
using geometry::Wedge;
using quantities::Length;
using quantities::Pow;
using quantities::Product;
using quantities::Speed;

namespace physics {

template<typename InertialFrame, typename ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
BarycentricRotatingDynamicFrame(
    not_null<Ephemeris<InertialFrame> const*> const ephemeris,
    not_null<MassiveBody const*> const primary,
    not_null<MassiveBody const*> const secondary)
    : ephemeris_(ephemeris),
      primary_(primary),
      secondary_(secondary),
      primary_trajectory_(ephemeris_->trajectory(primary_)),
      secondary_trajectory_(ephemeris_->trajectory(secondary_)) {}

template<typename InertialFrame, typename ThisFrame>
RigidMotion<InertialFrame, ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::ToThisFrameAtTime(
    Instant const& t) const {
  DegreesOfFreedom<InertialFrame> const primary_degrees_of_freedom =
      primary_trajectory_->EvaluateDegreesOfFreedom(t, &primary_hint_);
  DegreesOfFreedom<InertialFrame> const secondary_degrees_of_freedom =
      secondary_trajectory_->EvaluateDegreesOfFreedom(t, &secondary_hint_);
  DegreesOfFreedom<InertialFrame> const barycentre_degrees_of_freedom =
      Barycentre<DegreesOfFreedom<InertialFrame>, GravitationalParameter>(
          {primary_degrees_of_freedom,
           secondary_degrees_of_freedom},
          {primary_->gravitational_parameter(),
           secondary_->gravitational_parameter()});

  Rotation<InertialFrame, ThisFrame> rotation =
          Rotation<InertialFrame, ThisFrame>::Identity();
  AngularVelocity<InertialFrame> angular_velocity;
  ComputeAngularDegreesOfFreedom(primary_degrees_of_freedom,
                                 secondary_degrees_of_freedom,
                                 &rotation,
                                 &angular_velocity);

  RigidTransformation<InertialFrame, ThisFrame> const
      rigid_transformation(barycentre_degrees_of_freedom.position(),
                           ThisFrame::origin,
                           rotation.Forget());
  return RigidMotion<InertialFrame, ThisFrame>(
             rigid_transformation,
             angular_velocity,
             barycentre_degrees_of_freedom.velocity());
}

template<typename InertialFrame, typename ThisFrame>
RigidMotion<ThisFrame, InertialFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
FromThisFrameAtTime(Instant const& t) const {
  return ToThisFrameAtTime(t).Inverse();
}

template<typename InertialFrame, typename ThisFrame>
Vector<Acceleration, ThisFrame>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
GeometricAcceleration(
    Instant const& t,
    DegreesOfFreedom<ThisFrame> const& degrees_of_freedom) const {
  auto const to_this_frame = ToThisFrameAtTime(t);
  auto const from_this_frame = to_this_frame.Inverse();

  DegreesOfFreedom<InertialFrame> const primary_degrees_of_freedom =
      primary_trajectory_->EvaluateDegreesOfFreedom(t, &primary_hint_);
  DegreesOfFreedom<InertialFrame> const secondary_degrees_of_freedom =
      secondary_trajectory_->EvaluateDegreesOfFreedom(t, &secondary_hint_);

  // Beware, we want the angular velocity of ThisFrame as seen in the
  // InertialFrame, but pushed to ThisFrame.  Otherwise the sign is wrong.
  AngularVelocity<InertialFrame> const Ω_inertial =
      to_this_frame.angular_velocity_of_to_frame();
  AngularVelocity<ThisFrame> const Ω =
      to_this_frame.orthogonal_map()(Ω_inertial);

  Vector<Acceleration, InertialFrame> const primary_acceleration =
      ephemeris_->ComputeGravitationalAccelerationOnMassiveBody(
          primary_, t);
  Vector<Acceleration, InertialFrame> const secondary_acceleration =
      ephemeris_->ComputeGravitationalAccelerationOnMassiveBody(
          secondary_, t);

  // TODO(egg): TeX and reference.
  RelativeDegreesOfFreedom<InertialFrame> const primary_secondary =
      primary_degrees_of_freedom - secondary_degrees_of_freedom;
  Variation<AngularVelocity<ThisFrame>> const dΩ_over_dt =
      to_this_frame.orthogonal_map()
          (Wedge(primary_secondary.displacement(),
                 (primary_acceleration - secondary_acceleration)) * Radian -
           2 * Ω_inertial * InnerProduct(primary_secondary.displacement(),
                                         primary_secondary.velocity())) /
               InnerProduct(primary_secondary.displacement(),
                            primary_secondary.displacement());

  Displacement<ThisFrame> const r =
      degrees_of_freedom.position() - ThisFrame::origin;
  Vector<Acceleration, ThisFrame> const gravitational_acceleration_at_point =
      to_this_frame.orthogonal_map()(
          ephemeris_->ComputeGravitationalAccelerationOnMasslessBody(
              from_this_frame.rigid_transformation()(
                  degrees_of_freedom.position()), t));
  Vector<Acceleration, ThisFrame> const linear_acceleration =
      to_this_frame.orthogonal_map()(
          -Barycentre<Vector<Acceleration, InertialFrame>,
                      GravitationalParameter>(
              {primary_acceleration,
               secondary_acceleration},
              {primary_->gravitational_parameter(),
               secondary_->gravitational_parameter()}));
  Vector<Acceleration, ThisFrame> const coriolis_acceleration_at_point =
      -2 * Ω * degrees_of_freedom.velocity() / Radian;
  Vector<Acceleration, ThisFrame> const centrifugal_acceleration_at_point =
      -Ω * (Ω * r) / Pow<2>(Radian);
  Vector<Acceleration, ThisFrame> const euler_acceleration_at_point =
      -dΩ_over_dt * r / Radian;

  Vector<Acceleration, ThisFrame> const fictitious_acceleration =
      linear_acceleration +
      coriolis_acceleration_at_point +
      centrifugal_acceleration_at_point +
      euler_acceleration_at_point;
  return gravitational_acceleration_at_point + fictitious_acceleration;
}

template<typename InertialFrame, typename ThisFrame>
void BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
WriteToMessage(not_null<serialization::DynamicFrame*> const message) const {
  auto* const extension =
      message->MutableExtension(
          serialization::BarycentricRotatingDynamicFrame::
              barycentric_rotating_dynamic_frame);
  extension->set_primary(ephemeris_->serialization_index_for_body(primary_));
  extension->set_secondary(
      ephemeris_->serialization_index_for_body(secondary_));
}

template<typename InertialFrame, typename ThisFrame>
not_null<std::unique_ptr<
    BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>>>
BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::ReadFromMessage(
    not_null<Ephemeris<InertialFrame> const*> const ephemeris,
    serialization::BarycentricRotatingDynamicFrame const & message) {
  return std::make_unique<BarycentricRotatingDynamicFrame>(
      ephemeris,
      ephemeris->body_for_serialization_index(message.primary()),
      ephemeris->body_for_serialization_index(message.secondary()));
}

template<typename InertialFrame, typename ThisFrame>
void BarycentricRotatingDynamicFrame<InertialFrame, ThisFrame>::
ComputeAngularDegreesOfFreedom(
    DegreesOfFreedom<InertialFrame> const& primary_degrees_of_freedom,
    DegreesOfFreedom<InertialFrame> const& secondary_degrees_of_freedom,
    not_null<Rotation<InertialFrame, ThisFrame>*> const rotation,
    not_null<AngularVelocity<InertialFrame>*> const angular_velocity) {
  RelativeDegreesOfFreedom<InertialFrame> const reference =
      primary_degrees_of_freedom - secondary_degrees_of_freedom;
  Displacement<InertialFrame> const& reference_direction =
      reference.displacement();
  Velocity<InertialFrame> reference_normal = reference.velocity();
  reference_direction.template Orthogonalize<Speed>(&reference_normal);
  Bivector<Product<Length, Speed>, InertialFrame> const reference_binormal =
      Wedge(reference_direction, reference_normal);
  *rotation = Rotation<InertialFrame, ThisFrame>(
                  R3x3Matrix(Normalize(reference_direction).coordinates(),
                             Normalize(reference_normal).coordinates(),
                             Normalize(reference_binormal).coordinates()));
  *angular_velocity = reference_binormal * Radian /
                      InnerProduct(reference_direction, reference_direction);
}

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//------------------------------------------------------------------------
// Jet reader base class
// manages the reading of input for jet algorithms
// Authors: jgcn@mda.cinvestav.mx
//          magali.estienne@IReS.in2p3.fr
//------------------------------------------------------------------------

// root
#include <TClonesArray.h>
#include <TRefArray.h>
#include "TTask.h"
//AliRoot
#include "AliJetReader.h"
#include "AliJetReaderHeader.h"
#include "AliESDEvent.h"
#include "AliHeader.h"
#include "AliJetFillUnitArrayTracks.h"
#include "AliJetFillUnitArrayEMCalDigits.h"
#include "AliJetUnitArray.h"
#include "AliJetHadronCorrectionv1.h"

ClassImp(AliJetReader)

////////////////////////////////////////////////////////////////////////

AliJetReader::AliJetReader():
  // Constructor
  fChain(0),
  fTree(0),
  fMomentumArray(new TClonesArray("TLorentzVector",4000)),
  fArrayMC(0),
  fFillUnitArray(new TTask("fillUnitArray","Fill unit array jet finder")),
  fESD(0),
  fReaderHeader(0),
  fAliHeader(0),
  fSignalFlag(0),
  fCutFlag(0),
  fUnitArray(new TClonesArray("AliJetUnitArray",60000)),
  fUnitArrayNoCuts(new TClonesArray("AliJetUnitArray",60000)),
  fArrayInitialised(0),
  fFillUAFromTracks(new AliJetFillUnitArrayTracks()),
  fFillUAFromEMCalDigits(new AliJetFillUnitArrayEMCalDigits()),
  fNumCandidate(0),
  fNumCandidateCut(0),
  fHadronCorrector(0),
  fHCorrection(0),
  fECorrection(0),
  fEFlag(kFALSE)
{
  // Default constructor
  fSignalFlag = TArrayI();
  fCutFlag    = TArrayI();
}

////////////////////////////////////////////////////////////////////////

AliJetReader::~AliJetReader()
{
  // Destructor
  if (fMomentumArray) {
      fMomentumArray->Delete();
      delete fMomentumArray;
  }

  if (fUnitArray) {
      fUnitArray->Delete();
      delete fUnitArray;
  }

  if (fUnitArrayNoCuts) {
    fUnitArrayNoCuts->Delete();
    delete fUnitArrayNoCuts;
  }

  if (fFillUnitArray) {
    fFillUnitArray->Delete();
    delete fFillUnitArray;
  }
  delete fArrayMC;

}

////////////////////////////////////////////////////////////////////////

void AliJetReader::ClearArray()
{
  if (fMomentumArray)  fMomentumArray->Clear();
  if (fFillUnitArray)  fFillUnitArray->Clear();
}
<commit_msg>Correct destructor restored.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//------------------------------------------------------------------------
// Jet reader base class
// manages the reading of input for jet algorithms
// Authors: jgcn@mda.cinvestav.mx
//          magali.estienne@IReS.in2p3.fr
//------------------------------------------------------------------------

// root
#include <TClonesArray.h>
#include <TRefArray.h>
#include "TTask.h"
//AliRoot
#include "AliJetReader.h"
#include "AliJetReaderHeader.h"
#include "AliESDEvent.h"
#include "AliHeader.h"
#include "AliJetFillUnitArrayTracks.h"
#include "AliJetFillUnitArrayEMCalDigits.h"
#include "AliJetUnitArray.h"
#include "AliJetHadronCorrectionv1.h"

ClassImp(AliJetReader)

////////////////////////////////////////////////////////////////////////

AliJetReader::AliJetReader():
  // Constructor
  fChain(0),
  fTree(0),
  fMomentumArray(new TClonesArray("TLorentzVector",4000)),
  fArrayMC(0),
  fFillUnitArray(new TTask("fillUnitArray","Fill unit array jet finder")),
  fESD(0),
  fReaderHeader(0),
  fAliHeader(0),
  fSignalFlag(0),
  fCutFlag(0),
  fUnitArray(new TClonesArray("AliJetUnitArray",60000)),
  fUnitArrayNoCuts(new TClonesArray("AliJetUnitArray",60000)),
  fArrayInitialised(0),
  fFillUAFromTracks(new AliJetFillUnitArrayTracks()),
  fFillUAFromEMCalDigits(new AliJetFillUnitArrayEMCalDigits()),
  fNumCandidate(0),
  fNumCandidateCut(0),
  fHadronCorrector(0),
  fHCorrection(0),
  fECorrection(0),
  fEFlag(kFALSE)
{
  // Default constructor
  fSignalFlag = TArrayI();
  fCutFlag    = TArrayI();
}

////////////////////////////////////////////////////////////////////////

AliJetReader::~AliJetReader()
{
  // Destructor
  if (fMomentumArray) {
      fMomentumArray->Delete();
      delete fMomentumArray;
  }

  if (fUnitArray) {
      fUnitArray->Delete();
      delete fUnitArray;
  }

  if (fUnitArrayNoCuts) {
    fUnitArrayNoCuts->Delete();
    delete fUnitArrayNoCuts;
  }

  if (fFillUnitArray) {
    delete fFillUnitArray;
  }
  if (fArrayMC) {
      fArrayMC->Delete();
      delete fArrayMC;
  }

}

////////////////////////////////////////////////////////////////////////

void AliJetReader::ClearArray()
{
  if (fMomentumArray)  fMomentumArray->Clear();
  if (fFillUnitArray)  fFillUnitArray->Clear();
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Baidu, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Authors: Ge,Jun (gejun@baidu.com)

#include <gflags/gflags.h>
#include "brpc/reloadable_flags.h"
#include "brpc/load_balancer.h"

namespace brpc {

DEFINE_bool(show_lb_in_vars, false, "Describe LoadBalancers in vars");
BRPC_VALIDATE_GFLAG(show_lb_in_vars, PassValidate);

// For assigning unique names for lb.
static butil::static_atomic<int> g_lb_counter = BUTIL_STATIC_ATOMIC_INIT(0);

void SharedLoadBalancer::DescribeLB(std::ostream& os, void* arg) {
    (static_cast<SharedLoadBalancer*>(arg))->Describe(os, DescribeOptions());
}

void SharedLoadBalancer::ExposeLB() {
    bool changed = false;
    _st_mutex.lock();
    if (!_exposed) {
        _exposed = true;
        changed = true;
    }
    _st_mutex.unlock();
    if (changed) {
        char name[32];
        snprintf(name, sizeof(name), "_load_balancer_%d", g_lb_counter.fetch_add(
                     1, butil::memory_order_relaxed));
        _st.expose(name);
    }
}

SharedLoadBalancer::SharedLoadBalancer()
    : _lb(NULL)
    , _weight_sum(0)
    , _exposed(false)
    , _st(DescribeLB, this) {
}

SharedLoadBalancer::~SharedLoadBalancer() {
    _st.hide();
    if (_lb) {
        _lb->Destroy();
        _lb = NULL;
    }
}

int SharedLoadBalancer::Init(const char* lb_protocol) {
    std::string lb_name;
    butil::StringPairs lb_parms;
    if (!ParseParameters(lb_protocol, &lb_name, &lb_parms)) {
        LOG(FATAL) << "Fail to parse this load balancer protocol '" << lb_protocol << '\'';
        return -1;
    }
    const LoadBalancer* lb = LoadBalancerExtension()->Find(lb_name.c_str());
    if (lb == NULL) {
        LOG(FATAL) << "Fail to find LoadBalancer by `" << lb_name << "'";
        return -1;
    }
    LoadBalancer* lb_copy = lb->New();
    if (lb_copy == NULL) {
        LOG(FATAL) << "Fail to new LoadBalancer";
        return -1;
    }
    _lb = lb_copy;
    if (!_lb->SetParameters(lb_parms)) {
        LOG(FATAL) << "Fail to set parameters of lb `" << lb_protocol << "'";
        return -1;
    }
    if (FLAGS_show_lb_in_vars && !_exposed) {
        ExposeLB();
    }
    return 0;
}

void SharedLoadBalancer::Describe(std::ostream& os,
                                  const DescribeOptions& options) {
    if (_lb == NULL) {
        os << "lb=NULL";
    } else {
        _lb->Describe(os, options);
    }
}

bool SharedLoadBalancer::ParseParameters(const butil::StringPiece& lb_protocol,
                                         std::string* lb_name,
                                         butil::StringPairs* lb_params) {
    lb_name->clear();
    lb_params->clear();
    if (lb_protocol.empty()) {
        return false;
    }
    size_t pos = lb_protocol.find(':');
    if (pos == std::string::npos) {
        lb_name->append(lb_protocol.data(), lb_protocol.size());
    } else {
        lb_name->append(lb_protocol.data(), pos);
        butil::StringPiece params_piece = lb_protocol.substr(pos + sizeof(':'));
        std::string params_str(params_piece.data(), params_piece.size());
        if (!butil::SplitStringIntoKeyValuePairs(params_str, '=', ' ', lb_params)) {
            lb_params->clear();
            return false;
        }
    }

    return true;
}

} // namespace brpc
<commit_msg>fix typo<commit_after>// Copyright (c) 2014 Baidu, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Authors: Ge,Jun (gejun@baidu.com)

#include <gflags/gflags.h>
#include "brpc/reloadable_flags.h"
#include "brpc/load_balancer.h"

namespace brpc {

DEFINE_bool(show_lb_in_vars, false, "Describe LoadBalancers in vars");
BRPC_VALIDATE_GFLAG(show_lb_in_vars, PassValidate);

// For assigning unique names for lb.
static butil::static_atomic<int> g_lb_counter = BUTIL_STATIC_ATOMIC_INIT(0);

void SharedLoadBalancer::DescribeLB(std::ostream& os, void* arg) {
    (static_cast<SharedLoadBalancer*>(arg))->Describe(os, DescribeOptions());
}

void SharedLoadBalancer::ExposeLB() {
    bool changed = false;
    _st_mutex.lock();
    if (!_exposed) {
        _exposed = true;
        changed = true;
    }
    _st_mutex.unlock();
    if (changed) {
        char name[32];
        snprintf(name, sizeof(name), "_load_balancer_%d", g_lb_counter.fetch_add(
                     1, butil::memory_order_relaxed));
        _st.expose(name);
    }
}

SharedLoadBalancer::SharedLoadBalancer()
    : _lb(NULL)
    , _weight_sum(0)
    , _exposed(false)
    , _st(DescribeLB, this) {
}

SharedLoadBalancer::~SharedLoadBalancer() {
    _st.hide();
    if (_lb) {
        _lb->Destroy();
        _lb = NULL;
    }
}

int SharedLoadBalancer::Init(const char* lb_protocol) {
    std::string lb_name;
    butil::StringPairs lb_params;
    if (!ParseParameters(lb_protocol, &lb_name, &lb_params)) {
        LOG(FATAL) << "Fail to parse this load balancer protocol '" << lb_protocol << '\'';
        return -1;
    }
    const LoadBalancer* lb = LoadBalancerExtension()->Find(lb_name.c_str());
    if (lb == NULL) {
        LOG(FATAL) << "Fail to find LoadBalancer by `" << lb_name << "'";
        return -1;
    }
    LoadBalancer* lb_copy = lb->New();
    if (lb_copy == NULL) {
        LOG(FATAL) << "Fail to new LoadBalancer";
        return -1;
    }
    _lb = lb_copy;
    if (!_lb->SetParameters(lb_params)) {
        LOG(FATAL) << "Fail to set parameters of lb `" << lb_protocol << "'";
        return -1;
    }
    if (FLAGS_show_lb_in_vars && !_exposed) {
        ExposeLB();
    }
    return 0;
}

void SharedLoadBalancer::Describe(std::ostream& os,
                                  const DescribeOptions& options) {
    if (_lb == NULL) {
        os << "lb=NULL";
    } else {
        _lb->Describe(os, options);
    }
}

bool SharedLoadBalancer::ParseParameters(const butil::StringPiece& lb_protocol,
                                         std::string* lb_name,
                                         butil::StringPairs* lb_params) {
    lb_name->clear();
    lb_params->clear();
    if (lb_protocol.empty()) {
        return false;
    }
    size_t pos = lb_protocol.find(':');
    if (pos == std::string::npos) {
        lb_name->append(lb_protocol.data(), lb_protocol.size());
    } else {
        lb_name->append(lb_protocol.data(), pos);
        butil::StringPiece params_piece = lb_protocol.substr(pos + sizeof(':'));
        std::string params_str(params_piece.data(), params_piece.size());
        if (!butil::SplitStringIntoKeyValuePairs(params_str, '=', ' ', lb_params)) {
            lb_params->clear();
            return false;
        }
    }

    return true;
}

} // namespace brpc
<|endoftext|>