<commit_before>/*
 * Copyright (c) 2015, 2016, 2017, 2018, Intel Corporation
 *
 * 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.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * 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 COPYRIGHT
 * OWNER 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 LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef __APPLE__
#define _DARWIN_C_SOURCE
#include <sys/types.h>
#include <sys/sysctl.h>
#endif

#include <algorithm>
#include <iostream>
#include <sstream>

#include <float.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "geopm.h"
#include "geopm_message.h"
#include "geopm_time.h"
#include "geopm_signal_handler.h"
#include "geopm_sched.h"
#include "geopm_env.h"
#include "Helper.hpp"
#include "PlatformTopo.hpp"
#include "ProfileSampler.hpp"
#include "ProfileTable.hpp"
#include "ProfileThread.hpp"
#include "SampleScheduler.hpp"
#include "Comm.hpp"
#include "ControlMessage.hpp"
#include "SharedMemory.hpp"
#include "Exception.hpp"
#include "config.h"

static bool geopm_prof_compare(const std::pair<uint64_t, struct geopm_prof_message_s> &aa, const std::pair<uint64_t, struct geopm_prof_message_s> &bb)
{
    return geopm_time_comp(&(aa.second.timestamp), &(bb.second.timestamp));
}

namespace geopm
{
    const struct geopm_prof_message_s GEOPM_INVALID_PROF_MSG = {-1, 0, {{0, 0}}, -1.0};

    ProfileSampler::ProfileSampler(size_t table_size)
        : ProfileSampler(platform_topo(), table_size)
    {
    }

    ProfileSampler::ProfileSampler(IPlatformTopo &topo, size_t table_size)
        : m_table_size(table_size)
        , m_do_report(false)
        , m_tprof_shmem(nullptr)
        , m_tprof_table(nullptr)
        , m_ctl_shmem(nullptr)
        , m_ctl_msg(nullptr)
    {
        std::string sample_key(geopm_env_shmkey());
        sample_key += "-sample";
        std::string sample_key_path("/dev/shm/" + sample_key);
        // Remove shared memory file if one already exists.
        (void)unlink(sample_key_path.c_str());
        m_ctl_shmem = geopm::make_unique<SharedMemory>(sample_key, sizeof(struct geopm_ctl_message_s));
        m_ctl_msg = geopm::make_unique<ControlMessage>(*(struct geopm_ctl_message_s *)m_ctl_shmem->pointer(), true, true);

        std::string tprof_key(geopm_env_shmkey());
        tprof_key += "-tprof";
        std::string tprof_key_path("/dev/shm/" + tprof_key);
        // Remove shared memory file if one already exists.
        (void)unlink(tprof_key_path.c_str());
        size_t tprof_size = 64 * topo.num_domain(IPlatformTopo::M_DOMAIN_CPU);
        m_tprof_shmem = geopm::make_unique<SharedMemory>(tprof_key, tprof_size);
        m_tprof_table = geopm::make_unique<ProfileThreadTable>(tprof_size, m_tprof_shmem->pointer());
        errno = 0; // Ignore errors from the unlink calls.
    }

    ProfileSampler::~ProfileSampler(void)
    {
    }

    void ProfileSampler::initialize(int &rank_per_node)
    {
        std::ostringstream shm_key;

        m_ctl_msg->wait();
        m_ctl_msg->step();
        m_ctl_msg->wait();

        std::set<int> rank_set;
        for (int i = 0; i < GEOPM_MAX_NUM_CPU; i++) {
            if (m_ctl_msg->cpu_rank(i) >= 0) {
                (void) rank_set.insert(m_ctl_msg->cpu_rank(i));
            }
        }

        for (auto it = rank_set.begin(); it != rank_set.end(); ++it) {
            shm_key.str("");
            shm_key << m_ctl_shmem->key() <<  "-"  << *it;
            m_rank_sampler.push_front(geopm::make_unique<ProfileRankSampler>(shm_key.str(), m_table_size));
        }
        rank_per_node = rank_set.size();
        if (rank_per_node == 0) {
            m_ctl_msg->abort();
            throw Exception("ProfileSampler::initialize(): Application ranks were not listed as running on any CPUs.",
                            GEOPM_ERROR_LOGIC, __FILE__, __LINE__);
        }
        m_ctl_msg->step();
        m_ctl_msg->wait();
        m_ctl_msg->step();
    }

    void ProfileSampler::cpu_rank(std::vector<int> &cpu_rank)
    {
        uint32_t num_cpu = geopm_sched_num_cpu();
        cpu_rank.resize(num_cpu);
        if (num_cpu > GEOPM_MAX_NUM_CPU) {
            throw Exception("ProfileSampler::cpu_rank: Number of online CPUs is greater than GEOPM_MAX_NUM_CPU", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }

        for (unsigned cpu = 0; cpu < num_cpu; ++cpu) {
            cpu_rank[cpu] = m_ctl_msg->cpu_rank(cpu);
        }
    }

    size_t ProfileSampler::capacity(void)
    {
        size_t result = 0;
        for (auto it = m_rank_sampler.begin(); it != m_rank_sampler.end(); ++it) {
            result += (*it)->capacity();
        }
        return result;
    }

    void ProfileSampler::sample(std::vector<std::pair<uint64_t, struct geopm_prof_message_s> > &content, size_t &length, std::shared_ptr<IComm> comm)
    {
        length = 0;
        if (m_ctl_msg->is_sample_begin() ||
            m_ctl_msg->is_sample_end()) {
            auto content_it = content.begin();
            for (auto rank_sampler_it = m_rank_sampler.begin();
                 rank_sampler_it != m_rank_sampler.end();
                 ++rank_sampler_it) {
                size_t rank_length = 0;
                (*rank_sampler_it)->sample(content_it, rank_length);
                content_it += rank_length;
                length += rank_length;
            }
            if (m_ctl_msg->is_sample_end()) {
                comm->barrier();
                m_ctl_msg->step();
                while (!m_ctl_msg->is_name_begin() &&
                       !m_ctl_msg->is_shutdown()) {
                    geopm_signal_handler_check();
                }
                if (m_ctl_msg->is_name_begin()) {
                    region_names();
                }
            }
        }
        else if (!m_ctl_msg->is_shutdown()) {
            throw Exception("ProfileSampler: invalid application status, expected shutdown status", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
    }

    bool ProfileSampler::do_shutdown(void)
    {
        return m_ctl_msg->is_shutdown();
    }

    bool ProfileSampler::do_report(void)
    {
        return m_do_report;
    }

    void ProfileSampler::region_names(void)
    {
        m_ctl_msg->step();

        bool is_all_done = false;
        while (!is_all_done) {
            m_ctl_msg->loop_begin();
            m_ctl_msg->wait();
            is_all_done = true;
            for (auto it = m_rank_sampler.begin(); it != m_rank_sampler.end(); ++it) {
                if (!(*it)->name_fill(m_name_set)) {
                    is_all_done = false;
                }
            }
            m_ctl_msg->step();
            if (!is_all_done && m_ctl_msg->is_shutdown()) {
                throw Exception("ProfileSampler::region_names(): Application shutdown while report was being generated", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
            }
        }
        m_rank_sampler.front()->report_name(m_report_name);
        m_rank_sampler.front()->profile_name(m_profile_name);
        m_do_report = true;

        m_ctl_msg->wait();
        m_ctl_msg->step();
        m_ctl_msg->wait();
    }

    void ProfileSampler::name_set(std::set<std::string> &region_name)
    {
        region_name = m_name_set;
    }

    void ProfileSampler::report_name(std::string &report_str)
    {
        report_str = m_report_name;
    }

    void ProfileSampler::profile_name(std::string &prof_str)
    {
        prof_str = m_profile_name;
    }

    std::shared_ptr<IProfileThreadTable> ProfileSampler::tprof_table(void)
    {
        return m_tprof_table;
    }

    ProfileRankSampler::ProfileRankSampler(const std::string shm_key, size_t table_size)
        : m_table_shmem(nullptr)
        , m_table(nullptr)
        , m_region_entry(GEOPM_INVALID_PROF_MSG)
        , m_is_name_finished(false)
    {
        std::string key_path("/dev/shm/" + shm_key);
        (void)unlink(key_path.c_str());
        errno = 0; // Ignore errors from the unlink call.
        m_table_shmem = geopm::make_unique<SharedMemory>(shm_key, table_size);
        m_table = geopm::make_unique<ProfileTable>(m_table_shmem->size(), m_table_shmem->pointer());
    }

    ProfileRankSampler::~ProfileRankSampler()
    {
    }

    size_t ProfileRankSampler::capacity(void)
    {
        return m_table->capacity();
    }

    void ProfileRankSampler::sample(std::vector<std::pair<uint64_t, struct geopm_prof_message_s> >::iterator content_begin, size_t &length)
    {
        m_table->dump(content_begin, length);
        std::stable_sort(content_begin, content_begin + length, geopm_prof_compare);
    }

    bool ProfileRankSampler::name_fill(std::set<std::string> &name_set)
    {
        size_t header_offset = 0;

        if (!m_is_name_finished) {
            if (name_set.empty()) {
                m_report_name = (char *)m_table_shmem->pointer();
                header_offset += m_report_name.length() + 1;
                m_prof_name = (char *)m_table_shmem->pointer() + header_offset;
                header_offset += m_prof_name.length() + 1;
            }
            m_is_name_finished = m_table->name_set(header_offset, name_set);
        }

        return m_is_name_finished;
    }

    void ProfileRankSampler::report_name(std::string &report_str)
    {
        report_str = m_report_name;
    }

    void ProfileRankSampler::profile_name(std::string &prof_str)
    {
        prof_str = m_prof_name;
    }
}
<commit_msg>Fix broken build from c3a145d.<commit_after>/*
 * Copyright (c) 2015, 2016, 2017, 2018, Intel Corporation
 *
 * 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.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * 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 COPYRIGHT
 * OWNER 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 LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef __APPLE__
#define _DARWIN_C_SOURCE
#include <sys/types.h>
#include <sys/sysctl.h>
#endif

#include <algorithm>
#include <iostream>
#include <sstream>

#include <float.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "geopm.h"
#include "geopm_message.h"
#include "geopm_time.h"
#include "geopm_signal_handler.h"
#include "geopm_sched.h"
#include "geopm_env.h"
#include "Helper.hpp"
#include "PlatformTopo.hpp"
#include "ProfileSampler.hpp"
#include "ProfileTable.hpp"
#include "ProfileThread.hpp"
#include "SampleScheduler.hpp"
#include "Comm.hpp"
#include "ControlMessage.hpp"
#include "SharedMemory.hpp"
#include "Exception.hpp"
#include "config.h"

static bool geopm_prof_compare(const std::pair<uint64_t, struct geopm_prof_message_s> &aa, const std::pair<uint64_t, struct geopm_prof_message_s> &bb)
{
    return geopm_time_comp(&(aa.second.timestamp), &(bb.second.timestamp));
}

namespace geopm
{
    const struct geopm_prof_message_s GEOPM_INVALID_PROF_MSG = {-1, 0, {{0, 0}}, -1.0};

    ProfileSampler::ProfileSampler(size_t table_size)
        : ProfileSampler(platform_topo(), table_size)
    {
    }

    ProfileSampler::ProfileSampler(IPlatformTopo &topo, size_t table_size)
        : m_ctl_shmem(nullptr)
        , m_ctl_msg(nullptr)
        , m_table_size(table_size)
        , m_do_report(false)
        , m_tprof_shmem(nullptr)
        , m_tprof_table(nullptr)
    {
        std::string sample_key(geopm_env_shmkey());
        sample_key += "-sample";
        std::string sample_key_path("/dev/shm/" + sample_key);
        // Remove shared memory file if one already exists.
        (void)unlink(sample_key_path.c_str());
        m_ctl_shmem = geopm::make_unique<SharedMemory>(sample_key, sizeof(struct geopm_ctl_message_s));
        m_ctl_msg = geopm::make_unique<ControlMessage>(*(struct geopm_ctl_message_s *)m_ctl_shmem->pointer(), true, true);

        std::string tprof_key(geopm_env_shmkey());
        tprof_key += "-tprof";
        std::string tprof_key_path("/dev/shm/" + tprof_key);
        // Remove shared memory file if one already exists.
        (void)unlink(tprof_key_path.c_str());
        size_t tprof_size = 64 * topo.num_domain(IPlatformTopo::M_DOMAIN_CPU);
        m_tprof_shmem = geopm::make_unique<SharedMemory>(tprof_key, tprof_size);
        m_tprof_table = geopm::make_unique<ProfileThreadTable>(tprof_size, m_tprof_shmem->pointer());
        errno = 0; // Ignore errors from the unlink calls.
    }

    ProfileSampler::~ProfileSampler(void)
    {
    }

    void ProfileSampler::initialize(int &rank_per_node)
    {
        std::ostringstream shm_key;

        m_ctl_msg->wait();
        m_ctl_msg->step();
        m_ctl_msg->wait();

        std::set<int> rank_set;
        for (int i = 0; i < GEOPM_MAX_NUM_CPU; i++) {
            if (m_ctl_msg->cpu_rank(i) >= 0) {
                (void) rank_set.insert(m_ctl_msg->cpu_rank(i));
            }
        }

        for (auto it = rank_set.begin(); it != rank_set.end(); ++it) {
            shm_key.str("");
            shm_key << m_ctl_shmem->key() <<  "-"  << *it;
            m_rank_sampler.push_front(geopm::make_unique<ProfileRankSampler>(shm_key.str(), m_table_size));
        }
        rank_per_node = rank_set.size();
        if (rank_per_node == 0) {
            m_ctl_msg->abort();
            throw Exception("ProfileSampler::initialize(): Application ranks were not listed as running on any CPUs.",
                            GEOPM_ERROR_LOGIC, __FILE__, __LINE__);
        }
        m_ctl_msg->step();
        m_ctl_msg->wait();
        m_ctl_msg->step();
    }

    void ProfileSampler::cpu_rank(std::vector<int> &cpu_rank)
    {
        uint32_t num_cpu = geopm_sched_num_cpu();
        cpu_rank.resize(num_cpu);
        if (num_cpu > GEOPM_MAX_NUM_CPU) {
            throw Exception("ProfileSampler::cpu_rank: Number of online CPUs is greater than GEOPM_MAX_NUM_CPU", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }

        for (unsigned cpu = 0; cpu < num_cpu; ++cpu) {
            cpu_rank[cpu] = m_ctl_msg->cpu_rank(cpu);
        }
    }

    size_t ProfileSampler::capacity(void)
    {
        size_t result = 0;
        for (auto it = m_rank_sampler.begin(); it != m_rank_sampler.end(); ++it) {
            result += (*it)->capacity();
        }
        return result;
    }

    void ProfileSampler::sample(std::vector<std::pair<uint64_t, struct geopm_prof_message_s> > &content, size_t &length, std::shared_ptr<IComm> comm)
    {
        length = 0;
        if (m_ctl_msg->is_sample_begin() ||
            m_ctl_msg->is_sample_end()) {
            auto content_it = content.begin();
            for (auto rank_sampler_it = m_rank_sampler.begin();
                 rank_sampler_it != m_rank_sampler.end();
                 ++rank_sampler_it) {
                size_t rank_length = 0;
                (*rank_sampler_it)->sample(content_it, rank_length);
                content_it += rank_length;
                length += rank_length;
            }
            if (m_ctl_msg->is_sample_end()) {
                comm->barrier();
                m_ctl_msg->step();
                while (!m_ctl_msg->is_name_begin() &&
                       !m_ctl_msg->is_shutdown()) {
                    geopm_signal_handler_check();
                }
                if (m_ctl_msg->is_name_begin()) {
                    region_names();
                }
            }
        }
        else if (!m_ctl_msg->is_shutdown()) {
            throw Exception("ProfileSampler: invalid application status, expected shutdown status", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
    }

    bool ProfileSampler::do_shutdown(void)
    {
        return m_ctl_msg->is_shutdown();
    }

    bool ProfileSampler::do_report(void)
    {
        return m_do_report;
    }

    void ProfileSampler::region_names(void)
    {
        m_ctl_msg->step();

        bool is_all_done = false;
        while (!is_all_done) {
            m_ctl_msg->loop_begin();
            m_ctl_msg->wait();
            is_all_done = true;
            for (auto it = m_rank_sampler.begin(); it != m_rank_sampler.end(); ++it) {
                if (!(*it)->name_fill(m_name_set)) {
                    is_all_done = false;
                }
            }
            m_ctl_msg->step();
            if (!is_all_done && m_ctl_msg->is_shutdown()) {
                throw Exception("ProfileSampler::region_names(): Application shutdown while report was being generated", GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
            }
        }
        m_rank_sampler.front()->report_name(m_report_name);
        m_rank_sampler.front()->profile_name(m_profile_name);
        m_do_report = true;

        m_ctl_msg->wait();
        m_ctl_msg->step();
        m_ctl_msg->wait();
    }

    void ProfileSampler::name_set(std::set<std::string> &region_name)
    {
        region_name = m_name_set;
    }

    void ProfileSampler::report_name(std::string &report_str)
    {
        report_str = m_report_name;
    }

    void ProfileSampler::profile_name(std::string &prof_str)
    {
        prof_str = m_profile_name;
    }

    std::shared_ptr<IProfileThreadTable> ProfileSampler::tprof_table(void)
    {
        return m_tprof_table;
    }

    ProfileRankSampler::ProfileRankSampler(const std::string shm_key, size_t table_size)
        : m_table_shmem(nullptr)
        , m_table(nullptr)
        , m_region_entry(GEOPM_INVALID_PROF_MSG)
        , m_is_name_finished(false)
    {
        std::string key_path("/dev/shm/" + shm_key);
        (void)unlink(key_path.c_str());
        errno = 0; // Ignore errors from the unlink call.
        m_table_shmem = geopm::make_unique<SharedMemory>(shm_key, table_size);
        m_table = geopm::make_unique<ProfileTable>(m_table_shmem->size(), m_table_shmem->pointer());
    }

    ProfileRankSampler::~ProfileRankSampler()
    {
    }

    size_t ProfileRankSampler::capacity(void)
    {
        return m_table->capacity();
    }

    void ProfileRankSampler::sample(std::vector<std::pair<uint64_t, struct geopm_prof_message_s> >::iterator content_begin, size_t &length)
    {
        m_table->dump(content_begin, length);
        std::stable_sort(content_begin, content_begin + length, geopm_prof_compare);
    }

    bool ProfileRankSampler::name_fill(std::set<std::string> &name_set)
    {
        size_t header_offset = 0;

        if (!m_is_name_finished) {
            if (name_set.empty()) {
                m_report_name = (char *)m_table_shmem->pointer();
                header_offset += m_report_name.length() + 1;
                m_prof_name = (char *)m_table_shmem->pointer() + header_offset;
                header_offset += m_prof_name.length() + 1;
            }
            m_is_name_finished = m_table->name_set(header_offset, name_set);
        }

        return m_is_name_finished;
    }

    void ProfileRankSampler::report_name(std::string &report_str)
    {
        report_str = m_report_name;
    }

    void ProfileRankSampler::profile_name(std::string &prof_str)
    {
        prof_str = m_prof_name;
    }
}
<|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 "srciter.hxx"
#include <stdio.h>
#include <tools/fsys.hxx>

//
// class SourceTreeIterator
//

SourceTreeIterator::SourceTreeIterator(const rtl::OString &rRootDirectory)
    : bInExecute( sal_False )
{
    rtl::OUString sRootDirectory(rtl::OStringToOUString(rRootDirectory, RTL_TEXTENCODING_UTF8));
    aRootDirectory = transex::Directory( sRootDirectory );
}

/*****************************************************************************/
SourceTreeIterator::~SourceTreeIterator()
/*****************************************************************************/
{
}

/*****************************************************************************/
void SourceTreeIterator::ExecuteDirectory( transex::Directory& aDirectory )
/*****************************************************************************/
{
    if ( bInExecute ) {
        rtl::OUString sDirName = aDirectory.getDirectoryName();

        static rtl::OUString WCARD1 ( RTL_CONSTASCII_USTRINGPARAM("unxlng") );
        static rtl::OUString WCARD2 ( RTL_CONSTASCII_USTRINGPARAM("unxsol") );
        static rtl::OUString WCARD3 ( RTL_CONSTASCII_USTRINGPARAM("wntmsc") );
        static rtl::OUString WCARD4 ( RTL_CONSTASCII_USTRINGPARAM("common") );
        static rtl::OUString WCARD5 ( RTL_CONSTASCII_USTRINGPARAM("unxmac") );
        static rtl::OUString WCARD6 ( RTL_CONSTASCII_USTRINGPARAM("unxubt") );
        static rtl::OUString WCARD7 ( RTL_CONSTASCII_USTRINGPARAM(".git") );
        static rtl::OUString WCARD8 ( RTL_CONSTASCII_USTRINGPARAM("clone") );
        static rtl::OUString WCARD9 ( RTL_CONSTASCII_USTRINGPARAM("install") );

        if( sDirName.indexOf( WCARD1 , 0 ) > -1 ||
            sDirName.indexOf( WCARD2 , 0 ) > -1 ||
            sDirName.indexOf( WCARD3 , 0 ) > -1 ||
            sDirName.indexOf( WCARD4 , 0 ) > -1 ||
            sDirName.indexOf( WCARD5 , 0 ) > -1 ||
            sDirName.indexOf( WCARD6 , 0 ) > -1 ||
            sDirName.indexOf( WCARD7 , 0 ) > -1 ||
#ifndef WNT
            sDirName.indexOf( WCARD8 , 0 ) > -1 ||
#endif
            sDirName.indexOf( WCARD9 , 0 ) > -1
           )    return;
        //printf("**** %s \n", OUStringToOString( sDirName , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        rtl::OUString sDirNameTmp = aDirectory.getFullName();
        ByteString sDirNameTmpB( rtl::OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

#ifdef WNT
        sDirNameTmpB.Append( ByteString("\\no_localization") );
#else
        sDirNameTmpB.Append( ByteString("/no_localization") );
#endif
        //printf("**** %s \n", OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        DirEntry aDE( sDirNameTmpB.GetBuffer() );
        if( aDE.Exists() )
        {
            //printf("#### no_localization file found ... skipping");
            return;
        }

        aDirectory.setSkipLinks( bSkipLinks );
        aDirectory.readDirectory();
        OnExecuteDirectory( aDirectory.getFullName() );
        if ( aDirectory.getSubDirectories().size() )
            for ( sal_uLong i=0;i < aDirectory.getSubDirectories().size();i++ )
                ExecuteDirectory( aDirectory.getSubDirectories()[ i ] );
    }
}

/*****************************************************************************/
sal_Bool SourceTreeIterator::StartExecute()
/*****************************************************************************/
{

    bInExecute = sal_True;                  // FIXME
    ExecuteDirectory( aRootDirectory );

    if ( bInExecute ) {                 // FIXME
        bInExecute = sal_False;
        return sal_True;
    }
    return sal_False;
}

/*****************************************************************************/
void SourceTreeIterator::EndExecute()
/*****************************************************************************/
{
    bInExecute = sal_False;
}

/*****************************************************************************/
void SourceTreeIterator::OnExecuteDirectory( const rtl::OUString &rDirectory )
/*****************************************************************************/
{
    fprintf( stdout, "%s\n", rtl::OUStringToOString( rDirectory, RTL_TEXTENCODING_UTF8, rDirectory.getLength() ).getStr() );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>exclude wntgcc* directories from searching for translatable files<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 "srciter.hxx"
#include <stdio.h>
#include <tools/fsys.hxx>

//
// class SourceTreeIterator
//

SourceTreeIterator::SourceTreeIterator(const rtl::OString &rRootDirectory)
    : bInExecute( sal_False )
{
    rtl::OUString sRootDirectory(rtl::OStringToOUString(rRootDirectory, RTL_TEXTENCODING_UTF8));
    aRootDirectory = transex::Directory( sRootDirectory );
}

/*****************************************************************************/
SourceTreeIterator::~SourceTreeIterator()
/*****************************************************************************/
{
}

/*****************************************************************************/
void SourceTreeIterator::ExecuteDirectory( transex::Directory& aDirectory )
/*****************************************************************************/
{
    if ( bInExecute ) {
        rtl::OUString sDirName = aDirectory.getDirectoryName();

        static rtl::OUString WCARD1 ( RTL_CONSTASCII_USTRINGPARAM("unxlng") );
        static rtl::OUString WCARD2 ( RTL_CONSTASCII_USTRINGPARAM("unxsol") );
        static rtl::OUString WCARD3 ( RTL_CONSTASCII_USTRINGPARAM("wntmsc") );
        static rtl::OUString WCARD4 ( RTL_CONSTASCII_USTRINGPARAM("common") );
        static rtl::OUString WCARD5 ( RTL_CONSTASCII_USTRINGPARAM("unxmac") );
        static rtl::OUString WCARD6 ( RTL_CONSTASCII_USTRINGPARAM("unxubt") );
        static rtl::OUString WCARD7 ( RTL_CONSTASCII_USTRINGPARAM(".git") );
        static rtl::OUString WCARD8 ( RTL_CONSTASCII_USTRINGPARAM("clone") );
        static rtl::OUString WCARD9 ( RTL_CONSTASCII_USTRINGPARAM("install") );
        static rtl::OUString WCARDA ( RTL_CONSTASCII_USTRINGPARAM("wntgcc") );

        if( sDirName.indexOf( WCARD1 , 0 ) > -1 ||
            sDirName.indexOf( WCARD2 , 0 ) > -1 ||
            sDirName.indexOf( WCARD3 , 0 ) > -1 ||
            sDirName.indexOf( WCARD4 , 0 ) > -1 ||
            sDirName.indexOf( WCARD5 , 0 ) > -1 ||
            sDirName.indexOf( WCARD6 , 0 ) > -1 ||
            sDirName.indexOf( WCARD7 , 0 ) > -1 ||
#ifndef WNT
            sDirName.indexOf( WCARD8 , 0 ) > -1 ||
#endif
            sDirName.indexOf( WCARD9 , 0 ) > -1 ||
            sDirName.indexOf( WCARDA , 0 ) > -1
           )    return;
        //printf("**** %s \n", OUStringToOString( sDirName , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        rtl::OUString sDirNameTmp = aDirectory.getFullName();
        ByteString sDirNameTmpB( rtl::OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

#ifdef WNT
        sDirNameTmpB.Append( ByteString("\\no_localization") );
#else
        sDirNameTmpB.Append( ByteString("/no_localization") );
#endif
        //printf("**** %s \n", OUStringToOString( sDirNameTmp , RTL_TEXTENCODING_UTF8 , sDirName.getLength() ).getStr() );

        DirEntry aDE( sDirNameTmpB.GetBuffer() );
        if( aDE.Exists() )
        {
            //printf("#### no_localization file found ... skipping");
            return;
        }

        aDirectory.setSkipLinks( bSkipLinks );
        aDirectory.readDirectory();
        OnExecuteDirectory( aDirectory.getFullName() );
        if ( aDirectory.getSubDirectories().size() )
            for ( sal_uLong i=0;i < aDirectory.getSubDirectories().size();i++ )
                ExecuteDirectory( aDirectory.getSubDirectories()[ i ] );
    }
}

/*****************************************************************************/
sal_Bool SourceTreeIterator::StartExecute()
/*****************************************************************************/
{

    bInExecute = sal_True;                  // FIXME
    ExecuteDirectory( aRootDirectory );

    if ( bInExecute ) {                 // FIXME
        bInExecute = sal_False;
        return sal_True;
    }
    return sal_False;
}

/*****************************************************************************/
void SourceTreeIterator::EndExecute()
/*****************************************************************************/
{
    bInExecute = sal_False;
}

/*****************************************************************************/
void SourceTreeIterator::OnExecuteDirectory( const rtl::OUString &rDirectory )
/*****************************************************************************/
{
    fprintf( stdout, "%s\n", rtl::OUStringToOString( rDirectory, RTL_TEXTENCODING_UTF8, rDirectory.getLength() ).getStr() );
}

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


<commit_before>/* $Id$ */

testESDtrackCuts(Char_t* dataDir=, Int_t nRuns=10) {

  Char_t str[256];

  gSystem->Load("libESDtrackCuts.so");

  // ########################################################
  // definition of ESD track cuts

  AliESDtrackCuts* trackCuts = new AliESDtrackCuts();
  trackCuts->DefineHistograms(4);

  trackCuts->SetMinNClustersTPC(50);
  trackCuts->SetMaxChi2PerClusterTPC(3.5);
  trackCuts->SetMaxCovDiagonalElements(2,2,0.5,0.5,2);
  trackCuts->SetRequireTPCRefit(kTRUE);

  trackCuts->SetMinNsigmaToVertex(3);
  trackCuts->SetAcceptKingDaughters(kFALSE);

  trackCuts->SetPRange(0.3);

  AliLog::SetClassDebugLevel("AliESDtrackCuts",1);

  // ########################################################
  // definition of used pointers
  TFile* esdFile;
  TTree* esdTree;
  TBranch* esdBranch;

  AliESD* esd = 0;

  // ########################################################
  // get the data dir
  Char_t execDir[256];
  sprintf(execDir,gSystem->pwd());
  TSystemDirectory* baseDir = new TSystemDirectory(".",dataDir);
  TList* dirList            = baseDir->GetListOfFiles();
  Int_t nDirs               = dirList->GetEntries();
  // go back to the dir where this script is executed
  gSystem->cd(execDir);

  // ########################################################
  // loop over runs
  Int_t nRunCounter = 0;
  for (Int_t r=1; r<=nDirs; r++) {

    TSystemFile* presentDir = (TSystemFile*)dirList->At(r);
    if (!presentDir->IsDirectory())
      continue;
    // first check that the files are there
    sprintf(str,"%s/%s",dataDir, presentDir->GetName());
    if ((!gSystem->Which(str,"galice.root")) ||
        (!gSystem->Which(str,"AliESDs.root")))
      continue;

    if (nRunCounter++ >= nRuns)
      break;

    cout << "run #" << nRunCounter << endl;

    // #########################################################
    // setup galice and runloader
    if (gAlice) {
      delete gAlice->GetRunLoader();
      delete gAlice;
      gAlice=0;
    }

    sprintf(str,"%s/run%d/galice.root",dataDir,r);
    AliRunLoader* runLoader = AliRunLoader::Open(str);

    runLoader->LoadgAlice();
    gAlice = runLoader->GetAliRun();
    runLoader->LoadHeader();

    // #########################################################
    // open esd file and get the tree

    sprintf(str,"%s/run%d/AliESDs.root",dataDir,r);
    // close it first to avoid memory leak
    if (esdFile)
      if (esdFile->IsOpen())
        esdFile->Close();

    esdFile = TFile::Open(str);
    esdTree = (TTree*)esdFile->Get("esdTree");
    if (!esdTree)
      continue;
    esdBranch = esdTree->GetBranch("ESD");
    esdBranch->SetAddress(&esd);
    if (!esdBranch)
      continue;

    // ########################################################
    // Magnetic field
    AliTracker::SetFieldMap(gAlice->Field(),kTRUE); // kTRUE means uniform magnetic field

    // ########################################################
    // getting number of events
    Int_t nEvents    = (Int_t)runLoader->GetNumberOfEvents();
    Int_t nESDEvents = esdBranch->GetEntries();

    if (nEvents!=nESDEvents)
      cout << " Warning: Different number of events from runloader and esdtree!!!" << nEvents << " / " << nESDEvents << endl;

    // ########################################################
    // loop over number of events
    cout << " looping over events..." << endl;
    for(Int_t i=1; i<nEvents; i++) {

      esdBranch->GetEntry(i);
      runLoader->GetEvent(i);

      // ########################################################
      // get the EDS vertex
      AliESDVertex* vtxESD = esd->GetVertex();

      Double_t vtxSigma[3];
      vtxESD->GetSigmaXYZ(vtxSigma);

      // ########################################################
      // loop over esd tracks
      Int_t nTracks = esd->GetNumberOfTracks();

      for (Int_t t=0; t<nTracks; t++) {
	AliESDtrack* esdTrack = esd->GetTrack(t);

	//trackCuts->AcceptTrack(esdTrack, vtxESD, esd->GetMagneticField());
	trackCuts->AcceptTrack(esdTrack);

      } // end of track loop
    } // end  of event loop
  } // end of run loop

  TFile* fout = new TFile("out.root","RECREATE");

  trackCuts->SaveHistograms("esd_track_cuts");

  fout->Write();
  fout->Close();

}
<commit_msg>changed to new library<commit_after>/* $Id$ */

testESDtrackCuts(Char_t* dataDir=, Int_t nRuns=10) {

  Char_t str[256];

  gSystem->Load("libPWG0base.so");

  // ########################################################
  // definition of ESD track cuts

  AliESDtrackCuts* trackCuts = new AliESDtrackCuts();
  trackCuts->DefineHistograms(4);

  trackCuts->SetMinNClustersTPC(50);
  trackCuts->SetMaxChi2PerClusterTPC(3.5);
  trackCuts->SetMaxCovDiagonalElements(2,2,0.5,0.5,2);
  trackCuts->SetRequireTPCRefit(kTRUE);

  trackCuts->SetMinNsigmaToVertex(3);
  trackCuts->SetAcceptKingDaughters(kFALSE);

  trackCuts->SetPRange(0.3);

  AliLog::SetClassDebugLevel("AliESDtrackCuts",1);

  // ########################################################
  // definition of used pointers
  TFile* esdFile;
  TTree* esdTree;
  TBranch* esdBranch;

  AliESD* esd = 0;

  // ########################################################
  // get the data dir
  Char_t execDir[256];
  sprintf(execDir,gSystem->pwd());
  TSystemDirectory* baseDir = new TSystemDirectory(".",dataDir);
  TList* dirList            = baseDir->GetListOfFiles();
  Int_t nDirs               = dirList->GetEntries();
  // go back to the dir where this script is executed
  gSystem->cd(execDir);

  // ########################################################
  // loop over runs
  Int_t nRunCounter = 0;
  for (Int_t r=1; r<=nDirs; r++) {

    TSystemFile* presentDir = (TSystemFile*)dirList->At(r);
    if (!presentDir->IsDirectory())
      continue;
    // first check that the files are there
    sprintf(str,"%s/%s",dataDir, presentDir->GetName());
    if ((!gSystem->Which(str,"galice.root")) ||
        (!gSystem->Which(str,"AliESDs.root")))
      continue;

    if (nRunCounter++ >= nRuns)
      break;

    cout << "run #" << nRunCounter << endl;

    // #########################################################
    // setup galice and runloader
    if (gAlice) {
      delete gAlice->GetRunLoader();
      delete gAlice;
      gAlice=0;
    }

    sprintf(str,"%s/run%d/galice.root",dataDir,r);
    AliRunLoader* runLoader = AliRunLoader::Open(str);

    runLoader->LoadgAlice();
    gAlice = runLoader->GetAliRun();
    runLoader->LoadHeader();

    // #########################################################
    // open esd file and get the tree

    sprintf(str,"%s/run%d/AliESDs.root",dataDir,r);
    // close it first to avoid memory leak
    if (esdFile)
      if (esdFile->IsOpen())
        esdFile->Close();

    esdFile = TFile::Open(str);
    esdTree = (TTree*)esdFile->Get("esdTree");
    if (!esdTree)
      continue;
    esdBranch = esdTree->GetBranch("ESD");
    esdBranch->SetAddress(&esd);
    if (!esdBranch)
      continue;

    // ########################################################
    // Magnetic field
    AliTracker::SetFieldMap(gAlice->Field(),kTRUE); // kTRUE means uniform magnetic field

    // ########################################################
    // getting number of events
    Int_t nEvents    = (Int_t)runLoader->GetNumberOfEvents();
    Int_t nESDEvents = esdBranch->GetEntries();

    if (nEvents!=nESDEvents)
      cout << " Warning: Different number of events from runloader and esdtree!!!" << nEvents << " / " << nESDEvents << endl;

    // ########################################################
    // loop over number of events
    cout << " looping over events..." << endl;
    for(Int_t i=1; i<nEvents; i++) {

      esdBranch->GetEntry(i);
      runLoader->GetEvent(i);

      // ########################################################
      // get the EDS vertex
      AliESDVertex* vtxESD = esd->GetVertex();

      Double_t vtxSigma[3];
      vtxESD->GetSigmaXYZ(vtxSigma);

      // ########################################################
      // loop over esd tracks
      Int_t nTracks = esd->GetNumberOfTracks();

      for (Int_t t=0; t<nTracks; t++) {
	AliESDtrack* esdTrack = esd->GetTrack(t);

	//trackCuts->AcceptTrack(esdTrack, vtxESD, esd->GetMagneticField());
	trackCuts->AcceptTrack(esdTrack);

      } // end of track loop
    } // end  of event loop
  } // end of run loop

  TFile* fout = new TFile("out.root","RECREATE");

  trackCuts->SaveHistograms("esd_track_cuts");

  fout->Write();
  fout->Close();

}
<|endoftext|>


<commit_before>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

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 COPYRIGHT HOLDER 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.

*/

#ifndef ROUTED_OPTIONS_HPP
#define ROUTED_OPTIONS_HPP

#include "git_sha.hpp"
#include "ini_file.hpp"
#include "osrm_exception.hpp"
#include "simple_logger.hpp"

#include <boost/any.hpp>
#include <boost/program_options.hpp>

#include <osrm/server_paths.hpp>

#include <fstream>
#include <string>
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;

inline void populate_base_path(ServerPaths &server_paths)
{
    // populate the server_path object
    auto path_iterator = server_paths.find("base");

    // if a base path has been set, we populate it.
    if (path_iterator != server_paths.end())
    {
        const std::string base_string = path_iterator->second.string();
        SimpleLogger().Write() << "populating base path: " << base_string;

        server_paths["hsgrdata"] = base_string + ".hsgr";
        BOOST_ASSERT(server_paths.find("hsgrdata") != server_paths.end());
        server_paths["nodesdata"] = base_string + ".nodes";
        BOOST_ASSERT(server_paths.find("nodesdata") != server_paths.end());
        server_paths["edgesdata"] = base_string + ".edges";
        BOOST_ASSERT(server_paths.find("edgesdata") != server_paths.end());
        server_paths["geometries"] = base_string + ".geometry";
        BOOST_ASSERT(server_paths.find("geometries") != server_paths.end());
        server_paths["ramindex"] = base_string + ".ramIndex";
        BOOST_ASSERT(server_paths.find("ramindex") != server_paths.end());
        server_paths["fileindex"] = base_string + ".fileIndex";
        BOOST_ASSERT(server_paths.find("fileindex") != server_paths.end());
        server_paths["namesdata"] = base_string + ".names";
        BOOST_ASSERT(server_paths.find("namesdata") != server_paths.end());
        server_paths["timestamp"] = base_string + ".timestamp";
        BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
    }

    // check if files are give and whether they exist at all
    path_iterator = server_paths.find("hsgrdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        if (path_iterator == server_paths.end())
        {
            SimpleLogger().Write() << "hsgrdata unset";
        }
        if (!boost::filesystem::is_regular_file(path_iterator->second))
        {
            SimpleLogger().Write() << "not a regular file";
        }

        throw osrm::exception(".hsgr not found: " + path_iterator->second.string());
    }

    path_iterator = server_paths.find("nodesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".nodes not found");
    }

    path_iterator = server_paths.find("edgesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".edges not found");
    }

    path_iterator = server_paths.find("geometries");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".geometry not found");
    }

    path_iterator = server_paths.find("ramindex");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".ramIndex not found");
    }

    path_iterator = server_paths.find("fileindex");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".fileIndex not found");
    }

    path_iterator = server_paths.find("namesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".namesIndex not found");
    }

    SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
    SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
    SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
    SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
    SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
    SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
    SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
    SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
}

// generate boost::program_options object for the routing part
inline unsigned GenerateServerProgramOptions(const int argc,
                                             const char *argv[],
                                             ServerPaths &paths,
                                             std::string &ip_address,
                                             int &ip_port,
                                             int &requested_num_threads,
                                             bool &use_shared_memory,
                                             bool &trial,
                                             int &max_locations_distance_table,
                                             int &max_locations_map_matching)
{
    // declare a group of options that will be allowed only on command line
    boost::program_options::options_description generic_options("Options");
    generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
        "config,c", boost::program_options::value<boost::filesystem::path>(&paths["config"])
                        ->default_value("server.ini"),
        "Path to a configuration file")(
        "trial", boost::program_options::value<bool>(&trial)->implicit_value(true),
        "Quit after initialization");

    // declare a group of options that will be allowed both on command line
    // as well as in a config file
    boost::program_options::options_description config_options("Configuration");
    config_options.add_options()
        ("hsgrdata", boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
            ".hsgr file")
        ("nodesdata", boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
            ".nodes file")
        ("edgesdata", boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
            ".edges file")
        ("geometry", boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
            ".geometry file")
        ("ramindex", boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
            ".ramIndex file")
        ("fileindex", boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
            "File index file")
        ("namesdata", boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
            ".names file")
        ("timestamp", boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
           ".timestamp file")
        ("ip,i", boost::program_options::value<std::string>(&ip_address)->default_value("0.0.0.0"),
            "IP address")
        ("port,p", boost::program_options::value<int>(&ip_port)->default_value(5000),
            "TCP/IP port")
        ("threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8),
            "Number of threads to use")
        ("shared-memory,s", boost::program_options::value<bool>(&use_shared_memory)->implicit_value(true),
            "Load data from shared memory")
        ("max-table-size,m", boost::program_options::value<int>(&max_locations_distance_table)->default_value(100),
            "Max. locations supported in distance table query")
        ("max-matching-size,m", boost::program_options::value<int>(&max_locations_map_matching)->default_value(-1),
            "Max. locations supported in map matching query");

    // hidden options, will be allowed both on command line and in config
    // file, but will not be shown to the user
    boost::program_options::options_description hidden_options("Hidden options");
    hidden_options.add_options()(
        "base,b", boost::program_options::value<boost::filesystem::path>(&paths["base"]),
        "base path to .osrm file");

    // positional option
    boost::program_options::positional_options_description positional_options;
    positional_options.add("base", 1);

    // combine above options for parsing
    boost::program_options::options_description cmdline_options;
    cmdline_options.add(generic_options).add(config_options).add(hidden_options);

    boost::program_options::options_description config_file_options;
    config_file_options.add(config_options).add(hidden_options);

    boost::program_options::options_description visible_options(
        boost::filesystem::basename(argv[0]) + " <base.osrm> [<options>]");
    visible_options.add(generic_options).add(config_options);

    // parse command line options
    boost::program_options::variables_map option_variables;
    boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
                                      .options(cmdline_options)
                                      .positional(positional_options)
                                      .run(),
                                  option_variables);

    if (option_variables.count("version"))
    {
        SimpleLogger().Write() << g_GIT_DESCRIPTION;
        return INIT_OK_DO_NOT_START_ENGINE;
    }

    if (option_variables.count("help"))
    {
        SimpleLogger().Write() << visible_options;
        return INIT_OK_DO_NOT_START_ENGINE;
    }

    boost::program_options::notify(option_variables);

    // parse config file
    ServerPaths::iterator path_iterator = paths.find("config");
    if (path_iterator != paths.end() && boost::filesystem::is_regular_file(path_iterator->second) &&
        !option_variables.count("base"))
    {
        SimpleLogger().Write() << "Reading options from: " << path_iterator->second.string();
        std::string ini_file_contents = read_file_lower_content(path_iterator->second);
        std::stringstream config_stream(ini_file_contents);
        boost::program_options::store(parse_config_file(config_stream, config_file_options),
                                      option_variables);
        boost::program_options::notify(option_variables);
        return INIT_OK_START_ENGINE;
    }

    if (1 > requested_num_threads)
    {
        throw osrm::exception("Number of threads must be a positive number");
    }

    if (!use_shared_memory && option_variables.count("base"))
    {
        return INIT_OK_START_ENGINE;
    }
    if (use_shared_memory && !option_variables.count("base"))
    {
        return INIT_OK_START_ENGINE;
    }
    if (1 > max_locations_distance_table)
    {
        throw osrm::exception("Max location for distance table must be a positive number");
    }
    if (2 > max_locations_map_matching)
    {
        throw osrm::exception("Max location for map matching must be at least two");
    }

    SimpleLogger().Write() << visible_options;
    return INIT_OK_DO_NOT_START_ENGINE;
}

#endif // ROUTED_OPTIONS_HPP
<commit_msg>fix default value for max_locations_map_matching<commit_after>/*

Copyright (c) 2015, Project OSRM contributors
All rights reserved.

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 COPYRIGHT HOLDER 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.

*/

#ifndef ROUTED_OPTIONS_HPP
#define ROUTED_OPTIONS_HPP

#include "git_sha.hpp"
#include "ini_file.hpp"
#include "osrm_exception.hpp"
#include "simple_logger.hpp"

#include <boost/any.hpp>
#include <boost/program_options.hpp>

#include <osrm/server_paths.hpp>

#include <fstream>
#include <string>
const static unsigned INIT_OK_START_ENGINE = 0;
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
const static unsigned INIT_FAILED = -1;

inline void populate_base_path(ServerPaths &server_paths)
{
    // populate the server_path object
    auto path_iterator = server_paths.find("base");

    // if a base path has been set, we populate it.
    if (path_iterator != server_paths.end())
    {
        const std::string base_string = path_iterator->second.string();
        SimpleLogger().Write() << "populating base path: " << base_string;

        server_paths["hsgrdata"] = base_string + ".hsgr";
        BOOST_ASSERT(server_paths.find("hsgrdata") != server_paths.end());
        server_paths["nodesdata"] = base_string + ".nodes";
        BOOST_ASSERT(server_paths.find("nodesdata") != server_paths.end());
        server_paths["edgesdata"] = base_string + ".edges";
        BOOST_ASSERT(server_paths.find("edgesdata") != server_paths.end());
        server_paths["geometries"] = base_string + ".geometry";
        BOOST_ASSERT(server_paths.find("geometries") != server_paths.end());
        server_paths["ramindex"] = base_string + ".ramIndex";
        BOOST_ASSERT(server_paths.find("ramindex") != server_paths.end());
        server_paths["fileindex"] = base_string + ".fileIndex";
        BOOST_ASSERT(server_paths.find("fileindex") != server_paths.end());
        server_paths["namesdata"] = base_string + ".names";
        BOOST_ASSERT(server_paths.find("namesdata") != server_paths.end());
        server_paths["timestamp"] = base_string + ".timestamp";
        BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
    }

    // check if files are give and whether they exist at all
    path_iterator = server_paths.find("hsgrdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        if (path_iterator == server_paths.end())
        {
            SimpleLogger().Write() << "hsgrdata unset";
        }
        if (!boost::filesystem::is_regular_file(path_iterator->second))
        {
            SimpleLogger().Write() << "not a regular file";
        }

        throw osrm::exception(".hsgr not found: " + path_iterator->second.string());
    }

    path_iterator = server_paths.find("nodesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".nodes not found");
    }

    path_iterator = server_paths.find("edgesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".edges not found");
    }

    path_iterator = server_paths.find("geometries");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".geometry not found");
    }

    path_iterator = server_paths.find("ramindex");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".ramIndex not found");
    }

    path_iterator = server_paths.find("fileindex");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".fileIndex not found");
    }

    path_iterator = server_paths.find("namesdata");
    if (path_iterator == server_paths.end() ||
        !boost::filesystem::is_regular_file(path_iterator->second))
    {
        throw osrm::exception(".namesIndex not found");
    }

    SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
    SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
    SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
    SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
    SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
    SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
    SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
    SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
}

// generate boost::program_options object for the routing part
inline unsigned GenerateServerProgramOptions(const int argc,
                                             const char *argv[],
                                             ServerPaths &paths,
                                             std::string &ip_address,
                                             int &ip_port,
                                             int &requested_num_threads,
                                             bool &use_shared_memory,
                                             bool &trial,
                                             int &max_locations_distance_table,
                                             int &max_locations_map_matching)
{
    // declare a group of options that will be allowed only on command line
    boost::program_options::options_description generic_options("Options");
    generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
        "config,c", boost::program_options::value<boost::filesystem::path>(&paths["config"])
                        ->default_value("server.ini"),
        "Path to a configuration file")(
        "trial", boost::program_options::value<bool>(&trial)->implicit_value(true),
        "Quit after initialization");

    // declare a group of options that will be allowed both on command line
    // as well as in a config file
    boost::program_options::options_description config_options("Configuration");
    config_options.add_options()(
        "hsgrdata", boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
        ".hsgr file")("nodesdata",
                      boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
                      ".nodes file")(
        "edgesdata", boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
        ".edges file")("geometry",
                       boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
                       ".geometry file")(
        "ramindex", boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
        ".ramIndex file")(
        "fileindex", boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
        "File index file")(
        "namesdata", boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
        ".names file")("timestamp",
                       boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
                       ".timestamp file")(
        "ip,i", boost::program_options::value<std::string>(&ip_address)->default_value("0.0.0.0"),
        "IP address")("port,p", boost::program_options::value<int>(&ip_port)->default_value(5000),
                      "TCP/IP port")(
        "threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8),
        "Number of threads to use")(
        "shared-memory,s",
        boost::program_options::value<bool>(&use_shared_memory)->implicit_value(true),
        "Load data from shared memory")(
        "max-table-size,m",
        boost::program_options::value<int>(&max_locations_distance_table)->default_value(100),
        "Max. locations supported in distance table query")(
        "max-matching-size,m",
        boost::program_options::value<int>(&max_locations_map_matching)->default_value(2),
        "Max. locations supported in map matching query");

    // hidden options, will be allowed both on command line and in config
    // file, but will not be shown to the user
    boost::program_options::options_description hidden_options("Hidden options");
    hidden_options.add_options()(
        "base,b", boost::program_options::value<boost::filesystem::path>(&paths["base"]),
        "base path to .osrm file");

    // positional option
    boost::program_options::positional_options_description positional_options;
    positional_options.add("base", 1);

    // combine above options for parsing
    boost::program_options::options_description cmdline_options;
    cmdline_options.add(generic_options).add(config_options).add(hidden_options);

    boost::program_options::options_description config_file_options;
    config_file_options.add(config_options).add(hidden_options);

    boost::program_options::options_description visible_options(
        boost::filesystem::basename(argv[0]) + " <base.osrm> [<options>]");
    visible_options.add(generic_options).add(config_options);

    // parse command line options
    boost::program_options::variables_map option_variables;
    boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
                                      .options(cmdline_options)
                                      .positional(positional_options)
                                      .run(),
                                  option_variables);

    if (option_variables.count("version"))
    {
        SimpleLogger().Write() << g_GIT_DESCRIPTION;
        return INIT_OK_DO_NOT_START_ENGINE;
    }

    if (option_variables.count("help"))
    {
        SimpleLogger().Write() << visible_options;
        return INIT_OK_DO_NOT_START_ENGINE;
    }

    boost::program_options::notify(option_variables);

    // parse config file
    ServerPaths::iterator path_iterator = paths.find("config");
    if (path_iterator != paths.end() && boost::filesystem::is_regular_file(path_iterator->second) &&
        !option_variables.count("base"))
    {
        SimpleLogger().Write() << "Reading options from: " << path_iterator->second.string();
        std::string ini_file_contents = read_file_lower_content(path_iterator->second);
        std::stringstream config_stream(ini_file_contents);
        boost::program_options::store(parse_config_file(config_stream, config_file_options),
                                      option_variables);
        boost::program_options::notify(option_variables);
        return INIT_OK_START_ENGINE;
    }

    if (1 > requested_num_threads)
    {
        throw osrm::exception("Number of threads must be a positive number");
    }

    if (!use_shared_memory && option_variables.count("base"))
    {
        return INIT_OK_START_ENGINE;
    }
    if (use_shared_memory && !option_variables.count("base"))
    {
        return INIT_OK_START_ENGINE;
    }
    if (1 > max_locations_distance_table)
    {
        throw osrm::exception("Max location for distance table must be a positive number");
    }
    if (2 > max_locations_map_matching)
    {
        throw osrm::exception("Max location for map matching must be at least two");
    }

    SimpleLogger().Write() << visible_options;
    return INIT_OK_DO_NOT_START_ENGINE;
}

#endif // ROUTED_OPTIONS_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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 COPYRIGHT
 * OWNER 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.
 *
 * Authors: Nathan Binkert
 */

#include <fstream>
#include <iomanip>
#include <list>
#include <map>
#include <string>

#include "base/callback.hh"
#include "base/cprintf.hh"
#include "base/debug.hh"
#include "base/hostinfo.hh"
#include "base/misc.hh"
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
#include "base/trace.hh"

using namespace std;

namespace Stats {

std::string Info::separatorString = "::";

// We wrap these in a function to make sure they're built in time.
list<Info *> &
statsList()
{
    static list<Info *> the_list;
    return the_list;
}

MapType &
statsMap()
{
    static MapType the_map;
    return the_map;
}

void
InfoAccess::setInfo(Info *info)
{
    if (statsMap().find(this) != statsMap().end())
        panic("shouldn't register stat twice!");

    statsList().push_back(info);

#ifndef NDEBUG
    pair<MapType::iterator, bool> result =
#endif
        statsMap().insert(make_pair(this, info));
    assert(result.second && "this should never fail");
    assert(statsMap().find(this) != statsMap().end());
}

void
InfoAccess::setParams(const StorageParams *params)
{
    info()->storageParams = params;
}

void
InfoAccess::setInit()
{
    info()->flags.set(init);
}

Info *
InfoAccess::info()
{
    MapType::const_iterator i = statsMap().find(this);
    assert(i != statsMap().end());
    return (*i).second;
}

const Info *
InfoAccess::info() const
{
    MapType::const_iterator i = statsMap().find(this);
    assert(i != statsMap().end());
    return (*i).second;
}

StorageParams::~StorageParams()
{
}

NameMapType &
nameMap()
{
    static NameMapType the_map;
    return the_map;
}

int Info::id_count = 0;

int debug_break_id = -1;

Info::Info()
    : flags(none), precision(-1), prereq(0), storageParams(NULL)
{
    id = id_count++;
    if (debug_break_id >= 0 and debug_break_id == id)
        Debug::breakpoint();
}

Info::~Info()
{
}

bool
validateStatName(const string &name)
{
    if (name.empty())
        return false;

    vector<string> vec;
    tokenize(vec, name, '.');
    vector<string>::const_iterator item = vec.begin();
    while (item != vec.end()) {
        if (item->empty())
            return false;

        string::const_iterator c = item->begin();

        // The first character is different
        if (!isalpha(*c) && *c != '_')
            return false;

        // The rest of the characters have different rules.
        while (++c != item->end()) {
            if (!isalnum(*c) && *c != '_')
                return false;
        }

        ++item;
    }

    return true;
}

void
Info::setName(const string &name)
{
    if (!validateStatName(name))
        panic("invalid stat name '%s'", name);

    pair<NameMapType::iterator, bool> p =
        nameMap().insert(make_pair(name, this));

    Info *other = p.first->second;
    bool result = p.second;

    if (!result) {
      // using other->name instead of just name to avoid a compiler
      // warning.  They should be the same.
        panic("same statistic name used twice! name=%s\n", other->name);
    }

    this->name = name;
}

bool
Info::less(Info *stat1, Info *stat2)
{
    const string &name1 = stat1->name;
    const string &name2 = stat2->name;

    vector<string> v1;
    vector<string> v2;

    tokenize(v1, name1, '.');
    tokenize(v2, name2, '.');

    size_type last = min(v1.size(), v2.size()) - 1;
    for (off_type i = 0; i < last; ++i)
        if (v1[i] != v2[i])
            return v1[i] < v2[i];

    // Special compare for last element.
    if (v1[last] == v2[last])
        return v1.size() < v2.size();
    else
        return v1[last] < v2[last];

    return false;
}

bool
Info::baseCheck() const
{
    if (!(flags & Stats::init)) {
#ifdef DEBUG
        cprintf("this is stat number %d\n", id);
#endif
        panic("Not all stats have been initialized");
        return false;
    }

    if ((flags & display) && name.empty()) {
        panic("all printable stats must be named");
        return false;
    }

    return true;
}

void
Info::enable()
{
}

void
VectorInfo::enable()
{
    size_type s = size();
    if (subnames.size() < s)
        subnames.resize(s);
    if (subdescs.size() < s)
        subdescs.resize(s);
}

void
VectorDistInfo::enable()
{
    size_type s = size();
    if (subnames.size() < s)
        subnames.resize(s);
    if (subdescs.size() < s)
        subdescs.resize(s);
}

void
Vector2dInfo::enable()
{
    if (subnames.size() < x)
        subnames.resize(x);
    if (subdescs.size() < x)
        subdescs.resize(x);
    if (y_subnames.size() < y)
        y_subnames.resize(y);
}

void
HistStor::grow_out()
{
    int size = cvec.size();
    int zero = size / 2; // round down!
    int top_half = zero + (size - zero + 1) / 2; // round up!
    int bottom_half = (size - zero) / 2; // round down!

    // grow down
    int low_pair = zero - 1;
    for (int i = zero - 1; i >= bottom_half; i--) {
        cvec[i] = cvec[low_pair];
        if (low_pair - 1 >= 0)
            cvec[i] += cvec[low_pair - 1];
        low_pair -= 2;
    }
    assert(low_pair == 0 || low_pair == -1 || low_pair == -2);

    for (int i = bottom_half - 1; i >= 0; i--)
        cvec[i] = Counter();

    // grow up
    int high_pair = zero;
    for (int i = zero; i < top_half; i++) {
        cvec[i] = cvec[high_pair];
        if (high_pair + 1 < size)
            cvec[i] += cvec[high_pair + 1];
        high_pair += 2;
    }
    assert(high_pair == size || high_pair == size + 1);

    for (int i = top_half; i < size; i++)
        cvec[i] = Counter();

    max_bucket *= 2;
    min_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::grow_convert()
{
    int size = cvec.size();
    int half = (size + 1) / 2; // round up!
    //bool even = (size & 1) == 0;

    int pair = size - 1;
    for (int i = size - 1; i >= half; --i) {
        cvec[i] = cvec[pair];
        if (pair - 1 >= 0)
            cvec[i] += cvec[pair - 1];
        pair -= 2;
    }

    for (int i = half - 1; i >= 0; i--)
        cvec[i] = Counter();

    min_bucket = -max_bucket;// - (even ? bucket_size : 0);
    bucket_size *= 2;
}

void
HistStor::grow_up()
{
    int size = cvec.size();
    int half = (size + 1) / 2; // round up!

    int pair = 0;
    for (int i = 0; i < half; i++) {
        cvec[i] = cvec[pair];
        if (pair + 1 < size)
            cvec[i] += cvec[pair + 1];
        pair += 2;
    }
    assert(pair == size || pair == size + 1);

    for (int i = half; i < size; i++)
        cvec[i] = Counter();

    max_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::add(HistStor *hs)
{
    int b_size = hs->size();
    assert(size() == b_size);
    assert(min_bucket == hs->min_bucket);

    sum += hs->sum;
    logs += hs->logs;
    squares += hs->squares;
    samples += hs->samples;

    while (bucket_size > hs->bucket_size)
        hs->grow_up();
    while (bucket_size < hs->bucket_size)
        grow_up();

    for (uint32_t i = 0; i < b_size; i++)
        cvec[i] += hs->cvec[i];
}

Formula::Formula()
{
}

Formula::Formula(Temp r)
{
    root = r.getNodePtr();
    setInit();
    assert(size());
}

const Formula &
Formula::operator=(Temp r)
{
    assert(!root && "Can't change formulas");
    root = r.getNodePtr();
    setInit();
    assert(size());
    return *this;
}

const Formula &
Formula::operator+=(Temp r)
{
    if (root)
        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
    else {
        root = r.getNodePtr();
        setInit();
    }

    assert(size());
    return *this;
}

const Formula &
Formula::operator/=(Temp r)
{
    assert (root);
    root = NodePtr(new BinaryNode<std::divides<Result> >(root, r));

    assert(size());
    return *this;
}

void
Formula::result(VResult &vec) const
{
    if (root)
        vec = root->result();
}

Result
Formula::total() const
{
    return root ? root->total() : 0.0;
}

size_type
Formula::size() const
{
    if (!root)
        return 0;
    else
        return root->size();
}

void
Formula::reset()
{
}

bool
Formula::zero() const
{
    VResult vec;
    result(vec);
    for (VResult::size_type i = 0; i < vec.size(); ++i)
        if (vec[i] != 0.0)
            return false;
    return true;
}

string
Formula::str() const
{
    return root ? root->str() : "";
}

Handler resetHandler = NULL;
Handler dumpHandler = NULL;

void
registerHandlers(Handler reset_handler, Handler dump_handler)
{
    resetHandler = reset_handler;
    dumpHandler = dump_handler;
}

CallbackQueue dumpQueue;
CallbackQueue resetQueue;

void
processResetQueue()
{
    resetQueue.process();
}

void
processDumpQueue()
{
    dumpQueue.process();
}

void
registerResetCallback(Callback *cb)
{
    resetQueue.add(cb);
}

bool _enabled = false;

bool
enabled()
{
    return _enabled;
}

void
enable()
{
    if (_enabled)
        fatal("Stats are already enabled");

    _enabled = true;
}

void
dump()
{
    if (dumpHandler)
        dumpHandler();
    else
        fatal("No registered Stats::dump handler");
}

void
reset()
{
    if (resetHandler)
        resetHandler();
    else
        fatal("No registered Stats::reset handler");
}

void
registerDumpCallback(Callback *cb)
{
    dumpQueue.add(cb);
}

} // namespace Stats

void
debugDumpStats()
{
    Stats::dump();
}
<commit_msg>stats: Add more information to uninitialized error<commit_after>/*
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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 COPYRIGHT
 * OWNER 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.
 *
 * Authors: Nathan Binkert
 */

#include <fstream>
#include <iomanip>
#include <list>
#include <map>
#include <string>

#include "base/callback.hh"
#include "base/cprintf.hh"
#include "base/debug.hh"
#include "base/hostinfo.hh"
#include "base/misc.hh"
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
#include "base/trace.hh"

using namespace std;

namespace Stats {

std::string Info::separatorString = "::";

// We wrap these in a function to make sure they're built in time.
list<Info *> &
statsList()
{
    static list<Info *> the_list;
    return the_list;
}

MapType &
statsMap()
{
    static MapType the_map;
    return the_map;
}

void
InfoAccess::setInfo(Info *info)
{
    if (statsMap().find(this) != statsMap().end())
        panic("shouldn't register stat twice!");

    statsList().push_back(info);

#ifndef NDEBUG
    pair<MapType::iterator, bool> result =
#endif
        statsMap().insert(make_pair(this, info));
    assert(result.second && "this should never fail");
    assert(statsMap().find(this) != statsMap().end());
}

void
InfoAccess::setParams(const StorageParams *params)
{
    info()->storageParams = params;
}

void
InfoAccess::setInit()
{
    info()->flags.set(init);
}

Info *
InfoAccess::info()
{
    MapType::const_iterator i = statsMap().find(this);
    assert(i != statsMap().end());
    return (*i).second;
}

const Info *
InfoAccess::info() const
{
    MapType::const_iterator i = statsMap().find(this);
    assert(i != statsMap().end());
    return (*i).second;
}

StorageParams::~StorageParams()
{
}

NameMapType &
nameMap()
{
    static NameMapType the_map;
    return the_map;
}

int Info::id_count = 0;

int debug_break_id = -1;

Info::Info()
    : flags(none), precision(-1), prereq(0), storageParams(NULL)
{
    id = id_count++;
    if (debug_break_id >= 0 and debug_break_id == id)
        Debug::breakpoint();
}

Info::~Info()
{
}

bool
validateStatName(const string &name)
{
    if (name.empty())
        return false;

    vector<string> vec;
    tokenize(vec, name, '.');
    vector<string>::const_iterator item = vec.begin();
    while (item != vec.end()) {
        if (item->empty())
            return false;

        string::const_iterator c = item->begin();

        // The first character is different
        if (!isalpha(*c) && *c != '_')
            return false;

        // The rest of the characters have different rules.
        while (++c != item->end()) {
            if (!isalnum(*c) && *c != '_')
                return false;
        }

        ++item;
    }

    return true;
}

void
Info::setName(const string &name)
{
    if (!validateStatName(name))
        panic("invalid stat name '%s'", name);

    pair<NameMapType::iterator, bool> p =
        nameMap().insert(make_pair(name, this));

    Info *other = p.first->second;
    bool result = p.second;

    if (!result) {
      // using other->name instead of just name to avoid a compiler
      // warning.  They should be the same.
        panic("same statistic name used twice! name=%s\n", other->name);
    }

    this->name = name;
}

bool
Info::less(Info *stat1, Info *stat2)
{
    const string &name1 = stat1->name;
    const string &name2 = stat2->name;

    vector<string> v1;
    vector<string> v2;

    tokenize(v1, name1, '.');
    tokenize(v2, name2, '.');

    size_type last = min(v1.size(), v2.size()) - 1;
    for (off_type i = 0; i < last; ++i)
        if (v1[i] != v2[i])
            return v1[i] < v2[i];

    // Special compare for last element.
    if (v1[last] == v2[last])
        return v1.size() < v2.size();
    else
        return v1[last] < v2[last];

    return false;
}

bool
Info::baseCheck() const
{
    if (!(flags & Stats::init)) {
#ifdef DEBUG
        cprintf("this is stat number %d\n", id);
#endif
        panic("Not all stats have been initialized.\n"
              "You may need to add <ParentClass>::regStats() to a"
              " new SimObject's regStats() function.");
        return false;
    }

    if ((flags & display) && name.empty()) {
        panic("all printable stats must be named");
        return false;
    }

    return true;
}

void
Info::enable()
{
}

void
VectorInfo::enable()
{
    size_type s = size();
    if (subnames.size() < s)
        subnames.resize(s);
    if (subdescs.size() < s)
        subdescs.resize(s);
}

void
VectorDistInfo::enable()
{
    size_type s = size();
    if (subnames.size() < s)
        subnames.resize(s);
    if (subdescs.size() < s)
        subdescs.resize(s);
}

void
Vector2dInfo::enable()
{
    if (subnames.size() < x)
        subnames.resize(x);
    if (subdescs.size() < x)
        subdescs.resize(x);
    if (y_subnames.size() < y)
        y_subnames.resize(y);
}

void
HistStor::grow_out()
{
    int size = cvec.size();
    int zero = size / 2; // round down!
    int top_half = zero + (size - zero + 1) / 2; // round up!
    int bottom_half = (size - zero) / 2; // round down!

    // grow down
    int low_pair = zero - 1;
    for (int i = zero - 1; i >= bottom_half; i--) {
        cvec[i] = cvec[low_pair];
        if (low_pair - 1 >= 0)
            cvec[i] += cvec[low_pair - 1];
        low_pair -= 2;
    }
    assert(low_pair == 0 || low_pair == -1 || low_pair == -2);

    for (int i = bottom_half - 1; i >= 0; i--)
        cvec[i] = Counter();

    // grow up
    int high_pair = zero;
    for (int i = zero; i < top_half; i++) {
        cvec[i] = cvec[high_pair];
        if (high_pair + 1 < size)
            cvec[i] += cvec[high_pair + 1];
        high_pair += 2;
    }
    assert(high_pair == size || high_pair == size + 1);

    for (int i = top_half; i < size; i++)
        cvec[i] = Counter();

    max_bucket *= 2;
    min_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::grow_convert()
{
    int size = cvec.size();
    int half = (size + 1) / 2; // round up!
    //bool even = (size & 1) == 0;

    int pair = size - 1;
    for (int i = size - 1; i >= half; --i) {
        cvec[i] = cvec[pair];
        if (pair - 1 >= 0)
            cvec[i] += cvec[pair - 1];
        pair -= 2;
    }

    for (int i = half - 1; i >= 0; i--)
        cvec[i] = Counter();

    min_bucket = -max_bucket;// - (even ? bucket_size : 0);
    bucket_size *= 2;
}

void
HistStor::grow_up()
{
    int size = cvec.size();
    int half = (size + 1) / 2; // round up!

    int pair = 0;
    for (int i = 0; i < half; i++) {
        cvec[i] = cvec[pair];
        if (pair + 1 < size)
            cvec[i] += cvec[pair + 1];
        pair += 2;
    }
    assert(pair == size || pair == size + 1);

    for (int i = half; i < size; i++)
        cvec[i] = Counter();

    max_bucket *= 2;
    bucket_size *= 2;
}

void
HistStor::add(HistStor *hs)
{
    int b_size = hs->size();
    assert(size() == b_size);
    assert(min_bucket == hs->min_bucket);

    sum += hs->sum;
    logs += hs->logs;
    squares += hs->squares;
    samples += hs->samples;

    while (bucket_size > hs->bucket_size)
        hs->grow_up();
    while (bucket_size < hs->bucket_size)
        grow_up();

    for (uint32_t i = 0; i < b_size; i++)
        cvec[i] += hs->cvec[i];
}

Formula::Formula()
{
}

Formula::Formula(Temp r)
{
    root = r.getNodePtr();
    setInit();
    assert(size());
}

const Formula &
Formula::operator=(Temp r)
{
    assert(!root && "Can't change formulas");
    root = r.getNodePtr();
    setInit();
    assert(size());
    return *this;
}

const Formula &
Formula::operator+=(Temp r)
{
    if (root)
        root = NodePtr(new BinaryNode<std::plus<Result> >(root, r));
    else {
        root = r.getNodePtr();
        setInit();
    }

    assert(size());
    return *this;
}

const Formula &
Formula::operator/=(Temp r)
{
    assert (root);
    root = NodePtr(new BinaryNode<std::divides<Result> >(root, r));

    assert(size());
    return *this;
}

void
Formula::result(VResult &vec) const
{
    if (root)
        vec = root->result();
}

Result
Formula::total() const
{
    return root ? root->total() : 0.0;
}

size_type
Formula::size() const
{
    if (!root)
        return 0;
    else
        return root->size();
}

void
Formula::reset()
{
}

bool
Formula::zero() const
{
    VResult vec;
    result(vec);
    for (VResult::size_type i = 0; i < vec.size(); ++i)
        if (vec[i] != 0.0)
            return false;
    return true;
}

string
Formula::str() const
{
    return root ? root->str() : "";
}

Handler resetHandler = NULL;
Handler dumpHandler = NULL;

void
registerHandlers(Handler reset_handler, Handler dump_handler)
{
    resetHandler = reset_handler;
    dumpHandler = dump_handler;
}

CallbackQueue dumpQueue;
CallbackQueue resetQueue;

void
processResetQueue()
{
    resetQueue.process();
}

void
processDumpQueue()
{
    dumpQueue.process();
}

void
registerResetCallback(Callback *cb)
{
    resetQueue.add(cb);
}

bool _enabled = false;

bool
enabled()
{
    return _enabled;
}

void
enable()
{
    if (_enabled)
        fatal("Stats are already enabled");

    _enabled = true;
}

void
dump()
{
    if (dumpHandler)
        dumpHandler();
    else
        fatal("No registered Stats::dump handler");
}

void
reset()
{
    if (resetHandler)
        resetHandler();
    else
        fatal("No registered Stats::reset handler");
}

void
registerDumpCallback(Callback *cb)
{
    dumpQueue.add(cb);
}

} // namespace Stats

void
debugDumpStats()
{
    Stats::dump();
}
<|endoftext|>