text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/vinniefalco/url
//

#ifndef BOOST_URL_CONFIG_HPP
#define BOOST_URL_CONFIG_HPP

#include <boost/url/detail/config.hpp>
#include <string>

namespace boost {
namespace urls {

/// The string alias template return type for allocating member functions.
template<class Allocator>
using string_type =
    std::basic_string<char,
        std::char_traits<char>, Allocator>;

#ifndef BOOST_URL_STANDALONE

/// The type of string url_view used by the library.
using string_view = boost::string_view;

/// The type of error code used by the library.
using error_code = boost::system::error_code;

/// The type of system error thrown by the library.
using system_error = boost::system::system_error;

/// The type of error category used by the library.
using error_category = boost::system::error_category;

/// The type of error condition used by the library.
using error_condition = boost::system::error_condition;

/// The type of optional used by the library.
template<class T>
using optional = boost::optional<T>;

#ifdef BOOST_URL_DOCS
/// Returns the generic error category used by the library.
error_category const&
generic_category();
#else
using boost::system::generic_category;
#endif

#else

using error_code = std::error_code;
using error_category = std::error_category;
using error_condition = std::error_condition;
using string_view = std::string_view;
using system_error = std::system_error;
using std::generic_category;

template<class T>
using optional = std::optional<T>;

#endif

} // urls
} // boost

#endif

max_stars_repo_name: syoliver/url

max_issues_repo_name: syoliver/url

max_forks_repo_name: syoliver/url


text:
#ifndef HERMIT_SPIRIT_KARMA_HTTP_PRAGMA_HPP
#define HERMIT_SPIRIT_KARMA_HTTP_PRAGMA_HPP

#include <iterator>
#include <vector>
#include <string>
#include <utility>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/std_pair.hpp>

#include <hermit/http_pragma.hpp>

namespace hermit {
  namespace spirit {
    namespace karma {
      template <typename Iterator>
        class http_pragma :
          public boost::spirit::karma::grammar< Iterator, hermit::http::pragma() > {
            public:
              typedef boost::fusion::vector3< std::string, boost::optional< unsigned int >, boost::optional< std::string > > attr_type;
              http_pragma() : http_pragma::base_type( root ) {
                namespace karma = boost::spirit::karma;
                namespace phx = boost::phoenix;
                token_char = karma::ascii::char_[
                  karma::_pass = karma::_val >= ' ' && karma::_val != '(' && karma::_val != ')' &&
                    karma::_val != '<' && karma::_val != '>' && karma::_val != '@' && karma::_val != '.' &&
                    karma::_val != ';' && karma::_val != ':' && karma::_val != '\\' && karma::_val != '"' &&
                    karma::_val != '/' && karma::_val != '[' && karma::_val != ']' && karma::_val != '?' &&
                    karma::_val != '=' && karma::_val != '{' && karma::_val != '}' && karma::_val != ' ',
                  karma::_1 = karma::_val
                ];
                token = +token_char;
                text_char = karma::byte_[
                  karma::_pass = karma::_val >= ' ' && karma::_val != '"',
                  karma::_1 = karma::_val
                ];
                text = text_char | karma::standard::space;
                quoted_pair = '\\' << karma::ascii::char_;
                quoted_string = '"' << *( text|quoted_pair ) << '"';
                root = ( "Pragma: " <<
                  ( ( karma::string << -( '=' << karma::uint_ ) << -( '=' << quoted_string ) ) % ", " ) )[
                  phx::if_( phx::at_c< 0 >( karma::_val ) )[
                    phx::push_back( karma::_1,
                      phx::construct< attr_type >( "no-cache", boost::none, boost::none ) )
                  ],
                  phx::bind( &http_pragma::build_extensions, phx::at_c< 1 >( karma::_val ), karma::_1, karma::_pass )
                ];
              }
            private:
              static void build_extensions( const std::map< std::string, boost::optional< std::string > > src, std::vector< attr_type > &dest, bool &_pass ) {
                std::transform( src.begin(), src.end(), std::back_inserter( dest ), [&]( const std::pair< std::string, boost::optional< std::string > > &src ) -> attr_type { _pass = !src.first.empty(); return attr_type( src.first, boost::none, src.second ); } );
              }
              boost::spirit::karma::rule< Iterator, char() > text_char;
              boost::spirit::karma::rule< Iterator, char() > text;
              boost::spirit::karma::rule< Iterator, char() > quoted_pair;
              boost::spirit::karma::rule< Iterator, std::string() > quoted_string;
              boost::spirit::karma::rule< Iterator, char() > token_char;
              boost::spirit::karma::rule< Iterator, std::string() > token;
              boost::spirit::karma::rule< Iterator, hermit::http::pragma() > root;
      };
    }
  }
}

#endif

ext: hpp

max_stars_repo_name: Fadis/hermit

max_issues_repo_name: Fadis/hermit

max_forks_repo_name: Fadis/hermit


text:
/**
 * Copyright (c) 2017-present, Facebook, Inc. and its affiliates.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */
#include "SafetyChecker.h"

#include <boost/format.hpp>

#include "logdevice/admin/safety/CheckImpactRequest.h"
#include "logdevice/common/Processor.h"
#include "logdevice/common/configuration/LocalLogsConfig.h"
#include "logdevice/common/configuration/UpdateableConfig.h"
#include "logdevice/common/stats/Stats.h"

#include "CheckMetaDataLogRequest.h"

namespace facebook { namespace logdevice {

using namespace facebook::logdevice::configuration;

SafetyChecker::SafetyChecker(Processor* processor,
                             size_t logs_in_flight,
                             bool abort_on_error,
                             std::chrono::milliseconds timeout,
                             size_t error_sample_size,
                             bool read_epoch_metadata_from_sequencer)
    : processor_(processor),
      timeout_(timeout),
      logs_in_flight_(logs_in_flight),
      abort_on_error_(abort_on_error),
      error_sample_size_(error_sample_size),
      read_epoch_metadata_from_sequencer_(read_epoch_metadata_from_sequencer) {}

Impact
SafetyChecker::checkImpact(const ShardAuthoritativeStatusMap& shard_status,
                           const ShardSet& shards,
                           StorageState target_storage_state,
                           SafetyMargin safety_margin,
                           std::vector<logid_t> logids_to_check) {
  // There is no point of checking this. It's always safe.
  if (target_storage_state == StorageState::READ_WRITE) {
    return Impact();
  }

  ld_info("Shards to drain: %s", toString(shards).c_str());
  ld_info("Target storage state is: %s",
          storageStateToString(target_storage_state).c_str());

  std::chrono::steady_clock::time_point start_time =
      std::chrono::steady_clock::now();

  Semaphore sem;
  Impact impact_result;
  auto cb = [&](Impact impact) {
    SCOPE_EXIT {
      sem.post();
    };
    impact_result = std::move(impact);
  };

  WorkerType worker_type = CheckImpactRequest::workerType(processor_);
  std::unique_ptr<Request> request =
      std::make_unique<CheckImpactRequest>(shard_status,
                                           shards,
                                           target_storage_state,
                                           safety_margin,
                                           logids_to_check,
                                           logs_in_flight_,
                                           abort_on_error_,
                                           timeout_,
                                           error_sample_size_,
                                           worker_type,
                                           cb);
  int rv = processor_->postRequest(request);
  if (rv != 0) {
    // We couldn't submit the request to the processor.
    ld_error("We couldn't submit the CheckImpactRequest to the logdevice "
             "processor: %s",
             error_description(err));
    ld_check(err != E::OK);
    return Impact(err);
  }

  sem.wait();

  double runtime = std::chrono::duration_cast<std::chrono::duration<double>>(
                       std::chrono::steady_clock::now() - start_time)
                       .count();
  ld_info("Done. Elapsed time: %.1fs", runtime);
  return impact_result;
}

std::string
storageSetWithStatus(const ShardSet& highlighted_shards,
                     const StorageSet& storage_set,
                     const ShardAuthoritativeStatusMap& status_map) {
  std::stringstream ss;
  ;
  ss << "[";
  for (auto it = storage_set.begin(); it != storage_set.end(); ++it) {
    AuthoritativeStatus status =
        status_map.getShardStatus(it->node(), it->shard());
    if (highlighted_shards.count(*it) > 0) {
      ss << "\033[1;1m";
    }
    if (status != AuthoritativeStatus::FULLY_AUTHORITATIVE) {
      ss << "\033[31;1m";
    }
    ss << it->toString() << "(" << toShortString(status) << ")";
    ss << "\033[0m";
    if (std::next(it) != storage_set.end()) {
      ss << ", ";
    }
  }
  ss << "]";
  return ss.str();
}

std::string
SafetyChecker::impactToString(const ShardSet& shards,
                              const ShardAuthoritativeStatusMap& shard_status,
                              const Impact& impact) {
  std::stringstream ss;
  if (impact.status != E::OK) {
    ss << "ERROR: Could NOT determine impact of all logs due to error: "
       << error_description(impact.status);
  } else if (impact.result != Impact::ImpactResult::NONE) {
    ss << folly::format("\033[31;1mUNSAFE\033[0m: Operation(s) on ({} shards) "
                        "would cause "
                        "{} for some log(s), as in "
                        "that storage set, as no enough domains will be "
                        "available. Sample logs/epochs affected: \n",
                        shards.size(),
                        Impact::toStringImpactResult(impact.result).c_str())
              .str();
  }
  for (auto& epoch_info : impact.logs_affected) {
    ss << folly::format(
        "({} -> Log ID: {}, Epoch: {}, Replication: {}, StorageSet: {})\n",
        Impact::toStringImpactResult(epoch_info.impact_result),
        epoch_info.log_id.val(),
        epoch_info.epoch.val(),
        toString(epoch_info.replication),
        storageSetWithStatus(shards, epoch_info.storage_set, shard_status));
  }
  return ss.str();
}
}} // namespace facebook::logdevice

ext: cpp


text:
/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>
*/

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

#define OSVR_DEV_VERBOSE_DISABLE

// Internal Includes
#include "PluginSpecificRegistrationContextImpl.h"
#include <osvr/Util/Verbosity.h>

// Library/third-party includes
#include <boost/range/adaptor/reversed.hpp>

// Standard includes
#include <stdexcept>

namespace osvr {
namespace pluginhost {
    PluginSpecificRegistrationContextImpl::
        PluginSpecificRegistrationContextImpl(std::string const &name)
        : PluginSpecificRegistrationContext(name), m_parent(nullptr) {
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContextImpl:\t"
                         << "Creating a plugin registration context for "
                         << name);
    }

    PluginSpecificRegistrationContextImpl::
        ~PluginSpecificRegistrationContextImpl() {
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContextImpl:\t"
                         "Destroying plugin reg context for "
                         << getName());

        // Delete the data in reverse order.
        for (auto &ptr : m_dataList | boost::adaptors::reversed) {
            ptr.reset();
        }
        m_parent = nullptr; // before anything else destructs, for safety?
    }

    void PluginSpecificRegistrationContextImpl::takePluginHandle(
        libfunc::PluginHandle &handle) {
        m_handle = handle;
    }

    void PluginSpecificRegistrationContextImpl::setParent(
        RegistrationContext &parent) {
        if (m_parent != nullptr && m_parent != &parent) {
            throw std::logic_error(
                "Can't set the registration context parent - already set!");
        }
        m_parent = &parent;
    }

    RegistrationContext &PluginSpecificRegistrationContextImpl::getParent() {
        if (m_parent == nullptr) {
            throw std::logic_error(
                "Can't access the registration context parent - it is null!");
        }
        return *m_parent;
    }

    RegistrationContext const &
    PluginSpecificRegistrationContextImpl::getParent() const {
        if (m_parent == nullptr) {
            throw std::logic_error(
                "Can't access the registration context parent - it is null!");
        }
        return *m_parent;
    }

    void
    PluginSpecificRegistrationContextImpl::triggerHardwareDetectCallbacks() {
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContext:\t"
                         "In triggerHardwareDetectCallbacks for "
                         << getName());

        for (auto const &f : m_hardwareDetectCallbacks) {
            f(this);
        }
    }

    void PluginSpecificRegistrationContextImpl::instantiateDriver(
        const std::string &driverName, const std::string &params) const {
        auto it = m_driverInstantiationCallbacks.find(driverName);
        if (it == end(m_driverInstantiationCallbacks)) {
            throw std::logic_error("No driver initialization callback was "
                                   "registered for the driver name " +
                                   driverName);
        }
        OSVR_ReturnCode ret = (it->second)(params.c_str());
        if (ret != OSVR_RETURN_SUCCESS) {
            throw std::runtime_error("Failure returned from driver "
                                     "initialization callback by name " +
                                     driverName);
        }
    }

    void PluginSpecificRegistrationContextImpl::registerDataWithDeleteCallback(
        OSVR_PluginDataDeleteCallback deleteCallback, void *pluginData) {
        m_dataList.emplace_back(pluginData, deleteCallback);
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContext:\t"
                         "Now have "
                         << m_dataList.size()
                         << " data delete callbacks registered for "
                         << getName());
    }

    void PluginSpecificRegistrationContextImpl::registerHardwareDetectCallback(
        OSVR_HardwareDetectCallback detectCallback, void *userData) {
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContext:\t"
                         "In registerHardwareDetectCallback");
        m_hardwareDetectCallbacks.emplace_back(detectCallback, userData);
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContext:\t"
                         "Now have "
                         << m_hardwareDetectCallbacks.size()
                         << " hardware detect callbacks registered for "
                         << getName());
    }

    void
    PluginSpecificRegistrationContextImpl::registerDriverInstantiationCallback(
        const char *name, OSVR_DriverInstantiationCallback constructor,
        void *userData) {
        OSVR_DEV_VERBOSE("PluginSpecificRegistrationContext:\t"
                         "In registerDriverInstantiationCallback");
        std::string n(name);
        if (n.empty()) {
            throw std::logic_error("Cannot register a driver instantiation "
                                   "callback with an empty name!");
        }
        using namespace std::placeholders;
        auto it = m_driverInstantiationCallbacks.find(name);
        if (it != end(m_driverInstantiationCallbacks)) {
            throw std::logic_error("A driver initialization callback by this "
                                   "name for this plugin has already been "
                                   "registered!");
        }
        auto opaque = extractOpaquePointer();
        m_driverInstantiationCallbacks[name] =
            [constructor, opaque, userData](const char *params) {
                return constructor(opaque, params, userData);
            };
    }

    util::AnyMap &PluginSpecificRegistrationContextImpl::data() {
        return m_data;
    }

    util::AnyMap const &PluginSpecificRegistrationContextImpl::data() const {
        return m_data;
    }
} // namespace pluginhost
} // namespace osvr

max_stars_repo_name: ethanpeng/OSVR-Core

max_issues_repo_name: ethanpeng/OSVR-Core

max_forks_repo_name: ethanpeng/OSVR-Core


text:
#include <common/net/message/fsck/CreateDefDirInodesMsg.h>
#include <common/net/message/fsck/CreateDefDirInodesRespMsg.h>
#include <common/net/message/fsck/CreateEmptyContDirsMsg.h>
#include <common/net/message/fsck/CreateEmptyContDirsRespMsg.h>
#include <common/net/message/fsck/DeleteDirEntriesMsg.h>
#include <common/net/message/fsck/DeleteDirEntriesRespMsg.h>
#include <common/net/message/fsck/DeleteChunksMsg.h>
#include <common/net/message/fsck/DeleteChunksRespMsg.h>
#include <common/net/message/fsck/FixInodeOwnersMsg.h>
#include <common/net/message/fsck/FixInodeOwnersRespMsg.h>
#include <common/net/message/fsck/FixInodeOwnersInDentryMsg.h>
#include <common/net/message/fsck/FixInodeOwnersInDentryRespMsg.h>
#include <common/net/message/fsck/LinkToLostAndFoundMsg.h>
#include <common/net/message/fsck/LinkToLostAndFoundRespMsg.h>
#include <common/net/message/fsck/MoveChunkFileMsg.h>
#include <common/net/message/fsck/MoveChunkFileRespMsg.h>
#include <common/net/message/fsck/RecreateFsIDsMsg.h>
#include <common/net/message/fsck/RecreateFsIDsRespMsg.h>
#include <common/net/message/fsck/RecreateDentriesMsg.h>
#include <common/net/message/fsck/RecreateDentriesRespMsg.h>
#include <common/net/message/fsck/RemoveInodesMsg.h>
#include <common/net/message/fsck/RemoveInodesRespMsg.h>

#include <common/net/message/fsck/UpdateFileAttribsMsg.h>
#include <common/net/message/fsck/UpdateFileAttribsRespMsg.h>
#include <common/net/message/fsck/UpdateDirAttribsMsg.h>
#include <common/net/message/fsck/UpdateDirAttribsRespMsg.h>

#include <common/net/message/nodes/SetTargetConsistencyStatesMsg.h>
#include <common/net/message/nodes/SetTargetConsistencyStatesRespMsg.h>

#include <common/net/message/storage/creating/MkDirMsg.h>
#include <common/net/message/storage/creating/MkDirRespMsg.h>
#include <common/net/message/storage/creating/UnlinkFileMsg.h>
#include <common/net/message/storage/creating/UnlinkFileRespMsg.h>
#include <common/net/message/storage/attribs/SetLocalAttrMsg.h>
#include <common/net/message/storage/attribs/SetLocalAttrRespMsg.h>

#include <common/toolkit/MessagingTk.h>
#include <common/toolkit/MetadataTk.h>

#include <program/Program.h>

#include "MsgHelperRepair.h"

#include <boost/lexical_cast.hpp>

template<typename RepairItemT>
static bool setSecondaryBad(uint16_t groupID, std::set<NumNodeID>& secondariesWithRepair,
      const std::list<RepairItemT>& args, std::list<RepairItemT>& failed)
{
   auto* bgm = Program::getApp()->getMetaMirrorBuddyGroupMapper();
   NumNodeID secondary(bgm->getSecondaryTargetID(groupID));

   if (secondariesWithRepair.count(secondary))
      return true;

   auto setRes = MsgHelperRepair::setNodeState(secondary, TargetConsistencyState_BAD);
   if (setRes == FhgfsOpsErr_SUCCESS)
   {
      secondariesWithRepair.insert(NumNodeID(bgm->getSecondaryTargetID(groupID)));
      return true;
   }

   LOG(GENERAL, ERR, "Failed to set secondary consistency state, not attempting repair action.",
         groupID, setRes);
   failed = args;
   return false;
}

FhgfsOpsErr MsgHelperRepair::setNodeState(NumNodeID node, TargetConsistencyState state)
{
   std::list<uint16_t> targets(1, node.val());
   std::list<uint8_t> states(1, state);
   SetTargetConsistencyStatesMsg msg(NODETYPE_Meta, &targets, &states, false);

   {
      auto secondary = Program::getApp()->getMetaNodes()->referenceNode(node);

      MessagingTk::requestResponse(*secondary, msg, NETMSGTYPE_SetTargetConsistencyStatesResp);
   }

   {
      auto mgmt = Program::getApp()->getMgmtNodes()->referenceFirstNode();

      const auto respMsg = MessagingTk::requestResponse(*mgmt, msg,
            NETMSGTYPE_SetTargetConsistencyStatesResp);
      if (!respMsg)
         return FhgfsOpsErr_COMMUNICATION;

      return static_cast<SetTargetConsistencyStatesRespMsg&>(*respMsg).getResult();
   }
}

void MsgHelperRepair::deleteDanglingDirEntries(NumNodeID node, bool isBuddyMirrored,
   FsckDirEntryList* dentries, FsckDirEntryList* failedDeletes,
   std::set<NumNodeID>& secondariesWithRepair)
{
   DeleteDirEntriesMsg deleteDirEntriesMsg(dentries);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &deleteDirEntriesMsg, NETMSGTYPE_DeleteDirEntriesResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *dentries, *failedDeletes))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* deleteDirEntriesRespMsg = (DeleteDirEntriesRespMsg*) rrArgs.outRespMsg.get();

      deleteDirEntriesRespMsg->getFailedEntries().swap(*failedDeletes);

      if (! failedDeletes->empty())
      {
         for (auto iter = failedDeletes->begin(); iter != failedDeletes->end(); iter++)
            LOG(GENERAL, CRITICAL, "Failed to delete directory entry from metadata node.",
                 node, isBuddyMirrored, ("entryID", iter->getID()));
      }
   }
   else
   {
      *failedDeletes = *dentries;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }
}

void MsgHelperRepair::createDefDirInodes(NumNodeID node, bool isBuddyMirrored,
   const std::vector<std::tuple<std::string, bool>>& entries, FsckDirInodeList* createdInodes,
   std::set<NumNodeID>& secondariesWithRepair)
{
   StringList failedInodeIDs;

   CreateDefDirInodesMsg createDefDirInodesMsgEx(entries);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &createDefDirInodesMsgEx, NETMSGTYPE_CreateDefDirInodesResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, {}, *createdInodes))
      {
         for (auto it = entries.begin(); it != entries.end(); ++it)
            failedInodeIDs.push_back(std::get<0>(*it));
         return;
      }
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* createDefDirInodesRespMsg = (CreateDefDirInodesRespMsg*) rrArgs.outRespMsg.get();

      createDefDirInodesRespMsg->getFailedInodeIDs().swap(failedInodeIDs);
      createDefDirInodesRespMsg->getCreatedInodes().swap(*createdInodes);
   }
   else
   {
      for (auto it = entries.begin(); it != entries.end(); ++it)
         failedInodeIDs.push_back(std::get<0>(*it));

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if (! failedInodeIDs.empty())
   {
      for (StringListIter iter = failedInodeIDs.begin(); iter != failedInodeIDs.end(); iter++)
         LOG(GENERAL, CRITICAL, "Failed to create default directory inode.", node, isBuddyMirrored,
               ("entryID", *iter));
   }
}

void MsgHelperRepair::correctInodeOwnersInDentry(NumNodeID node, bool isBuddyMirrored,
   FsckDirEntryList* dentries, NumNodeIDList* owners, FsckDirEntryList* failedCorrections,
   std::set<NumNodeID>& secondariesWithRepair)
{
   FixInodeOwnersInDentryMsg fixInodeOwnersMsg(*dentries, *owners);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &fixInodeOwnersMsg, NETMSGTYPE_FixInodeOwnersInDentryResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *dentries, *failedCorrections))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* fixInodeOwnersRespMsg = (FixInodeOwnersInDentryRespMsg*) rrArgs.outRespMsg.get();

      fixInodeOwnersRespMsg->getFailedEntries().swap(*failedCorrections);
   }
   else
   {
      *failedCorrections = *dentries;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if (! failedCorrections->empty())
   {
      for (auto iter = failedCorrections->begin(); iter != failedCorrections->end(); iter++)
         LOG(GENERAL, CRITICAL, "Failed to correct inode owner information in dentry.",
               node, isBuddyMirrored, ("entryID", iter->getID()));
   }
}

void MsgHelperRepair::correctInodeOwners(NumNodeID node, bool isBuddyMirrored,
   FsckDirInodeList* dirInodes, FsckDirInodeList* failedCorrections,
   std::set<NumNodeID>& secondariesWithRepair)
{
   FixInodeOwnersMsg fixInodeOwnersMsg(dirInodes);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &fixInodeOwnersMsg, NETMSGTYPE_FixInodeOwnersResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *dirInodes, *failedCorrections))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* fixInodeOwnersRespMsg = (FixInodeOwnersRespMsg*) rrArgs.outRespMsg.get();

      fixInodeOwnersRespMsg->getFailedInodes().swap(*failedCorrections);
   }
   else
   {
      *failedCorrections = *dirInodes;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if (! failedCorrections->empty())
   {
      for (auto iter = failedCorrections->begin(); iter != failedCorrections->end(); iter++)
         LOG(GENERAL, CRITICAL, "Failed to correct inode owner information.", node, isBuddyMirrored,
              ("entryID", iter->getID()));
   }
}

void MsgHelperRepair::deleteFiles(NumNodeID node, bool isBuddyMirrored, FsckDirEntryList* dentries,
   FsckDirEntryList* failedDeletes)
{
   const char* logContext = "MsgHelperRepair (deleteFiles)";

   for ( FsckDirEntryListIter iter = dentries->begin(); iter != dentries->end(); iter++ )
   {
      EntryInfo parentInfo(node, "", iter->getParentDirID(), "", DirEntryType_DIRECTORY, 0);

      std::string entryName = iter->getName();
      UnlinkFileMsg unlinkFileMsg(&parentInfo, entryName);

      RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
      RequestResponseArgs rrArgs(nullptr, &unlinkFileMsg, NETMSGTYPE_UnlinkFileResp);

      if (isBuddyMirrored)
         rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);

      FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

      if (commRes == FhgfsOpsErr_SUCCESS)
      {
         const auto unlinkFileRespMsg = (const UnlinkFileRespMsg*) rrArgs.outRespMsg.get();

         // get result
         int unlinkRes = unlinkFileRespMsg->getValue();

         if ( unlinkRes )
         {
            LogContext(logContext).log(Log_CRITICAL,
               "Failed to delete file; entryID: " + iter->getID());
            failedDeletes->push_back(*iter);
         }
      }
      else
      {
         failedDeletes->push_back(*iter);

         LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
      }
   }
}

void MsgHelperRepair::deleteChunks(Node& node, FsckChunkList* chunks, FsckChunkList* failedDeletes)
{
   const char* logContext = "MsgHelperRepair (deleteChunks)";

   DeleteChunksMsg deleteChunksMsg(chunks);

   const auto respMsg = MessagingTk::requestResponse(node, deleteChunksMsg,
         NETMSGTYPE_DeleteChunksResp);

   if (respMsg)
   {
      DeleteChunksRespMsg* deleteChunksRespMsg = (DeleteChunksRespMsg*) respMsg.get();

      deleteChunksRespMsg->getFailedChunks().swap(*failedDeletes);

      if (! failedDeletes->empty())
      {
         for (FsckChunkListIter iter = failedDeletes->begin(); iter != failedDeletes->end();
            iter++)
         {
            LogContext(logContext).log(Log_CRITICAL, "Failed to delete chunk entry. targetID: " +
               StringTk::uintToStr(iter->getTargetID()) + " chunkID: " + iter->getID());
         }
      }
   }
   else
   {
      *failedDeletes = *chunks;

      LogContext(logContext).logErr("Communication error occured with node: " + node.getID());
   }
}

NodeHandle MsgHelperRepair::referenceLostAndFoundOwner(EntryInfo* outLostAndFoundEntryInfo)
{
   const char* logContext = "MsgHelperRepair (referenceLostAndFoundOwner)";
   App* app = Program::getApp();

// find owner node
   Path path("/" + std::string(META_LOSTANDFOUND_PATH));

   NodeHandle ownerNode;

   FhgfsOpsErr findRes = MetadataTk::referenceOwner(&path, app->getMetaNodes(), ownerNode,
      outLostAndFoundEntryInfo, app->getMetaRoot(), app->getMetaMirrorBuddyGroupMapper());

   if ( findRes != FhgfsOpsErr_SUCCESS )
   {
      LogContext(logContext).log(Log_DEBUG, "No owner node found for lost+found. Directory does not"
         " seem to exist (yet)");
   }

   return ownerNode;
}

bool MsgHelperRepair::createLostAndFound(NodeHandle& outReferencedNode,
   EntryInfo& outLostAndFoundEntryInfo)
{
   const char* logContext = "MsgHelperRepair (createLostAndFound)";
   App* app = Program::getApp();
   NodeStore* metaNodes = app->getMetaNodes();
   bool retVal = false;

   // get root owner node and entryInfo
   NodeHandle rootNode;
   Path rootPath("");
   // rootPath.setAbsolute(true);
   EntryInfo rootEntryInfo;

   FhgfsOpsErr findRes = MetadataTk::referenceOwner(&rootPath, metaNodes,
      rootNode, &rootEntryInfo, app->getMetaRoot(), app->getMetaMirrorBuddyGroupMapper());

   if ( findRes != FhgfsOpsErr_SUCCESS )
   {
      LogContext(logContext).log(Log_CRITICAL, "Unable to reference metadata node for root "
         "directory");
      return false;
   }

   // create the directory
   std::string lostFoundPathStr = META_LOSTANDFOUND_PATH;
   UInt16List preferredNodes;

   MkDirMsg mkDirMsg(&rootEntryInfo, lostFoundPathStr , 0, 0, S_IFDIR | S_IRWXU | S_IRWXG, 0000,
      &preferredNodes);

   RequestResponseNode rrNode(rootEntryInfo.getOwnerNodeID(), Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &mkDirMsg, NETMSGTYPE_MkDirResp);

   if (rootEntryInfo.getIsBuddyMirrored())
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes != FhgfsOpsErr_SUCCESS)
      return false;

   auto* mkDirRespMsg = (MkDirRespMsg*) rrArgs.outRespMsg.get();

   FhgfsOpsErr mkDirRes = (FhgfsOpsErr) mkDirRespMsg->getResult();
   if ( mkDirRes != FhgfsOpsErr_SUCCESS )
   {
      LogContext(logContext).log(Log_CRITICAL,
         "Node encountered an error: " + boost::lexical_cast<std::string>(mkDirRes));
      return false;
   }

   // create seems to have succeeded
   // copy is created because delete is called on mkDirRespMsg, but we still need this object
   outLostAndFoundEntryInfo = *(mkDirRespMsg->getEntryInfo());

   outReferencedNode = outLostAndFoundEntryInfo.getIsBuddyMirrored()
      ? metaNodes->referenceNode(
            NumNodeID(
               app->getMetaMirrorBuddyGroupMapper()->getPrimaryTargetID(
                  outLostAndFoundEntryInfo.getOwnerNodeID().val())))
      : metaNodes->referenceNode(outLostAndFoundEntryInfo.getOwnerNodeID());
   retVal = true;

   return retVal;
}

void MsgHelperRepair::linkToLostAndFound(Node& lostAndFoundNode, EntryInfo* lostAndFoundInfo,
   FsckDirInodeList* dirInodes, FsckDirInodeList* failedInodes, FsckDirEntryList* createdDentries,
   std::set<NumNodeID>& secondariesWithRepair)
{
   const char* logContext = "MsgHelperRepair (linkToLostAndFound)";

   if (lostAndFoundInfo->getIsBuddyMirrored() &&
         !setSecondaryBad(lostAndFoundInfo->getOwnerNodeID().val(), secondariesWithRepair,
            {}, *createdDentries))
   {
      return;
   }

   LinkToLostAndFoundMsg linkToLostAndFoundMsg(lostAndFoundInfo, dirInodes);

   const auto respMsg = MessagingTk::requestResponse(lostAndFoundNode, linkToLostAndFoundMsg,
      NETMSGTYPE_LinkToLostAndFoundResp);

   if (respMsg)
   {
      auto* linkToLostAndFoundRespMsg = (LinkToLostAndFoundRespMsg*) respMsg.get();

      linkToLostAndFoundRespMsg->getFailedDirInodes().swap(*failedInodes);
      linkToLostAndFoundRespMsg->getCreatedDirEntries().swap(*createdDentries);
   }
   else
   {
      *failedInodes = *dirInodes;

      LogContext(logContext).logErr("Communication error occured with node: " +
         lostAndFoundNode.getID());
   }

   if (! failedInodes->empty())
   {
      for (FsckDirInodeListIter iter = failedInodes->begin(); iter != failedInodes->end();
         iter++)
      {
         LogContext(logContext).log(Log_CRITICAL, "Failed to link directory inode to lost+found. "
            "entryID: " + iter->getID());
      }
   }
}

void MsgHelperRepair::linkToLostAndFound(Node& lostAndFoundNode, EntryInfo* lostAndFoundInfo,
   FsckFileInodeList* fileInodes, FsckFileInodeList* failedInodes,
   FsckDirEntryList* createdDentries, std::set<NumNodeID>& secondariesWithRepair)
{
   const char* logContext = "MsgHelperRepair (linkToLostAndFound)";

   if (lostAndFoundInfo->getIsBuddyMirrored() &&
         !setSecondaryBad(lostAndFoundInfo->getOwnerNodeID().val(), secondariesWithRepair,
            *fileInodes, *failedInodes))
   {
      return;
   }

   LinkToLostAndFoundMsg linkToLostAndFoundMsg(lostAndFoundInfo, fileInodes);

   const auto respMsg = MessagingTk::requestResponse(lostAndFoundNode, linkToLostAndFoundMsg,
      NETMSGTYPE_LinkToLostAndFoundResp);

   if (respMsg)
   {
      auto* linkToLostAndFoundRespMsg = (LinkToLostAndFoundRespMsg*) respMsg.get();

      linkToLostAndFoundRespMsg->getFailedFileInodes().swap(*failedInodes);
      linkToLostAndFoundRespMsg->getCreatedDirEntries().swap(*createdDentries);
   }
   else
   {
      *failedInodes = *fileInodes;

      LogContext(logContext).logErr("Communication error occured with node: " +
         lostAndFoundNode.getID());
   }

   if (! failedInodes->empty())
   {
      for (FsckFileInodeListIter iter = failedInodes->begin(); iter != failedInodes->end();
         iter++)
      {
         LogContext(logContext).log(Log_CRITICAL, "Failed to link file inode to lost+found. "
            "entryID: " + iter->getID());
      }
   }
}

void MsgHelperRepair::createContDirs(NumNodeID node, bool isBuddyMirrored, FsckDirInodeList* inodes,
   StringList* failedCreates, std::set<NumNodeID>& secondariesWithRepair)
{
   // create a string list with the IDs
   std::vector<CreateEmptyContDirsMsg::Item> items;
   for (FsckDirInodeListIter iter = inodes->begin(); iter != inodes->end(); iter++)
      items.emplace_back(iter->getID(), iter->getIsBuddyMirrored());

   CreateEmptyContDirsMsg createContDirsMsg(std::move(items));

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &createContDirsMsg, NETMSGTYPE_CreateEmptyContDirsResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, {}, *failedCreates))
      {
         for (auto it = inodes->begin(); it != inodes->end(); ++it)
            failedCreates->push_back(it->getID());
         return;
      }
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* createContDirsRespMsg = (CreateEmptyContDirsRespMsg*) rrArgs.outRespMsg.get();

      createContDirsRespMsg->getFailedIDs().swap(*failedCreates);
   }
   else
   {
      failedCreates->clear();
      for (auto it = inodes->begin(); it != inodes->end(); ++it)
         failedCreates->push_back(it->getID());

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if ( !failedCreates->empty() )
   {
      for ( StringListIter iter = failedCreates->begin(); iter != failedCreates->end(); iter++ )
         LOG(GENERAL, CRITICAL, "Failed to create empty content directory.", ("dirID", *iter));
   }
}

void MsgHelperRepair::updateFileAttribs(NumNodeID node, bool isBuddyMirrored, FsckFileInodeList* inodes,
   FsckFileInodeList* failedUpdates, std::set<NumNodeID>& secondariesWithRepair)
{
   UpdateFileAttribsMsg updateFileAttribsMsg(inodes);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &updateFileAttribsMsg, NETMSGTYPE_UpdateFileAttribsResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *inodes, *failedUpdates))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* updateFileAttribsRespMsg = (UpdateFileAttribsRespMsg*) rrArgs.outRespMsg.get();

      updateFileAttribsRespMsg->getFailedInodes().swap(*failedUpdates);
   }
   else
   {
      *failedUpdates = *inodes;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if ( !failedUpdates->empty() )
   {
      for (auto iter = failedUpdates->begin(); iter != failedUpdates->end(); iter++)
         LOG(GENERAL, CRITICAL, "Failed to update attributes of file inode.",
             ("entryID", iter->getID()));
   }
}

void MsgHelperRepair::updateDirAttribs(NumNodeID node, bool isBuddyMirrored,
   FsckDirInodeList* inodes, FsckDirInodeList* failedUpdates,
   std::set<NumNodeID>& secondariesWithRepair)
{
   UpdateDirAttribsMsg updateDirAttribsMsg(inodes);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &updateDirAttribsMsg, NETMSGTYPE_UpdateDirAttribsResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *inodes, *failedUpdates))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* updateDirAttribsRespMsg = (UpdateDirAttribsRespMsg*) rrArgs.outRespMsg.get();

      updateDirAttribsRespMsg->getFailedInodes().swap(*failedUpdates);
   }
   else
   {
      *failedUpdates = *inodes;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if ( !failedUpdates->empty() )
   {
      for (auto iter = failedUpdates->begin(); iter != failedUpdates->end(); iter++)
         LOG(GENERAL, CRITICAL, "Failed to update attributes of directory inode.",
               ("entryID", iter->getID()));
   }
}

void MsgHelperRepair::recreateFsIDs(NumNodeID node, bool isBuddyMirrored,
   FsckDirEntryList* dentries, FsckDirEntryList* failedEntries,
   std::set<NumNodeID>& secondariesWithRepair)
{
   const char* logContext = "MsgHelperRepair (recreateFsIDs)";

   RecreateFsIDsMsg recreateFsIDsMsg(dentries);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &recreateFsIDsMsg, NETMSGTYPE_RecreateFsIDsResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *dentries, *failedEntries))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      RecreateFsIDsRespMsg* recreateFsIDsRespMsg = (RecreateFsIDsRespMsg*) rrArgs.outRespMsg.get();

      recreateFsIDsRespMsg->getFailedEntries().swap(*failedEntries);
   }
   else
   {
      *failedEntries = *dentries;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if ( !failedEntries->empty() )
   {
      for ( FsckDirEntryListIter iter = failedEntries->begin(); iter != failedEntries->end();
         iter++ )
      {
         LogContext(logContext).log(Log_CRITICAL, "Failed to recreate dentry-by-ID file link."
            " entryID: " + iter->getID());
      }
   }
}

void MsgHelperRepair::recreateDentries(NumNodeID node, bool isBuddyMirrored, FsckFsIDList* fsIDs,
   FsckFsIDList* failedCreates, FsckDirEntryList* createdDentries, FsckFileInodeList* createdInodes,
   std::set<NumNodeID>& secondariesWithRepair)
{
   const char* logContext = "MsgHelperRepair (recreateDentries)";

   RecreateDentriesMsg recreateDentriesMsg(fsIDs);

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &recreateDentriesMsg, NETMSGTYPE_RecreateDentriesResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, *fsIDs, *failedCreates))
         return;
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      auto* recreateDentriesMsg = (RecreateDentriesRespMsg*) rrArgs.outRespMsg.get();

      recreateDentriesMsg->getFailedCreates().swap(*failedCreates);
      recreateDentriesMsg->getCreatedDentries().swap(*createdDentries);
      recreateDentriesMsg->getCreatedInodes().swap(*createdInodes);
   }
   else
   {
      *failedCreates = *fsIDs;

      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);
   }

   if ( !failedCreates->empty() )
   {
      for ( FsckFsIDListIter iter = failedCreates->begin(); iter != failedCreates->end();
         iter++ )
      {
         LogContext(logContext).log(Log_CRITICAL, "Failed to recreate dentry."
            " entryID: " + iter->getID());
      }
   }
}

void MsgHelperRepair::fixChunkPermissions(Node& node, FsckChunkList& chunkList,
   PathInfoList& pathInfoList, FsckChunkList& failedChunks)
{
   const char* logContext = "MsgHelperRepair (fixChunkPermissions)";

   if ( chunkList.size() != pathInfoList.size() )
   {
      LogContext(logContext).logErr(
         "Failed to set uid/gid for chunks. Size of lists does not match.");
      return;
   }

   FsckChunkListIter chunksIter = chunkList.begin();
   PathInfoListIter pathInfoIter = pathInfoList.begin();
   for ( ; chunksIter != chunkList.end(); chunksIter++, pathInfoIter++ )
   {
      std::string chunkID = chunksIter->getID();
      uint16_t targetID = chunksIter->getTargetID();
      int validAttribs = SETATTR_CHANGE_USERID | SETATTR_CHANGE_GROUPID; // only interested in these
      SettableFileAttribs attribs = {0, 0, 0, 0, 0};
      attribs.userID = chunksIter->getUserID();
      attribs.groupID = chunksIter->getGroupID();

      bool enableCreation = false;

      PathInfo pathInfo = *pathInfoIter;
      SetLocalAttrMsg setLocalAttrMsg(chunkID, targetID, &pathInfo, validAttribs, &attribs,
         enableCreation);
      setLocalAttrMsg.addMsgHeaderFeatureFlag(SETLOCALATTRMSG_FLAG_USE_QUOTA);

      const auto respMsg = MessagingTk::requestResponse(node, setLocalAttrMsg,
            NETMSGTYPE_SetLocalAttrResp);

      if (respMsg)
      {
         SetLocalAttrRespMsg* setLocalAttrRespMsg = (SetLocalAttrRespMsg*) respMsg.get();

         if ( setLocalAttrRespMsg->getResult() != FhgfsOpsErr_SUCCESS )
         {
            LogContext(logContext).logErr(
               "Failed to set uid/gid for chunk. chunkID: " + chunkID + "; targetID: "
                  + StringTk::uintToStr(targetID));

            failedChunks.push_back(*chunksIter);
         }
      }
      else
      {
         LogContext(logContext).logErr("Communication error occured with node: " + node.getID());

         failedChunks.push_back(*chunksIter);
      }
   }
}

/*
 * NOTE: chunk gets modified! (new savedPath is set)
 */
bool MsgHelperRepair::moveChunk(Node& node, FsckChunk& chunk, const std::string& moveTo,
   bool allowOverwrite)
{
   const char* logContext = "MsgHelperRepair (moveChunks)";
   bool result;

   MoveChunkFileMsg moveChunkFileMsg(chunk.getID(), chunk.getTargetID(),
         chunk.getBuddyGroupID() != 0, chunk.getSavedPath()->str(), moveTo, allowOverwrite);

   const auto respMsg = MessagingTk::requestResponse(node, moveChunkFileMsg,
      NETMSGTYPE_MoveChunkFileResp);

   if (respMsg)
   {
      MoveChunkFileRespMsg* moveChunkFileRespMsg = (MoveChunkFileRespMsg*) respMsg.get();

      result = moveChunkFileRespMsg->getValue() == FhgfsOpsErr_SUCCESS;

      if(!result)
      {
         LogContext(logContext).logErr(
            "Failed to move chunk. chunkID: " + chunk.getID() + "; targetID: "
               + StringTk::uintToStr(chunk.getTargetID() ) + "; fromPath: "
               + chunk.getSavedPath()->str() + "; toPath: "
               + moveTo);
      }
      else
      {
         // set newPath in chunk
         chunk.setSavedPath(Path(moveTo));
      }
   }
   else
   {
      LogContext(logContext).logErr("Communication error occured with node: " + node.getID());
      result = false;
   }

   return result;
}

void MsgHelperRepair::deleteFileInodes(NumNodeID node, bool isBuddyMirrored,
   FsckFileInodeList& inodes, StringList& failedDeletes, std::set<NumNodeID>& secondariesWithRepair)
{
   std::vector<RemoveInodesMsg::Item> items;

   for (auto it = inodes.begin(); it != inodes.end(); ++it)
      items.emplace_back(it->getID(), DirEntryType_REGULARFILE, it->getIsBuddyMirrored());

   RemoveInodesMsg removeInodesMsg(std::move(items));

   RequestResponseNode rrNode(node, Program::getApp()->getMetaNodes());
   RequestResponseArgs rrArgs(nullptr, &removeInodesMsg, NETMSGTYPE_RemoveInodesResp);

   if (isBuddyMirrored)
   {
      rrNode.setMirrorInfo(Program::getApp()->getMetaMirrorBuddyGroupMapper(), false);
      if (!setSecondaryBad(node.val(), secondariesWithRepair, {}, failedDeletes))
      {
         for (auto it = inodes.begin(); it != inodes.end(); ++it)
            failedDeletes.push_back(it->getID());
         return;
      }
   }

   FhgfsOpsErr commRes = MessagingTk::requestResponseNode(&rrNode, &rrArgs);

   if (commRes == FhgfsOpsErr_SUCCESS)
   {
      RemoveInodesRespMsg* removeInodesRespMsg = (RemoveInodesRespMsg*) rrArgs.outRespMsg.get();
      failedDeletes = removeInodesRespMsg->releaseFailedEntryIDList();

      for ( StringListIter iter = failedDeletes.begin(); iter != failedDeletes.end(); iter++ )
         LOG(GENERAL, ERR, "Failed to delete file inode.", node, isBuddyMirrored,
             ("entryID", *iter));
   }
   else
   {
      LOG(GENERAL, ERR, "Communication error occured.", node, isBuddyMirrored, commRes);

      failedDeletes.clear();
      for (auto it = inodes.begin(); it != inodes.end(); ++it)
         failedDeletes.push_back(it->getID());
   }
}

max_stars_repo_name: TomatoYoung/beegfs

max_issues_repo_name: TomatoYoung/beegfs

max_forks_repo_name: TomatoYoung/beegfs


text:
#include "Storage.h"
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/stream.hpp>

namespace bio = boost::iostreams;
namespace Gadgetron::Storage {
    GenericStorageSpace::GenericStorageSpace(
        std::shared_ptr<StreamProvider> provider,
        const Core::optional<std::string>& subject,
        boost::posix_time::time_duration default_duration
    ) : subject{subject},provider(std::move(provider)),  default_duration{default_duration} {}

    std::unique_ptr<std::istream> istream_from_data(const std::vector<char> &data) {

            return std::make_unique<bio::stream<bio::array_source>>(data.data(),data.size());

    }

    std::unique_ptr<std::ostream> ostream_view(std::vector<char> &data) {
        return std::make_unique<bio::stream<bio::back_insert_device<std::vector<char>>>>(data);
    }
}

max_stars_repo_name: fyrdahl/gadgetron

max_issues_repo_name: fyrdahl/gadgetron

max_forks_repo_name: fyrdahl/gadgetron


text:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * File:   ModuleManager.cpp
 * Author: ubuntu
 *
 * Created on January 15, 2018, 3:12 PM
 */

#include <iterator>
#include <vector>
#include <algorithm>
#include <iostream>

#include <boost/filesystem/operations.hpp>
#include <condition_variable>

#include "keto/common/Log.hpp"
#include "keto/environment/EnvironmentManager.hpp"
#include "keto/module/ModuleManager.hpp"
#include "keto/module/Constants.hpp"
#include "keto/module/Exception.hpp"
#include "keto/module/ModuleWrapper.hpp"
#include "keto/module/ModuleManagementInterface.hpp"
#include "include/keto/module/ModuleWrapper.hpp"

namespace keto {
namespace module {

namespace ketoEnv = keto::environment;

static std::shared_ptr<ModuleManager> singleton;

ModuleManager::ModuleManager() {
    this->currentState = inited;
    this->moduleDir = ketoEnv::EnvironmentManager::getInstance()->getEnv()->getInstallDir()
            / Constants::KETO_SHARE;
    if (!boost::filesystem::exists(this->moduleDir)) {
        BOOST_THROW_EXCEPTION(ModuleSharedDirException());
    }
    this->tmpDir = ketoEnv::EnvironmentManager::getInstance()->getEnv()->getInstallDir()
            / Constants::KETO_TMP;
    if (!boost::filesystem::exists(this->tmpDir)) {
        if (!boost::filesystem::create_directories(this->tmpDir)) {
            BOOST_THROW_EXCEPTION(ModuleTmpDirException("Failed to create the directory : " +
                this->tmpDir.string()));
        }
    }
}

ModuleManager::~ModuleManager() {
}

std::shared_ptr<ModuleManager>& ModuleManager::init() {
    if (!singleton) {
        singleton = std::shared_ptr<ModuleManager>(new ModuleManager());
    }
    return singleton;
}

std::shared_ptr<ModuleManager>& ModuleManager::getInstance() {
    return singleton;
}

// module lifecycle methods
void ModuleManager::load() {
    // load
    this->setState(State::loading);
    std::vector<boost::filesystem::path> files;                                // so we can sort them later

    std::copy(boost::filesystem::directory_iterator(this->moduleDir),
            boost::filesystem::directory_iterator(), std::back_inserter(files));

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

    for (std::vector<boost::filesystem::path>::const_iterator it(files.begin()),
            it_end(files.end()); it != it_end; ++it) {
        load(*it);
    }

    for (std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>>::iterator it=loadedLibraryModuleManagers.begin();
            it!=loadedLibraryModuleManagers.end(); ++it) {
        it->second->getModuleManagerInterface()->postStart();
    }

    this->setState(State::loaded);

}

void ModuleManager::monitor() {

    this->setState(State::monitoring);
    while(this->checkState() != State::terminated) {
        if (this->checkForReload()) {
            this->unload();
            this->load();
            this->setState(State::monitoring);
        }
    }

}

void ModuleManager::unload() {
    this->setState(State::unloading);
    std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>> loadedLibraryModule;
    {
        std::lock_guard<std::mutex> guard(this->classMutex);
        // copy the contents
        loadedLibraryModule = this->loadedLibraryModuleManagers;

    }

    for (std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>>::reverse_iterator it=loadedLibraryModule.rbegin();
            it!=loadedLibraryModule.rend(); ++it) {
        it->second->getModuleManagerInterface()->stop();
    }

    {
        std::lock_guard<std::mutex> guard(this->classMutex);
        this->loadedModules.clear();
        this->loadedModuleManagementInterfaces.clear();
        this->loadedLibraryModuleManagers.clear();

    }

    for (std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>>::reverse_iterator it=loadedLibraryModule.rbegin();
            it!=loadedLibraryModule.rend(); ++it) {
        it->second->unload();
    }
    // clear the modules
    loadedLibraryModule.clear();

    // set the state
    this->setState(State::unloaded);
}

void ModuleManager::terminate() {
    std::unique_lock<std::mutex> uniqueLock(this->classMutex);
    this->currentState = State::terminated;
    this->stateCondition.notify_all();
}

ModuleManager::State ModuleManager::getState() {
    std::lock_guard<std::mutex> guard(this->classMutex);
    return this->currentState;
}

// modules methods
std::vector<std::string> ModuleManager::listModules() {
    std::lock_guard<std::mutex> guard(this->classMutex);
    std::vector<std::string> keys;
    std::transform(
        this->loadedModules.begin(),
        this->loadedModules.end(),
        std::back_inserter(keys),
        [](const std::map<std::string,std::shared_ptr<ModuleInterface>>::value_type &pair)
        {return pair.first;});
    return keys;
}

std::shared_ptr<ModuleInterface> ModuleManager::getModule(
    const std::string& moduleName) {
    std::lock_guard<std::mutex> guard(this->classMutex);
    return this->loadedModules[moduleName];
}

std::vector<std::string> ModuleManager::listModuleManagementInterfaces() {
    std::lock_guard<std::mutex> guard(this->classMutex);
    std::vector<std::string> keys;
    std::transform(
        this->loadedModuleManagementInterfaces.begin(),
        this->loadedModuleManagementInterfaces.end(),
        std::back_inserter(keys),
        [](const std::map<std::string,boost::shared_ptr<ModuleManagementInterface>>::value_type
            &pair){return pair.first;});
    return keys;
}

boost::shared_ptr<ModuleManagementInterface> ModuleManager::getModuleManagementInterface(
    const std::string& moduleManagement) {
    std::lock_guard<std::mutex> guard(this->classMutex);
    return this->loadedModuleManagementInterfaces[moduleManagement];
}

std::vector<boost::filesystem::path> ModuleManager::listModuleFiles() {
    std::lock_guard<std::mutex> guard(this->classMutex);
    std::vector<boost::filesystem::path> keys;
    std::transform(
        this->loadedLibraryModuleManagers.begin(),
        this->loadedLibraryModuleManagers.end(),
        std::back_inserter(keys),
        [](const std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>>::value_type
            &pair){return pair.first;});
    return keys;
}

std::shared_ptr<ModuleWrapper> ModuleManager::getModuleWrapper(
    const boost::filesystem::path& modulePath) {
    std::lock_guard<std::mutex> guard(this->classMutex);
    return this->loadedLibraryModuleManagers[modulePath];
}

void ModuleManager::load(const boost::filesystem::path& libraryPath) {
    // set the module wrapper ptr at an appropriate point to prevent the
    // library from being unloaded before we can extract the message
    std::shared_ptr<ModuleWrapper> moduleWrapperPtr;
    boost::shared_ptr<ModuleManagementInterface> moduleManagerInterfacePtr;

    try {

        // setup a module wrapper and load and start the module
        moduleWrapperPtr = std::shared_ptr<ModuleWrapper>(
                new ModuleWrapper(libraryPath,this->tmpDir));
        moduleWrapperPtr->load();
        moduleManagerInterfacePtr =
                moduleWrapperPtr->getModuleManagerInterface();
        moduleManagerInterfacePtr->start();

        // add the module to the cointainers
        std::lock_guard<std::mutex> guard(this->classMutex);
        this->loadedLibraryModuleManagers[libraryPath] = moduleWrapperPtr;
        this->loadedModuleManagementInterfaces[moduleWrapperPtr->getModuleManagerInterface()->getName()] =
                moduleWrapperPtr->getModuleManagerInterface();
        std::vector<std::string> modules = moduleWrapperPtr->getModuleManagerInterface()->listModules();
        for (std::string name : modules) {
            this->loadedModules[name] =
                    moduleWrapperPtr->getModuleManagerInterface()->getModule(name);
        }

    } catch (keto::common::Exception& ex) {
        if (moduleManagerInterfacePtr) {
            moduleManagerInterfacePtr->stop();
        }
        std::stringstream ss;
        ss << "Failed to load the module [" << libraryPath.string() << "] : " << ex.what() << std::endl;
        ss << "Cause: " << boost::diagnostic_information(ex,true) << std::endl;
        BOOST_THROW_EXCEPTION(keto::module::ModuleLoadException(
                ss.str()));
    } catch (boost::exception& ex) {
        // attempt to clear up
        if (moduleManagerInterfacePtr) {
            moduleManagerInterfacePtr->stop();
        }
        std::stringstream ss;
        ss << "Failed to load the module [" << libraryPath.string() << "] : "
                << boost::diagnostic_information(ex,true) << std::endl;
        BOOST_THROW_EXCEPTION(keto::module::ModuleLoadException(
                ss.str()));
    } catch (std::exception& ex) {
        // attempt to clear up
        if (moduleManagerInterfacePtr) {
            moduleManagerInterfacePtr->stop();
        }
        std::stringstream ss;
        ss << "Failed to load the module [" << libraryPath.string() << "] : " << ex.what() << std::endl;
        BOOST_THROW_EXCEPTION(keto::module::ModuleLoadException(
                ss.str()));
    } catch (...) {
        // attempt to clear up
        if (moduleManagerInterfacePtr) {
            moduleManagerInterfacePtr->stop();
        }
        std::stringstream ss;
        ss << "Failed to load the module [" << libraryPath.string() << "]" << std::endl;
        BOOST_THROW_EXCEPTION(keto::module::ModuleLoadException(
                ss.str()));
    }
}

bool ModuleManager::checkForReload() {

    std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>> loadedLibraryModuleManagers;
    {
        std::lock_guard<std::mutex> guard(this->classMutex);
        // copy the contents
        loadedLibraryModuleManagers = this->loadedLibraryModuleManagers;
    }
    for (std::map<boost::filesystem::path,std::shared_ptr<ModuleWrapper>>::iterator it=loadedLibraryModuleManagers.begin();
            it!=loadedLibraryModuleManagers.end(); ++it) {
        if (it->second->requireReload()) {
            return true;
        }
    }
    return false;
}

ModuleManager::State ModuleManager::checkState() {
    std::unique_lock<std::mutex> uniqueLock(this->classMutex);
    KETO_LOG_DEBUG << "Before check state";
    this->stateCondition.wait_for(uniqueLock,std::chrono::milliseconds(60 * 1000));
    KETO_LOG_DEBUG << "After check state";
    return this->currentState;
}

void ModuleManager::setState(const ModuleManager::State& state) {
    std::lock_guard<std::mutex> guard(this->classMutex);
    if (this->currentState == State::terminated) {
        return;
    }
    this->currentState = state;
}

}
}

max_stars_repo_name: burntjam/keto

max_issues_repo_name: burntjam/keto

max_forks_repo_name: burntjam/keto


text:
/***************************************************************************
 * Copyright 1998-2018 by authors (see AUTHORS.txt)                        *
 *                                                                         *
 *   This file is part of LuxCoreRender.                                   *
 *                                                                         *
 * 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 <limits>
#include <algorithm>
#include <exception>

#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>

#include "slg/film/film.h"
#include "slg/film/sampleresult.h"
#include "slg/utils/varianceclamping.h"
#include "slg/film/denoiser/filmdenoiser.h"

using namespace std;
using namespace luxrays;
using namespace slg;

//------------------------------------------------------------------------------
// Film
//------------------------------------------------------------------------------

Film::Film() : filmDenoiser(this) {
	initialized = false;

	width = 0;
	height = 0;
	subRegion[0] = 0;
	subRegion[1] = 0;
	subRegion[2] = 0;
	subRegion[3] = 0;
	radianceGroupCount = 0;

	channel_ALPHA = NULL;
	channel_DEPTH = NULL;
	channel_POSITION = NULL;
	channel_GEOMETRY_NORMAL = NULL;
	channel_SHADING_NORMAL = NULL;
	channel_MATERIAL_ID = NULL;
	channel_DIRECT_DIFFUSE = NULL;
	channel_DIRECT_GLOSSY = NULL;
	channel_EMISSION = NULL;
	channel_INDIRECT_DIFFUSE = NULL;
	channel_INDIRECT_GLOSSY = NULL;
	channel_INDIRECT_SPECULAR = NULL;
	channel_DIRECT_SHADOW_MASK = NULL;
	channel_INDIRECT_SHADOW_MASK = NULL;
	channel_UV = NULL;
	channel_RAYCOUNT = NULL;
	channel_IRRADIANCE = NULL;
	channel_OBJECT_ID = NULL;
	channel_SAMPLECOUNT = NULL;
	channel_CONVERGENCE = NULL;
	channel_MATERIAL_ID_COLOR = NULL;

	convTest = NULL;
	haltTime = 0.0;
	haltSPP = 0;
	haltThreshold = 0.f;

	isAsyncImagePipelineRunning = false;
	imagePipelineThread = NULL;

	// Initialize variables to NULL
	SetUpOCL();
}

Film::Film(const u_int w, const u_int h, const u_int *sr) : filmDenoiser(this) {
	if ((w == 0) || (h == 0))
		throw runtime_error("Film can not have 0 width or a height");

	initialized = false;

	width = w;
	height = h;
	if (sr) {
		subRegion[0] = sr[0];
		subRegion[1] = sr[1];
		subRegion[2] = sr[2];
		subRegion[3] = sr[3];
	} else {
		subRegion[0] = 0;
		subRegion[1] = w - 1;
		subRegion[2] = 0;
		subRegion[3] = h - 1;
	}
	radianceGroupCount = 1;

	channel_ALPHA = NULL;
	channel_DEPTH = NULL;
	channel_POSITION = NULL;
	channel_GEOMETRY_NORMAL = NULL;
	channel_SHADING_NORMAL = NULL;
	channel_MATERIAL_ID = NULL;
	channel_DIRECT_DIFFUSE = NULL;
	channel_DIRECT_GLOSSY = NULL;
	channel_EMISSION = NULL;
	channel_INDIRECT_DIFFUSE = NULL;
	channel_INDIRECT_GLOSSY = NULL;
	channel_INDIRECT_SPECULAR = NULL;
	channel_DIRECT_SHADOW_MASK = NULL;
	channel_INDIRECT_SHADOW_MASK = NULL;
	channel_UV = NULL;
	channel_RAYCOUNT = NULL;
	channel_IRRADIANCE = NULL;
	channel_OBJECT_ID = NULL;
	channel_SAMPLECOUNT = NULL;
	channel_CONVERGENCE = NULL;
	channel_MATERIAL_ID_COLOR = NULL;

	convTest = NULL;
	haltTime = 0.0;

	haltSPP = 0;
	haltThreshold = .02f;
	haltThresholdWarmUp = 64;
	haltThresholdTestStep = 64;
	haltThresholdUseFilter = true;
	haltThresholdStopRendering = true;

	isAsyncImagePipelineRunning = false;
	imagePipelineThread = NULL;

	// Initialize variables to NULL
	SetUpOCL();
}

Film::~Film() {
	if (imagePipelineThread) {
		imagePipelineThread->interrupt();
		imagePipelineThread->join();
		delete imagePipelineThread;
	}

	BOOST_FOREACH(ImagePipeline *ip, imagePipelines)
		delete ip;

#if !defined(LUXRAYS_DISABLE_OPENCL)
	// I have to delete the OCL context after the image pipeline because it
	// can be used by plugins
	DeleteOCLContext();
#endif

	delete convTest;

	FreeChannels();
}

void Film::CopyDynamicSettings(const Film &film) {
	channels = film.channels;
	maskMaterialIDs = film.maskMaterialIDs;
	byMaterialIDs = film.byMaterialIDs;
	maskObjectIDs = film.maskObjectIDs;
	byObjectIDs = film.byObjectIDs;
	radianceGroupCount = film.radianceGroupCount;

	// Copy the image pipeline
	imagePipelines.resize(0);
	BOOST_FOREACH(ImagePipeline *ip, film.imagePipelines)
		imagePipelines.push_back(ip->Copy());

	filmDenoiser.SetEnabled(film.filmDenoiser.IsEnabled());
}

void Film::Init() {
	if (initialized)
		throw runtime_error("A Film can not be initialized multiple times");

	if (imagePipelines.size() > 0)
		AddChannel(IMAGEPIPELINE);

	// CONVERGENCE is generated by the convergence test
	if (HasChannel(CONVERGENCE) && !convTest) {
		// The test has to be enabled to update the CONVERGNCE AOV

		// Using the default values
		convTest = new FilmConvTest(this, haltThreshold, haltThresholdWarmUp, haltThresholdTestStep, haltThresholdUseFilter);
	}

	initialized = true;

	Resize(width, height);
}

void Film::SetSampleCount(const double count) {
	statsTotalSampleCount = count;

	// Check the if Film denoiser warmup is done
	if (filmDenoiser.IsEnabled() && !filmDenoiser.HasReferenceFilm() &&
			!filmDenoiser.IsWarmUpDone())
		filmDenoiser.CheckIfWarmUpDone();
}

void Film::Resize(const u_int w, const u_int h) {
	if ((w == 0) || (h == 0))
		throw runtime_error("Film can not have 0 width or a height");

	width = w;
	height = h;
	pixelCount = w * h;

	// Delete all already allocated channels
	FreeChannels();

	// Allocate all required channels
	hasDataChannel = false;
	hasComposingChannel = false;
	if (HasChannel(RADIANCE_PER_PIXEL_NORMALIZED)) {
		channel_RADIANCE_PER_PIXEL_NORMALIZEDs.resize(radianceGroupCount, NULL);
		for (u_int i = 0; i < radianceGroupCount; ++i) {
			channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i] = new GenericFrameBuffer<4, 1, float>(width, height);
			channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->Clear();
		}
	}
	if (HasChannel(RADIANCE_PER_SCREEN_NORMALIZED)) {
		channel_RADIANCE_PER_SCREEN_NORMALIZEDs.resize(radianceGroupCount, NULL);
		for (u_int i = 0; i < radianceGroupCount; ++i) {
			channel_RADIANCE_PER_SCREEN_NORMALIZEDs[i] = new GenericFrameBuffer<3, 0, float>(width, height);
			channel_RADIANCE_PER_SCREEN_NORMALIZEDs[i]->Clear();
		}
	}

	// Update the radiance group count of all image pipelines
	BOOST_FOREACH(ImagePipeline *ip, imagePipelines)
		ip->SetRadianceGroupCount(radianceGroupCount);

	if (HasChannel(ALPHA)) {
		channel_ALPHA = new GenericFrameBuffer<2, 1, float>(width, height);
		channel_ALPHA->Clear();
	}
	if (HasChannel(IMAGEPIPELINE)) {
		channel_IMAGEPIPELINEs.resize(imagePipelines.size(), NULL);
		for (u_int i = 0; i < channel_IMAGEPIPELINEs.size(); ++i) {
			channel_IMAGEPIPELINEs[i] = new GenericFrameBuffer<3, 0, float>(width, height);
			channel_IMAGEPIPELINEs[i]->Clear();
		}

		// Resize the converge test too if required
		if (convTest)
			convTest->Reset();
	} else {
		delete convTest;
		convTest = NULL;
	}
	if (HasChannel(DEPTH)) {
		channel_DEPTH = new GenericFrameBuffer<1, 0, float>(width, height);
		channel_DEPTH->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(POSITION)) {
		channel_POSITION = new GenericFrameBuffer<3, 0, float>(width, height);
		channel_POSITION->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(GEOMETRY_NORMAL)) {
		channel_GEOMETRY_NORMAL = new GenericFrameBuffer<3, 0, float>(width, height);
		channel_GEOMETRY_NORMAL->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(SHADING_NORMAL)) {
		channel_SHADING_NORMAL = new GenericFrameBuffer<3, 0, float>(width, height);
		channel_SHADING_NORMAL->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(MATERIAL_ID)) {
		channel_MATERIAL_ID = new GenericFrameBuffer<1, 0, u_int>(width, height);
		channel_MATERIAL_ID->Clear(numeric_limits<u_int>::max());
		hasDataChannel = true;
	}
	if (HasChannel(DIRECT_DIFFUSE)) {
		channel_DIRECT_DIFFUSE = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_DIRECT_DIFFUSE->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(DIRECT_GLOSSY)) {
		channel_DIRECT_GLOSSY = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_DIRECT_GLOSSY->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(EMISSION)) {
		channel_EMISSION = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_EMISSION->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(INDIRECT_DIFFUSE)) {
		channel_INDIRECT_DIFFUSE = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_INDIRECT_DIFFUSE->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(INDIRECT_GLOSSY)) {
		channel_INDIRECT_GLOSSY = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_INDIRECT_GLOSSY->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(INDIRECT_SPECULAR)) {
		channel_INDIRECT_SPECULAR = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_INDIRECT_SPECULAR->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(MATERIAL_ID_MASK)) {
		for (u_int i = 0; i < maskMaterialIDs.size(); ++i) {
			GenericFrameBuffer<2, 1, float> *buf = new GenericFrameBuffer<2, 1, float>(width, height);
			buf->Clear();
			channel_MATERIAL_ID_MASKs.push_back(buf);
		}
		hasComposingChannel = true;
	}
	if (HasChannel(DIRECT_SHADOW_MASK)) {
		channel_DIRECT_SHADOW_MASK = new GenericFrameBuffer<2, 1, float>(width, height);
		channel_DIRECT_SHADOW_MASK->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(INDIRECT_SHADOW_MASK)) {
		channel_INDIRECT_SHADOW_MASK = new GenericFrameBuffer<2, 1, float>(width, height);
		channel_INDIRECT_SHADOW_MASK->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(UV)) {
		channel_UV = new GenericFrameBuffer<2, 0, float>(width, height);
		channel_UV->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(RAYCOUNT)) {
		channel_RAYCOUNT = new GenericFrameBuffer<1, 0, float>(width, height);
		channel_RAYCOUNT->Clear();
		hasDataChannel = true;
	}
	if (HasChannel(BY_MATERIAL_ID)) {
		for (u_int i = 0; i < byMaterialIDs.size(); ++i) {
			GenericFrameBuffer<4, 1, float> *buf = new GenericFrameBuffer<4, 1, float>(width, height);
			buf->Clear();
			channel_BY_MATERIAL_IDs.push_back(buf);
		}
		hasComposingChannel = true;
	}
	if (HasChannel(IRRADIANCE)) {
		channel_IRRADIANCE = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_IRRADIANCE->Clear();
		hasComposingChannel = true;
	}
	if (HasChannel(OBJECT_ID)) {
		channel_OBJECT_ID = new GenericFrameBuffer<1, 0, u_int>(width, height);
		channel_OBJECT_ID->Clear(numeric_limits<u_int>::max());
		hasDataChannel = true;
	}
	if (HasChannel(OBJECT_ID_MASK)) {
		for (u_int i = 0; i < maskObjectIDs.size(); ++i) {
			GenericFrameBuffer<2, 1, float> *buf = new GenericFrameBuffer<2, 1, float>(width, height);
			buf->Clear();
			channel_OBJECT_ID_MASKs.push_back(buf);
		}
		hasComposingChannel = true;
	}
	if (HasChannel(BY_OBJECT_ID)) {
		for (u_int i = 0; i < byObjectIDs.size(); ++i) {
			GenericFrameBuffer<4, 1, float> *buf = new GenericFrameBuffer<4, 1, float>(width, height);
			buf->Clear();
			channel_BY_OBJECT_IDs.push_back(buf);
		}
		hasComposingChannel = true;
	}
	if (HasChannel(SAMPLECOUNT)) {
		channel_SAMPLECOUNT = new GenericFrameBuffer<1, 0, u_int>(width, height);
		channel_SAMPLECOUNT->Clear();
		hasDataChannel = true;
	}
	if (HasChannel(CONVERGENCE)) {
		channel_CONVERGENCE = new GenericFrameBuffer<1, 0, float>(width, height);
		channel_CONVERGENCE->Clear(numeric_limits<float>::infinity());
		hasDataChannel = true;
	}
	if (HasChannel(MATERIAL_ID_COLOR)) {
		channel_MATERIAL_ID_COLOR = new GenericFrameBuffer<4, 1, float>(width, height);
		channel_MATERIAL_ID_COLOR->Clear();
		hasComposingChannel = true;
	}

	// Reset BCD statistics accumulator (I need to redo the warmup period)
	filmDenoiser.Reset();

	// Initialize the statistics
	statsTotalSampleCount = 0.0;
	statsConvergence = 0.0;
	statsStartSampleTime = WallClockTime();
}

void Film::Clear() {
	if (HasChannel(RADIANCE_PER_PIXEL_NORMALIZED)) {
		for (u_int i = 0; i < radianceGroupCount; ++i)
			channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->Clear();
	}
	if (HasChannel(RADIANCE_PER_SCREEN_NORMALIZED)) {
		for (u_int i = 0; i < radianceGroupCount; ++i)
			channel_RADIANCE_PER_SCREEN_NORMALIZEDs[i]->Clear();
	}
	if (HasChannel(ALPHA))
		channel_ALPHA->Clear();
	if (HasChannel(DEPTH))
		channel_DEPTH->Clear(numeric_limits<float>::infinity());
	if (HasChannel(POSITION))
		channel_POSITION->Clear(numeric_limits<float>::infinity());
	if (HasChannel(GEOMETRY_NORMAL))
		channel_GEOMETRY_NORMAL->Clear(numeric_limits<float>::infinity());
	if (HasChannel(SHADING_NORMAL))
		channel_SHADING_NORMAL->Clear(numeric_limits<float>::infinity());
	if (HasChannel(MATERIAL_ID))
		channel_MATERIAL_ID->Clear(numeric_limits<u_int>::max());
	if (HasChannel(DIRECT_DIFFUSE))
		channel_DIRECT_DIFFUSE->Clear();
	if (HasChannel(DIRECT_GLOSSY))
		channel_DIRECT_GLOSSY->Clear();
	if (HasChannel(EMISSION))
		channel_EMISSION->Clear();
	if (HasChannel(INDIRECT_DIFFUSE))
		channel_INDIRECT_DIFFUSE->Clear();
	if (HasChannel(INDIRECT_GLOSSY))
		channel_INDIRECT_GLOSSY->Clear();
	if (HasChannel(INDIRECT_SPECULAR))
		channel_INDIRECT_SPECULAR->Clear();
	if (HasChannel(MATERIAL_ID_MASK)) {
		for (u_int i = 0; i < channel_MATERIAL_ID_MASKs.size(); ++i)
			channel_MATERIAL_ID_MASKs[i]->Clear();
	}
	if (HasChannel(DIRECT_SHADOW_MASK))
		channel_DIRECT_SHADOW_MASK->Clear();
	if (HasChannel(INDIRECT_SHADOW_MASK))
		channel_INDIRECT_SHADOW_MASK->Clear();
	if (HasChannel(UV))
		channel_UV->Clear();
	if (HasChannel(RAYCOUNT))
		channel_RAYCOUNT->Clear();
	if (HasChannel(BY_MATERIAL_ID)) {
		for (u_int i = 0; i < channel_BY_MATERIAL_IDs.size(); ++i)
			channel_BY_MATERIAL_IDs[i]->Clear();
	}
	if (HasChannel(IRRADIANCE))
		channel_IRRADIANCE->Clear();
	if (HasChannel(OBJECT_ID))
		channel_OBJECT_ID->Clear(numeric_limits<u_int>::max());
	if (HasChannel(OBJECT_ID_MASK)) {
		for (u_int i = 0; i < channel_OBJECT_ID_MASKs.size(); ++i)
			channel_OBJECT_ID_MASKs[i]->Clear();
	}
	if (HasChannel(BY_OBJECT_ID)) {
		for (u_int i = 0; i < channel_BY_OBJECT_IDs.size(); ++i)
			channel_BY_OBJECT_IDs[i]->Clear();
	}
	if (HasChannel(SAMPLECOUNT))
		channel_SAMPLECOUNT->Clear();
	// channel_CONVERGENCE is not cleared otherwise the result of the halt test
	// would be lost
	if (HasChannel(MATERIAL_ID_COLOR))
		channel_MATERIAL_ID_COLOR->Clear();

	// denoiser is not cleared otherwise the collected data would be lost

	statsTotalSampleCount = 0.0;
	// statsConvergence is not cleared otherwise the result of the halt test
	// would be lost
}

void Film::Reset() {
	Clear();

	// denoiser  has to be reset explicitly

	// convTest has to be reset explicitly

	statsTotalSampleCount = 0.0;
	statsConvergence = 0.0;
	statsStartSampleTime = WallClockTime();
}

void Film::VarianceClampFilm(const VarianceClamping &varianceClamping,
		const Film &film, const u_int srcOffsetX, const u_int srcOffsetY,
		const u_int srcWidth, const u_int srcHeight,
		const u_int dstOffsetX, const u_int dstOffsetY) {
	if (HasChannel(RADIANCE_PER_PIXEL_NORMALIZED) && film.HasChannel(RADIANCE_PER_PIXEL_NORMALIZED)) {
		for (u_int i = 0; i < Min(radianceGroupCount, film.radianceGroupCount); ++i) {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					float *srcPixel = film.channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->GetPixel(srcOffsetX + x, srcOffsetY + y);
					const float *dstPixel = channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->GetPixel(dstOffsetX + x, dstOffsetY + y);

					varianceClamping.Clamp(dstPixel, srcPixel);
				}
			}
		}
	}
}

void Film::AddFilm(const Film &film,
		const u_int srcOffsetX, const u_int srcOffsetY,
		const u_int srcWidth, const u_int srcHeight,
		const u_int dstOffsetX, const u_int dstOffsetY) {
	statsTotalSampleCount += film.statsTotalSampleCount;

	if (HasChannel(RADIANCE_PER_PIXEL_NORMALIZED) && film.HasChannel(RADIANCE_PER_PIXEL_NORMALIZED)) {
		for (u_int i = 0; i < Min(radianceGroupCount, film.radianceGroupCount); ++i) {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_RADIANCE_PER_PIXEL_NORMALIZEDs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(RADIANCE_PER_SCREEN_NORMALIZED) && film.HasChannel(RADIANCE_PER_SCREEN_NORMALIZED)) {
		for (u_int i = 0; i < Min(radianceGroupCount, film.radianceGroupCount); ++i) {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_RADIANCE_PER_SCREEN_NORMALIZEDs[i]->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_RADIANCE_PER_SCREEN_NORMALIZEDs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(ALPHA) && film.HasChannel(ALPHA)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_ALPHA->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_ALPHA->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(POSITION) && film.HasChannel(POSITION)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const float *srcPixel = film.channel_POSITION->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_POSITION->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_POSITION->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_POSITION->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(GEOMETRY_NORMAL) && film.HasChannel(GEOMETRY_NORMAL)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const float *srcPixel = film.channel_GEOMETRY_NORMAL->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_GEOMETRY_NORMAL->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_GEOMETRY_NORMAL->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_GEOMETRY_NORMAL->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(SHADING_NORMAL) && film.HasChannel(SHADING_NORMAL)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const float *srcPixel = film.channel_SHADING_NORMAL->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_SHADING_NORMAL->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_SHADING_NORMAL->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_SHADING_NORMAL->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(MATERIAL_ID) && film.HasChannel(MATERIAL_ID)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const u_int *srcPixel = film.channel_MATERIAL_ID->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_MATERIAL_ID->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const u_int *srcPixel = film.channel_MATERIAL_ID->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_MATERIAL_ID->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(DIRECT_DIFFUSE) && film.HasChannel(DIRECT_DIFFUSE)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_DIRECT_DIFFUSE->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_DIRECT_DIFFUSE->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(DIRECT_GLOSSY) && film.HasChannel(DIRECT_GLOSSY)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_DIRECT_GLOSSY->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_DIRECT_GLOSSY->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(EMISSION) && film.HasChannel(EMISSION)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_EMISSION->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_EMISSION->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(INDIRECT_DIFFUSE) && film.HasChannel(INDIRECT_DIFFUSE)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_INDIRECT_DIFFUSE->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_INDIRECT_DIFFUSE->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(INDIRECT_GLOSSY) && film.HasChannel(INDIRECT_GLOSSY)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_INDIRECT_GLOSSY->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_INDIRECT_GLOSSY->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(INDIRECT_SPECULAR) && film.HasChannel(INDIRECT_SPECULAR)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_INDIRECT_SPECULAR->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_INDIRECT_SPECULAR->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(MATERIAL_ID_MASK) && film.HasChannel(MATERIAL_ID_MASK)) {
		for (u_int i = 0; i < channel_MATERIAL_ID_MASKs.size(); ++i) {
			for (u_int j = 0; j < film.maskMaterialIDs.size(); ++j) {
				if (maskMaterialIDs[i] == film.maskMaterialIDs[j]) {
					for (u_int y = 0; y < srcHeight; ++y) {
						for (u_int x = 0; x < srcWidth; ++x) {
							const float *srcPixel = film.channel_MATERIAL_ID_MASKs[j]->GetPixel(srcOffsetX + x, srcOffsetY + y);
							channel_MATERIAL_ID_MASKs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
						}
					}
				}
			}
		}
	}

	if (HasChannel(DIRECT_SHADOW_MASK) && film.HasChannel(DIRECT_SHADOW_MASK)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_DIRECT_SHADOW_MASK->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_DIRECT_SHADOW_MASK->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(INDIRECT_SHADOW_MASK) && film.HasChannel(INDIRECT_SHADOW_MASK)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_INDIRECT_SHADOW_MASK->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_INDIRECT_SHADOW_MASK->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(UV) && film.HasChannel(UV)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const float *srcPixel = film.channel_UV->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_UV->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const float *srcPixel = film.channel_UV->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_UV->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(RAYCOUNT) && film.HasChannel(RAYCOUNT)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_RAYCOUNT->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_RAYCOUNT->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(BY_MATERIAL_ID) && film.HasChannel(BY_MATERIAL_ID)) {
		for (u_int i = 0; i < channel_BY_MATERIAL_IDs.size(); ++i) {
			for (u_int j = 0; j < film.byMaterialIDs.size(); ++j) {
				if (byMaterialIDs[i] == film.byMaterialIDs[j]) {
					for (u_int y = 0; y < srcHeight; ++y) {
						for (u_int x = 0; x < srcWidth; ++x) {
							const float *srcPixel = film.channel_BY_MATERIAL_IDs[j]->GetPixel(srcOffsetX + x, srcOffsetY + y);
							channel_BY_MATERIAL_IDs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
						}
					}
				}
			}
		}
	}

	if (HasChannel(IRRADIANCE) && film.HasChannel(IRRADIANCE)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_IRRADIANCE->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_IRRADIANCE->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	if (HasChannel(OBJECT_ID) && film.HasChannel(OBJECT_ID)) {
		if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
			// Used DEPTH information to merge Films
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					if (film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y)[0] < channel_DEPTH->GetPixel(dstOffsetX + x, dstOffsetY + y)[0]) {
						const u_int *srcPixel = film.channel_OBJECT_ID->GetPixel(srcOffsetX + x, srcOffsetY + y);
						channel_OBJECT_ID->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
					}
				}
			}
		} else {
			for (u_int y = 0; y < srcHeight; ++y) {
				for (u_int x = 0; x < srcWidth; ++x) {
					const u_int *srcPixel = film.channel_OBJECT_ID->GetPixel(srcOffsetX + x, srcOffsetY + y);
					channel_OBJECT_ID->SetPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
				}
			}
		}
	}

	if (HasChannel(OBJECT_ID_MASK) && film.HasChannel(OBJECT_ID_MASK)) {
		for (u_int i = 0; i < channel_OBJECT_ID_MASKs.size(); ++i) {
			for (u_int j = 0; j < film.maskObjectIDs.size(); ++j) {
				if (maskObjectIDs[i] == film.maskObjectIDs[j]) {
					for (u_int y = 0; y < srcHeight; ++y) {
						for (u_int x = 0; x < srcWidth; ++x) {
							const float *srcPixel = film.channel_OBJECT_ID_MASKs[j]->GetPixel(srcOffsetX + x, srcOffsetY + y);
							channel_OBJECT_ID_MASKs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
						}
					}
				}
			}
		}
	}

	if (HasChannel(BY_OBJECT_ID) && film.HasChannel(BY_OBJECT_ID)) {
		for (u_int i = 0; i < channel_BY_OBJECT_IDs.size(); ++i) {
			for (u_int j = 0; j < film.byObjectIDs.size(); ++j) {
				if (byObjectIDs[i] == film.byObjectIDs[j]) {
					for (u_int y = 0; y < srcHeight; ++y) {
						for (u_int x = 0; x < srcWidth; ++x) {
							const float *srcPixel = film.channel_BY_OBJECT_IDs[j]->GetPixel(srcOffsetX + x, srcOffsetY + y);
							channel_BY_OBJECT_IDs[i]->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
						}
					}
				}
			}
		}
	}

	if (HasChannel(SAMPLECOUNT) && film.HasChannel(SAMPLECOUNT)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const u_int *srcPixel = film.channel_SAMPLECOUNT->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_SAMPLECOUNT->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	// CONVERGENCE values can not really be added, they will be updated at the next test

	if (HasChannel(MATERIAL_ID_COLOR) && film.HasChannel(MATERIAL_ID_COLOR)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_MATERIAL_ID_COLOR->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_MATERIAL_ID_COLOR->AddPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	// NOTE: update DEPTH channel last because it is used to merge other channels
	if (HasChannel(DEPTH) && film.HasChannel(DEPTH)) {
		for (u_int y = 0; y < srcHeight; ++y) {
			for (u_int x = 0; x < srcWidth; ++x) {
				const float *srcPixel = film.channel_DEPTH->GetPixel(srcOffsetX + x, srcOffsetY + y);
				channel_DEPTH->MinPixel(dstOffsetX + x, dstOffsetY + y, srcPixel);
			}
		}
	}

	//--------------------------------------------------------------------------
	// Film denoiser related code
	//--------------------------------------------------------------------------

	if (filmDenoiser.IsEnabled() && !filmDenoiser.HasReferenceFilm()) {
		// Add denoiser SamplesAccumulator statistics
		filmDenoiser.AddDenoiser(film.GetDenoiser(),
				srcOffsetX, srcOffsetY,
				srcWidth, srcHeight,
				dstOffsetX, dstOffsetY);

		// Check if the BCD denoiser warm up period is over
		if (!filmDenoiser.IsWarmUpDone())
			filmDenoiser.CheckIfWarmUpDone();
	}
}

void Film::ResetHaltTests() {
	if (convTest)
		convTest->Reset();
}

void Film::RunHaltTests() {
	if (statsConvergence == 1.f)
		return;

	// Check if it is time to stop
	if ((haltTime > 0.0) && (GetTotalTime() > haltTime)) {
		SLG_LOG("Time 100%, rendering done.");
		statsConvergence = 1.f;

		return;
	}

	// Check the halt SPP condition with the average samples of
	// the rendered region
	const double spp = statsTotalSampleCount / ((subRegion[1] - subRegion[0] + 1) * (subRegion[3] - subRegion[2] + 1));
	if ((haltSPP > 0.0) && (spp > haltSPP)) {
		SLG_LOG("Samples per pixel 100%, rendering done.");
		statsConvergence = 1.f;

		return;
	}

	if (convTest) {
		assert (HasChannel(IMAGEPIPELINE));

		// Required in order to have a valid convergence test
		ExecuteImagePipeline(0);

		// Run the test
		const u_int testResult = convTest->Test();

		// Set statsConvergence only if the haltThresholdStopRendering is true
		if (haltThresholdStopRendering)
			statsConvergence = 1.f - testResult / static_cast<float>(pixelCount);
	}
}

max_stars_repo_name: rebpdx/LuxCore

max_issues_repo_name: rebpdx/LuxCore

max_forks_repo_name: rebpdx/LuxCore


text:
#include "CDefDataProvider.h"

#include <chrono>

#include <boost/random/random_device.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/lexical_cast.hpp>

namespace services
{
    CDefDataProvider::CDefDataProvider()
    {}

    CDefDataProvider::~CDefDataProvider()
    {
        stop();
        wait();
    }

    IDataProvider::Connection CDefDataProvider::onNewData(const FNewDataHandler& handler)
    {
        return m_newDataReady.connect(handler);
    }

    void CDefDataProvider::setNewData(const Data& data)
    {
        if (!m_newDataReady.empty())
        {
            m_newDataReady(data);
        }
    }

    void CDefDataProvider::start()
    {
        m_isStopped.store(false, std::memory_order_relaxed);
        m_worker = std::thread([this] {
            boost::random::random_device rng;

            boost::random::uniform_real_distribution<> dist(-100.0, 100.0);
            boost::random::uniform_int_distribution<> errDist(1, 100);

            while (!m_isStopped.load(std::memory_order_relaxed))
            {
                using namespace std::chrono_literals;

                auto isError = errDist(rng) % 5 == 0;

                if (isError)
                {
                    setNewData("an error");
                }
                else {
                    auto newValue = dist(rng);
                    setNewData(boost::lexical_cast<std::string>(newValue));
                }

                std::this_thread::sleep_for(1s);
            }
        });
    }

    void CDefDataProvider::stop()
    {
        m_isStopped.store(true, std::memory_order_relaxed);
    }

    void CDefDataProvider::wait()
    {
        if (m_worker.joinable())
        {
            m_worker.join();
        }
    }

} // end namepsace services