<commit_before>#pragma once

#include <vector>
#include <tuple>
#include <array>

#include <tudocomp/util.hpp>
#include <tudocomp/io.hpp>
#include <tudocomp/Algorithm.hpp>

#include <tudocomp/ds/IntVector.hpp>

#include <sdsl/cst_sct3.hpp>

namespace tdc {
namespace lfs {

template<uint min_lrf = 2 >
class SimSTStrategy : public Algorithm {
private:

    inline virtual std::vector<int> select_starting_positions(std::vector<int> starting_positions, int length){
        std::vector<int> selected_starting_positions;
        //select occurences greedily non-overlapping:
        selected_starting_positions.reserve(starting_positions.size());

        int last =  0-length;
        int current;
        for (auto it=starting_positions.begin(); it!=starting_positions.end(); ++it){

            current = *it;
            //DLOG(INFO) << "checking starting position: " << current << " length: " << top.first << "last " << last;
            if(last+length <= current && !dead_positions[current] && !dead_positions[current+length-1]){

                selected_starting_positions.push_back(current);
                last = current;

            }

        }
        return selected_starting_positions;
    }

    //(position in text, non_terminal_symbol_number, length_of_symbol);
    typedef std::tuple<uint,uint,uint> non_term;
    typedef std::vector<non_term> non_terminal_symbols;
    typedef std::vector<std::pair<uint,uint>> rules;

    typedef sdsl::cst_sct3<> cst_t;
    cst_t stree;

    BitVector dead_positions;

public:

    using Algorithm::Algorithm; //import constructor

    inline static Meta meta() {
        Meta m("lfs_comp", "sim_st");
        return m;
    }

    inline void compute_rules(io::InputView & input, rules & dictionary, non_terminal_symbols & nts_symbols){

        //build suffixtree
        DLOG(INFO)<<"build suffixtree";

        dead_positions = BitVector(input.size(), 0);

        typedef sdsl::bp_interval<long unsigned int> node_type;

        StatPhase::wrap("Constructing ST", [&]{
             sdsl::construct_im(stree, (const char*) input.data(), 1);
        });

        StatPhase::wrap("Computing LRF", [&]{

            //array of vectors for bins of nodes with string depth
            std::vector<std::vector<node_type> > bins;
            bins.resize(stree.size()+1);

            uint node_counter = 0;

            typedef sdsl::cst_bfs_iterator<cst_t> iterator;
            iterator begin = iterator(&stree, stree.root());
            iterator end   = iterator(&stree, stree.root(), true, true);

            StatPhase::wrap("Iterate over ST", [&]{

                for (iterator it = begin; it != end; ++it) {
                    bins[stree.depth(*it)].push_back(*it);
                    node_counter++;
                }
            });

            uint nts_number =0;
            StatPhase::wrap("Iterate over Node Bins", [&]{

                for(uint i = bins.size()-1; i>=min_lrf; i--){
                    auto bin_it = bins[i].begin();
                    while (bin_it!= bins[i].end()){

                        node_type node = *bin_it;

                        uint offset = stree.csa[stree.lb(node)];
                        uint fac_length = stree.depth(node);

                        bin_it++;

                        if(stree.size(node)>=2){

                            //iterate over corresponding sa and find min and max
                            offset = stree.lb(node);
                            int min = stree.csa[offset];
                            int max = stree.csa[offset];
                            //int min_pos = offset;
                            //int max_pos = offset;
                            std::vector<int> beginning_positions;
                            for(uint c = 0;c<stree.size(node); c++){
                                int val = stree.csa[c+offset];
                                beginning_positions.push_back(val);
                                if(min > val){
                                    min = val;
                                    //   min_pos = offset+c;
                                }
                                if(max < val){
                                    max = val;
                                    //  max_pos = offset+c;
                                }

                            }
                            uint dif = max -min;
                            if(dif < stree.depth(node)){
                                continue;
                            }

                            std::sort(beginning_positions.begin(), beginning_positions.end());

                            //Add new rule

                            //and add new non-terminal symbols
                            std::vector<int> selected_bp = select_starting_positions(beginning_positions, stree.depth(node));
                            if(! (selected_bp.size() >=2) ){
                                continue;
                            }

                            //vector of text position, length
                            std::pair<uint,uint> rule = std::make_pair(selected_bp.at(0), fac_length);

                            dictionary.push_back(rule);

                            //iterate over selected pos, add non terminal symbols
                            for(auto bp_it = selected_bp.begin(); bp_it != selected_bp.end(); bp_it++){
                                //(position in text, non_terminal_symbol_number, length_of_symbol);
                                //typedef std::tuple<uint,uint,uint> non_term;
                                non_term nts = std::make_tuple(*bp_it, nts_number, fac_length);
                                nts_symbols.push_back(nts);
                                //typedef std::vector<non_term> non_terminal_symbols;
                                //mark as used
                                for(uint pos = 0; pos<=fac_length;pos++){
                                    dead_positions[pos+ *bp_it] = 1;
                                }
                            }
                            nts_number++;
                        }

                    }

                }

            });
        });

        StatPhase::wrap("Sorting occurences", [&]{

            DLOG(INFO) << "sorting occurences";
            std::sort(nts_symbols.begin(), nts_symbols.end());

        });

    }
};
}

}
<commit_msg>changed sa to sa with usable  access times<commit_after>#pragma once

#include <vector>
#include <tuple>
#include <array>

#include <tudocomp/util.hpp>
#include <tudocomp/io.hpp>
#include <tudocomp/Algorithm.hpp>

#include <tudocomp/ds/IntVector.hpp>

//#include <sdsl/suffixarrays.hpp>

#include <sdsl/suffix_trees.hpp>
//#include <sdsl/suffix_arrays.hpp>
//#include <sdsl/csa_bitcompressed.hpp>
//#include <sdsl/csa_uncompressed.hpp>

namespace tdc {
namespace lfs {

template<uint min_lrf = 2 >
class SimSTStrategy : public Algorithm {
private:

    inline virtual std::vector<int> select_starting_positions(std::vector<int> starting_positions, int length){
        std::vector<int> selected_starting_positions;
        //select occurences greedily non-overlapping:
        selected_starting_positions.reserve(starting_positions.size());

        int last =  0-length;
        int current;
        for (auto it=starting_positions.begin(); it!=starting_positions.end(); ++it){

            current = *it;
            //DLOG(INFO) << "checking starting position: " << current << " length: " << top.first << "last " << last;
            if(last+length <= current && !dead_positions[current] && !dead_positions[current+length-1]){

                selected_starting_positions.push_back(current);
                last = current;

            }

        }
        return selected_starting_positions;
    }

    //(position in text, non_terminal_symbol_number, length_of_symbol);
    typedef std::tuple<uint,uint,uint> non_term;
    typedef std::vector<non_term> non_terminal_symbols;
    typedef std::vector<std::pair<uint,uint>> rules;

    //sdsl::t_csa sa =sdsl::csa_uncompressed<>
    typedef sdsl::cst_sct3< sdsl::csa_bitcompressed<> > cst_t;
    cst_t stree;

    BitVector dead_positions;

public:

    using Algorithm::Algorithm; //import constructor

    inline static Meta meta() {
        Meta m("lfs_comp", "sim_st");
        return m;
    }

    inline void compute_rules(io::InputView & input, rules & dictionary, non_terminal_symbols & nts_symbols){

        //build suffixtree
        DLOG(INFO)<<"build suffixtree";

        dead_positions = BitVector(input.size(), 0);

        typedef sdsl::bp_interval<long unsigned int> node_type;

        StatPhase::wrap("Constructing ST", [&]{
             sdsl::construct_im(stree, (const char*) input.data(), 1);
        });

        StatPhase::wrap("Computing LRF", [&]{

            //array of vectors for bins of nodes with string depth
            std::vector<std::vector<node_type> > bins;
            bins.resize(stree.size()+1);

            uint node_counter = 0;

            typedef sdsl::cst_bfs_iterator<cst_t> iterator;
            iterator begin = iterator(&stree, stree.root());
            iterator end   = iterator(&stree, stree.root(), true, true);

            StatPhase::wrap("Iterate over ST", [&]{

                for (iterator it = begin; it != end; ++it) {
                    bins[stree.depth(*it)].push_back(*it);
                    node_counter++;
                }
            });

            uint nts_number =0;
            StatPhase::wrap("Iterate over Node Bins", [&]{

                for(uint i = bins.size()-1; i>=min_lrf; i--){
                    auto bin_it = bins[i].begin();
                    while (bin_it!= bins[i].end()){

                        node_type node = *bin_it;

                        uint offset = stree.csa[stree.lb(node)];
                        uint fac_length = stree.depth(node);

                        bin_it++;

                        if(stree.size(node)>=2){

                            //iterate over corresponding sa and find min and max
                            offset = stree.lb(node);
                            int min = stree.csa[offset];
                            int max = stree.csa[offset];
                            //int min_pos = offset;
                            //int max_pos = offset;
                            std::vector<int> beginning_positions;
                            for(uint c = 0;c<stree.size(node); c++){
                                int val = stree.csa[c+offset];
                                beginning_positions.push_back(val);
                                if(min > val){
                                    min = val;
                                    //   min_pos = offset+c;
                                }
                                if(max < val){
                                    max = val;
                                    //  max_pos = offset+c;
                                }

                            }
                            uint dif = max -min;
                            if(dif < stree.depth(node)){
                                continue;
                            }

                            std::sort(beginning_positions.begin(), beginning_positions.end());

                            //Add new rule

                            //and add new non-terminal symbols
                            std::vector<int> selected_bp = select_starting_positions(beginning_positions, stree.depth(node));
                            if(! (selected_bp.size() >=2) ){
                                continue;
                            }

                            //vector of text position, length
                            std::pair<uint,uint> rule = std::make_pair(selected_bp.at(0), fac_length);

                            dictionary.push_back(rule);

                            //iterate over selected pos, add non terminal symbols
                            for(auto bp_it = selected_bp.begin(); bp_it != selected_bp.end(); bp_it++){
                                //(position in text, non_terminal_symbol_number, length_of_symbol);
                                //typedef std::tuple<uint,uint,uint> non_term;
                                non_term nts = std::make_tuple(*bp_it, nts_number, fac_length);
                                nts_symbols.push_back(nts);
                                //typedef std::vector<non_term> non_terminal_symbols;
                                //mark as used
                                for(uint pos = 0; pos<=fac_length;pos++){
                                    dead_positions[pos+ *bp_it] = 1;
                                }
                            }
                            nts_number++;
                        }

                    }

                }

            });
        });

        StatPhase::wrap("Sorting occurences", [&]{

            DLOG(INFO) << "sorting occurences";
            std::sort(nts_symbols.begin(), nts_symbols.end());

        });

    }
};
}

}
<|endoftext|>


<commit_before>//===- LTO.cpp ------------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "LTO.h"
#include "Config.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/Config.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cstddef>
#include <memory>
#include <string>
#include <system_error>
#include <vector>

using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;

using namespace lld;
using namespace lld::elf;

// This is for use when debugging LTO.
static void saveBuffer(StringRef Buffer, const Twine &Path) {
  std::error_code EC;
  raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
  if (EC)
    error("cannot create " + Path + ": " + EC.message());
  OS << Buffer;
}

static void diagnosticHandler(const DiagnosticInfo &DI) {
  SmallString<128> S;
  raw_svector_ostream OS(S);
  DiagnosticPrinterRawOStream DP(OS);
  DI.print(DP);
  warn(S);
}

static void checkError(Error E) {
  handleAllErrors(std::move(E),
                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
}

// Creates an empty file to store a list of object files for final
// linking of distributed ThinLTO.
static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) {
  std::error_code EC;
  auto Ret =
      llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None);
  if (EC) {
    error("cannot open " + File + ": " + EC.message());
    return nullptr;
  }
  return Ret;
}

static std::string getThinLTOOutputFile(StringRef ModulePath) {
  return lto::getThinLTOOutputFile(ModulePath,
                                   Config->ThinLTOPrefixReplace.first,
                                   Config->ThinLTOPrefixReplace.second);
}

static lto::Config createConfig() {
  lto::Config C;

  // LLD supports the new relocations.
  C.Options = InitTargetOptionsFromCodeGenFlags();
  C.Options.RelaxELFRelocations = true;

  // Always emit a section per function/datum with LTO.
  C.Options.FunctionSections = true;
  C.Options.DataSections = true;

  if (Config->Relocatable)
    C.RelocModel = None;
  else if (Config->Pic)
    C.RelocModel = Reloc::PIC_;
  else
    C.RelocModel = Reloc::Static;

  C.CodeModel = GetCodeModelFromCMModel();
  C.DisableVerify = Config->DisableVerify;
  C.DiagHandler = diagnosticHandler;
  C.OptLevel = Config->LTOO;
  C.CPU = GetCPUStr();

  // Set up a custom pipeline if we've been asked to.
  C.OptPipeline = Config->LTONewPmPasses;
  C.AAPipeline = Config->LTOAAPipeline;

  // Set up optimization remarks if we've been asked to.
  C.RemarksFilename = Config->OptRemarksFilename;
  C.RemarksWithHotness = Config->OptRemarksWithHotness;

  C.SampleProfile = Config->LTOSampleProfile;
  C.UseNewPM = Config->LTONewPassManager;
  C.DebugPassManager = Config->LTODebugPassManager;

  if (Config->SaveTemps)
    checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
                              /*UseInputModulePath*/ true));
  return C;
}

BitcodeCompiler::BitcodeCompiler() {
  // Initialize LTOObj.
  lto::ThinBackend Backend;

  if (Config->ThinLTOIndexOnly) {
    StringRef Path = Config->ThinLTOIndexOnlyArg;
    if (!Path.empty())
      IndexFile = openFile(Path);

    Backend = lto::createWriteIndexesThinBackend(
        Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
        Config->ThinLTOEmitImportsFiles, IndexFile.get(), nullptr);
  } else if (Config->ThinLTOJobs != -1U) {
    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
  }

  LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend,
                                       Config->LTOPartitions);

  // Initialize UsedStartStop.
  for (Symbol *Sym : Symtab->getSymbols()) {
    StringRef Name = Sym->getName();
    for (StringRef Prefix : {"__start_", "__stop_"})
      if (Name.startswith(Prefix))
        UsedStartStop.insert(Name.substr(Prefix.size()));
  }
}

BitcodeCompiler::~BitcodeCompiler() = default;

static void undefine(Symbol *S) {
  replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT,
                           S->Type);
}

void BitcodeCompiler::add(BitcodeFile &F) {
  lto::InputFile &Obj = *F.Obj;

  // Create the empty files which, if indexed, will be overwritten later.
  if (Config->ThinLTOIndexOnly) {
    std::string Path = getThinLTOOutputFile(Obj.getName());
    openFile(Path + ".thinlto.bc");

    if (Config->ThinLTOEmitImportsFiles)
      openFile(Path + ".imports");
  }

  unsigned SymNum = 0;
  std::vector<Symbol *> Syms = F.getSymbols();
  std::vector<lto::SymbolResolution> Resols(Syms.size());

  bool IsExecutable = !Config->Shared && !Config->Relocatable;

  // Provide a resolution to the LTO API for each symbol.
  for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
    Symbol *Sym = Syms[SymNum];
    lto::SymbolResolution &R = Resols[SymNum];
    ++SymNum;

    // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
    // reports two symbols for module ASM defined. Without this check, lld
    // flags an undefined in IR with a definition in ASM as prevailing.
    // Once IRObjectFile is fixed to report only one symbol this hack can
    // be removed.
    R.Prevailing = !ObjSym.isUndefined() && Sym->File == &F;

    // We ask LTO to preserve following global symbols:
    // 1) All symbols when doing relocatable link, so that them can be used
    //    for doing final link.
    // 2) Symbols that are used in regular objects.
    // 3) C named sections if we have corresponding __start_/__stop_ symbol.
    // 4) Symbols that are defined in bitcode files and used for dynamic linking.
    R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
                            (R.Prevailing && Sym->includeInDynsym()) ||
                            UsedStartStop.count(ObjSym.getSectionName());
    const auto *DR = dyn_cast<Defined>(Sym);
    R.FinalDefinitionInLinkageUnit =
        (IsExecutable || Sym->Visibility != STV_DEFAULT) && DR &&
        // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
        // will be generated by for them, triggering linker errors.
        // Symbol section is always null for bitcode symbols, hence the check
        // for isElf(). Skip linker script defined symbols as well: they have
        // no File defined.
        !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf()));

    if (R.Prevailing)
      undefine(Sym);

    // We tell LTO to not apply interprocedural optimization for wrapped
    // (with --wrap) symbols because otherwise LTO would inline them while
    // their values are still not final.
    R.LinkerRedefined = !Sym->CanInline;
  }
  checkError(LTOObj->add(std::move(F.Obj), Resols));
}

// Merge all the bitcode files we have seen, codegen the result
// and return the resulting ObjectFile(s).
std::vector<InputFile *> BitcodeCompiler::compile() {
  std::vector<InputFile *> Ret;
  unsigned MaxTasks = LTOObj->getMaxTasks();
  Buff.resize(MaxTasks);
  Files.resize(MaxTasks);

  // The --thinlto-cache-dir option specifies the path to a directory in which
  // to cache native object files for ThinLTO incremental builds. If a path was
  // specified, configure LTO to use it as the cache directory.
  lto::NativeObjectCache Cache;
  if (!Config->ThinLTOCacheDir.empty())
    Cache = check(
        lto::localCache(Config->ThinLTOCacheDir,
                        [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
                          Files[Task] = std::move(MB);
                        }));

  checkError(LTOObj->run(
      [&](size_t Task) {
        return llvm::make_unique<lto::NativeObjectStream>(
            llvm::make_unique<raw_svector_ostream>(Buff[Task]));
      },
      Cache));

  if (!Config->ThinLTOCacheDir.empty())
    pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);

  for (unsigned I = 0; I != MaxTasks; ++I) {
    if (Buff[I].empty())
      continue;
    if (Config->SaveTemps) {
      if (I == 0)
        saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
      else
        saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
    }
    InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
    Ret.push_back(Obj);
  }

  // If LazyObjFile has not been added to link, emit empty index files.
  // This is needed because this is what GNU gold plugin does and we have a
  // distributed build system that depends on that behavior.
  if (Config->ThinLTOIndexOnly) {
    for (LazyObjFile *F : LazyObjFiles) {
      if (F->AddedToLink || !isBitcode(F->MB))
        continue;

      std::string Path = getThinLTOOutputFile(F->getName());
      std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
      if (!OS)
        continue;

      ModuleSummaryIndex M(false);
      M.setSkipModuleByDistributedBackend();
      WriteIndexToFile(M, *OS);

      if (Config->ThinLTOEmitImportsFiles)
        openFile(Path + ".imports");
    }

    // ThinLTO with index only option is required to generate only the index
    // files. After that, we exit from linker and ThinLTO backend runs in a
    // distributed environment.
    if (IndexFile)
      IndexFile->close();
    return {};
  }

  for (std::unique_ptr<MemoryBuffer> &File : Files)
    if (File)
      Ret.push_back(createObjectFile(*File));
  return Ret;
}
<commit_msg>Fix a bug that a copy of a large vector was created. NFC.<commit_after>//===- LTO.cpp ------------------------------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "LTO.h"
#include "Config.h"
#include "InputFiles.h"
#include "LinkerScript.h"
#include "SymbolTable.h"
#include "Symbols.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/TargetOptionsCommandFlags.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/Config.h"
#include "llvm/LTO/LTO.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <algorithm>
#include <cstddef>
#include <memory>
#include <string>
#include <system_error>
#include <vector>

using namespace llvm;
using namespace llvm::object;
using namespace llvm::ELF;

using namespace lld;
using namespace lld::elf;

// This is for use when debugging LTO.
static void saveBuffer(StringRef Buffer, const Twine &Path) {
  std::error_code EC;
  raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
  if (EC)
    error("cannot create " + Path + ": " + EC.message());
  OS << Buffer;
}

static void diagnosticHandler(const DiagnosticInfo &DI) {
  SmallString<128> S;
  raw_svector_ostream OS(S);
  DiagnosticPrinterRawOStream DP(OS);
  DI.print(DP);
  warn(S);
}

static void checkError(Error E) {
  handleAllErrors(std::move(E),
                  [&](ErrorInfoBase &EIB) { error(EIB.message()); });
}

// Creates an empty file to store a list of object files for final
// linking of distributed ThinLTO.
static std::unique_ptr<raw_fd_ostream> openFile(StringRef File) {
  std::error_code EC;
  auto Ret =
      llvm::make_unique<raw_fd_ostream>(File, EC, sys::fs::OpenFlags::F_None);
  if (EC) {
    error("cannot open " + File + ": " + EC.message());
    return nullptr;
  }
  return Ret;
}

static std::string getThinLTOOutputFile(StringRef ModulePath) {
  return lto::getThinLTOOutputFile(ModulePath,
                                   Config->ThinLTOPrefixReplace.first,
                                   Config->ThinLTOPrefixReplace.second);
}

static lto::Config createConfig() {
  lto::Config C;

  // LLD supports the new relocations.
  C.Options = InitTargetOptionsFromCodeGenFlags();
  C.Options.RelaxELFRelocations = true;

  // Always emit a section per function/datum with LTO.
  C.Options.FunctionSections = true;
  C.Options.DataSections = true;

  if (Config->Relocatable)
    C.RelocModel = None;
  else if (Config->Pic)
    C.RelocModel = Reloc::PIC_;
  else
    C.RelocModel = Reloc::Static;

  C.CodeModel = GetCodeModelFromCMModel();
  C.DisableVerify = Config->DisableVerify;
  C.DiagHandler = diagnosticHandler;
  C.OptLevel = Config->LTOO;
  C.CPU = GetCPUStr();

  // Set up a custom pipeline if we've been asked to.
  C.OptPipeline = Config->LTONewPmPasses;
  C.AAPipeline = Config->LTOAAPipeline;

  // Set up optimization remarks if we've been asked to.
  C.RemarksFilename = Config->OptRemarksFilename;
  C.RemarksWithHotness = Config->OptRemarksWithHotness;

  C.SampleProfile = Config->LTOSampleProfile;
  C.UseNewPM = Config->LTONewPassManager;
  C.DebugPassManager = Config->LTODebugPassManager;

  if (Config->SaveTemps)
    checkError(C.addSaveTemps(Config->OutputFile.str() + ".",
                              /*UseInputModulePath*/ true));
  return C;
}

BitcodeCompiler::BitcodeCompiler() {
  // Initialize LTOObj.
  lto::ThinBackend Backend;

  if (Config->ThinLTOIndexOnly) {
    StringRef Path = Config->ThinLTOIndexOnlyArg;
    if (!Path.empty())
      IndexFile = openFile(Path);

    Backend = lto::createWriteIndexesThinBackend(
        Config->ThinLTOPrefixReplace.first, Config->ThinLTOPrefixReplace.second,
        Config->ThinLTOEmitImportsFiles, IndexFile.get(), nullptr);
  } else if (Config->ThinLTOJobs != -1U) {
    Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
  }

  LTOObj = llvm::make_unique<lto::LTO>(createConfig(), Backend,
                                       Config->LTOPartitions);

  // Initialize UsedStartStop.
  for (Symbol *Sym : Symtab->getSymbols()) {
    StringRef Name = Sym->getName();
    for (StringRef Prefix : {"__start_", "__stop_"})
      if (Name.startswith(Prefix))
        UsedStartStop.insert(Name.substr(Prefix.size()));
  }
}

BitcodeCompiler::~BitcodeCompiler() = default;

static void undefine(Symbol *S) {
  replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT,
                           S->Type);
}

void BitcodeCompiler::add(BitcodeFile &F) {
  lto::InputFile &Obj = *F.Obj;

  // Create the empty files which, if indexed, will be overwritten later.
  if (Config->ThinLTOIndexOnly) {
    std::string Path = getThinLTOOutputFile(Obj.getName());
    openFile(Path + ".thinlto.bc");

    if (Config->ThinLTOEmitImportsFiles)
      openFile(Path + ".imports");
  }

  unsigned SymNum = 0;
  ArrayRef<Symbol *> Syms = F.getSymbols();
  std::vector<lto::SymbolResolution> Resols(Syms.size());

  bool IsExecutable = !Config->Shared && !Config->Relocatable;

  // Provide a resolution to the LTO API for each symbol.
  for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
    Symbol *Sym = Syms[SymNum];
    lto::SymbolResolution &R = Resols[SymNum];
    ++SymNum;

    // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
    // reports two symbols for module ASM defined. Without this check, lld
    // flags an undefined in IR with a definition in ASM as prevailing.
    // Once IRObjectFile is fixed to report only one symbol this hack can
    // be removed.
    R.Prevailing = !ObjSym.isUndefined() && Sym->File == &F;

    // We ask LTO to preserve following global symbols:
    // 1) All symbols when doing relocatable link, so that them can be used
    //    for doing final link.
    // 2) Symbols that are used in regular objects.
    // 3) C named sections if we have corresponding __start_/__stop_ symbol.
    // 4) Symbols that are defined in bitcode files and used for dynamic linking.
    R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
                            (R.Prevailing && Sym->includeInDynsym()) ||
                            UsedStartStop.count(ObjSym.getSectionName());
    const auto *DR = dyn_cast<Defined>(Sym);
    R.FinalDefinitionInLinkageUnit =
        (IsExecutable || Sym->Visibility != STV_DEFAULT) && DR &&
        // Skip absolute symbols from ELF objects, otherwise PC-rel relocations
        // will be generated by for them, triggering linker errors.
        // Symbol section is always null for bitcode symbols, hence the check
        // for isElf(). Skip linker script defined symbols as well: they have
        // no File defined.
        !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf()));

    if (R.Prevailing)
      undefine(Sym);

    // We tell LTO to not apply interprocedural optimization for wrapped
    // (with --wrap) symbols because otherwise LTO would inline them while
    // their values are still not final.
    R.LinkerRedefined = !Sym->CanInline;
  }
  checkError(LTOObj->add(std::move(F.Obj), Resols));
}

// Merge all the bitcode files we have seen, codegen the result
// and return the resulting ObjectFile(s).
std::vector<InputFile *> BitcodeCompiler::compile() {
  std::vector<InputFile *> Ret;
  unsigned MaxTasks = LTOObj->getMaxTasks();
  Buff.resize(MaxTasks);
  Files.resize(MaxTasks);

  // The --thinlto-cache-dir option specifies the path to a directory in which
  // to cache native object files for ThinLTO incremental builds. If a path was
  // specified, configure LTO to use it as the cache directory.
  lto::NativeObjectCache Cache;
  if (!Config->ThinLTOCacheDir.empty())
    Cache = check(
        lto::localCache(Config->ThinLTOCacheDir,
                        [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
                          Files[Task] = std::move(MB);
                        }));

  checkError(LTOObj->run(
      [&](size_t Task) {
        return llvm::make_unique<lto::NativeObjectStream>(
            llvm::make_unique<raw_svector_ostream>(Buff[Task]));
      },
      Cache));

  if (!Config->ThinLTOCacheDir.empty())
    pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);

  for (unsigned I = 0; I != MaxTasks; ++I) {
    if (Buff[I].empty())
      continue;
    if (Config->SaveTemps) {
      if (I == 0)
        saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
      else
        saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
    }
    InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
    Ret.push_back(Obj);
  }

  // If LazyObjFile has not been added to link, emit empty index files.
  // This is needed because this is what GNU gold plugin does and we have a
  // distributed build system that depends on that behavior.
  if (Config->ThinLTOIndexOnly) {
    for (LazyObjFile *F : LazyObjFiles) {
      if (F->AddedToLink || !isBitcode(F->MB))
        continue;

      std::string Path = getThinLTOOutputFile(F->getName());
      std::unique_ptr<raw_fd_ostream> OS = openFile(Path + ".thinlto.bc");
      if (!OS)
        continue;

      ModuleSummaryIndex M(false);
      M.setSkipModuleByDistributedBackend();
      WriteIndexToFile(M, *OS);

      if (Config->ThinLTOEmitImportsFiles)
        openFile(Path + ".imports");
    }

    // ThinLTO with index only option is required to generate only the index
    // files. After that, we exit from linker and ThinLTO backend runs in a
    // distributed environment.
    if (IndexFile)
      IndexFile->close();
    return {};
  }

  for (std::unique_ptr<MemoryBuffer> &File : Files)
    if (File)
      Ret.push_back(createObjectFile(*File));
  return Ret;
}
<|endoftext|>


<commit_before>//
//  ByteBuffer.hpp
//  G3MiOSSDK
//
//  Created by Agustín Trujillo Pino on 29/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_ByteBuffer_hpp
#define G3MiOSSDK_ByteBuffer_hpp

class ByteBuffer{

#ifdef C_CODE
  unsigned char* _data;
#endif
#ifdef JAVA_CODE
  byte[] _data;
#endif

  const int      _length;

public:
  ByteBuffer(unsigned char* const data,
             int dataLength) :
  _data(data),
  _length(dataLength)
  {
  };

  ByteBuffer(const ByteBuffer& bb) :
  _length(bb._length),
  _data(new unsigned char[bb._length])
  {
#ifdef C_CODE
    memcpy(_data, bb._data, _length * sizeof(unsigned char));
#endif
#ifdef JAVA_CODE
      System.arraycopy(bb._data, 0, _data, 0, _length);
#endif
  };

  ~ByteBuffer(){
#ifdef C_CODE
    if (_data != NULL) delete [] _data;
#endif
  }

#ifdef C_CODE
  unsigned char* getData() const{ return _data;}
#endif

#ifdef JAVA_CODE
  byte[] getData() const{ return _data;}
#endif

  int getLength() const{
    return _length;
  }

};

#endif
<commit_msg>Java conversion tasks<commit_after>//
//  ByteBuffer.hpp
//  G3MiOSSDK
//
//  Created by Agustín Trujillo Pino on 29/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_ByteBuffer_hpp
#define G3MiOSSDK_ByteBuffer_hpp

class ByteBuffer{

#ifdef C_CODE
  unsigned char* _data;
#endif
#ifdef JAVA_CODE
  byte[] _data;
#endif

  const int      _length;

public:
  ByteBuffer(unsigned char* const data,
             int dataLength) :
  _data(data),
  _length(dataLength)
  {
  };

  ByteBuffer(const ByteBuffer& bb) :
  _length(bb._length),
  _data(new unsigned char[bb._length])
  {
#ifdef C_CODE
    memcpy(_data, bb._data, _length * sizeof(unsigned char));
#endif
#ifdef JAVA_CODE
      System.arraycopy(bb._data, 0, _data, 0, _length);
#endif
  };

  ~ByteBuffer(){
#ifdef C_CODE
    if (_data != NULL) delete [] _data;
#endif
  }

#ifdef C_CODE
  unsigned char* getData() const{ return _data;}
#endif

#ifdef JAVA_CODE
  byte[] getData() { return _data;}
#endif

  int getLength() const{
    return _length;
  }

};

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// 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.

#include <atomic>

#include <ioxdds/gateway/iox2dds.hpp>
#include <iceoryx_utils/cxx/helplets.hpp>
#include <iceoryx_utils/cxx/optional.hpp>
#include <iceoryx_posh/runtime/posh_runtime.hpp>

class ShutdownManager
{
  public:
    static void scheduleShutdown(int num)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        char reason;
        psignal(num, &reason);
        m_shutdownFlag.store(true, std::memory_order_relaxed);
    }
    static bool shouldShutdown()
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_shutdownFlag.load(std::memory_order_relaxed);
    }

  private:
    static std::mutex m_mutex;
    static std::atomic_bool m_shutdownFlag;
    ShutdownManager() = default;
};
std::mutex ShutdownManager::m_mutex;
std::atomic_bool ShutdownManager::m_shutdownFlag(false);

int main(int argc, char* argv[])
{
    // Set OS signal handlers
    signal(SIGINT, ShutdownManager::scheduleShutdown);
    signal(SIGTERM, ShutdownManager::scheduleShutdown);

    // Start application
    iox::runtime::PoshRuntime::getInstance("/gateway_iox2dds");

    //iox::gateway::dds::Iceoryx2DDSGateway<> gateway;
    static iox::cxx::optional<iox::gateway::dds::Iceoryx2DDSGateway<>> gateway;
    auto gatewayScopeGuard = iox::cxx::makeScopedStatic(gateway);

    auto discoveryThread = std::thread([] { gateway.value().discoveryLoop(); });
    auto forwardingThread = std::thread([] { gateway.value().forwardingLoop(); });

    // Run until SIGINT or SIGTERM
    while (!ShutdownManager::shouldShutdown())
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    };

    // Shutdown gracefully
    gateway.value().shutdown();
    discoveryThread.join();
    forwardingThread.join();

    return 0;
}
<commit_msg>iox-#64 Do not initialize gateway in data segment - gateway class no longer holds Subscriber or DataWriter object pools.<commit_after>// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
//
// 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.

#include <atomic>

#include <ioxdds/gateway/iox2dds.hpp>
#include <iceoryx_utils/cxx/helplets.hpp>
#include <iceoryx_utils/cxx/optional.hpp>
#include <iceoryx_posh/runtime/posh_runtime.hpp>

class ShutdownManager
{
  public:
    static void scheduleShutdown(int num)
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        char reason;
        psignal(num, &reason);
        m_shutdownFlag.store(true, std::memory_order_relaxed);
    }
    static bool shouldShutdown()
    {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_shutdownFlag.load(std::memory_order_relaxed);
    }

  private:
    static std::mutex m_mutex;
    static std::atomic_bool m_shutdownFlag;
    ShutdownManager() = default;
};
std::mutex ShutdownManager::m_mutex;
std::atomic_bool ShutdownManager::m_shutdownFlag(false);

int main(int argc, char* argv[])
{
    // Set OS signal handlers
    signal(SIGINT, ShutdownManager::scheduleShutdown);
    signal(SIGTERM, ShutdownManager::scheduleShutdown);

    // Start application
    iox::runtime::PoshRuntime::getInstance("/gateway_iox2dds");

    iox::gateway::dds::Iceoryx2DDSGateway<> gateway;
    auto discoveryThread = std::thread([&gateway] { gateway.discoveryLoop(); });
    auto forwardingThread = std::thread([&gateway] { gateway.forwardingLoop(); });

    // Run until SIGINT or SIGTERM
    while (!ShutdownManager::shouldShutdown())
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    };

    // Shutdown gracefully
    gateway.shutdown();
    discoveryThread.join();
    forwardingThread.join();

    return 0;
}
<|endoftext|>


<commit_before>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_STATIC_MAIN_CONFIG_HPP_
#define POSEIDON_STATIC_MAIN_CONFIG_HPP_

#include "../fwd.hpp"
#include "../core/config_file.hpp"

namespace poseidon {

class Main_Config
  {
  private:
    ASTERIA_NONCOPYABLE_DESTRUCTOR(Main_Config)
      = delete;

  public:
    // Clears all data.
    // This function is thread-safe.
    static
    void
    clear()
    noexcept;

    // Reloads the file `etc/poseidon/main.conf'.
    // If this function fails, an exception is thrown, and there is no effect.
    // This function is thread-safe.
    static
    void
    reload();

    // Obtains a copy the global config file.
    // Because config files are copy-on-write, this function never fails.
    // This function is thread-safe.
    static
    Config_File
    copy()
    noexcept;
  };

}  // namespace poseidon

#endif
<commit_msg>static/main_config: Fix typo in comments<commit_after>// This file is part of Poseidon.
// Copyleft 2020, LH_Mouse. All wrongs reserved.

#ifndef POSEIDON_STATIC_MAIN_CONFIG_HPP_
#define POSEIDON_STATIC_MAIN_CONFIG_HPP_

#include "../fwd.hpp"
#include "../core/config_file.hpp"

namespace poseidon {

class Main_Config
  {
  private:
    ASTERIA_NONCOPYABLE_DESTRUCTOR(Main_Config)
      = delete;

  public:
    // Clears all data.
    // This function is thread-safe.
    static
    void
    clear()
    noexcept;

    // Reloads the file `etc/poseidon/main.conf'.
    // If this function fails, an exception is thrown, and there is no effect.
    // This function is thread-safe.
    static
    void
    reload();

    // Obtains a copy of the global config file.
    // Because config files are copy-on-write, this function never fails.
    // This function is thread-safe.
    static
    Config_File
    copy()
    noexcept;
  };

}  // namespace poseidon

#endif
<|endoftext|>


<commit_before>#pragma once
#ifndef NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX
#define NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX

#include <iostream>

#include "vigra/multi_array.hxx"
//#include "vigra/random_forest.hxx"
#include "vigra/random_forest_3.hxx"
#include "nifty/tools/timer.hxx"

namespace nifty{
namespace graph{

    /*
    template<class T>
    class RfClassifierOld{
    public:
        RfClassifierOld(const size_t numberOfTrees=255)
        :   classifier_(nullptr),
            numberOfTrees_(numberOfTrees){

        }
        void initialize(const size_t numberOfFeatures){
            numberOfFeatures_ = numberOfFeatures;
            classifier_ = nullptr;
        }
        void addTrainingExample(const T * features, const uint8_t label){
            newRfLabels_.push_back(label);
            for(size_t fi=0; fi<numberOfFeatures_; ++fi){
                newRfFeatruresFlat_.push_back(features[fi]);
            }
        }
        void train(){
            tools::VerboseTimer t(false);
            t.startAndPrint("       makeTZrainingSet");
            makeTrainingSet();
            t.stopAndPrint();
            t.reset();

             t.startAndPrint("      do training");
            if(classifier_ != nullptr){
                delete classifier_;
            }
            auto rfOpts = vigra::RandomForestOptions();
            rfOpts.tree_count(numberOfTrees_);
            rfOpts.predict_weighted();
            classifier_ = new  vigra::RandomForest<uint8_t>(rfOpts);

            // construct visitor to calculate out-of-bag error
            vigra::rf::visitors::OOB_Error oob_v;
            // perform training
            classifier_->learn(rfFeatures_, rfLabels_, vigra::rf::visitors::create_visitor(oob_v));
            t.stopAndPrint();
            t.reset();
        }

        double predictProbability(const T * features)const{
            // copy stuff atm
            vigra::MultiArray<2, T>       f(vigra::Shape2(1,numberOfFeatures_));
            vigra::MultiArray<2, double>  p(vigra::Shape2(1,2));
            for(size_t i=0; i<numberOfFeatures_; ++i){
                f[i] = features[i];
            }
            classifier_->predictProbabilities(f,p);
            return p(0,1);
        }
    private:
        void makeTrainingSet(){

            const auto nOld = rfFeatures_.shape(0);
            const auto nAdded = newRfLabels_.size();
            const auto nTotal = nOld + nAdded;

            //std::cout<<"new added examples "<<nAdded<<" total "<<nTotal<<"\n";
            vigra::MultiArray<2, T> fNew(vigra::Shape2( nTotal ,numberOfFeatures_));
            vigra::MultiArray<2, uint8_t> lNew(vigra::Shape2( nTotal ,1));

            for(auto i=0; i<nOld; ++i){
                lNew[i] = rfLabels_[i];
                for(auto fi=0; fi<numberOfFeatures_; ++fi)
                    fNew(i, fi) = rfFeatures_(i,fi);
            }
            auto c = 0;
            for(auto i=nOld; i<nTotal; ++i){
                lNew[i] = newRfLabels_[i-nOld];
                for(auto fi=0; fi<numberOfFeatures_; ++fi){
                    fNew(i, fi) = newRfFeatruresFlat_[c];
                    ++c;
                }
            }
            rfFeatures_ = fNew;
            rfLabels_ = lNew;
            newRfLabels_.resize(0);
            newRfFeatruresFlat_.resize(0);
        }

        vigra::RandomForest<uint8_t> *  classifier_;
        const size_t                    numberOfTrees_;
        vigra::MultiArray<2, T>         rfFeatures_;
        vigra::MultiArray<2, uint8_t>   rfLabels_;

        std::vector< T >        newRfFeatruresFlat_;
        std::vector<uint8_t>    newRfLabels_;
        uint64_t numberOfFeatures_;
    };
    */

    template<class T>
    class RfClassifier{
    public:

        typedef vigra::MultiArray<2, double>            Features;
        typedef vigra::MultiArray<1, uint8_t>           Labels;
        typedef typename vigra::rf3::DefaultRF<Features, Labels>::type RfImpl;

        RfClassifier(const size_t numberOfTrees=255)
        :   classifier_(),
            numberOfTrees_(numberOfTrees){

        }
        void initialize(const size_t numberOfFeatures){
            numberOfFeatures_ = numberOfFeatures;
        }
        void addTrainingExample(const T * features, const uint8_t label){
            newRfLabels_.push_back(label);
            for(size_t fi=0; fi<numberOfFeatures_; ++fi){
                newRfFeatruresFlat_.push_back(features[fi]);
            }
        }
        void train(){
            tools::VerboseTimer t(false);
            t.startAndPrint("       makeTZrainingSet");
            makeTrainingSet();
            t.stopAndPrint();
            t.reset();

            t.startAndPrint("      do training");

            vigra::rf3::RandomForestOptions const options = vigra::rf3::RandomForestOptions()
                                                   .tree_count(numberOfTrees_)
                                                   .bootstrap_sampling(true)
                                                   .n_threads(-1);
            vigra::rf3::OOBError oob;
            classifier_ = random_forest(rfFeatures_, rfLabels_, options, create_visitor(oob));

            t.stopAndPrint();
            t.reset();
        }

        double predictProbability(const T * features)const{
            // copy stuff atm
            vigra::MultiArray<2, T>       f(vigra::Shape2(1,numberOfFeatures_));
            vigra::MultiArray<2, double>  p(vigra::Shape2(1,2));
            for(size_t i=0; i<numberOfFeatures_; ++i){
                f[i] = features[i];
            }
            classifier_.predict_proba(f,p);
            return p(0,1);
        }
    private:
        void makeTrainingSet(){

            const auto nOld = rfFeatures_.shape(0);
            const auto nAdded = newRfLabels_.size();
            const auto nTotal = nOld + nAdded;

            //std::cout<<"new added examples "<<nAdded<<" total "<<nTotal<<"\n";
            Features fNew(vigra::Shape2( nTotal ,numberOfFeatures_));
            Labels lNew = Labels(vigra::Shape1( nTotal));

            for(auto i=0; i<nOld; ++i){
                lNew[i] = rfLabels_[i];
                for(auto fi=0; fi<numberOfFeatures_; ++fi)
                    fNew(i, fi) = rfFeatures_(i,fi);
            }
            auto c = 0;
            for(auto i=nOld; i<nTotal; ++i){
                lNew[i] = newRfLabels_[i-nOld];
                for(auto fi=0; fi<numberOfFeatures_; ++fi){
                    fNew(i, fi) = newRfFeatruresFlat_[c];
                    ++c;
                }
            }
            rfFeatures_ = fNew;
            rfLabels_ = lNew;
            newRfLabels_.resize(0);
            newRfFeatruresFlat_.resize(0);
        }

        RfImpl classifier_;
        const size_t                    numberOfTrees_;
        vigra::MultiArray<2, T>         rfFeatures_;
        vigra::MultiArray<1, uint8_t>   rfLabels_;

        std::vector< T >        newRfFeatruresFlat_;
        std::vector<uint8_t>    newRfLabels_;
        uint64_t numberOfFeatures_;
    };

} // namespace nifty::graph
} // namespace nifty

#endif  // NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX
<commit_msg>switched back to old rf<commit_after>#pragma once
#ifndef NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX
#define NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX

#include <iostream>

#include "vigra/multi_array.hxx"
#include "vigra/random_forest.hxx"
#include "vigra/random_forest_3.hxx"
#include "nifty/tools/timer.hxx"

namespace nifty{
namespace graph{

    template<class T>
    class RfClassifier{
    public:
        RfClassifier(const size_t numberOfTrees=255)
        :   classifier_(nullptr),
            numberOfTrees_(numberOfTrees){

        }
        void initialize(const size_t numberOfFeatures){
            numberOfFeatures_ = numberOfFeatures;
            classifier_ = nullptr;
        }
        void addTrainingExample(const T * features, const uint8_t label){
            newRfLabels_.push_back(label);
            for(size_t fi=0; fi<numberOfFeatures_; ++fi){
                newRfFeatruresFlat_.push_back(features[fi]);
            }
        }
        void train(){
            tools::VerboseTimer t(false);
            t.startAndPrint("       makeTZrainingSet");
            makeTrainingSet();
            t.stopAndPrint();
            t.reset();

             t.startAndPrint("      do training");
            if(classifier_ != nullptr){
                delete classifier_;
            }
            auto rfOpts = vigra::RandomForestOptions();
            rfOpts.tree_count(numberOfTrees_);
            rfOpts.predict_weighted();
            classifier_ = new  vigra::RandomForest<uint8_t>(rfOpts);

            // construct visitor to calculate out-of-bag error
            vigra::rf::visitors::OOB_Error oob_v;
            // perform training
            classifier_->learn(rfFeatures_, rfLabels_, vigra::rf::visitors::create_visitor(oob_v));
            t.stopAndPrint();
            t.reset();
        }

        double predictProbability(const T * features)const{
            // copy stuff atm
            vigra::MultiArray<2, T>       f(vigra::Shape2(1,numberOfFeatures_));
            vigra::MultiArray<2, double>  p(vigra::Shape2(1,2));
            for(size_t i=0; i<numberOfFeatures_; ++i){
                f[i] = features[i];
            }
            classifier_->predictProbabilities(f,p);
            return p(0,1);
        }
    private:
        void makeTrainingSet(){

            const auto nOld = rfFeatures_.shape(0);
            const auto nAdded = newRfLabels_.size();
            const auto nTotal = nOld + nAdded;

            //std::cout<<"new added examples "<<nAdded<<" total "<<nTotal<<"\n";
            vigra::MultiArray<2, T> fNew(vigra::Shape2( nTotal ,numberOfFeatures_));
            vigra::MultiArray<2, uint8_t> lNew(vigra::Shape2( nTotal ,1));

            for(auto i=0; i<nOld; ++i){
                lNew[i] = rfLabels_[i];
                for(auto fi=0; fi<numberOfFeatures_; ++fi)
                    fNew(i, fi) = rfFeatures_(i,fi);
            }
            auto c = 0;
            for(auto i=nOld; i<nTotal; ++i){
                lNew[i] = newRfLabels_[i-nOld];
                for(auto fi=0; fi<numberOfFeatures_; ++fi){
                    fNew(i, fi) = newRfFeatruresFlat_[c];
                    ++c;
                }
            }
            rfFeatures_ = fNew;
            rfLabels_ = lNew;
            newRfLabels_.resize(0);
            newRfFeatruresFlat_.resize(0);
        }

        vigra::RandomForest<uint8_t> *  classifier_;
        const size_t                    numberOfTrees_;
        vigra::MultiArray<2, T>         rfFeatures_;
        vigra::MultiArray<2, uint8_t>   rfLabels_;

        std::vector< T >        newRfFeatruresFlat_;
        std::vector<uint8_t>    newRfLabels_;
        uint64_t numberOfFeatures_;
    };

    /*
    template<class T>
    class RfClassifier{
    public:

        typedef vigra::MultiArray<2, double>            Features;
        typedef vigra::MultiArray<1, uint8_t>           Labels;
        typedef typename vigra::rf3::DefaultRF<Features, Labels>::type RfImpl;

        RfClassifier(const size_t numberOfTrees=255)
        :   classifier_(),
            numberOfTrees_(numberOfTrees){

        }
        void initialize(const size_t numberOfFeatures){
            numberOfFeatures_ = numberOfFeatures;
        }
        void addTrainingExample(const T * features, const uint8_t label){
            newRfLabels_.push_back(label);
            for(size_t fi=0; fi<numberOfFeatures_; ++fi){
                newRfFeatruresFlat_.push_back(features[fi]);
            }
        }
        void train(){
            tools::VerboseTimer t(false);
            t.startAndPrint("       makeTZrainingSet");
            makeTrainingSet();
            t.stopAndPrint();
            t.reset();

            t.startAndPrint("      do training");

            vigra::rf3::RandomForestOptions const options = vigra::rf3::RandomForestOptions()
                                                   .tree_count(numberOfTrees_)
                                                   .bootstrap_sampling(true)
                                                   .n_threads(-1);
            vigra::rf3::OOBError oob;
            classifier_ = random_forest(rfFeatures_, rfLabels_, options, create_visitor(oob));

            t.stopAndPrint();
            t.reset();
        }

        double predictProbability(const T * features)const{
            // copy stuff atm
            vigra::MultiArray<2, T>       f(vigra::Shape2(1,numberOfFeatures_));
            vigra::MultiArray<2, double>  p(vigra::Shape2(1,2));
            for(size_t i=0; i<numberOfFeatures_; ++i){
                f[i] = features[i];
            }
            classifier_.predict_proba(f,p);
            return p(0,1);
        }
    private:
        void makeTrainingSet(){

            const auto nOld = rfFeatures_.shape(0);
            const auto nAdded = newRfLabels_.size();
            const auto nTotal = nOld + nAdded;

            //std::cout<<"new added examples "<<nAdded<<" total "<<nTotal<<"\n";
            Features fNew(vigra::Shape2( nTotal ,numberOfFeatures_));
            Labels lNew = Labels(vigra::Shape1( nTotal));

            for(auto i=0; i<nOld; ++i){
                lNew[i] = rfLabels_[i];
                for(auto fi=0; fi<numberOfFeatures_; ++fi)
                    fNew(i, fi) = rfFeatures_(i,fi);
            }
            auto c = 0;
            for(auto i=nOld; i<nTotal; ++i){
                lNew[i] = newRfLabels_[i-nOld];
                for(auto fi=0; fi<numberOfFeatures_; ++fi){
                    fNew(i, fi) = newRfFeatruresFlat_[c];
                    ++c;
                }
            }
            rfFeatures_ = fNew;
            rfLabels_ = lNew;
            newRfLabels_.resize(0);
            newRfFeatruresFlat_.resize(0);
        }

        RfImpl classifier_;
        const size_t                    numberOfTrees_;
        vigra::MultiArray<2, T>         rfFeatures_;
        vigra::MultiArray<1, uint8_t>   rfLabels_;

        std::vector< T >        newRfFeatruresFlat_;
        std::vector<uint8_t>    newRfLabels_;
        uint64_t numberOfFeatures_;
    };
    */

} // namespace nifty::graph
} // namespace nifty

#endif  // NIFTY_GRAPH_GALA_CLASSIFIER_RF_HXX
<|endoftext|>


<commit_before>/**
    This is a CPP template for CS3230 - Programming Assignment 1 - Part 1
    (January-2015)

    You are not required to follow the template. Feel free to modify any part.

    Comment your code!
**/

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char RADIX_POINT = '.';
const int MAX_LEN = 10010;

int valueOf(char x) { // integer value of a digit
    if ('0' <= x and x <= '9') {
        return x - '0';
    }

    if ('A' <= x and x <= 'Z') {
        return x - 'A' + 10;
    }

    return 0;
};

char digitOf(int val) { // val must be < base <= 36
    return digits[val];
};

//Trim leading and trailing zeros, and radixpoint
string trim(string aStr) {
    string X = aStr;
    //leading zeros: 000.001
    while (X.length() > 1 and X[0] == '0' and X[1] != RADIX_POINT) {
        X.erase(0,1);
    }

    // trailing zeros and radix point:
    if (X.find(RADIX_POINT) != string::npos) {
        // 0.010; 1.000
        while (X.length() >= 1 and X[X.length()-1] =='0') {
            X.erase(X.length() - 1, 1);
        }

        // 123.
        if (X.length() >= 1 and X[X.length()-1] == RADIX_POINT) {
            X.erase(X.length() - 1);
        }
        if (X[0] == RADIX_POINT) {
            X = "0" + X; // insert "0" into ".123"
        }
    }

    if (X == "") {
        X = "0";
    }

    return X;
};

void convertStrToArr(string str, char* arr) {
    strcpy(arr, str.c_str());
};

void resetArray(char* arr) {
    memset(arr, '\0', sizeof(char) * MAX_LEN);
}

string convertArrToStr(char arr[]) {
    string S(arr);
    return S;
};

void reverseStr(string &str) {
    std::reverse(str.begin(), str.end());
};

void printArray(char arr[]) {
    int len = strlen(arr);
    for (int i = 0; i < len; i++) {
        cout << arr[i];
    }
    cout << endl;
};

void printArrayAsNumber(char arr[]) {
    string sum = convertArrToStr(arr);
    reverseStr(sum);
    cout << trim(sum) << endl;
}

void intToString(int number, int base, char arr[]) {
    arr[0] = digitOf(number % base);
    arr[1] = digitOf(number / base);
};

// void copyArrays(char srcArray[], char dstArray[]) {
//     for (int i = 0; i < MAX_LEN; i++) {
//         dstArray[i] = srcArray[i];
//     }
// }

// void addArrays(char aArray[], char bArray[], int base, char rArray[]) {
//     resetArray(rArray);
//     int lenA = strlen(aArray);
//     int lenB = strlen(bArray);
//     cout << lenA << endl;
//     cout << lenB << endl;
//     int longerLength = lenA > lenB ? lenA : lenB;
//     char carryOver = '0';
//     for (int i = 0; i < longerLength; i++) {
//         int aDigit = valueOf(aArray[i]);
//         int bDigit = valueOf(bArray[i]);
//         char productAsString[2];
//         intToString(aDigit + bDigit + valueOf(carryOver), base, productAsString);
//         rArray[i] = productAsString[0];
//         carryOver = productAsString[1];
//     }
//     rArray[longerLength] = carryOver;
// }

void multiplyArrays(char aArray[], char bArray[], int base, char rArray[]) {
    resetArray(rArray);
    char iArray[MAX_LEN];
    char *tempArray = new char[MAX_LEN];
    int lenA = strlen(aArray);
    int lenB = strlen(bArray);
    for (int i = 0; i < lenA; i++) {
        char carryOver = '0';
        resetArray(iArray);
        int j = 0;
        for (j = 0; j < lenB; j++) {
            int aDigit = valueOf(aArray[i]);
            int bDigit = valueOf(bArray[j]);
            char productAsString[2];
            intToString(aDigit * bDigit + valueOf(carryOver), base, productAsString);
            iArray[j+i] = productAsString[0];
            carryOver = productAsString[1];
        }
        iArray[j+i] = carryOver;

        // Add iArray to existing rArray
        carryOver = '0';
        for (int k = i; k <= j+i; k++) {
            int aDigit = valueOf(rArray[k]);
            int bDigit = valueOf(iArray[k]);
            char productAsString[2];
            intToString(aDigit + bDigit + valueOf(carryOver), base, productAsString);
            rArray[k] = productAsString[0];
            carryOver = productAsString[1];
        }
        rArray[j+i+1] = carryOver;
    }
}

long int milisecond(struct timeval tp){
    long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
    return ms;
};

int main() {
    int T;
    cin >> T;
    int base;
    string V, M, P;
    char vArray[MAX_LEN];
    char mArray[MAX_LEN];
    char *rArray = new char[MAX_LEN];
    for (int i = 0; i < T; i++) {
        cin >> base;
        cin >> V;
        cin >> M;
        reverseStr(V);
        reverseStr(M);

        resetArray(vArray);
        resetArray(mArray);
        resetArray(rArray);

        convertStrToArr(V, vArray);
        convertStrToArr(M, mArray);
        multiplyArrays(vArray, mArray, base, rArray);

        printArrayAsNumber(rArray);
    };

    return 0;
}
<commit_msg>[PA1] Converted to integer<commit_after>/**
    This is a CPP template for CS3230 - Programming Assignment 1 - Part 1
    (January-2015)

    You are not required to follow the template. Feel free to modify any part.

    Comment your code!
**/

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

const string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char RADIX_POINT = '.';
const int MAX_LEN = 10010;

int lenV;
int lenM;
int lenTotal;

int valueOf(char x) { // integer value of a digit
    if ('0' <= x and x <= '9') {
        return x - '0';
    }

    if ('A' <= x and x <= 'Z') {
        return x - 'A' + 10;
    }

    return 0;
};

char digitOf(int val) { // val must be < base <= 36
    return digits[val];
};

//Trim leading and trailing zeros, and radixpoint
string trim(string aStr) {
    string X = aStr;
    //leading zeros: 000.001
    while (X.length() > 1 and X[0] == '0' and X[1] != RADIX_POINT) {
        X.erase(0,1);
    }

    // trailing zeros and radix point:
    if (X.find(RADIX_POINT) != string::npos) {
        // 0.010; 1.000
        while (X.length() >= 1 and X[X.length()-1] =='0') {
            X.erase(X.length() - 1, 1);
        }

        // 123.
        if (X.length() >= 1 and X[X.length()-1] == RADIX_POINT) {
            X.erase(X.length() - 1);
        }
        if (X[0] == RADIX_POINT) {
            X = "0" + X; // insert "0" into ".123"
        }
    }

    if (X == "") {
        X = "0";
    }

    return X;
};

void resetArray(int* arr, int len) {
    memset(arr, 0, sizeof(int) * len);
}

void convertStrToIntArr(string str, int* arr, int len) {
    string::iterator it;
    int i = 0;
    for (it = str.begin(); it < str.end(); it++, i++) {
        arr[i] = valueOf(*it);
    }
};

string convertIntArrToStr(int arr[], int len) {
    char *tmp = new char[len];
    for (int i = 0; i < len; i++) {
        tmp[i] = digitOf(arr[i]);
    }
    string S(tmp);
    return S;
};

void reverseStr(string &str) {
    std::reverse(str.begin(), str.end());
};

void printStrArray(char arr[]) {
    int len = strlen(arr);
    for (int i = 0; i < len; i++) {
        cout << arr[i];
    }
    cout << endl;
};

void printIntArray(int arr[], int len) {
    for (int i = 0; i < len; i++) {
        cout << arr[i];
    }
    cout << endl;
};

void printArrayAsNumber(int arr[], int len) {

    string result = "";
    for (int i = len-1; i >= 0; i--) {
        result.append(1, digitOf(arr[i]));
    }

    cout << trim(result) << endl;
}

void intToString(int number, int base, int arr[]) {
    arr[0] = digitOf(number % base);
    arr[1] = digitOf(number / base);
};

void multiplyArrays(int aArray[], int bArray[], int lenA, int lenB, int base, int rArray[]) {
    int lenTotal = lenA + lenB;
    resetArray(rArray, lenTotal);

    int iArray[lenTotal];
    int *tempArray = new int[lenTotal];
    int carryOver = 0;
    for (int i = 0; i < lenA; i++) {
        carryOver = 0;
        resetArray(iArray, lenTotal);
        int j = 0;
        for (j = 0; j < lenB; j++) {
            int product = aArray[i] * bArray[j] + carryOver;
            iArray[j+i] = product % base;
            carryOver = product / base;
        }
        iArray[j+i] = carryOver;

        // Add iArray to existing rArray
        carryOver = 0;
        for (int k = i; k <= j+i; k++) {
            int product = rArray[k] + iArray[k] + carryOver;
            rArray[k] = product % base;
            carryOver = product / base;
        }
        // cout << j+i << endl;
        rArray[j+i+1] = carryOver;
        // cout << lenA << "," << lenB << "," << j+i << endl;
    }
}

long int milisecond(struct timeval tp){
    long int ms = tp.tv_sec * 1000 + tp.tv_usec / 1000;
    return ms;
};

int main() {
    int T;
    cin >> T;
    int base;
    string V, M, P;
    for (int i = 0; i < T; i++) {
        cin >> base;
        cin >> V;
        cin >> M;
        reverseStr(V);
        reverseStr(M);

        lenV = V.length();
        lenM = M.length();
        lenTotal = lenV + lenM;

        int vArray[lenV];
        int mArray[lenM];
        int *rArray = new int[lenTotal];

        resetArray(vArray, lenV);
        resetArray(mArray, lenM);
        resetArray(rArray, lenTotal);

        convertStrToIntArr(V, vArray, lenV);
        convertStrToIntArr(M, mArray, lenM);
        // cout << lenV << lenM << lenTotal << endl;
        multiplyArrays(vArray, mArray, lenV, lenM, base, rArray);
        // printIntArray(rArray, lenTotal);
        printArrayAsNumber(rArray, lenTotal);
    };

    return 0;
}
<|endoftext|>


<commit_before>#include <elevator/sessionmanager.h>
#include <elevator/serialization.h>
#include <elevator/restartwrapper.h>

namespace elevator {

using namespace serialization;

const udp::Address SessionManager::commSend{ udp::IPv4Address::any, udp::Port{ 64032 } };
const udp::Address SessionManager::commRcv{ udp::IPv4Address::any, udp::Port{ 64033 } };
const udp::Address SessionManager::commBroadcast{ udp::IPv4Address::broadcast, udp::Port{ 64033 } };

struct Initial {
    Initial() = default;
    Initial( std::tuple<> ) { };
    std::tuple<> tuple() const { return std::tuple<>(); }
    static TypeSignature type() {
        return TypeSignature::InitialPacket;
    }
};

struct Ready {
    Ready() = default;
    Ready( std::tuple<> ) { };
    std::tuple<> tuple() const { return std::tuple<>(); }
    static TypeSignature type() {
        return TypeSignature::ElevatorReady;
    }
};

struct RecoveryState {
    RecoveryState() = default;
    RecoveryState( ElevatorState state, std::set< udp::IPv4Address > peers ) :
        state( state ), peers( peers )
    { }
    RecoveryState( std::tuple< ElevatorState, std::set< udp::IPv4Address > > t )
        : RecoveryState( std::get< 0 >( t ), std::get< 1 >( t ) )
    { }
    static TypeSignature type() { return TypeSignature::RecoveryState; }
    std::tuple< ElevatorState, std::set< udp::IPv4Address > > tuple() const {
        return std::make_tuple( state, peers );
    }

    ElevatorState state;
    std::set< udp::IPv4Address > peers;
};

SessionManager::SessionManager( GlobalState &glo ) : _state( glo ),
    _sendSock{ commSend, true }, _recvSock{ commRcv, true }
{ }

void SessionManager::_initSender( std::atomic< int > *initPhase ) {
    _sendSock.enableBroadcast();
    while( *initPhase < 2 ) {
          udp::Packet pack;
          switch ( *initPhase ) {
                case 0: {
                    pack = Serializer::toPacket( Initial() );
                    break; }
                case 1: {
                    pack = Serializer::toPacket( Ready() );
                    break; }
          }
          pack.address() = commBroadcast;
          bool sent = _sendSock.sendPacket( pack );
          assert( sent, "send failed" );
          std::this_thread::sleep_for( std::chrono::milliseconds( 500 ) );
    }
}

void SessionManager::_initListener( std::atomic< int > *initPhase, int count ) {
    std::set< udp::IPv4Address > barrier;

    while ( *initPhase < 2 ) {
        udp::Packet pack = _recvSock.recvPacketWithTimeout( 300 );
        if ( pack.size() != 0 ) {
            switch ( Serializer::packetType( pack ) ) {
                case TypeSignature::InitialPacket: {
                    _peers.insert( pack.address().ip() );
                    break; }
                case TypeSignature::ElevatorReady: {
                    _peers.insert( pack.address().ip() ); // it might still be that we dont know
                    barrier.insert( pack.address().ip() );
                    break; }
                case TypeSignature::RecoveryState: {
                    _needRecovery = true;
                    auto maybeRecovered = Serializer::fromPacket< RecoveryState >( pack );
                    assert( !maybeRecovered.isNothing(), "error deserializing Recovery" );
                    RecoveryState recovered = maybeRecovered.value();
                    _state.update( recovered.state );
                    _peers = recovered.peers;
                    *initPhase = 2;
                    break; }
                default:
                    std::cerr << "Unknown packet received on service channel" << std::endl;
            }
            if ( int( barrier.size() ) == count )
                *initPhase = 2;
            else if ( int( _peers.size() ) == count )
                *initPhase = 1;
        }
    }
}

void SessionManager::connect( int count ) {
    // first continue sending Initial messages untill we have count peers

    std::atomic< int > initPhase{ 0 };
    std::thread findPeers( &SessionManager::_initSender, this, &initPhase );
    _initListener( &initPhase, count );
    findPeers.join();

    auto localAddrs = udp::IPv4Address::getMachineAddresses();
    int i = 0;

    // the set is sorted (guaranteed by C++) and therefore same on all elevators
    for ( auto addr : _peers ) {
        if ( localAddrs.find( addr ) != localAddrs.end() ) {
            _id = i;
            break;
        }
        ++i;
    }
    assert_leq( 0, _id, "Could not assing ID" );
    std::cout << "detected id " << _id << std::endl;

    // if RecoveryState is received use it for initialization, save it
    // and save recovery flag

    // when we have count peers start sending Ready message untill we have
    // count peers in ready set

    // if Ready is received add to ready set

    // now start monitoring thread
    _thr = std::thread( restartWrapper( &SessionManager::_loop ), this );
}

void SessionManager::_loop() {

    while ( true ) {
        udp::Packet pack = _recvSock.recvPacketWithTimeout( 300 );
        if ( pack.size() != 0
                && (Serializer::packetType( pack ) == TypeSignature::InitialPacket
                    || Serializer::packetType( pack ) == TypeSignature::ElevatorReady ) ) {
            int i = 0;
            bool found = false;
            for ( auto addr : _peers ) {
                if ( addr == pack.address().ip() ) {
                    found = true;
                    break;
                }
                ++i;
            }
            if ( !found ) {
                /* NOTE: we can't add unknown elevator, it would change IDs and make
                 * mess in recovery mechanisms */
                std::cerr << "WARNING: Attempt to socialization from unknown IP "
                          << pack.address().ip() << ". It will be ignored." << std::endl;
                continue;
            }

            if ( _state.has( i ) ) {
                std::cerr << "NOTICE: Sending recovery to elevator " << i << ", ("
                          << pack.address().ip() << ")" << std::endl;
                udp::Packet recovery = Serializer::toPacket( RecoveryState( _state.get( i ), _peers ) );
                recovery.address() = commBroadcast;
                _sendSock.sendPacket( recovery );
            } else {
                std::cerr << "NOTICE: Late initialization of elevator " << i << ", ("
                          << pack.address().ip() << ")" << std::endl;
                // this is rare case when elevator initializes and then fails before
                // sending state, it is so rare we will no wait for it to confirm
                // explicitly (if it resends initial or ready, then we would
                // resend ready anyway in this loop)
                udp::Packet ready = Serializer::toPacket( Ready() );
                ready.address() = commBroadcast;
                _sendSock.sendPacket( ready );
            }
        }
    }
}

}
<commit_msg>sessionmanager: Do not use broadcast for recovery messages.<commit_after>#include <elevator/sessionmanager.h>
#include <elevator/serialization.h>
#include <elevator/restartwrapper.h>

namespace elevator {

using namespace serialization;

const udp::Address SessionManager::commSend{ udp::IPv4Address::any, udp::Port{ 64032 } };
const udp::Address SessionManager::commRcv{ udp::IPv4Address::any, udp::Port{ 64033 } };
const udp::Address SessionManager::commBroadcast{ udp::IPv4Address::broadcast, udp::Port{ 64033 } };

struct Initial {
    Initial() = default;
    Initial( std::tuple<> ) { };
    std::tuple<> tuple() const { return std::tuple<>(); }
    static TypeSignature type() {
        return TypeSignature::InitialPacket;
    }
};

struct Ready {
    Ready() = default;
    Ready( std::tuple<> ) { };
    std::tuple<> tuple() const { return std::tuple<>(); }
    static TypeSignature type() {
        return TypeSignature::ElevatorReady;
    }
};

struct RecoveryState {
    RecoveryState() = default;
    RecoveryState( ElevatorState state, std::set< udp::IPv4Address > peers ) :
        state( state ), peers( peers )
    { }
    RecoveryState( std::tuple< ElevatorState, std::set< udp::IPv4Address > > t )
        : RecoveryState( std::get< 0 >( t ), std::get< 1 >( t ) )
    { }
    static TypeSignature type() { return TypeSignature::RecoveryState; }
    std::tuple< ElevatorState, std::set< udp::IPv4Address > > tuple() const {
        return std::make_tuple( state, peers );
    }

    ElevatorState state;
    std::set< udp::IPv4Address > peers;
};

SessionManager::SessionManager( GlobalState &glo ) : _state( glo ),
    _sendSock{ commSend, true }, _recvSock{ commRcv, true }
{ }

void SessionManager::_initSender( std::atomic< int > *initPhase ) {
    _sendSock.enableBroadcast();
    while( *initPhase < 2 ) {
          udp::Packet pack;
          switch ( *initPhase ) {
                case 0: {
                    pack = Serializer::toPacket( Initial() );
                    break; }
                case 1: {
                    pack = Serializer::toPacket( Ready() );
                    break; }
          }
          pack.address() = commBroadcast;
          bool sent = _sendSock.sendPacket( pack );
          assert( sent, "send failed" );
          std::this_thread::sleep_for( std::chrono::milliseconds( 500 ) );
    }
}

void SessionManager::_initListener( std::atomic< int > *initPhase, int count ) {
    std::set< udp::IPv4Address > barrier;

    while ( *initPhase < 2 ) {
        udp::Packet pack = _recvSock.recvPacketWithTimeout( 300 );
        if ( pack.size() != 0 ) {
            switch ( Serializer::packetType( pack ) ) {
                case TypeSignature::InitialPacket: {
                    _peers.insert( pack.address().ip() );
                    break; }
                case TypeSignature::ElevatorReady: {
                    _peers.insert( pack.address().ip() ); // it might still be that we dont know
                    barrier.insert( pack.address().ip() );
                    break; }
                case TypeSignature::RecoveryState: {
                    _needRecovery = true;
                    auto maybeRecovered = Serializer::fromPacket< RecoveryState >( pack );
                    assert( !maybeRecovered.isNothing(), "error deserializing Recovery" );
                    RecoveryState recovered = maybeRecovered.value();
                    _state.update( recovered.state );
                    _peers = recovered.peers;
                    *initPhase = 2;
                    break; }
                default:
                    std::cerr << "Unknown packet received on service channel" << std::endl;
            }
            if ( int( barrier.size() ) == count )
                *initPhase = 2;
            else if ( int( _peers.size() ) == count )
                *initPhase = 1;
        }
    }
}

void SessionManager::connect( int count ) {
    // first continue sending Initial messages untill we have count peers

    std::atomic< int > initPhase{ 0 };
    std::thread findPeers( &SessionManager::_initSender, this, &initPhase );
    _initListener( &initPhase, count );
    findPeers.join();

    auto localAddrs = udp::IPv4Address::getMachineAddresses();
    int i = 0;

    // the set is sorted (guaranteed by C++) and therefore same on all elevators
    for ( auto addr : _peers ) {
        if ( localAddrs.find( addr ) != localAddrs.end() ) {
            _id = i;
            break;
        }
        ++i;
    }
    assert_leq( 0, _id, "Could not assing ID" );
    std::cout << "detected id " << _id << std::endl;

    // if RecoveryState is received use it for initialization, save it
    // and save recovery flag

    // when we have count peers start sending Ready message untill we have
    // count peers in ready set

    // if Ready is received add to ready set

    // now start monitoring thread
    _thr = std::thread( restartWrapper( &SessionManager::_loop ), this );
}

void SessionManager::_loop() {

    while ( true ) {
        udp::Packet pack = _recvSock.recvPacketWithTimeout( 300 );
        if ( pack.size() != 0
                && (Serializer::packetType( pack ) == TypeSignature::InitialPacket
                    || Serializer::packetType( pack ) == TypeSignature::ElevatorReady ) ) {
            int i = 0;
            bool found = false;
            for ( auto addr : _peers ) {
                if ( addr == pack.address().ip() ) {
                    found = true;
                    break;
                }
                ++i;
            }
            if ( !found ) {
                /* NOTE: we can't add unknown elevator, it would change IDs and make
                 * mess in recovery mechanisms */
                std::cerr << "WARNING: Attempt to socialization from unknown IP "
                          << pack.address().ip() << ". It will be ignored." << std::endl;
                continue;
            }

            // we cannot use broadcast here: it would cause infinite recovery loop
            udp::Address target{ pack.address().ip(), commBroadcast.port() };

            if ( _state.has( i ) ) {
                std::cerr << "NOTICE: Sending recovery to elevator " << i << ", ("
                          << pack.address().ip() << ")" << std::endl;
                udp::Packet recovery = Serializer::toPacket( RecoveryState( _state.get( i ), _peers ) );
                recovery.address() = target;
                _sendSock.sendPacket( recovery );
            } else {
                std::cerr << "NOTICE: Late initialization of elevator " << i << ", ("
                          << pack.address().ip() << ")" << std::endl;
                // this is rare case when elevator initializes and then fails before
                // sending state, it is so rare we will no wait for it to confirm
                // explicitly (if it resends initial or ready, then we would
                // resend ready anyway in this loop)
                udp::Packet ready = Serializer::toPacket( Ready() );
                ready.address() = target;
                _sendSock.sendPacket( ready );
            }
        }
    }
}

}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "EC_Sound.h"
#include "IModule.h"
#include "Framework.h"
#include "Entity.h"
#include "EC_OgrePlaceable.h"
#include "SceneManager.h"
#include "SoundServiceInterface.h"

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("EC_Sound")

#include "MemoryLeakCheck.h"

EC_Sound::EC_Sound(IModule *module):
    IComponent(module->GetFramework()),
    sound_id_(0),
    soundId(this, "Sound ref"),
    soundInnerRadius(this, "Sound radius inner", 0.0f),
    soundOuterRadius(this, "Sound radius outer", 20.0f),
    loopSound(this, "Loop sound", false),
    triggerSound(this, "Trigger sound", false),
    soundGain(this, "Sound gain", 1.0f)
{
    static AttributeMetadata metaData("", "0", "1", "0.1");
    soundGain.SetMetadata(&metaData);

    QObject::connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()));
}

EC_Sound::~EC_Sound()
{
    StopSound();
}

void EC_Sound::AttributeUpdated(IComponent *component, IAttribute *attribute)
{
    if(component != this)
        return;

    if(attribute->GetNameString() == soundId.GetNameString())
    {
        Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
        if(soundService && soundService->GetSoundName(sound_id_) != soundId.Get().toStdString())
            StopSound();
    }
    else if(attribute->GetNameString() == triggerSound.GetNameString())
    {
        // Play sound if sound asset id has been setted and if sound has been triggered or looped.
        if(triggerSound.Get() == true && (!soundId.Get().isNull() || loopSound.Get()))
            PlaySound();
    }
    UpdateSoundSettings();
}

void EC_Sound::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        entity->ConnectAction("PlaySound", this, SLOT(PlaySound()));
        entity->ConnectAction("StopSound", this, SLOT(StopSound()));
    }
}

void EC_Sound::PlaySound()
{
    triggerSound.Set(false, AttributeChange::LocalOnly);
    ComponentChanged(AttributeChange::LocalOnly);

    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if(!soundService)
        return;

    if(sound_id_)
        StopSound();

    OgreRenderer::EC_OgrePlaceable *placeable = dynamic_cast<OgreRenderer::EC_OgrePlaceable *>(FindPlaceable().get());
    if(placeable)
    {
        sound_id_ = soundService->PlaySound3D(soundId.Get().toStdString(), Foundation::SoundServiceInterface::Triggered, false, placeable->GetPosition());
        soundService->SetGain(sound_id_, soundGain.Get());
        soundService->SetLooped(sound_id_, loopSound.Get());
        soundService->SetRange(sound_id_, soundInnerRadius.Get(), soundOuterRadius.Get(), 2.0f);
    }
    else // If entity isn't holding placeable component treat sound as ambient sound.
    {
        sound_id_ = soundService->PlaySound(soundId.Get().toStdString(), Foundation::SoundServiceInterface::Ambient);
        soundService->SetGain(sound_id_, soundGain.Get());
    }
}

void EC_Sound::StopSound()
{
    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if(!soundService)
        return;

    soundService->StopSound(sound_id_);
    sound_id_ = 0;
}

void EC_Sound::UpdateSoundSettings()
{
    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if(!soundService || !sound_id_)
        return;

    soundService->SetGain(sound_id_, soundGain.Get());
    soundService->SetLooped(sound_id_, loopSound.Get());
    soundService->SetRange(sound_id_, soundInnerRadius.Get(), soundOuterRadius.Get(), 2.0f);
}

void EC_Sound::UpdateSignals()
{
    disconnect(this, SLOT(AttributeUpdated(IComponent *, IAttribute *)));
    if(GetParentEntity())
    {
        Scene::SceneManager *scene = GetParentEntity()->GetScene();
        if(scene)
        connect(scene, SIGNAL(AttributeChanged(IComponent*, IAttribute*, AttributeChange::Type)),
                this, SLOT(AttributeUpdated(IComponent*, IAttribute*)));
        RegisterActions();
    }
}

ComponentPtr EC_Sound::FindPlaceable() const
{
    assert(framework_);
    ComponentPtr comp;
    if(!GetParentEntity())
        return comp;
    comp = GetParentEntity()->GetComponent<OgreRenderer::EC_OgrePlaceable>();
    return comp;
}<commit_msg>Annotated silent-fail issues with EC_Sound.cpp<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "DebugOperatorNew.h"
#include "EC_Sound.h"
#include "IModule.h"
#include "Framework.h"
#include "Entity.h"
#include "EC_OgrePlaceable.h"
#include "SceneManager.h"
#include "SoundServiceInterface.h"

#include "LoggingFunctions.h"
DEFINE_POCO_LOGGING_FUNCTIONS("EC_Sound")

#include "MemoryLeakCheck.h"

EC_Sound::EC_Sound(IModule *module):
    IComponent(module->GetFramework()),
    sound_id_(0),
    soundId(this, "Sound ref"),
    soundInnerRadius(this, "Sound radius inner", 0.0f),
    soundOuterRadius(this, "Sound radius outer", 20.0f),
    loopSound(this, "Loop sound", false),
    triggerSound(this, "Trigger sound", false),
    soundGain(this, "Sound gain", 1.0f)
{
    static AttributeMetadata metaData("", "0", "1", "0.1");
    soundGain.SetMetadata(&metaData);

    QObject::connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()));
}

EC_Sound::~EC_Sound()
{
    StopSound();
}

void EC_Sound::AttributeUpdated(IComponent *component, IAttribute *attribute)
{
    if(component != this)
        return;

    if(attribute->GetNameString() == soundId.GetNameString())
    {
        Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
        if(soundService && soundService->GetSoundName(sound_id_) != soundId.Get().toStdString())
            StopSound();
    }
    else if(attribute->GetNameString() == triggerSound.GetNameString())
    {
        // Play sound if sound asset id has been setted and if sound has been triggered or looped.
        if(triggerSound.Get() == true && (!soundId.Get().isNull() || loopSound.Get()))
            PlaySound();
    }
    UpdateSoundSettings();
}

void EC_Sound::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        entity->ConnectAction("PlaySound", this, SLOT(PlaySound()));
        entity->ConnectAction("StopSound", this, SLOT(StopSound()));
    }
}

void EC_Sound::PlaySound()
{
    triggerSound.Set(false, AttributeChange::LocalOnly);
    ComponentChanged(AttributeChange::LocalOnly);

    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if(!soundService)
    {
        // log warning
        return;
    }

    if(sound_id_)
        StopSound();

    OgreRenderer::EC_OgrePlaceable *placeable = dynamic_cast<OgreRenderer::EC_OgrePlaceable *>(FindPlaceable().get());
    if(placeable)
    {
        sound_id_ = soundService->PlaySound3D(soundId.Get().toStdString(), Foundation::SoundServiceInterface::Triggered, false, placeable->GetPosition());
        soundService->SetGain(sound_id_, soundGain.Get());
        soundService->SetLooped(sound_id_, loopSound.Get());
        soundService->SetRange(sound_id_, soundInnerRadius.Get(), soundOuterRadius.Get(), 2.0f);
    }
    else // If entity isn't holding placeable component treat sound as ambient sound.
    {
        sound_id_ = soundService->PlaySound(soundId.Get().toStdString(), Foundation::SoundServiceInterface::Ambient);
        soundService->SetGain(sound_id_, soundGain.Get());
    }
}

void EC_Sound::StopSound()
{
    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if (soundService)
        soundService->StopSound(sound_id_);

    sound_id_ = 0;
}

void EC_Sound::UpdateSoundSettings()
{
    Foundation::SoundServiceInterface *soundService = framework_->GetService<Foundation::SoundServiceInterface>();
    if(!soundService || !sound_id_)
    {
        // log warning
        return;
    }

    soundService->SetGain(sound_id_, soundGain.Get());
    soundService->SetLooped(sound_id_, loopSound.Get());
    soundService->SetRange(sound_id_, soundInnerRadius.Get(), soundOuterRadius.Get(), 2.0f);
}

void EC_Sound::UpdateSignals()
{
    disconnect(this, SLOT(AttributeUpdated(IComponent *, IAttribute *)));
    if (!GetParentEntity())
    {
        // log warning
        return;
    }
    Scene::SceneManager *scene = GetParentEntity()->GetScene();
    if(!scene)
    {
        // log warning
        return;
    }

    connect(scene, SIGNAL(AttributeChanged(IComponent*, IAttribute*, AttributeChange::Type)),
            this, SLOT(AttributeUpdated(IComponent*, IAttribute*)));
    RegisterActions();
}

ComponentPtr EC_Sound::FindPlaceable() const
{
    assert(framework_);
    ComponentPtr comp;
    if(!GetParentEntity())
        return comp;
    comp = GetParentEntity()->GetComponent<OgreRenderer::EC_OgrePlaceable>();
    return comp;
}<|endoftext|>