<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "routablefactories50.h"
#include "routablefactories51.h"
#include "routablefactories52.h"
#include "routablefactories60.h"
#include "routingpolicyfactories.h"
#include "routablerepository.h"
#include "routingpolicyrepository.h"
#include "replymerger.h"
#include <vespa/document/util/stringutil.h>
#include <vespa/documentapi/documentapi.h>
#include <vespa/messagebus/emptyreply.h>
#include <vespa/vespalib/util/exceptions.h>
#include <sstream>

#include <vespa/log/log.h>
LOG_SETUP(".documentprotocol");

using document::DocumentTypeRepo;

namespace documentapi {

const mbus::string DocumentProtocol::NAME = "document";

DocumentProtocol::DocumentProtocol(const LoadTypeSet& loadTypes,
                                   DocumentTypeRepo::SP repo,
                                   const string &configId) :
    _routingPolicyRepository(new RoutingPolicyRepository()),
    _routableRepository(new RoutableRepository(loadTypes)),
    _systemState(SystemState::newInstance("")),
    _repo(repo)
{
    // Prepare config string for routing policy factories.
    string cfg = (configId.empty() ? "client" : configId);

    // When adding factories to this list, please KEEP THEM ORDERED alphabetically like they are now.
    putRoutingPolicyFactory("AND", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::AndPolicyFactory()));
    putRoutingPolicyFactory("Content", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::ContentPolicyFactory()));
    putRoutingPolicyFactory("MessageType", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::MessageTypePolicyFactory()));
    putRoutingPolicyFactory("DocumentRouteSelector", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::DocumentRouteSelectorPolicyFactory(*_repo, cfg)));
    putRoutingPolicyFactory("Extern", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::ExternPolicyFactory()));
    putRoutingPolicyFactory("LocalService", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::LocalServicePolicyFactory()));
    putRoutingPolicyFactory("RoundRobin", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::RoundRobinPolicyFactory()));
    putRoutingPolicyFactory("Storage", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::StoragePolicyFactory()));
    putRoutingPolicyFactory("SubsetService", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::SubsetServicePolicyFactory()));
    putRoutingPolicyFactory("LoadBalancer", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::LoadBalancerPolicyFactory()));

    // Prepare version specifications to use when adding routable factories.
    vespalib::VersionSpecification version50(5, 0);
    vespalib::VersionSpecification version51(5, 1);
    vespalib::VersionSpecification version52(5, 115);
    vespalib::VersionSpecification version6(6, 197); // TODO finalize version

    std::vector<vespalib::VersionSpecification> from50 = { version50, version51, version52 };
    std::vector<vespalib::VersionSpecification> from51 = { version51, version52 };
    std::vector<vespalib::VersionSpecification> from52 = { version52 };
    std::vector<vespalib::VersionSpecification> from6 = { version6 };

    // Add 5.0 serialization
    putRoutableFactory(MESSAGE_BATCHDOCUMENTUPDATE, IRoutableFactory::SP(new RoutableFactories50::BatchDocumentUpdateMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories50::CreateVisitorMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories50::DestroyVisitorMessageFactory()), from50);
    putRoutableFactory(MESSAGE_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories50::DocumentListMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories50::DocumentSummaryMessageFactory()), from50);
    putRoutableFactory(MESSAGE_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories50::EmptyBucketsMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories50::GetBucketListMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories50::GetBucketStateMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::GetDocumentMessageFactory()), from50);
    putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories50::MapVisitorMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::PutDocumentMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories50::QueryResultMessageFactory()), from50);
    putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::RemoveDocumentMessageFactory()), from50);
    putRoutableFactory(MESSAGE_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories50::RemoveLocationMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories50::SearchResultMessageFactory()), from50);
    putRoutableFactory(MESSAGE_STATBUCKET, IRoutableFactory::SP(new RoutableFactories50::StatBucketMessageFactory()), from50);
    putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::UpdateDocumentMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_VISITORINFO, IRoutableFactory::SP(new RoutableFactories50::VisitorInfoMessageFactory()), from50);
    putRoutableFactory(REPLY_BATCHDOCUMENTUPDATE, IRoutableFactory::SP(new RoutableFactories50::BatchDocumentUpdateReplyFactory()), from50);
    putRoutableFactory(REPLY_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories50::CreateVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories50::DestroyVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories50::DocumentListReplyFactory()), from50);
    putRoutableFactory(REPLY_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories50::DocumentSummaryReplyFactory()), from50);
    putRoutableFactory(REPLY_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories50::EmptyBucketsReplyFactory()), from50);
    putRoutableFactory(REPLY_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories50::GetBucketListReplyFactory()), from50);
    putRoutableFactory(REPLY_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories50::GetBucketStateReplyFactory()), from50);
    putRoutableFactory(REPLY_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::GetDocumentReplyFactory(*_repo)), from50);
    putRoutableFactory(REPLY_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories50::MapVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::PutDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories50::QueryResultReplyFactory()), from50);
    putRoutableFactory(REPLY_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::RemoveDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories50::RemoveLocationReplyFactory()), from50);
    putRoutableFactory(REPLY_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories50::SearchResultReplyFactory()), from50);
    putRoutableFactory(REPLY_STATBUCKET, IRoutableFactory::SP(new RoutableFactories50::StatBucketReplyFactory()), from50);
    putRoutableFactory(REPLY_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::UpdateDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_VISITORINFO, IRoutableFactory::SP(new RoutableFactories50::VisitorInfoReplyFactory()), from50);
    putRoutableFactory(REPLY_WRONGDISTRIBUTION, IRoutableFactory::SP(new RoutableFactories50::WrongDistributionReplyFactory()), from50);

    // Add 5.1 serialization
    putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories51::GetDocumentMessageFactory()), from51);
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories51::CreateVisitorMessageFactory(*_repo)), from51);
    putRoutableFactory(REPLY_DOCUMENTIGNORED, IRoutableFactory::SP(new RoutableFactories51::DocumentIgnoredReplyFactory()), from51);

    // Add 5.2 serialization
    putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::PutDocumentMessageFactory(*_repo)), from52);
    putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::UpdateDocumentMessageFactory(*_repo)), from52);
    putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::RemoveDocumentMessageFactory()), from52);

    // Add 6.x serialization (TODO finalize version)
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorMessageFactory(*_repo)), from6);
}

DocumentProtocol::~DocumentProtocol() = default;

mbus::IRoutingPolicy::UP
DocumentProtocol::createPolicy(const mbus::string &name, const mbus::string &param) const
{
    return _routingPolicyRepository->createPolicy(name, param);
}

DocumentProtocol &
DocumentProtocol::putRoutingPolicyFactory(const string &name, IRoutingPolicyFactory::SP factory)
{
    _routingPolicyRepository->putFactory(name, factory);
    return *this;
}

mbus::Blob
DocumentProtocol::encode(const vespalib::Version &version, const mbus::Routable &routable) const
{
    mbus::Blob blob(_routableRepository->encode(version, routable));
        // When valgrind reports errors of uninitialized data being written to
        // the network, it is useful to be able to see the serialized data to
        // try to identify what bits are uninitialized.
    if (LOG_WOULD_LOG(spam)) {
        std::ostringstream message;
        document::StringUtil::printAsHex(
                message, blob.data(), blob.size());
        LOG(spam, "Encoded message of protocol %s type %u using version %s serialization:\n%s",
            routable.getProtocol().c_str(), routable.getType(),
            version.toString().c_str(), message.str().c_str());
    }
    return blob;
}

mbus::Routable::UP
DocumentProtocol::decode(const vespalib::Version &version, mbus::BlobRef data) const
{
    try {
        return _routableRepository->decode(version, data);
    } catch (vespalib::Exception &e) {
        LOG(warning, "%s", e.getMessage().c_str());
        return mbus::Routable::UP();
    }
}

uint32_t
DocumentProtocol::getRoutableTypes(const vespalib::Version &version, std::vector<uint32_t> &out) const
{
    return _routableRepository->getRoutableTypes(version, out);
}

DocumentProtocol &
DocumentProtocol::putRoutableFactory(uint32_t type, IRoutableFactory::SP factory,
                                     const vespalib::VersionSpecification &version)
{
    _routableRepository->putFactory(version, type, factory);
    return *this;
}

DocumentProtocol &
DocumentProtocol::putRoutableFactory(uint32_t type, IRoutableFactory::SP factory,
                                     const std::vector<vespalib::VersionSpecification> &versions)
{
    for (std::vector<vespalib::VersionSpecification>::const_iterator it = versions.begin();
         it != versions.end(); ++it)
    {
        putRoutableFactory(type, factory, *it);
    }
    return *this;
}

string
DocumentProtocol::getErrorName(uint32_t errorCode) {
    switch (errorCode) {
        case ERROR_MESSAGE_IGNORED:               return "MESSAGE_IGNORED";
        case ERROR_POLICY_FAILURE:                return "POLICY_FAILURE";
        case ERROR_DOCUMENT_NOT_FOUND:            return "DOCUMENT_NOT_FOUND";
        case ERROR_EXISTS:                        return "EXISTS";
        case ERROR_BUCKET_NOT_FOUND:              return "BUCKET_NOT_FOUND";
        case ERROR_BUCKET_DELETED:                return "BUCKET_DELETED";
        case ERROR_NOT_IMPLEMENTED:               return "NOT_IMPLEMENTED";
        case ERROR_ILLEGAL_PARAMETERS:            return "ILLEGAL_PARAMETERS";
        case ERROR_IGNORED:                       return "IGNORED";
        case ERROR_UNKNOWN_COMMAND:               return "UNKNOWN_COMMAND";
        case ERROR_UNPARSEABLE:                   return "UNPARSEABLE";
        case ERROR_NO_SPACE:                      return "NO_SPACE";
        case ERROR_INTERNAL_FAILURE:              return "INTERNAL_FAILURE";
        case ERROR_PROCESSING_FAILURE:            return "PROCESSING_FAILURE";
        case ERROR_TIMESTAMP_EXIST:               return "TIMESTAMP_EXIST";
        case ERROR_STALE_TIMESTAMP:               return "STALE_TIMESTAMP";
        case ERROR_NODE_NOT_READY:                return "NODE_NOT_READY";
        case ERROR_WRONG_DISTRIBUTION:            return "WRONG_DISTRIBUTION";
        case ERROR_REJECTED:                      return "REJECTED";
        case ERROR_ABORTED:                       return "ABORTED";
        case ERROR_BUSY:                          return "BUSY";
        case ERROR_NOT_CONNECTED:                 return "NOT_CONNECTED";
        case ERROR_DISK_FAILURE:                  return "DISK_FAILURE";
        case ERROR_IO_FAILURE:                    return "IO_FAILURE";
        case ERROR_SUSPENDED:                     return "SUSPENDED";
        case ERROR_TEST_AND_SET_CONDITION_FAILED: return "TEST_AND_SET_CONDITION_FAILED";
    }
    return mbus::ErrorCode::getName(errorCode);
}

void
DocumentProtocol::merge(mbus::RoutingContext &ctx)
{
    std::set<uint32_t> mask;
    merge(ctx, mask);
}

void
DocumentProtocol::merge(mbus::RoutingContext& ctx,
                        const std::set<uint32_t>& mask)
{
    ReplyMerger rm;
    uint32_t idx = 0;
    for (mbus::RoutingNodeIterator it = ctx.getChildIterator();
         it.isValid(); it.next(), ++idx)
    {
        if (mask.find(idx) != mask.end()) {
            continue;
        }
        rm.merge(idx, it.getReplyRef());
    }
    assert(idx != 0);
    ReplyMerger::Result res(rm.mergedReply());
    if (res.isSuccessful()) {
        const uint32_t okIdx = res.getSuccessfulReplyIndex();
        ctx.setReply(ctx.getChildIterator().skip(okIdx).removeReply());
    } else {
        assert(res.hasGeneratedReply());
        ctx.setReply(mbus::Reply::UP(res.releaseGeneratedReply().release()));
    }
}

bool
DocumentProtocol::hasOnlyErrorsOfType(const mbus::Reply &reply, uint32_t errCode)
{
    for (uint32_t i = 0; i < reply.getNumErrors(); ++i) {
        if (reply.getError(i).getCode() != errCode) {
            return false;
        }
    }
    return true;
}

}
<commit_msg>Also use 6.0 protocols in C++<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "routablefactories50.h"
#include "routablefactories51.h"
#include "routablefactories52.h"
#include "routablefactories60.h"
#include "routingpolicyfactories.h"
#include "routablerepository.h"
#include "routingpolicyrepository.h"
#include "replymerger.h"
#include <vespa/document/util/stringutil.h>
#include <vespa/documentapi/documentapi.h>
#include <vespa/messagebus/emptyreply.h>
#include <vespa/vespalib/util/exceptions.h>
#include <sstream>

#include <vespa/log/log.h>
LOG_SETUP(".documentprotocol");

using document::DocumentTypeRepo;

namespace documentapi {

const mbus::string DocumentProtocol::NAME = "document";

DocumentProtocol::DocumentProtocol(const LoadTypeSet& loadTypes,
                                   DocumentTypeRepo::SP repo,
                                   const string &configId) :
    _routingPolicyRepository(new RoutingPolicyRepository()),
    _routableRepository(new RoutableRepository(loadTypes)),
    _systemState(SystemState::newInstance("")),
    _repo(repo)
{
    // Prepare config string for routing policy factories.
    string cfg = (configId.empty() ? "client" : configId);

    // When adding factories to this list, please KEEP THEM ORDERED alphabetically like they are now.
    putRoutingPolicyFactory("AND", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::AndPolicyFactory()));
    putRoutingPolicyFactory("Content", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::ContentPolicyFactory()));
    putRoutingPolicyFactory("MessageType", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::MessageTypePolicyFactory()));
    putRoutingPolicyFactory("DocumentRouteSelector", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::DocumentRouteSelectorPolicyFactory(*_repo, cfg)));
    putRoutingPolicyFactory("Extern", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::ExternPolicyFactory()));
    putRoutingPolicyFactory("LocalService", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::LocalServicePolicyFactory()));
    putRoutingPolicyFactory("RoundRobin", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::RoundRobinPolicyFactory()));
    putRoutingPolicyFactory("Storage", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::StoragePolicyFactory()));
    putRoutingPolicyFactory("SubsetService", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::SubsetServicePolicyFactory()));
    putRoutingPolicyFactory("LoadBalancer", IRoutingPolicyFactory::SP(new RoutingPolicyFactories::LoadBalancerPolicyFactory()));

    // Prepare version specifications to use when adding routable factories.
    vespalib::VersionSpecification version50(5, 0);
    vespalib::VersionSpecification version51(5, 1);
    vespalib::VersionSpecification version52(5, 115);
    vespalib::VersionSpecification version6(6, 197); // TODO finalize version

    std::vector<vespalib::VersionSpecification> from50 = { version50, version51, version52, version6 };
    std::vector<vespalib::VersionSpecification> from51 = { version51, version52, version6 };
    std::vector<vespalib::VersionSpecification> from52 = { version52, version6 };
    std::vector<vespalib::VersionSpecification> from6  = { version6 };

    // Add 5.0 serialization
    putRoutableFactory(MESSAGE_BATCHDOCUMENTUPDATE, IRoutableFactory::SP(new RoutableFactories50::BatchDocumentUpdateMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories50::CreateVisitorMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories50::DestroyVisitorMessageFactory()), from50);
    putRoutableFactory(MESSAGE_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories50::DocumentListMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories50::DocumentSummaryMessageFactory()), from50);
    putRoutableFactory(MESSAGE_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories50::EmptyBucketsMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories50::GetBucketListMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories50::GetBucketStateMessageFactory()), from50);
    putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::GetDocumentMessageFactory()), from50);
    putRoutableFactory(MESSAGE_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories50::MapVisitorMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::PutDocumentMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories50::QueryResultMessageFactory()), from50);
    putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::RemoveDocumentMessageFactory()), from50);
    putRoutableFactory(MESSAGE_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories50::RemoveLocationMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories50::SearchResultMessageFactory()), from50);
    putRoutableFactory(MESSAGE_STATBUCKET, IRoutableFactory::SP(new RoutableFactories50::StatBucketMessageFactory()), from50);
    putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::UpdateDocumentMessageFactory(*_repo)), from50);
    putRoutableFactory(MESSAGE_VISITORINFO, IRoutableFactory::SP(new RoutableFactories50::VisitorInfoMessageFactory()), from50);
    putRoutableFactory(REPLY_BATCHDOCUMENTUPDATE, IRoutableFactory::SP(new RoutableFactories50::BatchDocumentUpdateReplyFactory()), from50);
    putRoutableFactory(REPLY_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories50::CreateVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_DESTROYVISITOR, IRoutableFactory::SP(new RoutableFactories50::DestroyVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_DOCUMENTLIST, IRoutableFactory::SP(new RoutableFactories50::DocumentListReplyFactory()), from50);
    putRoutableFactory(REPLY_DOCUMENTSUMMARY, IRoutableFactory::SP(new RoutableFactories50::DocumentSummaryReplyFactory()), from50);
    putRoutableFactory(REPLY_EMPTYBUCKETS, IRoutableFactory::SP(new RoutableFactories50::EmptyBucketsReplyFactory()), from50);
    putRoutableFactory(REPLY_GETBUCKETLIST, IRoutableFactory::SP(new RoutableFactories50::GetBucketListReplyFactory()), from50);
    putRoutableFactory(REPLY_GETBUCKETSTATE, IRoutableFactory::SP(new RoutableFactories50::GetBucketStateReplyFactory()), from50);
    putRoutableFactory(REPLY_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::GetDocumentReplyFactory(*_repo)), from50);
    putRoutableFactory(REPLY_MAPVISITOR, IRoutableFactory::SP(new RoutableFactories50::MapVisitorReplyFactory()), from50);
    putRoutableFactory(REPLY_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::PutDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_QUERYRESULT, IRoutableFactory::SP(new RoutableFactories50::QueryResultReplyFactory()), from50);
    putRoutableFactory(REPLY_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::RemoveDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_REMOVELOCATION, IRoutableFactory::SP(new RoutableFactories50::RemoveLocationReplyFactory()), from50);
    putRoutableFactory(REPLY_SEARCHRESULT, IRoutableFactory::SP(new RoutableFactories50::SearchResultReplyFactory()), from50);
    putRoutableFactory(REPLY_STATBUCKET, IRoutableFactory::SP(new RoutableFactories50::StatBucketReplyFactory()), from50);
    putRoutableFactory(REPLY_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories50::UpdateDocumentReplyFactory()), from50);
    putRoutableFactory(REPLY_VISITORINFO, IRoutableFactory::SP(new RoutableFactories50::VisitorInfoReplyFactory()), from50);
    putRoutableFactory(REPLY_WRONGDISTRIBUTION, IRoutableFactory::SP(new RoutableFactories50::WrongDistributionReplyFactory()), from50);

    // Add 5.1 serialization
    putRoutableFactory(MESSAGE_GETDOCUMENT, IRoutableFactory::SP(new RoutableFactories51::GetDocumentMessageFactory()), from51);
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories51::CreateVisitorMessageFactory(*_repo)), from51);
    putRoutableFactory(REPLY_DOCUMENTIGNORED, IRoutableFactory::SP(new RoutableFactories51::DocumentIgnoredReplyFactory()), from51);

    // Add 5.2 serialization
    putRoutableFactory(MESSAGE_PUTDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::PutDocumentMessageFactory(*_repo)), from52);
    putRoutableFactory(MESSAGE_UPDATEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::UpdateDocumentMessageFactory(*_repo)), from52);
    putRoutableFactory(MESSAGE_REMOVEDOCUMENT, IRoutableFactory::SP(new RoutableFactories52::RemoveDocumentMessageFactory()), from52);

    // Add 6.x serialization (TODO finalize version)
    putRoutableFactory(MESSAGE_CREATEVISITOR, IRoutableFactory::SP(new RoutableFactories60::CreateVisitorMessageFactory(*_repo)), from6);
}

DocumentProtocol::~DocumentProtocol() = default;

mbus::IRoutingPolicy::UP
DocumentProtocol::createPolicy(const mbus::string &name, const mbus::string &param) const
{
    return _routingPolicyRepository->createPolicy(name, param);
}

DocumentProtocol &
DocumentProtocol::putRoutingPolicyFactory(const string &name, IRoutingPolicyFactory::SP factory)
{
    _routingPolicyRepository->putFactory(name, factory);
    return *this;
}

mbus::Blob
DocumentProtocol::encode(const vespalib::Version &version, const mbus::Routable &routable) const
{
    mbus::Blob blob(_routableRepository->encode(version, routable));
        // When valgrind reports errors of uninitialized data being written to
        // the network, it is useful to be able to see the serialized data to
        // try to identify what bits are uninitialized.
    if (LOG_WOULD_LOG(spam)) {
        std::ostringstream message;
        document::StringUtil::printAsHex(
                message, blob.data(), blob.size());
        LOG(spam, "Encoded message of protocol %s type %u using version %s serialization:\n%s",
            routable.getProtocol().c_str(), routable.getType(),
            version.toString().c_str(), message.str().c_str());
    }
    return blob;
}

mbus::Routable::UP
DocumentProtocol::decode(const vespalib::Version &version, mbus::BlobRef data) const
{
    try {
        return _routableRepository->decode(version, data);
    } catch (vespalib::Exception &e) {
        LOG(warning, "%s", e.getMessage().c_str());
        return mbus::Routable::UP();
    }
}

uint32_t
DocumentProtocol::getRoutableTypes(const vespalib::Version &version, std::vector<uint32_t> &out) const
{
    return _routableRepository->getRoutableTypes(version, out);
}

DocumentProtocol &
DocumentProtocol::putRoutableFactory(uint32_t type, IRoutableFactory::SP factory,
                                     const vespalib::VersionSpecification &version)
{
    _routableRepository->putFactory(version, type, factory);
    return *this;
}

DocumentProtocol &
DocumentProtocol::putRoutableFactory(uint32_t type, IRoutableFactory::SP factory,
                                     const std::vector<vespalib::VersionSpecification> &versions)
{
    for (std::vector<vespalib::VersionSpecification>::const_iterator it = versions.begin();
         it != versions.end(); ++it)
    {
        putRoutableFactory(type, factory, *it);
    }
    return *this;
}

string
DocumentProtocol::getErrorName(uint32_t errorCode) {
    switch (errorCode) {
        case ERROR_MESSAGE_IGNORED:               return "MESSAGE_IGNORED";
        case ERROR_POLICY_FAILURE:                return "POLICY_FAILURE";
        case ERROR_DOCUMENT_NOT_FOUND:            return "DOCUMENT_NOT_FOUND";
        case ERROR_EXISTS:                        return "EXISTS";
        case ERROR_BUCKET_NOT_FOUND:              return "BUCKET_NOT_FOUND";
        case ERROR_BUCKET_DELETED:                return "BUCKET_DELETED";
        case ERROR_NOT_IMPLEMENTED:               return "NOT_IMPLEMENTED";
        case ERROR_ILLEGAL_PARAMETERS:            return "ILLEGAL_PARAMETERS";
        case ERROR_IGNORED:                       return "IGNORED";
        case ERROR_UNKNOWN_COMMAND:               return "UNKNOWN_COMMAND";
        case ERROR_UNPARSEABLE:                   return "UNPARSEABLE";
        case ERROR_NO_SPACE:                      return "NO_SPACE";
        case ERROR_INTERNAL_FAILURE:              return "INTERNAL_FAILURE";
        case ERROR_PROCESSING_FAILURE:            return "PROCESSING_FAILURE";
        case ERROR_TIMESTAMP_EXIST:               return "TIMESTAMP_EXIST";
        case ERROR_STALE_TIMESTAMP:               return "STALE_TIMESTAMP";
        case ERROR_NODE_NOT_READY:                return "NODE_NOT_READY";
        case ERROR_WRONG_DISTRIBUTION:            return "WRONG_DISTRIBUTION";
        case ERROR_REJECTED:                      return "REJECTED";
        case ERROR_ABORTED:                       return "ABORTED";
        case ERROR_BUSY:                          return "BUSY";
        case ERROR_NOT_CONNECTED:                 return "NOT_CONNECTED";
        case ERROR_DISK_FAILURE:                  return "DISK_FAILURE";
        case ERROR_IO_FAILURE:                    return "IO_FAILURE";
        case ERROR_SUSPENDED:                     return "SUSPENDED";
        case ERROR_TEST_AND_SET_CONDITION_FAILED: return "TEST_AND_SET_CONDITION_FAILED";
    }
    return mbus::ErrorCode::getName(errorCode);
}

void
DocumentProtocol::merge(mbus::RoutingContext &ctx)
{
    std::set<uint32_t> mask;
    merge(ctx, mask);
}

void
DocumentProtocol::merge(mbus::RoutingContext& ctx,
                        const std::set<uint32_t>& mask)
{
    ReplyMerger rm;
    uint32_t idx = 0;
    for (mbus::RoutingNodeIterator it = ctx.getChildIterator();
         it.isValid(); it.next(), ++idx)
    {
        if (mask.find(idx) != mask.end()) {
            continue;
        }
        rm.merge(idx, it.getReplyRef());
    }
    assert(idx != 0);
    ReplyMerger::Result res(rm.mergedReply());
    if (res.isSuccessful()) {
        const uint32_t okIdx = res.getSuccessfulReplyIndex();
        ctx.setReply(ctx.getChildIterator().skip(okIdx).removeReply());
    } else {
        assert(res.hasGeneratedReply());
        ctx.setReply(mbus::Reply::UP(res.releaseGeneratedReply().release()));
    }
}

bool
DocumentProtocol::hasOnlyErrorsOfType(const mbus::Reply &reply, uint32_t errCode)
{
    for (uint32_t i = 0; i < reply.getNumErrors(); ++i) {
        if (reply.getError(i).getCode() != errCode) {
            return false;
        }
    }
    return true;
}

}
<|endoftext|>


<commit_before>/*
 * avsutil.hpp
 *  Utility classes for AviSynth
 *  Copyright (C) 2010 janus_wel<janus.wel.3@gmail.com>
 *  see LICENSE for redistributing, modifying, and so on.
 * */

#ifndef AVSUTIL_HPP
#define AVSUTIL_HPP

#include <stdexcept>
#include <ostream>

namespace avsutil {
    // forward declarations
    class Avs;          // an interface class to handle AVS file
    class Video;        // an interface class to handle a video stream in AVS file
    struct VideoInfo;   // a struct that has informations about a video stream
    class Audio;        // an interface class to handle an audio stream in AVS file
    struct AudioInfo;   // a struct that has informations about an audio stream
    class AvsUtilError; // an exception class

    // These instantiate the object about AVS.
    // The returned pointer MUST be "delete"ed.
    Avs* CreateAvsObj(void);
    Avs* CreateAvsObj(const char* filename);   // with a filename

    /*
     * A class has basic features about AVS,
     * by wrapping classes defined in avisynth.h,
     * e.g. opening AVS file and getting audio informations.
     * */
    class Avs {
        public:
            // to open a file
            virtual void open(const char* avsfile) = 0;
            // get informations
            virtual const char* filename(void) = 0;
            virtual bool is_fine(void) = 0;
            virtual const char* errmsg(void) = 0;
            // get audio
            // the returned pointer MUST be "delete"ed
            virtual Video* video(void) = 0;
            // the returned pointer MUST be "delete"ed
            virtual Audio* audio(void) = 0;

            // typical destructor
            virtual ~Avs(void) {}
    };

    // for a video stream
    class Video {
        public:
            // get informations
            virtual const VideoInfo& info(void) = 0;

            // typical destructor
            virtual ~Video(void) {}
    };

    // informations of a video stream
    struct VideoInfo {
        // Enumerations for representation as color spaces (pixel type) by FOURCC
        // refer: http://www.fourcc.org/
        enum fourcc_t {
            UNKOWN,
            // In AviSynth, this denote data is represented as raw DIB
            // - Device Independent Bitmap that doesn't have pallette data
            // and bytes per pixel is 24 or 32.
            // This is an alias for BI_RGB
            RGB,
            // YUV 4:2:2 packed
            // byte ordering in a macropixel is YUYV.
            YUY2,
            // YUV 4:2:0 planar
            // 1 sample per 2x2 for V and U, plane order is YVU
            YV12,
            // YUV 4:2:0 planar
            // 1 sample per 2x2 for U and V, plane order is YUV.
            // a.k.a IYUV
            I420
        };

        bool exists;
        unsigned __int32 width;             // a number of horizontal pixels
        unsigned __int32 height;            // a number of scan lines
        double time;                        // numof_frames * fps_denominator / fps_numerator
        double fps;                         // fps_numerator / fps_denominator
        unsigned __int32 fps_numerator;
        unsigned __int32 fps_denominator;
        unsigned __int32 numof_frames;      // a number of frames
        fourcc_t color_space;               // represented by FOURCC
        unsigned __int16 bpp;               // effective bit per pixcel
        bool is_fieldbased;                 // field-based if true, frame-based if false
        bool is_tff;                        // Top Field First if true, Bottom Field First if false
                                            // This should be evaluated only when is_fieldbased is true.
        // AviSynth doesn't contain this information (in 2.58)
        //bool is_progressive;              // progressive if true, interlaced if false

        // constructor for convenience with new statement
        VideoInfo(
                bool exists,
                unsigned __int32 width,
                unsigned __int32 height,
                double time,
                double fps,
                unsigned __int32 fps_numerator,
                unsigned __int32 fps_denominator,
                unsigned __int32 numof_frames,
                fourcc_t color_space,
                unsigned __int16 bpp,
                bool is_fieldbased,
                bool is_tff
                ) :
            exists(exists),
            width(width),
            height(height),
            time(time),
            fps(fps),
            fps_numerator(fps_numerator),
            fps_denominator(fps_denominator),
            numof_frames(numof_frames),
            color_space(color_space),
            bpp(bpp),
            is_fieldbased(is_fieldbased),
            is_tff(is_tff)
        {}
    };

    // for an audio stream
    class Audio {
        public:
            // get informations
            virtual const AudioInfo& info(void) = 0;
            // output audio data in the format of RIFF linear PCM
            virtual void write(std::ostream&) const = 0;
            // setter for the function to show progress
            virtual void progress_callback(void (*progress_callback)(const unsigned __int64 processed_samples, const unsigned __int64 total_samples)) = 0;
            // setter for a samples of a buffer
            // default is 4096
            // an actual buffer size is:
            //      min     buf_samples *  1 byte ( 8bit, mono)
            //      max     buf_samples * 24 byte (32bit, 5.1ch)
            virtual void buf_samples(const unsigned __int32) = 0;

            // typical destructor
            virtual ~Audio(void) {}
    };

    // informations of audio stream
    struct AudioInfo {
        bool exists;
        unsigned __int16 channels;      // left, [right, [center, ...]]
        unsigned __int16 bit_depth;     // a.k.a sample precision
        bool is_int;                    // int if true, float if false
        double time;                    // numof_samples / sampling_rate
        unsigned __int32 sampling_rate; // a.k.a sampling frequency
        unsigned __int64 numof_samples; // a number of samples
        unsigned __int16 block_size;    // bytes per sample: channels * (bit_depth / 8)

        // constructor for convenience with new statement
        AudioInfo(
                bool exists,
                unsigned __int16 channels,
                unsigned __int16 bit_depth,
                bool is_int,
                double time,
                unsigned __int32 sampling_rate,
                unsigned __int64 numof_samples,
                unsigned __int16 block_size
                ) :
            exists(exists),
            channels(channels),
            bit_depth(bit_depth),
            is_int(is_int),
            time(time),
            sampling_rate(sampling_rate),
            numof_samples(numof_samples),
            block_size(block_size)
        {}
    };

    // an exception that be thrown by functions in this namespace
    class AvsUtilError : public std::domain_error {
        public:
            AvsUtilError(const char* errmsg) : std::domain_error(errmsg) {}
    };

    // output audio data in the format of RIFF linear PCM
    std::ostream& operator <<(std::ostream&, const Audio&);
    std::ostream& operator <<(std::ostream&, const Audio* const);
};

#endif // AVSUTIL_HPP

<commit_msg>Add the function to give FOURCC name<commit_after>/*
 * avsutil.hpp
 *  Utility classes for AviSynth
 *  Copyright (C) 2010 janus_wel<janus.wel.3@gmail.com>
 *  see LICENSE for redistributing, modifying, and so on.
 * */

#ifndef AVSUTIL_HPP
#define AVSUTIL_HPP

#include <stdexcept>
#include <ostream>

namespace avsutil {
    // forward declarations
    class Avs;          // an interface class to handle AVS file
    class Video;        // an interface class to handle a video stream in AVS file
    struct VideoInfo;   // a struct that has informations about a video stream
    class Audio;        // an interface class to handle an audio stream in AVS file
    struct AudioInfo;   // a struct that has informations about an audio stream
    class AvsUtilError; // an exception class

    // These instantiate the object about AVS.
    // The returned pointer MUST be "delete"ed.
    Avs* CreateAvsObj(void);
    Avs* CreateAvsObj(const char* filename);   // with a filename

    /*
     * A class has basic features about AVS,
     * by wrapping classes defined in avisynth.h,
     * e.g. opening AVS file and getting audio informations.
     * */
    class Avs {
        public:
            // to open a file
            virtual void open(const char* avsfile) = 0;
            // get informations
            virtual const char* filename(void) = 0;
            virtual bool is_fine(void) = 0;
            virtual const char* errmsg(void) = 0;
            // get audio
            // the returned pointer MUST be "delete"ed
            virtual Video* video(void) = 0;
            // the returned pointer MUST be "delete"ed
            virtual Audio* audio(void) = 0;

            // typical destructor
            virtual ~Avs(void) {}
    };

    // for a video stream
    class Video {
        public:
            // get informations
            virtual const VideoInfo& info(void) = 0;

            // typical destructor
            virtual ~Video(void) {}
    };

    // informations of a video stream
    struct VideoInfo {
        // Enumerations for representation as color spaces (pixel type) by FOURCC
        // refer: http://www.fourcc.org/
        enum fourcc_t {
            UNKOWN,
            // In AviSynth, this denote data is represented as raw DIB
            // - Device Independent Bitmap that doesn't have pallette data
            // and bytes per pixel is 24 or 32.
            // This is an alias for BI_RGB
            RGB,
            // YUV 4:2:2 packed
            // byte ordering in a macropixel is YUYV.
            YUY2,
            // YUV 4:2:0 planar
            // 1 sample per 2x2 for V and U, plane order is YVU
            YV12,
            // YUV 4:2:0 planar
            // 1 sample per 2x2 for U and V, plane order is YUV.
            // a.k.a IYUV
            I420
        };

        static const char* fourcc_name(const fourcc_t f) {
            switch(f) {
                case UNKOWN:    return "unkown";
                case RGB:       return "RGB";
                case YUY2:      return "YUY2";
                case YV12:      return "YV12";
                case I420:      return "I420";
            };
        }

        bool exists;
        unsigned __int32 width;             // a number of horizontal pixels
        unsigned __int32 height;            // a number of scan lines
        double time;                        // numof_frames * fps_denominator / fps_numerator
        double fps;                         // fps_numerator / fps_denominator
        unsigned __int32 fps_numerator;
        unsigned __int32 fps_denominator;
        unsigned __int32 numof_frames;      // a number of frames
        fourcc_t color_space;               // represented by FOURCC
        unsigned __int16 bpp;               // effective bit per pixcel
        bool is_fieldbased;                 // field-based if true, frame-based if false
        bool is_tff;                        // Top Field First if true, Bottom Field First if false
                                            // This should be evaluated only when is_fieldbased is true.
        // AviSynth doesn't contain this information (in 2.58)
        //bool is_progressive;              // progressive if true, interlaced if false

        // constructor for convenience with new statement
        VideoInfo(
                bool exists,
                unsigned __int32 width,
                unsigned __int32 height,
                double time,
                double fps,
                unsigned __int32 fps_numerator,
                unsigned __int32 fps_denominator,
                unsigned __int32 numof_frames,
                fourcc_t color_space,
                unsigned __int16 bpp,
                bool is_fieldbased,
                bool is_tff
                ) :
            exists(exists),
            width(width),
            height(height),
            time(time),
            fps(fps),
            fps_numerator(fps_numerator),
            fps_denominator(fps_denominator),
            numof_frames(numof_frames),
            color_space(color_space),
            bpp(bpp),
            is_fieldbased(is_fieldbased),
            is_tff(is_tff)
        {}
    };

    // for an audio stream
    class Audio {
        public:
            // get informations
            virtual const AudioInfo& info(void) = 0;
            // output audio data in the format of RIFF linear PCM
            virtual void write(std::ostream&) const = 0;
            // setter for the function to show progress
            virtual void progress_callback(void (*progress_callback)(const unsigned __int64 processed_samples, const unsigned __int64 total_samples)) = 0;
            // setter for a samples of a buffer
            // default is 4096
            // an actual buffer size is:
            //      min     buf_samples *  1 byte ( 8bit, mono)
            //      max     buf_samples * 24 byte (32bit, 5.1ch)
            virtual void buf_samples(const unsigned __int32) = 0;

            // typical destructor
            virtual ~Audio(void) {}
    };

    // informations of audio stream
    struct AudioInfo {
        bool exists;
        unsigned __int16 channels;      // left, [right, [center, ...]]
        unsigned __int16 bit_depth;     // a.k.a sample precision
        bool is_int;                    // int if true, float if false
        double time;                    // numof_samples / sampling_rate
        unsigned __int32 sampling_rate; // a.k.a sampling frequency
        unsigned __int64 numof_samples; // a number of samples
        unsigned __int16 block_size;    // bytes per sample: channels * (bit_depth / 8)

        // constructor for convenience with new statement
        AudioInfo(
                bool exists,
                unsigned __int16 channels,
                unsigned __int16 bit_depth,
                bool is_int,
                double time,
                unsigned __int32 sampling_rate,
                unsigned __int64 numof_samples,
                unsigned __int16 block_size
                ) :
            exists(exists),
            channels(channels),
            bit_depth(bit_depth),
            is_int(is_int),
            time(time),
            sampling_rate(sampling_rate),
            numof_samples(numof_samples),
            block_size(block_size)
        {}
    };

    // an exception that be thrown by functions in this namespace
    class AvsUtilError : public std::domain_error {
        public:
            AvsUtilError(const char* errmsg) : std::domain_error(errmsg) {}
    };

    // output audio data in the format of RIFF linear PCM
    std::ostream& operator <<(std::ostream&, const Audio&);
    std::ostream& operator <<(std::ostream&, const Audio* const);
};

#endif // AVSUTIL_HPP

<|endoftext|>


<commit_before>//
// Created by david on 2018-07-04.
//

#include "class_mpo_site.h"
#include <general/nmspc_quantum_mechanics.h>
#include <general/nmspc_tensor_extra.h>
#include <h5pp/h5pp.h>
#include <math/rnd.h>

using namespace qm;
using Scalar = std::complex<double>;

class_mpo_site::class_mpo_site(ModelType model_type_, size_t position_) : model_type(model_type_), position(position_) {}

Eigen::Tensor<Scalar, 4>class_mpo_site::get_uncompressed_mpo() const {
    const auto &mpo = MPO();
    auto        d0  = mpo.dimension(0) * mpo.dimension(0);
    auto        d1  = mpo.dimension(1) * mpo.dimension(1);
    auto        d2  = mpo.dimension(2);
    auto        d3  = mpo.dimension(3);
    return mpo.contract(mpo, Textra::idx({3}, {2})).shuffle(Textra::array6{0, 3, 1, 4, 2, 5}).reshape(Textra::array4{d0, d1, d2, d3});
}

void class_mpo_site::build_mpo_squared() {
    mpo_squared     = get_uncompressed_mpo();
    if(Textra::hasNaN(mpo_squared.value())) {
        print_parameter_names();
        print_parameter_values();
        throw std::runtime_error(fmt::format("MPO squared at position {} has NAN's", get_position()));
    }
}

void class_mpo_site::set_mpo_squared(const Eigen::Tensor<Scalar, 4> &mpo_sq) { mpo_squared = mpo_sq; }

const Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO() const {
    if(all_mpo_parameters_have_been_set) {
        return mpo_internal;
    } else {
        throw std::runtime_error("All MPO parameters haven't been set yet.");
    }
}

const Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO2() const {
    if(mpo_squared and all_mpo_parameters_have_been_set) return mpo_squared.value();
    else
        throw std::runtime_error("MPO squared has not been set.");
}

Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO2() {
    if(mpo_squared and all_mpo_parameters_have_been_set) return mpo_squared.value();
    else {
        build_mpo_squared();
        return mpo_squared.value();
    }
}

bool class_mpo_site::is_real() const { return Textra::isReal(MPO(), "MPO"); }

bool class_mpo_site::has_nan() const {
    for(auto &param : get_parameters()) {
        if(param.second.type() == typeid(double))
            if(std::isnan(std::any_cast<double>(param.second))) { return true; }
    }
    return (Textra::hasNaN(mpo_internal, "MPO"));
}

void class_mpo_site::assert_validity() const {
    for(auto &param : get_parameters())
        if(param.second.type() == typeid(double))
            if(std::isnan(std::any_cast<double>(param.second))) {
                print_parameter_names();
                print_parameter_values();
                throw std::runtime_error(fmt::format("Param [{}] = {}", param.first, std::any_cast<double>(param.second)));
            }
    if(Textra::hasNaN(mpo_internal, "MPO")) throw std::runtime_error(fmt::format("MPO has NAN on position {}", get_position()));
    if(not Textra::isReal(mpo_internal, "MPO")) throw std::runtime_error(fmt::format("MPO has IMAG on position {}", get_position()));
    if(mpo_squared) {
        if(Textra::hasNaN(mpo_squared.value(), "MPO2")) throw std::runtime_error(fmt::format("MPO2 squared has NAN on position {}", get_position()));
        if(not Textra::isReal(mpo_squared.value(), "MPO2")) throw std::runtime_error(fmt::format("MPO2 squared has IMAG on position {}", get_position()));
    }
}

void class_mpo_site::set_position(size_t position_) { position = position_; }

std::vector<std::string> class_mpo_site::get_parameter_names() const {
    std::vector<std::string> parameter_names;
    for(auto &item : get_parameters()) parameter_names.push_back(item.first);
    return parameter_names;
}
std::vector<std::any> class_mpo_site::get_parameter_values() const {
    std::vector<std::any> parameter_values;
    for(auto &item : get_parameters()) parameter_values.push_back(item.second);
    return parameter_values;
}

size_t class_mpo_site::get_position() const {
    if(position) {
        return position.value();
    } else {
        throw std::runtime_error("Position of MPO has not been set");
    }
}

bool class_mpo_site::is_damped() const { return alpha != 0.0 or beta != 0.0; }

bool class_mpo_site::is_reduced() const { return e_reduced != 0.0; }

double class_mpo_site::get_reduced_energy() const { return e_reduced; }

void class_mpo_site::set_reduced_energy(double site_energy) {
    if(e_reduced != site_energy) {
        e_reduced    = site_energy;
        mpo_internal = MPO_reduced_view();
        mpo_squared  = std::nullopt;
    }
}

void class_mpo_site::print_parameter_names() const {
    std::cout << std::setprecision(10);
    for(auto &item : get_parameters()) fmt::print("{:<16}", item.first);
    fmt::print("\n");
}

void class_mpo_site::print_parameter_values() const {
    for(auto &item : get_parameters()) {
        if(item.second.type() == typeid(int)) fmt::print("{:<16}", std::any_cast<int>(item.second));
        if(item.second.type() == typeid(bool)) fmt::print("{:<16}", std::any_cast<bool>(item.second));
        if(item.second.type() == typeid(size_t)) fmt::print("{:<16}", std::any_cast<size_t>(item.second));
        if(item.second.type() == typeid(std::string)) fmt::print("{:<16}", std::any_cast<std::string>(item.second));
        if(item.second.type() == typeid(double)) fmt::print("{:<16.12f}", std::any_cast<double>(item.second));
    }
    fmt::print("\n");
}

//
// const std::any &class_model_base::find_val(const Parameters &parameters, std::string_view key) const {
//    for(auto &param : parameters) {
//        if(key == param.first) return param.second;
//    }
//    throw std::runtime_error("No parameter named [" + std::string(key) + "]");
//}
//
// std::any &class_model_base::find_val(Parameters &parameters, std::string_view key) const {
//    for(auto &param : parameters) {
//        if(key == param.first) return param.second;
//    }
//    throw std::runtime_error("No parameter named [" + std::string(key) + "]");
//}
//
//

void class_mpo_site::save_mpo(h5pp::File &file, const std::string &mpo_prefix) const {
    std::string dataset_name = fmt::format("{}/H_{}", mpo_prefix, get_position());
    file.writeDataset(MPO(), dataset_name, H5D_layout_t::H5D_COMPACT);
    file.writeAttribute(get_position(), "position", dataset_name);
    for(auto &params : get_parameters()) {
        if(params.second.type() == typeid(double)) file.writeAttribute(std::any_cast<double>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(size_t)) file.writeAttribute(std::any_cast<size_t>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(uint64_t)) file.writeAttribute(std::any_cast<uint64_t>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(int)) file.writeAttribute(std::any_cast<int>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(bool)) file.writeAttribute(std::any_cast<bool>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(std::string)) file.writeAttribute(std::any_cast<std::string>(params.second), params.first, dataset_name);
    }
}

void class_mpo_site::load_mpo(const h5pp::File &file, const std::string &mpo_prefix) {
    std::string mpo_dset = fmt::format("{}/H_{}", mpo_prefix, get_position());
    TableMap    map;
    if(file.linkExists(mpo_dset)) {
        auto param_names = file.getAttributeNames(mpo_dset);
        for(auto &param_name : param_names) {
            auto param_type = file.getTypeInfoAttribute(mpo_dset, param_name);
            if(param_type.cppTypeIndex) {
                if(param_type.cppTypeIndex.value() == typeid(double)) map[param_name] = file.readAttribute<double>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(size_t)) map[param_name] = file.readAttribute<size_t>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(uint64_t)) map[param_name] = file.readAttribute<uint64_t>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(int)) map[param_name] = file.readAttribute<int>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(bool)) map[param_name] = file.readAttribute<bool>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(std::string)) map[param_name] = file.readAttribute<std::string>(mpo_dset, param_name);
            }
        }
        set_parameters(map);
        build_mpo();
        if(Textra::Tensor_to_Vector(MPO()) != Textra::Tensor_to_Vector(file.readDataset<Eigen::Tensor<Scalar, 4>>(mpo_dset)))
            throw std::runtime_error("Built MPO does not match the MPO on file");
    } else {
        throw std::runtime_error(fmt::format("Could not load MPO. Dataset [{}] does not exist", mpo_dset));
    }
}
<commit_msg>Removed setprecision to avoid compiler error<commit_after>//
// Created by david on 2018-07-04.
//

#include "class_mpo_site.h"
#include <general/nmspc_quantum_mechanics.h>
#include <general/nmspc_tensor_extra.h>
#include <h5pp/h5pp.h>
#include <math/rnd.h>

using namespace qm;
using Scalar = std::complex<double>;

class_mpo_site::class_mpo_site(ModelType model_type_, size_t position_) : model_type(model_type_), position(position_) {}

Eigen::Tensor<Scalar, 4>class_mpo_site::get_uncompressed_mpo() const {
    const auto &mpo = MPO();
    auto        d0  = mpo.dimension(0) * mpo.dimension(0);
    auto        d1  = mpo.dimension(1) * mpo.dimension(1);
    auto        d2  = mpo.dimension(2);
    auto        d3  = mpo.dimension(3);
    return mpo.contract(mpo, Textra::idx({3}, {2})).shuffle(Textra::array6{0, 3, 1, 4, 2, 5}).reshape(Textra::array4{d0, d1, d2, d3});
}

void class_mpo_site::build_mpo_squared() {
    mpo_squared     = get_uncompressed_mpo();
    if(Textra::hasNaN(mpo_squared.value())) {
        print_parameter_names();
        print_parameter_values();
        throw std::runtime_error(fmt::format("MPO squared at position {} has NAN's", get_position()));
    }
}

void class_mpo_site::set_mpo_squared(const Eigen::Tensor<Scalar, 4> &mpo_sq) { mpo_squared = mpo_sq; }

const Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO() const {
    if(all_mpo_parameters_have_been_set) {
        return mpo_internal;
    } else {
        throw std::runtime_error("All MPO parameters haven't been set yet.");
    }
}

const Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO2() const {
    if(mpo_squared and all_mpo_parameters_have_been_set) return mpo_squared.value();
    else
        throw std::runtime_error("MPO squared has not been set.");
}

Eigen::Tensor<Scalar, 4> &class_mpo_site::MPO2() {
    if(mpo_squared and all_mpo_parameters_have_been_set) return mpo_squared.value();
    else {
        build_mpo_squared();
        return mpo_squared.value();
    }
}

bool class_mpo_site::is_real() const { return Textra::isReal(MPO(), "MPO"); }

bool class_mpo_site::has_nan() const {
    for(auto &param : get_parameters()) {
        if(param.second.type() == typeid(double))
            if(std::isnan(std::any_cast<double>(param.second))) { return true; }
    }
    return (Textra::hasNaN(mpo_internal, "MPO"));
}

void class_mpo_site::assert_validity() const {
    for(auto &param : get_parameters())
        if(param.second.type() == typeid(double))
            if(std::isnan(std::any_cast<double>(param.second))) {
                print_parameter_names();
                print_parameter_values();
                throw std::runtime_error(fmt::format("Param [{}] = {}", param.first, std::any_cast<double>(param.second)));
            }
    if(Textra::hasNaN(mpo_internal, "MPO")) throw std::runtime_error(fmt::format("MPO has NAN on position {}", get_position()));
    if(not Textra::isReal(mpo_internal, "MPO")) throw std::runtime_error(fmt::format("MPO has IMAG on position {}", get_position()));
    if(mpo_squared) {
        if(Textra::hasNaN(mpo_squared.value(), "MPO2")) throw std::runtime_error(fmt::format("MPO2 squared has NAN on position {}", get_position()));
        if(not Textra::isReal(mpo_squared.value(), "MPO2")) throw std::runtime_error(fmt::format("MPO2 squared has IMAG on position {}", get_position()));
    }
}

void class_mpo_site::set_position(size_t position_) { position = position_; }

std::vector<std::string> class_mpo_site::get_parameter_names() const {
    std::vector<std::string> parameter_names;
    for(auto &item : get_parameters()) parameter_names.push_back(item.first);
    return parameter_names;
}
std::vector<std::any> class_mpo_site::get_parameter_values() const {
    std::vector<std::any> parameter_values;
    for(auto &item : get_parameters()) parameter_values.push_back(item.second);
    return parameter_values;
}

size_t class_mpo_site::get_position() const {
    if(position) {
        return position.value();
    } else {
        throw std::runtime_error("Position of MPO has not been set");
    }
}

bool class_mpo_site::is_damped() const { return alpha != 0.0 or beta != 0.0; }

bool class_mpo_site::is_reduced() const { return e_reduced != 0.0; }

double class_mpo_site::get_reduced_energy() const { return e_reduced; }

void class_mpo_site::set_reduced_energy(double site_energy) {
    if(e_reduced != site_energy) {
        e_reduced    = site_energy;
        mpo_internal = MPO_reduced_view();
        mpo_squared  = std::nullopt;
    }
}

void class_mpo_site::print_parameter_names() const {
    for(auto &item : get_parameters()) fmt::print("{:<16}", item.first);
    fmt::print("\n");
}

void class_mpo_site::print_parameter_values() const {
    for(auto &item : get_parameters()) {
        if(item.second.type() == typeid(int)) fmt::print("{:<16}", std::any_cast<int>(item.second));
        if(item.second.type() == typeid(bool)) fmt::print("{:<16}", std::any_cast<bool>(item.second));
        if(item.second.type() == typeid(size_t)) fmt::print("{:<16}", std::any_cast<size_t>(item.second));
        if(item.second.type() == typeid(std::string)) fmt::print("{:<16}", std::any_cast<std::string>(item.second));
        if(item.second.type() == typeid(double)) fmt::print("{:<16.12f}", std::any_cast<double>(item.second));
    }
    fmt::print("\n");
}

//
// const std::any &class_model_base::find_val(const Parameters &parameters, std::string_view key) const {
//    for(auto &param : parameters) {
//        if(key == param.first) return param.second;
//    }
//    throw std::runtime_error("No parameter named [" + std::string(key) + "]");
//}
//
// std::any &class_model_base::find_val(Parameters &parameters, std::string_view key) const {
//    for(auto &param : parameters) {
//        if(key == param.first) return param.second;
//    }
//    throw std::runtime_error("No parameter named [" + std::string(key) + "]");
//}
//
//

void class_mpo_site::save_mpo(h5pp::File &file, const std::string &mpo_prefix) const {
    std::string dataset_name = fmt::format("{}/H_{}", mpo_prefix, get_position());
    file.writeDataset(MPO(), dataset_name, H5D_layout_t::H5D_COMPACT);
    file.writeAttribute(get_position(), "position", dataset_name);
    for(auto &params : get_parameters()) {
        if(params.second.type() == typeid(double)) file.writeAttribute(std::any_cast<double>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(size_t)) file.writeAttribute(std::any_cast<size_t>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(uint64_t)) file.writeAttribute(std::any_cast<uint64_t>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(int)) file.writeAttribute(std::any_cast<int>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(bool)) file.writeAttribute(std::any_cast<bool>(params.second), params.first, dataset_name);
        if(params.second.type() == typeid(std::string)) file.writeAttribute(std::any_cast<std::string>(params.second), params.first, dataset_name);
    }
}

void class_mpo_site::load_mpo(const h5pp::File &file, const std::string &mpo_prefix) {
    std::string mpo_dset = fmt::format("{}/H_{}", mpo_prefix, get_position());
    TableMap    map;
    if(file.linkExists(mpo_dset)) {
        auto param_names = file.getAttributeNames(mpo_dset);
        for(auto &param_name : param_names) {
            auto param_type = file.getTypeInfoAttribute(mpo_dset, param_name);
            if(param_type.cppTypeIndex) {
                if(param_type.cppTypeIndex.value() == typeid(double)) map[param_name] = file.readAttribute<double>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(size_t)) map[param_name] = file.readAttribute<size_t>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(uint64_t)) map[param_name] = file.readAttribute<uint64_t>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(int)) map[param_name] = file.readAttribute<int>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(bool)) map[param_name] = file.readAttribute<bool>(mpo_dset, param_name);
                if(param_type.cppTypeIndex.value() == typeid(std::string)) map[param_name] = file.readAttribute<std::string>(mpo_dset, param_name);
            }
        }
        set_parameters(map);
        build_mpo();
        if(Textra::Tensor_to_Vector(MPO()) != Textra::Tensor_to_Vector(file.readDataset<Eigen::Tensor<Scalar, 4>>(mpo_dset)))
            throw std::runtime_error("Built MPO does not match the MPO on file");
    } else {
        throw std::runtime_error(fmt::format("Could not load MPO. Dataset [{}] does not exist", mpo_dset));
    }
}
<|endoftext|>


<commit_before>/*
 * Calculate maximum cache item age.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "http_cache_age.hxx"
#include "http_cache_info.hxx"
#include "strmap.hxx"

#include <string.h>

static constexpr time_t SECOND = 1;
static constexpr time_t MINUTE = 60 * SECOND;
static constexpr time_t HOUR = 60 * MINUTE;
static constexpr time_t DAY = 24 * HOUR;
static constexpr time_t WEEK = 7 * DAY;

gcc_pure
static bool
vary_exists(const char *vary, const struct strmap *request_headers,
            const char *key)
{
    assert(vary != nullptr);
    assert(key != nullptr);
    assert(*key != 0);

    return request_headers != nullptr &&
        strstr(vary, key) != nullptr &&
        request_headers->Get(key) != nullptr;
}

/**
 * Returns the upper "maximum age" limit.  If the server specifies a
 * bigger maximum age, it will be clipped at this return value.
 */
gcc_pure
static time_t
http_cache_age_limit(const struct http_cache_info *info,
                     const struct strmap *request_headers)
{
    if (info->vary != nullptr) {
        /* if there's a "Vary" response header, we may assume that the
           response is much more volatile, and lower limits apply */

        if (vary_exists(info->vary, request_headers, "x-cm4all-beng-user") ||
            vary_exists(info->vary, request_headers, "cookie") ||
            vary_exists(info->vary, request_headers, "cookie2"))
            /* this response is specific to this one authenticated
               user, and caching it for a long time will not be
               helpful */
            return 5 * MINUTE;

        if (strstr(info->vary, "x-widgetid") != nullptr ||
            strstr(info->vary, "x-widgethref") != nullptr)
            /* this response is specific to one widget instance */
            return 30 * MINUTE;

        return HOUR;
    }

    return WEEK;
}

time_t
http_cache_calc_expires(const struct http_cache_info *info,
                        const struct strmap *request_headers)
{
    const time_t now = time(nullptr);

    time_t max_age;
    if (info->expires == (time_t)-1)
        /* there is no Expires response header; keep it in the cache
           for 1 hour, but check with If-Modified-Since */
        max_age = HOUR;
    else {
        const time_t expires = info->expires;
        if (expires <= now)
            /* already expired, bail out */
            return expires;

        max_age = info->expires - now;
    }

    const time_t age_limit = http_cache_age_limit(info, request_headers);
    if (age_limit < max_age)
        max_age = age_limit;

    return now + max_age;
}
<commit_msg>http_cache_age: simplify http_cache_age_limit()<commit_after>/*
 * Calculate maximum cache item age.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "http_cache_age.hxx"
#include "http_cache_info.hxx"
#include "strmap.hxx"

#include <string.h>

static constexpr time_t SECOND = 1;
static constexpr time_t MINUTE = 60 * SECOND;
static constexpr time_t HOUR = 60 * MINUTE;
static constexpr time_t DAY = 24 * HOUR;
static constexpr time_t WEEK = 7 * DAY;

gcc_pure
static bool
vary_exists(const char *vary, const struct strmap *request_headers,
            const char *key)
{
    assert(vary != nullptr);
    assert(key != nullptr);
    assert(*key != 0);

    return request_headers != nullptr &&
        strstr(vary, key) != nullptr &&
        request_headers->Get(key) != nullptr;
}

/**
 * Returns the upper "maximum age" limit.  If the server specifies a
 * bigger maximum age, it will be clipped at this return value.
 */
gcc_pure
static time_t
http_cache_age_limit(const struct http_cache_info *info,
                     const struct strmap *request_headers)
{
    if (info->vary == nullptr)
        return WEEK;

    /* if there's a "Vary" response header, we may assume that the
       response is much more volatile, and lower limits apply */

    if (vary_exists(info->vary, request_headers, "x-cm4all-beng-user") ||
        vary_exists(info->vary, request_headers, "cookie") ||
        vary_exists(info->vary, request_headers, "cookie2"))
        /* this response is specific to this one authenticated
           user, and caching it for a long time will not be
           helpful */
        return 5 * MINUTE;

    if (strstr(info->vary, "x-widgetid") != nullptr ||
        strstr(info->vary, "x-widgethref") != nullptr)
        /* this response is specific to one widget instance */
        return 30 * MINUTE;

    return HOUR;
}

time_t
http_cache_calc_expires(const struct http_cache_info *info,
                        const struct strmap *request_headers)
{
    const time_t now = time(nullptr);

    time_t max_age;
    if (info->expires == (time_t)-1)
        /* there is no Expires response header; keep it in the cache
           for 1 hour, but check with If-Modified-Since */
        max_age = HOUR;
    else {
        const time_t expires = info->expires;
        if (expires <= now)
            /* already expired, bail out */
            return expires;

        max_age = info->expires - now;
    }

    const time_t age_limit = http_cache_age_limit(info, request_headers);
    if (age_limit < max_age)
        max_age = age_limit;

    return now + max_age;
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "progressiveexrimagefilereader.h"

// appleseed.foundation headers.
#include "foundation/core/exceptions/exceptionioerror.h"
#include "foundation/core/exceptions/exceptionnotimplemented.h"
#include "foundation/image/canvasproperties.h"
#include "foundation/image/pixel.h"
#include "foundation/image/tile.h"
#include "foundation/platform/types.h"
#include "foundation/utility/log.h"
#include "foundation/utility/memory.h"

// OpenEXR headers.
#include "openexr/ImathBox.h"
#include "openexr/ImfChannelList.h"
#include "openexr/ImfFrameBuffer.h"
#include "openexr/ImfHeader.h"
#include "openexr/ImfInputFile.h"
#include "openexr/ImfPixelType.h"
#include "openexr/ImfTileDescription.h"
#include "openexr/ImfTiledInputFile.h"

// Standard headers.
#include <algorithm>
#include <cassert>
#include <cstring>
#include <memory>
#include <vector>

using namespace Iex;
using namespace Imath;
using namespace Imf;
using namespace std;

namespace foundation
{

//
// ProgressiveEXRImageFileReader class implementation.
//

struct ProgressiveEXRImageFileReader::Impl
{
    Logger*                     m_logger;
    size_t                      m_default_tile_width;
    size_t                      m_default_tile_height;
    auto_ptr<InputFile>         m_scanline_file;
    auto_ptr<TiledInputFile>    m_tiled_file;
    bool                        m_is_tiled;
    const Channel*              m_red;
    const Channel*              m_green;
    const Channel*              m_blue;
    const Channel*              m_alpha;
    Box2i                       m_dw;
    CanvasProperties            m_props;
    vector<uint8>               m_scanlines;
    size_t                      m_last_tile_y;
};

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(Logger* logger)
  : impl(new Impl())
{
    impl->m_logger = logger;
    impl->m_default_tile_width = 64;
    impl->m_default_tile_height = 16;
}

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(
    const size_t        default_tile_width,
    const size_t        default_tile_height)
  : impl(new Impl())
{
    impl->m_logger = 0;
    impl->m_default_tile_width = default_tile_width;
    impl->m_default_tile_height = default_tile_height;
}

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(
    Logger*             logger,
    const size_t        default_tile_width,
    const size_t        default_tile_height)
  : impl(new Impl())
{
    impl->m_logger = logger;
    impl->m_default_tile_width = default_tile_width;
    impl->m_default_tile_height = default_tile_height;
}

ProgressiveEXRImageFileReader::~ProgressiveEXRImageFileReader()
{
    if (is_open())
        close();

    delete impl;
}

void ProgressiveEXRImageFileReader::open(const char* filename)
{
    assert(filename);
    assert(!is_open());

    try
    {
        try
        {
            // Open the file for reading, assuming the file is tiled.
            impl->m_tiled_file.reset(new TiledInputFile(filename));
            impl->m_is_tiled = true;
        }
        catch (const ArgExc&)
        {
            // The file is not tiled, open it as a scanline file.
            impl->m_scanline_file.reset(new InputFile(filename));
            impl->m_is_tiled = false;

            // Print a warning message if a logger was provided.
            if (impl->m_logger)
            {
                LOG_WARNING(
                    *impl->m_logger,
                    "the texture file %s is not tiled, performances might suffer.",
                    filename);
            }
        }

        // Retrieve the file header, and perform basic sanity checks on it.
        const Header& header = impl->m_is_tiled
            ? impl->m_tiled_file->header()
            : impl->m_scanline_file->header();
        header.sanityCheck(impl->m_is_tiled);

        // Retrieve the image channels.
        const ChannelList& channels = header.channels();
        impl->m_red = channels.findChannel("R");
        impl->m_green = channels.findChannel("G");
        impl->m_blue = channels.findChannel("B");
        impl->m_alpha = channels.findChannel("A");
        if (!(impl->m_red && impl->m_green && impl->m_blue))
            throw ExceptionUnsupportedImageFormat();

        // Make sure all channels use the same pixel format.
        if (!(impl->m_red->type == impl->m_green->type && impl->m_red->type == impl->m_blue->type))
            throw ExceptionUnsupportedImageFormat();
        if (impl->m_alpha)
        {
            if (impl->m_red->type != impl->m_alpha->type)
                throw ExceptionUnsupportedImageFormat();
        }

        // Figure out the pixel format, based on the pixel type of the file.
        PixelFormat pixel_format = PixelFormatFloat;
        switch (impl->m_red->type)
        {
          case UINT: pixel_format = PixelFormatUInt32; break;
          case HALF: pixel_format = PixelFormatHalf; break;
          case FLOAT: pixel_format = PixelFormatFloat; break;
          default: throw ExceptionUnsupportedImageFormat();
        }

        // Retrieve the dimensions of the image.
        impl->m_dw = header.dataWindow();

        // Retrieve the dimensions of the tiles.
        size_t tile_width, tile_height;
        if (impl->m_is_tiled)
        {
            assert(header.hasTileDescription());
            const TileDescription& td = header.tileDescription();
            tile_width = static_cast<size_t>(td.xSize);
            tile_height = static_cast<size_t>(td.ySize);
        }
        else
        {
            tile_width = impl->m_default_tile_width;
            tile_height = impl->m_default_tile_height;
        }

        // Retrieve the number of tiles in each direction.
        size_t tile_count_x, tile_count_y;
        if (impl->m_is_tiled)
        {
            tile_count_x = static_cast<size_t>(impl->m_tiled_file->numXTiles());
            tile_count_y = static_cast<size_t>(impl->m_tiled_file->numYTiles());
        }
        else
        {
            const double nx = ceil(static_cast<double>(impl->m_dw.max.x - impl->m_dw.min.x) / tile_width);
            const double ny = ceil(static_cast<double>(impl->m_dw.max.y - impl->m_dw.min.y) / tile_height);
            tile_count_x = truncate<size_t>(nx);
            tile_count_y = truncate<size_t>(ny);
        }

        // Set canvas properties.
        impl->m_props.m_canvas_width = static_cast<size_t>(impl->m_dw.max.x - impl->m_dw.min.x + 1);
        impl->m_props.m_canvas_height = static_cast<size_t>(impl->m_dw.max.y - impl->m_dw.min.y + 1);
        impl->m_props.m_rcp_canvas_width = 1.0 / impl->m_props.m_canvas_width;
        impl->m_props.m_rcp_canvas_height = 1.0 / impl->m_props.m_canvas_height;
        impl->m_props.m_pixel_count = impl->m_props.m_canvas_width * impl->m_props.m_canvas_height;
        impl->m_props.m_tile_width = tile_width;
        impl->m_props.m_tile_height = tile_height;
        impl->m_props.m_rcp_tile_width = 1.0 / impl->m_props.m_tile_width;
        impl->m_props.m_rcp_tile_height = 1.0 / impl->m_props.m_tile_height;
        impl->m_props.m_tile_count_x = tile_count_x;
        impl->m_props.m_tile_count_y = tile_count_y;
        impl->m_props.m_tile_count = impl->m_props.m_tile_count_x * impl->m_props.m_tile_count_y;
        impl->m_props.m_pixel_format = pixel_format;
        impl->m_props.m_channel_count = impl->m_alpha ? 4 : 3;
        impl->m_props.m_pixel_size = impl->m_props.m_channel_count * Pixel::size(impl->m_props.m_pixel_format);

        // Allocate memory to store scanlines, if the file is not tiled.
        if (!impl->m_is_tiled)
        {
            const size_t size =
                  impl->m_props.m_canvas_width
                * impl->m_props.m_pixel_size
                * tile_height;
            impl->m_scanlines.resize(size);
        }

        // No tile previously accessed.
        impl->m_last_tile_y = ~size_t(0);
    }
    catch (const BaseExc& e)
    {
        // I/O error.
        throw ExceptionIOError(e.what());
    }
}

void ProgressiveEXRImageFileReader::close()
{
    assert(is_open());

    impl->m_scanline_file.reset();
    impl->m_tiled_file.reset();

    clear_release_memory(impl->m_scanlines);
}

bool ProgressiveEXRImageFileReader::is_open() const
{
    return impl->m_is_tiled
        ? impl->m_tiled_file.get() != 0
        : impl->m_scanline_file.get() != 0;
}

void ProgressiveEXRImageFileReader::read_canvas_properties(
    CanvasProperties&   props)
{
    assert(is_open());
    props = impl->m_props;
}

void ProgressiveEXRImageFileReader::read_image_attributes(
    ImageAttributes&    attrs)
{
    assert(is_open());
    throw ExceptionNotImplemented();
}

Tile* ProgressiveEXRImageFileReader::read_tile(
    const size_t        tile_x,
    const size_t        tile_y)
{
    assert(is_open());

    try
    {
        const int ix = static_cast<int>(tile_x);
        const int iy = static_cast<int>(tile_y);

        // Retrieve the data window of the tile.
        Box2i range;
        if (impl->m_is_tiled)
        {
            range = impl->m_tiled_file->dataWindowForTile(ix, iy);
        }
        else
        {
            const int tw = static_cast<int>(impl->m_props.m_tile_width);
            const int th = static_cast<int>(impl->m_props.m_tile_height);
            range.min.x = impl->m_dw.min.x + ix * tw;
            range.min.y = impl->m_dw.min.y + iy * th;
            range.max.x = min(range.min.x + tw - 1, impl->m_dw.max.x);
            range.max.y = min(range.min.y + th - 1, impl->m_dw.max.y);
        }

        // Compute the dimensions of the tile.
        const size_t tile_width = range.max.x - range.min.x + 1;
        const size_t tile_height = range.max.y - range.min.y + 1;

        // Create a new tile.
        Tile* tile =
            new Tile(
                tile_width,
                tile_height,
                impl->m_props.m_channel_count,
                impl->m_props.m_pixel_format);

        const size_t channel_size = Pixel::size(impl->m_props.m_pixel_format);
        const size_t stride_x = impl->m_props.m_pixel_size;
        const size_t stride_y = impl->m_is_tiled
            ? stride_x * tile_width
            : stride_x * impl->m_props.m_canvas_width;
        const size_t origin = impl->m_is_tiled
            ? range.min.y * stride_y + range.min.x * stride_x
            : range.min.y * stride_y;
        const char* base = impl->m_is_tiled
            ? reinterpret_cast<const char*>(tile->pixel(0, 0)) - origin
            : reinterpret_cast<const char*>(&impl->m_scanlines[0]) - origin;

        // Construct the FrameBuffer object.
        FrameBuffer framebuffer;
        framebuffer.insert(
            "R",
            Slice(
                impl->m_red->type,
                const_cast<char*>(base + 0 * channel_size),
                stride_x,
                stride_y));
        framebuffer.insert(
            "G",
            Slice(
                impl->m_green->type,
                const_cast<char*>(base + 1 * channel_size),
                stride_x,
                stride_y));
        framebuffer.insert(
            "B",
            Slice(
                impl->m_blue->type,
                const_cast<char*>(base + 2 * channel_size),
                stride_x,
                stride_y));
        if (impl->m_alpha)
        {
            framebuffer.insert(
                "A",
                Slice(
                    impl->m_alpha->type,
                    const_cast<char*>(base + 3 * channel_size),
                    stride_x,
                    stride_y));
        }

        if (impl->m_is_tiled)
        {
            // Read the tile.
            impl->m_tiled_file->setFrameBuffer(framebuffer);
            impl->m_tiled_file->readTile(ix, iy);
        }
        else
        {
            if (impl->m_last_tile_y != tile_y)
            {
                // Read the scanlines intersecting the tile.
                impl->m_scanline_file->setFrameBuffer(framebuffer);
                impl->m_scanline_file->readPixels(range.min.y, range.max.y);
                impl->m_last_tile_y = tile_y;
            }

            // Extract the tile from the scanlines.
            for (size_t y = 0; y < tile_height; ++y)
            {
                const size_t index = (impl->m_props.m_canvas_width * y + range.min.x) * stride_x;
                memcpy(
                    tile->pixel(0, y),
                    &impl->m_scanlines[index],
                    tile_width * stride_x);
            }
        }

        return tile;
    }
    catch (const BaseExc& e)
    {
        // I/O error.
        throw ExceptionIOError(e.what());
    }
}

}   // namespace foundation
<commit_msg>changed the default tile size in the progressive OpenEXR image file reader from 64x16 to 32x32.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "progressiveexrimagefilereader.h"

// appleseed.foundation headers.
#include "foundation/core/exceptions/exceptionioerror.h"
#include "foundation/core/exceptions/exceptionnotimplemented.h"
#include "foundation/image/canvasproperties.h"
#include "foundation/image/pixel.h"
#include "foundation/image/tile.h"
#include "foundation/platform/types.h"
#include "foundation/utility/log.h"
#include "foundation/utility/memory.h"

// OpenEXR headers.
#include "openexr/ImathBox.h"
#include "openexr/ImfChannelList.h"
#include "openexr/ImfFrameBuffer.h"
#include "openexr/ImfHeader.h"
#include "openexr/ImfInputFile.h"
#include "openexr/ImfPixelType.h"
#include "openexr/ImfTileDescription.h"
#include "openexr/ImfTiledInputFile.h"

// Standard headers.
#include <algorithm>
#include <cassert>
#include <cstring>
#include <memory>
#include <vector>

using namespace Iex;
using namespace Imath;
using namespace Imf;
using namespace std;

namespace foundation
{

//
// ProgressiveEXRImageFileReader class implementation.
//

struct ProgressiveEXRImageFileReader::Impl
{
    Logger*                     m_logger;
    size_t                      m_default_tile_width;
    size_t                      m_default_tile_height;
    auto_ptr<InputFile>         m_scanline_file;
    auto_ptr<TiledInputFile>    m_tiled_file;
    bool                        m_is_tiled;
    const Channel*              m_red;
    const Channel*              m_green;
    const Channel*              m_blue;
    const Channel*              m_alpha;
    Box2i                       m_dw;
    CanvasProperties            m_props;
    vector<uint8>               m_scanlines;
    size_t                      m_last_tile_y;
};

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(Logger* logger)
  : impl(new Impl())
{
    impl->m_logger = logger;
    impl->m_default_tile_width = 32;
    impl->m_default_tile_height = 32;
}

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(
    const size_t        default_tile_width,
    const size_t        default_tile_height)
  : impl(new Impl())
{
    impl->m_logger = 0;
    impl->m_default_tile_width = default_tile_width;
    impl->m_default_tile_height = default_tile_height;
}

ProgressiveEXRImageFileReader::ProgressiveEXRImageFileReader(
    Logger*             logger,
    const size_t        default_tile_width,
    const size_t        default_tile_height)
  : impl(new Impl())
{
    impl->m_logger = logger;
    impl->m_default_tile_width = default_tile_width;
    impl->m_default_tile_height = default_tile_height;
}

ProgressiveEXRImageFileReader::~ProgressiveEXRImageFileReader()
{
    if (is_open())
        close();

    delete impl;
}

void ProgressiveEXRImageFileReader::open(const char* filename)
{
    assert(filename);
    assert(!is_open());

    try
    {
        try
        {
            // Open the file for reading, assuming the file is tiled.
            impl->m_tiled_file.reset(new TiledInputFile(filename));
            impl->m_is_tiled = true;
        }
        catch (const ArgExc&)
        {
            // The file is not tiled, open it as a scanline file.
            impl->m_scanline_file.reset(new InputFile(filename));
            impl->m_is_tiled = false;

            // Print a warning message if a logger was provided.
            if (impl->m_logger)
            {
                LOG_WARNING(
                    *impl->m_logger,
                    "the texture file %s is not tiled, performances might suffer.",
                    filename);
            }
        }

        // Retrieve the file header, and perform basic sanity checks on it.
        const Header& header = impl->m_is_tiled
            ? impl->m_tiled_file->header()
            : impl->m_scanline_file->header();
        header.sanityCheck(impl->m_is_tiled);

        // Retrieve the image channels.
        const ChannelList& channels = header.channels();
        impl->m_red = channels.findChannel("R");
        impl->m_green = channels.findChannel("G");
        impl->m_blue = channels.findChannel("B");
        impl->m_alpha = channels.findChannel("A");
        if (!(impl->m_red && impl->m_green && impl->m_blue))
            throw ExceptionUnsupportedImageFormat();

        // Make sure all channels use the same pixel format.
        if (!(impl->m_red->type == impl->m_green->type && impl->m_red->type == impl->m_blue->type))
            throw ExceptionUnsupportedImageFormat();
        if (impl->m_alpha)
        {
            if (impl->m_red->type != impl->m_alpha->type)
                throw ExceptionUnsupportedImageFormat();
        }

        // Figure out the pixel format, based on the pixel type of the file.
        PixelFormat pixel_format = PixelFormatFloat;
        switch (impl->m_red->type)
        {
          case UINT: pixel_format = PixelFormatUInt32; break;
          case HALF: pixel_format = PixelFormatHalf; break;
          case FLOAT: pixel_format = PixelFormatFloat; break;
          default: throw ExceptionUnsupportedImageFormat();
        }

        // Retrieve the dimensions of the image.
        impl->m_dw = header.dataWindow();

        // Retrieve the dimensions of the tiles.
        size_t tile_width, tile_height;
        if (impl->m_is_tiled)
        {
            assert(header.hasTileDescription());
            const TileDescription& td = header.tileDescription();
            tile_width = static_cast<size_t>(td.xSize);
            tile_height = static_cast<size_t>(td.ySize);
        }
        else
        {
            tile_width = impl->m_default_tile_width;
            tile_height = impl->m_default_tile_height;
        }

        // Retrieve the number of tiles in each direction.
        size_t tile_count_x, tile_count_y;
        if (impl->m_is_tiled)
        {
            tile_count_x = static_cast<size_t>(impl->m_tiled_file->numXTiles());
            tile_count_y = static_cast<size_t>(impl->m_tiled_file->numYTiles());
        }
        else
        {
            const double nx = ceil(static_cast<double>(impl->m_dw.max.x - impl->m_dw.min.x) / tile_width);
            const double ny = ceil(static_cast<double>(impl->m_dw.max.y - impl->m_dw.min.y) / tile_height);
            tile_count_x = truncate<size_t>(nx);
            tile_count_y = truncate<size_t>(ny);
        }

        // Set canvas properties.
        impl->m_props.m_canvas_width = static_cast<size_t>(impl->m_dw.max.x - impl->m_dw.min.x + 1);
        impl->m_props.m_canvas_height = static_cast<size_t>(impl->m_dw.max.y - impl->m_dw.min.y + 1);
        impl->m_props.m_rcp_canvas_width = 1.0 / impl->m_props.m_canvas_width;
        impl->m_props.m_rcp_canvas_height = 1.0 / impl->m_props.m_canvas_height;
        impl->m_props.m_pixel_count = impl->m_props.m_canvas_width * impl->m_props.m_canvas_height;
        impl->m_props.m_tile_width = tile_width;
        impl->m_props.m_tile_height = tile_height;
        impl->m_props.m_rcp_tile_width = 1.0 / impl->m_props.m_tile_width;
        impl->m_props.m_rcp_tile_height = 1.0 / impl->m_props.m_tile_height;
        impl->m_props.m_tile_count_x = tile_count_x;
        impl->m_props.m_tile_count_y = tile_count_y;
        impl->m_props.m_tile_count = impl->m_props.m_tile_count_x * impl->m_props.m_tile_count_y;
        impl->m_props.m_pixel_format = pixel_format;
        impl->m_props.m_channel_count = impl->m_alpha ? 4 : 3;
        impl->m_props.m_pixel_size = impl->m_props.m_channel_count * Pixel::size(impl->m_props.m_pixel_format);

        // Allocate memory to store scanlines, if the file is not tiled.
        if (!impl->m_is_tiled)
        {
            const size_t size =
                  impl->m_props.m_canvas_width
                * impl->m_props.m_pixel_size
                * tile_height;
            impl->m_scanlines.resize(size);
        }

        // No tile previously accessed.
        impl->m_last_tile_y = ~size_t(0);
    }
    catch (const BaseExc& e)
    {
        // I/O error.
        throw ExceptionIOError(e.what());
    }
}

void ProgressiveEXRImageFileReader::close()
{
    assert(is_open());

    impl->m_scanline_file.reset();
    impl->m_tiled_file.reset();

    clear_release_memory(impl->m_scanlines);
}

bool ProgressiveEXRImageFileReader::is_open() const
{
    return impl->m_is_tiled
        ? impl->m_tiled_file.get() != 0
        : impl->m_scanline_file.get() != 0;
}

void ProgressiveEXRImageFileReader::read_canvas_properties(
    CanvasProperties&   props)
{
    assert(is_open());
    props = impl->m_props;
}

void ProgressiveEXRImageFileReader::read_image_attributes(
    ImageAttributes&    attrs)
{
    assert(is_open());
    throw ExceptionNotImplemented();
}

Tile* ProgressiveEXRImageFileReader::read_tile(
    const size_t        tile_x,
    const size_t        tile_y)
{
    assert(is_open());

    try
    {
        const int ix = static_cast<int>(tile_x);
        const int iy = static_cast<int>(tile_y);

        // Retrieve the data window of the tile.
        Box2i range;
        if (impl->m_is_tiled)
        {
            range = impl->m_tiled_file->dataWindowForTile(ix, iy);
        }
        else
        {
            const int tw = static_cast<int>(impl->m_props.m_tile_width);
            const int th = static_cast<int>(impl->m_props.m_tile_height);
            range.min.x = impl->m_dw.min.x + ix * tw;
            range.min.y = impl->m_dw.min.y + iy * th;
            range.max.x = min(range.min.x + tw - 1, impl->m_dw.max.x);
            range.max.y = min(range.min.y + th - 1, impl->m_dw.max.y);
        }

        // Compute the dimensions of the tile.
        const size_t tile_width = range.max.x - range.min.x + 1;
        const size_t tile_height = range.max.y - range.min.y + 1;

        // Create a new tile.
        Tile* tile =
            new Tile(
                tile_width,
                tile_height,
                impl->m_props.m_channel_count,
                impl->m_props.m_pixel_format);

        const size_t channel_size = Pixel::size(impl->m_props.m_pixel_format);
        const size_t stride_x = impl->m_props.m_pixel_size;
        const size_t stride_y = impl->m_is_tiled
            ? stride_x * tile_width
            : stride_x * impl->m_props.m_canvas_width;
        const size_t origin = impl->m_is_tiled
            ? range.min.y * stride_y + range.min.x * stride_x
            : range.min.y * stride_y;
        const char* base = impl->m_is_tiled
            ? reinterpret_cast<const char*>(tile->pixel(0, 0)) - origin
            : reinterpret_cast<const char*>(&impl->m_scanlines[0]) - origin;

        // Construct the FrameBuffer object.
        FrameBuffer framebuffer;
        framebuffer.insert(
            "R",
            Slice(
                impl->m_red->type,
                const_cast<char*>(base + 0 * channel_size),
                stride_x,
                stride_y));
        framebuffer.insert(
            "G",
            Slice(
                impl->m_green->type,
                const_cast<char*>(base + 1 * channel_size),
                stride_x,
                stride_y));
        framebuffer.insert(
            "B",
            Slice(
                impl->m_blue->type,
                const_cast<char*>(base + 2 * channel_size),
                stride_x,
                stride_y));
        if (impl->m_alpha)
        {
            framebuffer.insert(
                "A",
                Slice(
                    impl->m_alpha->type,
                    const_cast<char*>(base + 3 * channel_size),
                    stride_x,
                    stride_y));
        }

        if (impl->m_is_tiled)
        {
            // Read the tile.
            impl->m_tiled_file->setFrameBuffer(framebuffer);
            impl->m_tiled_file->readTile(ix, iy);
        }
        else
        {
            if (impl->m_last_tile_y != tile_y)
            {
                // Read the scanlines intersecting the tile.
                impl->m_scanline_file->setFrameBuffer(framebuffer);
                impl->m_scanline_file->readPixels(range.min.y, range.max.y);
                impl->m_last_tile_y = tile_y;
            }

            // Extract the tile from the scanlines.
            for (size_t y = 0; y < tile_height; ++y)
            {
                const size_t index = (impl->m_props.m_canvas_width * y + range.min.x) * stride_x;
                memcpy(
                    tile->pixel(0, y),
                    &impl->m_scanlines[index],
                    tile_width * stride_x);
            }
        }

        return tile;
    }
    catch (const BaseExc& e)
    {
        // I/O error.
        throw ExceptionIOError(e.what());
    }
}

}   // namespace foundation
<|endoftext|>


<commit_before>// sourcecode
// Include the ROS C++ APIs
#include <ros/ros.h>

// Standard C++ entry point
int main(int argc, char** argv) {
  // Announce this program to the ROS master as a "node" called "hello_world_node"
  ros::init(argc, argv, "hello_world_node");
  // Start the node resource managers (communication, time, etc)
  ros::start();
  // Broadcast a simple log message
  ROS_INFO_STREAM("Hello, ROSworld!");
  // Process ROS callbacks until receiving a SIGINT (ctrl-c)
  ros::spin();
  // Stop the node's resources
  ros::shutdown();
  // Exit tranquilly
  return 0;
}
<commit_msg>Update base_controller_node.cpp<commit_after>#include <ros/ros.h>
#include <geometry_msgs/Twist.h>

void cmd_vel_callback(const geometry_msgs::Twist& vel_cmd)
{
    ROS_INFO("I heard: [%f]", vel_cmd.linear.y);
    std::cout << "Twist Received " << std::endl;
}

int main( int argc, char* argv[] )
{
ros::init(argc, argv, "toeminator_publisher" );

ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/cmd_vel", 1000, cmd_vel_callback);

while( n.ok() )
{
    ros::spin();
}

return 1;
}
<|endoftext|>