<commit_before>/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrRecordingContextPriv.h"

#include "src/gpu/GrCaps.h"
#include "src/gpu/GrDrawingManager.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrSurfaceProxyView.h"

#if SK_GPU_V1
#include "src/gpu/v1/Device_v1.h"
#include "src/gpu/v1/SurfaceDrawContext_v1.h"
#include "src/gpu/v1/SurfaceFillContext_v1.h"
#endif
#if SK_GPU_V2
#include "src/gpu/v2/Device_v2.h"
#include "src/gpu/v2/SurfaceDrawContext_v2.h"
#include "src/gpu/v2/SurfaceFillContext_v2.h"
#endif

void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
    this->context()->addOnFlushCallbackObject(onFlushCBObject);
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(GrColorType colorType,
                                                              sk_sp<GrSurfaceProxy> proxy,
                                                              sk_sp<SkColorSpace> colorSpace,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return skgpu::v2::Device::Make(this->context(), colorType, std::move(proxy),
                                       std::move(colorSpace), origin, props, init);
#else
        return nullptr;
#endif // GR_TEST_UTILS
    } else
#endif
    {
#if SK_GPU_V1
        return skgpu::v1::Device::Make(this->context(), colorType, std::move(proxy),
                                       std::move(colorSpace), origin, props, init);
#else
        return nullptr;
#endif
    }
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(SkBudgeted budgeted,
                                                              const SkImageInfo& ii,
                                                              SkBackingFit fit,
                                                              int sampleCount,
                                                              GrMipmapped mipmapped,
                                                              GrProtected isProtected,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return skgpu::v2::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
                                       mipmapped, isProtected, origin, props, init);
#else
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        return skgpu::v1::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
                                       mipmapped, isProtected, origin, props, init);
#else
        return nullptr;
#endif
    }
}

void GrRecordingContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
    this->context()->drawingManager()->moveRenderTasksToDDL(ddl);
}

GrSDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const {
    return GrSDFTControl{
            this->caps()->shaderCaps()->supportsDistanceFieldText(),
            useSDFTForSmallText,
            this->options().fMinDistanceFieldFontSize,
            this->options().fGlyphsAsPathsFontSize};
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(GrSurfaceProxyView readView,
                                                                      const GrColorInfo& info) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        // It is probably not necessary to check if the context is abandoned here since uses of the
        // SurfaceContext which need the context will mostly likely fail later on w/o an issue.
        // However having this here adds some reassurance in case there is a path that doesn't
        // handle an abandoned context correctly. It also lets us early out of some extra work.
        if (this->context()->abandoned()) {
            return nullptr;
        }
        GrSurfaceProxy* proxy = readView.proxy();
        SkASSERT(proxy && proxy->asTextureProxy());

        std::unique_ptr<skgpu::SurfaceContext> sc;
        if (proxy->asRenderTargetProxy()) {
            // Will we ever want a swizzle that is not the default write swizzle for the format and
            // colorType here? If so we will need to manually pass that in.
            GrSwizzle writeSwizzle;
            if (info.colorType() != GrColorType::kUnknown) {
                writeSwizzle = this->caps()->getWriteSwizzle(proxy->backendFormat(),
                                                             info.colorType());
            }
            GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
            if (info.alphaType() == kPremul_SkAlphaType ||
                info.alphaType() == kOpaque_SkAlphaType) {
                sc = std::make_unique<skgpu::v1::SurfaceDrawContext>(this->context(),
                                                                     std::move(readView),
                                                                     std::move(writeView),
                                                                     info.colorType(),
                                                                     info.refColorSpace(),
                                                                     SkSurfaceProps());
            } else {
                sc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                                     std::move(readView),
                                                                     std::move(writeView),
                                                                     info);
            }
        } else {
            sc = std::make_unique<skgpu::SurfaceContext>(this->context(),
                                                         std::move(readView),
                                                         info);
        }
        SkDEBUGCODE(sc->validate();)
        return sc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(const GrImageInfo& info,
                                                                      const GrBackendFormat& format,
                                                                      SkBackingFit fit,
                                                                      GrSurfaceOrigin origin,
                                                                      GrRenderable renderable,
                                                                      int sampleCount,
                                                                      GrMipmapped mipmapped,
                                                                      GrProtected isProtected,
                                                                      SkBudgeted budgeted) {
    SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1);
    if (this->abandoned()) {
        return nullptr;
    }
    sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                     info.dimensions(),
                                                                     renderable,
                                                                     sampleCount,
                                                                     mipmapped,
                                                                     fit,
                                                                     budgeted,
                                                                     isProtected);
    if (!proxy) {
        return nullptr;
    }

    GrSwizzle swizzle;
    if (info.colorType() != GrColorType::kUnknown &&
        !this->caps()->isFormatCompressed(format)) {
        swizzle = this->caps()->getReadSwizzle(format, info.colorType());
    }

    GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
    return this->makeSC(std::move(view), info.colorInfo());
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(GrImageInfo info,
                                                                           SkBackingFit fit,
                                                                           int sampleCount,
                                                                           GrMipmapped mipmapped,
                                                                           GrProtected isProtected,
                                                                           GrSurfaceOrigin origin,
                                                                           SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                       info.colorType(),
                                                       info.refColorSpace(),
                                                       fit,
                                                       info.dimensions(),
                                                       SkSurfaceProps(),
                                                       sampleCount,
                                                       mipmapped,
                                                       isProtected,
                                                       origin,
                                                       budgeted);
        }
        GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(),
                                                                       GrRenderable::kYes);
        sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                         info.dimensions(),
                                                                         GrRenderable::kYes,
                                                                         sampleCount,
                                                                         mipmapped,
                                                                         fit,
                                                                         budgeted,
                                                                         isProtected);
        if (!proxy) {
            return nullptr;
        }
        GrSwizzle readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
        GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());

        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
        std::unique_ptr<skgpu::SurfaceFillContext> sfc;
        sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                              std::move(readView),
                                                              std::move(writeView),
                                                              info.colorInfo());
        sfc->discard();
        return sfc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
        SkAlphaType alphaType,
        sk_sp<SkColorSpace> colorSpace,
        SkISize dimensions,
        SkBackingFit fit,
        const GrBackendFormat& format,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        GrSwizzle readSwizzle,
        GrSwizzle writeSwizzle,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->context()->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        SkASSERT(!dimensions.isEmpty());
        SkASSERT(sampleCount >= 1);
        SkASSERT(format.isValid() && format.backend() == fContext->backend());
        if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                       std::move(colorSpace),
                                                       fit,
                                                       dimensions,
                                                       format,
                                                       sampleCount,
                                                       mipmapped,
                                                       isProtected,
                                                       readSwizzle,
                                                       writeSwizzle,
                                                       origin,
                                                       budgeted,
                                                       SkSurfaceProps());
        }

        sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                         dimensions,
                                                                         GrRenderable::kYes,
                                                                         sampleCount,
                                                                         mipmapped,
                                                                         fit,
                                                                         budgeted,
                                                                         isProtected);
        if (!proxy) {
            return nullptr;
        }
        GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions);
        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
        std::unique_ptr<skgpu::SurfaceFillContext> sfc;
        sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                              std::move(readView),
                                                              std::move(writeView),
                                                              info.colorInfo());
        sfc->discard();
        return sfc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCWithFallback(
        GrImageInfo info,
        SkBackingFit fit,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::MakeWithFallback(this->context(),
                                                                   info.colorType(),
                                                                   info.refColorSpace(),
                                                                   fit,
                                                                   info.dimensions(),
                                                                   SkSurfaceProps(),
                                                                   sampleCount,
                                                                   mipmapped,
                                                                   isProtected,
                                                                   origin,
                                                                   budgeted);
        }
        const GrCaps* caps = this->caps();

        auto [ct, _] = caps->getFallbackColorTypeAndFormat(info.colorType(), sampleCount);
        if (ct == GrColorType::kUnknown) {
            return nullptr;
        }
        info = info.makeColorType(ct);
        return this->makeSFC(info,
                             fit,
                             sampleCount,
                             mipmapped,
                             isProtected,
                             origin,
                             budgeted);
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCFromBackendTexture(
        GrColorInfo info,
        const GrBackendTexture& tex,
        int sampleCount,
        GrSurfaceOrigin origin,
        sk_sp<GrRefCntedCallback> releaseHelper) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        SkASSERT(sampleCount > 0);

        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::MakeFromBackendTexture(this->context(),
                                                                         info.colorType(),
                                                                         info.refColorSpace(),
                                                                         tex,
                                                                         sampleCount,
                                                                         origin,
                                                                         SkSurfaceProps(),
                                                                         std::move(releaseHelper));
        }
        const GrBackendFormat& format = tex.getBackendFormat();
        GrSwizzle readSwizzle, writeSwizzle;
        if (info.colorType() != GrColorType::kUnknown) {
            if (!this->caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) {
                return nullptr;
            }
            readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
            writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());
        }

        sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
                tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
                std::move(releaseHelper)));
        if (!proxy) {
            return nullptr;
        }

        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);

        return std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                               std::move(readView),
                                                               std::move(writeView),
                                                               std::move(info));
#endif
    }

    return nullptr;
}
<commit_msg>Disallow SFCs w/ GrColorType::kUnknown in makeSFCFromBackendTexture<commit_after>/*
 * Copyright 2020 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/GrRecordingContextPriv.h"

#include "src/gpu/GrCaps.h"
#include "src/gpu/GrDrawingManager.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRenderTargetProxy.h"
#include "src/gpu/GrSurfaceProxyView.h"

#if SK_GPU_V1
#include "src/gpu/v1/Device_v1.h"
#include "src/gpu/v1/SurfaceDrawContext_v1.h"
#include "src/gpu/v1/SurfaceFillContext_v1.h"
#endif
#if SK_GPU_V2
#include "src/gpu/v2/Device_v2.h"
#include "src/gpu/v2/SurfaceDrawContext_v2.h"
#include "src/gpu/v2/SurfaceFillContext_v2.h"
#endif

void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
    this->context()->addOnFlushCallbackObject(onFlushCBObject);
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(GrColorType colorType,
                                                              sk_sp<GrSurfaceProxy> proxy,
                                                              sk_sp<SkColorSpace> colorSpace,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return skgpu::v2::Device::Make(this->context(), colorType, std::move(proxy),
                                       std::move(colorSpace), origin, props, init);
#else
        return nullptr;
#endif // GR_TEST_UTILS
    } else
#endif
    {
#if SK_GPU_V1
        return skgpu::v1::Device::Make(this->context(), colorType, std::move(proxy),
                                       std::move(colorSpace), origin, props, init);
#else
        return nullptr;
#endif
    }
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(SkBudgeted budgeted,
                                                              const SkImageInfo& ii,
                                                              SkBackingFit fit,
                                                              int sampleCount,
                                                              GrMipmapped mipmapped,
                                                              GrProtected isProtected,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return skgpu::v2::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
                                       mipmapped, isProtected, origin, props, init);
#else
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        return skgpu::v1::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
                                       mipmapped, isProtected, origin, props, init);
#else
        return nullptr;
#endif
    }
}

void GrRecordingContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
    this->context()->drawingManager()->moveRenderTasksToDDL(ddl);
}

GrSDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const {
    return GrSDFTControl{
            this->caps()->shaderCaps()->supportsDistanceFieldText(),
            useSDFTForSmallText,
            this->options().fMinDistanceFieldFontSize,
            this->options().fGlyphsAsPathsFontSize};
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(GrSurfaceProxyView readView,
                                                                      const GrColorInfo& info) {
#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        // It is probably not necessary to check if the context is abandoned here since uses of the
        // SurfaceContext which need the context will mostly likely fail later on w/o an issue.
        // However having this here adds some reassurance in case there is a path that doesn't
        // handle an abandoned context correctly. It also lets us early out of some extra work.
        if (this->context()->abandoned()) {
            return nullptr;
        }
        GrSurfaceProxy* proxy = readView.proxy();
        SkASSERT(proxy && proxy->asTextureProxy());

        std::unique_ptr<skgpu::SurfaceContext> sc;
        if (proxy->asRenderTargetProxy()) {
            // Will we ever want a swizzle that is not the default write swizzle for the format and
            // colorType here? If so we will need to manually pass that in.
            GrSwizzle writeSwizzle;
            if (info.colorType() != GrColorType::kUnknown) {
                writeSwizzle = this->caps()->getWriteSwizzle(proxy->backendFormat(),
                                                             info.colorType());
            }
            GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
            if (info.alphaType() == kPremul_SkAlphaType ||
                info.alphaType() == kOpaque_SkAlphaType) {
                sc = std::make_unique<skgpu::v1::SurfaceDrawContext>(this->context(),
                                                                     std::move(readView),
                                                                     std::move(writeView),
                                                                     info.colorType(),
                                                                     info.refColorSpace(),
                                                                     SkSurfaceProps());
            } else {
                sc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                                     std::move(readView),
                                                                     std::move(writeView),
                                                                     info);
            }
        } else {
            sc = std::make_unique<skgpu::SurfaceContext>(this->context(),
                                                         std::move(readView),
                                                         info);
        }
        SkDEBUGCODE(sc->validate();)
        return sc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(const GrImageInfo& info,
                                                                      const GrBackendFormat& format,
                                                                      SkBackingFit fit,
                                                                      GrSurfaceOrigin origin,
                                                                      GrRenderable renderable,
                                                                      int sampleCount,
                                                                      GrMipmapped mipmapped,
                                                                      GrProtected isProtected,
                                                                      SkBudgeted budgeted) {
    SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1);
    if (this->abandoned()) {
        return nullptr;
    }
    sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                     info.dimensions(),
                                                                     renderable,
                                                                     sampleCount,
                                                                     mipmapped,
                                                                     fit,
                                                                     budgeted,
                                                                     isProtected);
    if (!proxy) {
        return nullptr;
    }

    GrSwizzle swizzle;
    if (info.colorType() != GrColorType::kUnknown &&
        !this->caps()->isFormatCompressed(format)) {
        swizzle = this->caps()->getReadSwizzle(format, info.colorType());
    }

    GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
    return this->makeSC(std::move(view), info.colorInfo());
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(GrImageInfo info,
                                                                           SkBackingFit fit,
                                                                           int sampleCount,
                                                                           GrMipmapped mipmapped,
                                                                           GrProtected isProtected,
                                                                           GrSurfaceOrigin origin,
                                                                           SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                       info.colorType(),
                                                       info.refColorSpace(),
                                                       fit,
                                                       info.dimensions(),
                                                       SkSurfaceProps(),
                                                       sampleCount,
                                                       mipmapped,
                                                       isProtected,
                                                       origin,
                                                       budgeted);
        }
        GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(),
                                                                       GrRenderable::kYes);
        sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                         info.dimensions(),
                                                                         GrRenderable::kYes,
                                                                         sampleCount,
                                                                         mipmapped,
                                                                         fit,
                                                                         budgeted,
                                                                         isProtected);
        if (!proxy) {
            return nullptr;
        }
        GrSwizzle readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
        GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());

        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
        std::unique_ptr<skgpu::SurfaceFillContext> sfc;
        sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                              std::move(readView),
                                                              std::move(writeView),
                                                              info.colorInfo());
        sfc->discard();
        return sfc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
        SkAlphaType alphaType,
        sk_sp<SkColorSpace> colorSpace,
        SkISize dimensions,
        SkBackingFit fit,
        const GrBackendFormat& format,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        GrSwizzle readSwizzle,
        GrSwizzle writeSwizzle,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->context()->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        SkASSERT(!dimensions.isEmpty());
        SkASSERT(sampleCount >= 1);
        SkASSERT(format.isValid() && format.backend() == fContext->backend());
        if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                       std::move(colorSpace),
                                                       fit,
                                                       dimensions,
                                                       format,
                                                       sampleCount,
                                                       mipmapped,
                                                       isProtected,
                                                       readSwizzle,
                                                       writeSwizzle,
                                                       origin,
                                                       budgeted,
                                                       SkSurfaceProps());
        }

        sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                         dimensions,
                                                                         GrRenderable::kYes,
                                                                         sampleCount,
                                                                         mipmapped,
                                                                         fit,
                                                                         budgeted,
                                                                         isProtected);
        if (!proxy) {
            return nullptr;
        }
        GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions);
        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
        std::unique_ptr<skgpu::SurfaceFillContext> sfc;
        sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                              std::move(readView),
                                                              std::move(writeView),
                                                              info.colorInfo());
        sfc->discard();
        return sfc;
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCWithFallback(
        GrImageInfo info,
        SkBackingFit fit,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::MakeWithFallback(this->context(),
                                                                   info.colorType(),
                                                                   info.refColorSpace(),
                                                                   fit,
                                                                   info.dimensions(),
                                                                   SkSurfaceProps(),
                                                                   sampleCount,
                                                                   mipmapped,
                                                                   isProtected,
                                                                   origin,
                                                                   budgeted);
        }
        const GrCaps* caps = this->caps();

        auto [ct, _] = caps->getFallbackColorTypeAndFormat(info.colorType(), sampleCount);
        if (ct == GrColorType::kUnknown) {
            return nullptr;
        }
        info = info.makeColorType(ct);
        return this->makeSFC(info,
                             fit,
                             sampleCount,
                             mipmapped,
                             isProtected,
                             origin,
                             budgeted);
#endif
    }

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCFromBackendTexture(
        GrColorInfo info,
        const GrBackendTexture& tex,
        int sampleCount,
        GrSurfaceOrigin origin,
        sk_sp<GrRefCntedCallback> releaseHelper) {

#if GR_TEST_UTILS
    if (this->options().fUseSkGpuV2 == GrContextOptions::Enable::kYes) {
#if SK_GPU_V2
        return nullptr;
#endif
    } else
#endif // GR_TEST_UTILS
    {
#if SK_GPU_V1
        SkASSERT(sampleCount > 0);

        if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
            return skgpu::v1::SurfaceDrawContext::MakeFromBackendTexture(this->context(),
                                                                         info.colorType(),
                                                                         info.refColorSpace(),
                                                                         tex,
                                                                         sampleCount,
                                                                         origin,
                                                                         SkSurfaceProps(),
                                                                         std::move(releaseHelper));
        }

        if (info.colorType() == GrColorType::kUnknown) {
            return nullptr;
        }

        const GrBackendFormat& format = tex.getBackendFormat();
        if (!this->caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) {
            return nullptr;
        }
        GrSwizzle readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
        GrSwizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());

        sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
                tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
                std::move(releaseHelper)));
        if (!proxy) {
            return nullptr;
        }

        GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
        GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);

        return std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                               std::move(readView),
                                                               std::move(writeView),
                                                               std::move(info));
#endif
    }

    return nullptr;
}
<|endoftext|>


<commit_before>#include "HHRecoUtil/NaiveConeMatch.h"

// constructor
NaiveConeMatch::NaiveConeMatch () {
  SetPartnerConeR(3.0);
  SetMPole(120.);
  SetMWidth(20.);
  SetFirstHiggsCone(3.0);
}

NaiveConeMatch::NaiveConeMatch (Double_t partnerConeR) : NaiveConeMatch() {
  SetPartnerConeR(partnerConeR);
}

NaiveConeMatch::NaiveConeMatch (Double_t mPole,
                                Double_t mWidth) : NaiveConeMatch() {
  SetMPole(mPole);
  SetMWidth(mWidth);
}

NaiveConeMatch::NaiveConeMatch (Double_t partnerConeR,
                                Double_t mPole,
                                Double_t mWidth,
                                Double_t firstHiggsCone) {
  SetPartnerConeR(partnerConeR);
  SetMPole(mPole);
  SetMWidth(mWidth);
  SetFirstHiggsCone(firstHiggsCone);
}

// destructor
NaiveConeMatch::~NaiveConeMatch () {}

/* Apply a Naive Cone Matching algorithm to a vector of jet pointers and return the jets
   that passed the algorithm as a vector of jet pointers. In doing so also find the
   invariant mass of j1j2 and j3j4 pre and post mass window cut.*/
std::vector<const xAOD::Jet*> NaiveConeMatch::GetNCMJets (
  const std::vector<const xAOD::Jet*> &v) {
  std::vector<const xAOD::Jet*> searchjets(v);

  // sort the vector of jets by their pT from greatest to least
  std::sort(searchjets.begin(), searchjets.end(), jetpTCompare);

  m_mjjbuilderjets.clear();

  if (searchjets.size() > 3) {
    // store the highest pT jet
    m_conematchedjets.push_back(searchjets[0]);
    searchjets.erase(std::remove(searchjets.begin(), searchjets.end(),
                                 searchjets[0]), searchjets.end());

    if (m_conematchedjets.size() > 0) {
      // find the second highest pT

      for (const auto &jet_itr : searchjets) {
        if ((m_conematchedjets[0]->p4().DeltaR(jet_itr->p4()) < m_partnerConeR)
            && (jet_itr->pt() < m_conematchedjets[0]->pt())) {
          m_conematchedjets.push_back(jet_itr);
          searchjets.erase(std::remove(searchjets.begin(), searchjets.end(),
                                       jet_itr), searchjets.end());

          if (m_conematchedjets.size() > 1) break;
        }
      }

      if (m_conematchedjets.size() > 1) {
        TLorentzVector higgsDirection { m_conematchedjets[0]->p4() +
                                        m_conematchedjets[1]->p4() };
        SetMj1j2Cone(higgsDirection.M() * MeVtoGeV);

        if ((higgsDirection.M() * MeVtoGeV >= (m_mPole - m_mWidth)) &&
            (higgsDirection.M() * MeVtoGeV <= (m_mPole + m_mWidth))) {
          SetMj1j2Cut(GetMj1j2Cone());
          higgsDirection.SetVect(-1. * higgsDirection.Vect());

          for (const auto &jet_itr : searchjets) {
            if (higgsDirection.DeltaR(
                  jet_itr->p4()) < m_firstHiggsCone) m_conematchedjets.push_back(jet_itr);
          }

          if (m_conematchedjets.size() > 3) {
            TLorentzVector h34Cone { m_conematchedjets[2]->p4() +
                                     m_conematchedjets[3]->p4() };
            SetMj3j4Cone(h34Cone.M() * MeVtoGeV);
            std::copy(m_conematchedjets.begin(), m_conematchedjets.begin() + 4,
                      std::back_inserter(m_mjjbuilderjets));

            if ((m_m_j3j4_cone >= (m_mPole - m_mWidth))
                && (m_m_j3j4_cone <= (m_mPole + m_mWidth))) SetMj3j4Cut(GetMj3j4Cone());
          }
        }
      } // m_conematchedjets > 1
    }   // m_conematchedjets > 0
  }     // searchjets > 3

  return m_conematchedjets;
} // GetNCMJets

/* Apply a Naive Cone Matching algorithm if needed and then use the MCTruthClassifier
   class to classify the selected jets, placing those classified as BJets in a vector of
   jet pointers and those classified as BJets with a Higgs as an origin into another
   vector of jet pointers.*/
void NaiveConeMatch::ClassifyNCMJets (
  const std::vector<const xAOD::Jet*> &v, MCTruthClassifier *mcclasstool = nullptr) {
  std::vector<const xAOD::Jet*> conematchedjets;

  // if passed m_conematchedjets don't redo NCM
  if (&v == &m_conematchedjets) conematchedjets = v;
  else conematchedjets = GetNCMJets(v);

  if (mcclasstool != nullptr) {
    m_Bclassifiedjets.clear();
    m_Hclassifiedjets.clear();
    m_jheritage.clear();

    m_BclassifiedNumber = 0;
    m_HclassifiedNumber = 0;

    std::pair<MCTruthPartClassifier::ParticleType,
              MCTruthPartClassifier::ParticleOrigin> classifyResult;

    for (const auto &jet_itr : conematchedjets) {
      classifyResult = mcclasstool->particleTruthClassifier(jet_itr, true);

      if (classifyResult.first == MCTruthPartClassifier::BJet) {
        ++m_BclassifiedNumber;
        m_Bclassifiedjets.push_back(jet_itr);

        if (classifyResult.second == MCTruthPartClassifier::Higgs) {
          ++m_HclassifiedNumber;
          m_Hclassifiedjets.push_back(jet_itr);

          if (mcclasstool->getMotherPDG() == 25) m_jheritage.emplace_back(
              jet_itr, mcclasstool->getMotherBarcode());
        }
      }
    }
  }
} // ClassifyNCMJets

/* Return the number of jets that were used to make m_j1j2 and m_j3j4 that also were
   classified by MCTruthClassifier as BJets with Higgs origin.*/
Int_t NaiveConeMatch::GetNumberBHClassBuilderJets (
  MCTruthClassifier *mcclasstool = nullptr) {
  Int_t BHclassifiedbuilderNumber { 0 };

  if (mcclasstool != nullptr) {
    std::pair<MCTruthPartClassifier::ParticleType,
              MCTruthPartClassifier::ParticleOrigin> classifyResult;

    if (m_mjjbuilderjets.size() > 0) {
      for (const auto &jet_itr : m_mjjbuilderjets) {
        classifyResult = mcclasstool->particleTruthClassifier(jet_itr, true);

        if ((classifyResult.first == MCTruthPartClassifier::BJet) &&
            (classifyResult.second ==
             MCTruthPartClassifier::Higgs)) ++BHclassifiedbuilderNumber;
      }
    }
  }

  return BHclassifiedbuilderNumber;
} // GetNumberBHClassBuilderJets

/* Return the number of jets that were classified as BJets with Higgs origin that were
   matched with a jet that comes from the same parent Higgs (and so has formed a
   correct pair).*/
Int_t NaiveConeMatch::GetNumberPairedJets () {
  Int_t jetswithpairsNumber { 0 }; // number of jets with pair, not number of pairs

  if (m_jheritage.size() > 0) {
    for (UInt_t i = 0; i < m_jheritage.size(); ++i) {
      for (UInt_t j = 0; j < m_jheritage.size(); ++j) {
        if ((m_jheritage[i] != m_jheritage[j]) &&
            (m_jheritage[i].second == m_jheritage[j].second)) ++jetswithpairsNumber;
      }
    }
  }

  return jetswithpairsNumber;
} // GetNumberPairedJets
<commit_msg>Fix double decleration of defualt arguments in class error<commit_after>#include "HHRecoUtil/NaiveConeMatch.h"

// constructor
NaiveConeMatch::NaiveConeMatch () {
  SetPartnerConeR(3.0);
  SetMPole(120.);
  SetMWidth(20.);
  SetFirstHiggsCone(3.0);
}

NaiveConeMatch::NaiveConeMatch (Double_t partnerConeR) : NaiveConeMatch() {
  SetPartnerConeR(partnerConeR);
}

NaiveConeMatch::NaiveConeMatch (Double_t mPole,
                                Double_t mWidth) : NaiveConeMatch() {
  SetMPole(mPole);
  SetMWidth(mWidth);
}

NaiveConeMatch::NaiveConeMatch (Double_t partnerConeR,
                                Double_t mPole,
                                Double_t mWidth,
                                Double_t firstHiggsCone) {
  SetPartnerConeR(partnerConeR);
  SetMPole(mPole);
  SetMWidth(mWidth);
  SetFirstHiggsCone(firstHiggsCone);
}

// destructor
NaiveConeMatch::~NaiveConeMatch () {}

/* Apply a Naive Cone Matching algorithm to a vector of jet pointers and return the jets
   that passed the algorithm as a vector of jet pointers. In doing so also find the
   invariant mass of j1j2 and j3j4 pre and post mass window cut.*/
std::vector<const xAOD::Jet*> NaiveConeMatch::GetNCMJets (
  const std::vector<const xAOD::Jet*> &v) {
  std::vector<const xAOD::Jet*> searchjets(v);

  // sort the vector of jets by their pT from greatest to least
  std::sort(searchjets.begin(), searchjets.end(), jetpTCompare);

  m_mjjbuilderjets.clear();

  if (searchjets.size() > 3) {
    // store the highest pT jet
    m_conematchedjets.push_back(searchjets[0]);
    searchjets.erase(std::remove(searchjets.begin(), searchjets.end(),
                                 searchjets[0]), searchjets.end());

    if (m_conematchedjets.size() > 0) {
      // find the second highest pT

      for (const auto &jet_itr : searchjets) {
        if ((m_conematchedjets[0]->p4().DeltaR(jet_itr->p4()) < m_partnerConeR)
            && (jet_itr->pt() < m_conematchedjets[0]->pt())) {
          m_conematchedjets.push_back(jet_itr);
          searchjets.erase(std::remove(searchjets.begin(), searchjets.end(),
                                       jet_itr), searchjets.end());

          if (m_conematchedjets.size() > 1) break;
        }
      }

      if (m_conematchedjets.size() > 1) {
        TLorentzVector higgsDirection { m_conematchedjets[0]->p4() +
                                        m_conematchedjets[1]->p4() };
        SetMj1j2Cone(higgsDirection.M() * MeVtoGeV);

        if ((higgsDirection.M() * MeVtoGeV >= (m_mPole - m_mWidth)) &&
            (higgsDirection.M() * MeVtoGeV <= (m_mPole + m_mWidth))) {
          SetMj1j2Cut(GetMj1j2Cone());
          higgsDirection.SetVect(-1. * higgsDirection.Vect());

          for (const auto &jet_itr : searchjets) {
            if (higgsDirection.DeltaR(
                  jet_itr->p4()) < m_firstHiggsCone) m_conematchedjets.push_back(jet_itr);
          }

          if (m_conematchedjets.size() > 3) {
            TLorentzVector h34Cone { m_conematchedjets[2]->p4() +
                                     m_conematchedjets[3]->p4() };
            SetMj3j4Cone(h34Cone.M() * MeVtoGeV);
            std::copy(m_conematchedjets.begin(), m_conematchedjets.begin() + 4,
                      std::back_inserter(m_mjjbuilderjets));

            if ((m_m_j3j4_cone >= (m_mPole - m_mWidth))
                && (m_m_j3j4_cone <= (m_mPole + m_mWidth))) SetMj3j4Cut(GetMj3j4Cone());
          }
        }
      } // m_conematchedjets > 1
    }   // m_conematchedjets > 0
  }     // searchjets > 3

  return m_conematchedjets;
} // GetNCMJets

/* Apply a Naive Cone Matching algorithm if needed and then use the MCTruthClassifier
   class to classify the selected jets, placing those classified as BJets in a vector of
   jet pointers and those classified as BJets with a Higgs as an origin into another
   vector of jet pointers.*/
void NaiveConeMatch::ClassifyNCMJets (const std::vector<const xAOD::Jet*> &v,
                                      MCTruthClassifier                   *mcclasstool) {
  std::vector<const xAOD::Jet*> conematchedjets;

  // if passed m_conematchedjets don't redo NCM
  if (&v == &m_conematchedjets) conematchedjets = v;
  else conematchedjets = GetNCMJets(v);

  if (mcclasstool != nullptr) {
    m_Bclassifiedjets.clear();
    m_Hclassifiedjets.clear();
    m_jheritage.clear();

    m_BclassifiedNumber = 0;
    m_HclassifiedNumber = 0;

    std::pair<MCTruthPartClassifier::ParticleType,
              MCTruthPartClassifier::ParticleOrigin> classifyResult;

    for (const auto &jet_itr : conematchedjets) {
      classifyResult = mcclasstool->particleTruthClassifier(jet_itr, true);

      if (classifyResult.first == MCTruthPartClassifier::BJet) {
        ++m_BclassifiedNumber;
        m_Bclassifiedjets.push_back(jet_itr);

        if (classifyResult.second == MCTruthPartClassifier::Higgs) {
          ++m_HclassifiedNumber;
          m_Hclassifiedjets.push_back(jet_itr);

          if (mcclasstool->getMotherPDG() == 25) m_jheritage.emplace_back(
              jet_itr, mcclasstool->getMotherBarcode());
        }
      }
    }
  }
} // ClassifyNCMJets

/* Return the number of jets that were used to make m_j1j2 and m_j3j4 that also were
   classified by MCTruthClassifier as BJets with Higgs origin.*/
Int_t NaiveConeMatch::GetNumberBHClassBuilderJets (MCTruthClassifier *mcclasstool) {
  Int_t BHclassifiedbuilderNumber { 0 };

  if (mcclasstool != nullptr) {
    std::pair<MCTruthPartClassifier::ParticleType,
              MCTruthPartClassifier::ParticleOrigin> classifyResult;

    if (m_mjjbuilderjets.size() > 0) {
      for (const auto &jet_itr : m_mjjbuilderjets) {
        classifyResult = mcclasstool->particleTruthClassifier(jet_itr, true);

        if ((classifyResult.first == MCTruthPartClassifier::BJet) &&
            (classifyResult.second ==
             MCTruthPartClassifier::Higgs)) ++BHclassifiedbuilderNumber;
      }
    }
  }

  return BHclassifiedbuilderNumber;
} // GetNumberBHClassBuilderJets

/* Return the number of jets that were classified as BJets with Higgs origin that were
   matched with a jet that comes from the same parent Higgs (and so has formed a
   correct pair).*/
Int_t NaiveConeMatch::GetNumberPairedJets () {
  Int_t jetswithpairsNumber { 0 }; // number of jets with pair, not number of pairs

  if (m_jheritage.size() > 0) {
    for (UInt_t i = 0; i < m_jheritage.size(); ++i) {
      for (UInt_t j = 0; j < m_jheritage.size(); ++j) {
        if ((m_jheritage[i] != m_jheritage[j]) &&
            (m_jheritage[i].second == m_jheritage[j].second)) ++jetswithpairsNumber;
      }
    }
  }

  return jetswithpairsNumber;
} // GetNumberPairedJets
<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.getCurrentNb() << "/{"
         << _progressStatus.getExpectedNb() << ","
         << _progressStatus.getActualNb() << "}";
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {

      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";

      const ProgressStatus& lProgressStatus = itNbOfEventsMap->second;
      oStr << lProgressStatus;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    // Reset only the current number of events, not the expected one
    _progressStatus.setCurrentNb (DEFAULT_PROGRESS_STATUS);

    //
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const ProgressStatus lProgressStatus (1, lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lProgressStatus)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.setExpectedNb (_progressStatus.getExpectedNb()
                                   + iExpectedTotalNbOfEvents);

    _progressStatus.setActualNb (_progressStatus.getActualNb()
                                   + iExpectedTotalNbOfEvents);
  }

  // //////////////////////////////////////////////////////////////////////
  ProgressStatus EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const ProgressStatus& oProgressStatus = itNbOfEventsMap->second;
      return oProgressStatus;
    }

    return ProgressStatus();
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const ProgressStatus& lProgressStatus = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lProgressStatus);

    // Update the (current number part of the) overall progress
    // status, to account for the event that is being popped out of
    // the event queue
    ++_progressStatus;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.

The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      ProgressStatus& lProgressStatus = itNbOfEventsMap->second;
      ++lProgressStatus;
    }

    return insertionSucceeded;
  }

}
<commit_msg>[Dev] Added the ProgressStatus structure to track the progress status.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.getCurrentNb() << "/{"
         << _progressStatus.getExpectedNb() << ","
         << _progressStatus.getActualNb() << "}";
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {

      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";

      const ProgressStatus& lProgressStatus = itNbOfEventsMap->second;
      oStr << lProgressStatus;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    // Reset only the current number of events, not the expected one
    _progressStatus.setCurrentNb (DEFAULT_PROGRESS_STATUS);

    //
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const ProgressStatus lProgressStatus (1, lExpectedTotalNbOfEventsInt,
                                          lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lProgressStatus)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.setExpectedNb (_progressStatus.getExpectedNb()
                                   + iExpectedTotalNbOfEvents);

    _progressStatus.setActualNb (_progressStatus.getActualNb()
                                   + iExpectedTotalNbOfEvents);
  }

  // //////////////////////////////////////////////////////////////////////
  ProgressStatus EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const ProgressStatus& oProgressStatus = itNbOfEventsMap->second;
      return oProgressStatus;
    }

    return ProgressStatus();
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const ProgressStatus& lProgressStatus = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lProgressStatus);

    // Update the (current number part of the) overall progress
    // status, to account for the event that is being popped out of
    // the event queue
    ++_progressStatus;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.

The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      ProgressStatus& lProgressStatus = itNbOfEventsMap->second;
      ++lProgressStatus;
    }

    return insertionSucceeded;
  }

}
<|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.first << "/" << _progressStatus.second;
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {
      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
      oStr << lCurrentNbOfEvents << "/" << lExpectedTotalNbOfEvents;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const NbOfEventsPair_T lNbOfEventsPair (1, lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lNbOfEventsPair)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.second += iExpectedTotalNbOfEvents;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  initProgressDisplays (ProgressDisplayMap_T& ioProgressDisplayMap) {

    ProgressDisplayMap_T::iterator itProgressDisplayMap =
      ioProgressDisplayMap.begin();
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin();  itNbOfEventsMap != _nbOfEvents.end();
          ++itProgressDisplayMap, ++itNbOfEventsMap) {
      // Demand stream
      const DemandStreamKeyStr_T& lDemandStreamKeyStr = itNbOfEventsMap->first;

      // Expected total number of events for the current demand stream
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;

      // Initialise the (Boost) progress display object for the
      // current demand stream
      ProgressDisplayPtr lProgressDisplayPtr =
        boost::make_shared<boost::progress_display> (lExpectedTotalNbOfEvents);

      // Insert the (Boost) progress display object into the dedicated map
      const bool hasInsertBeenSuccessful =
        ioProgressDisplayMap.insert (ProgressDisplayMap_T::
                                     value_type (lDemandStreamKeyStr,
                                                 lProgressDisplayPtr)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No Boost progress_display can be inserted "
                          << "for the following DemandStream: "
                          << lDemandStreamKeyStr
                          << ". EventQueue: " << toString());
        throw EventException ("No Boost progress_display can be inserted for "
                              "the following DemandStream: "
                              + lDemandStreamKeyStr + ". EventQueue: "
                              + toString());
      }
    }
  }

  // //////////////////////////////////////////////////////////////////////
  NbOfEventsPair_T EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const NbOfEventsPair_T& oNbOfEventsPair = itNbOfEventsMap->second;
      return oNbOfEventsPair;
    }

    return NbOfEventsPair_T (stdair::DEFAULT_PROGRESS_STATUS,
                             stdair::DEFAULT_PROGRESS_STATUS);
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const NbOfEventsPair_T& lNbOfEventsPair = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lNbOfEventsPair);

    // Update the overall progress status, to account for the event
    // that is being popped out of the event queue
    ++_progressStatus.first;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.
       <br>The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      ++lCurrentNbOfEvents;
    }

    return insertionSucceeded;
  }

}
<commit_msg>[Dev] Improved a little bit the debugging output of the EventQueue object.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
// Boost
#include <boost/make_shared.hpp>
// StdAir
#include <stdair/stdair_exceptions.hpp>
#include <stdair/basic/BasConst_Event.hpp>
#include <stdair/bom/EventStruct.hpp>
#include <stdair/bom/EventQueue.hpp>
#include <stdair/service/Logger.hpp>

namespace stdair {

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue ()
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const Key_T& iKey)
    : _key (iKey), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::EventQueue (const EventQueue& iEventQueue)
    : _key (DEFAULT_EVENT_QUEUE_ID), _parent (NULL),
      _progressStatus (stdair::DEFAULT_PROGRESS_STATUS,
                       stdair::DEFAULT_PROGRESS_STATUS) {
    assert (false);
  }

  // //////////////////////////////////////////////////////////////////////
  EventQueue::~EventQueue () {
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::toString() const {
    std::ostringstream oStr;
    oStr << "(" << _eventList.size() << ") "
         << _progressStatus.first << "/" << _progressStatus.second;
    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  std::string EventQueue::display() const {
    std::ostringstream oStr;

    oStr << toString();

    /*
     * \note The following can be very consuming (in time, CPU and
     * memory) when there are a lot of demand streams (e.g., several
     * hundreds of thousands). Uncomment it only for debug purposes.
    */
    unsigned int demandStreamIdx = 1;
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin(); itNbOfEventsMap != _nbOfEvents.end();
         ++itNbOfEventsMap, ++demandStreamIdx) {
      const DemandStreamKeyStr_T& lDemandStreyKeyStr = itNbOfEventsMap->first;
      oStr << ", [" << demandStreamIdx << "][" << lDemandStreyKeyStr << "] ";
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      const stdair::Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;
      oStr << lCurrentNbOfEvents << "/" << lExpectedTotalNbOfEvents;
    }

    return oStr.str();
  }

  // //////////////////////////////////////////////////////////////////////
  Count_T EventQueue::getQueueSize() const {
    return _eventList.size();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueEmpty() const {
    return _eventList.empty();
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::isQueueDone() const {
    const bool isQueueEmpty = _eventList.empty();
    return isQueueEmpty;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::reset() {
    // Reset only the current number of events, not the expected one
    _progressStatus.first = stdair::DEFAULT_PROGRESS_STATUS;

    //
    _holderMap.clear();
    _eventList.clear();
    _nbOfEvents.clear();
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  addStatus (const DemandStreamKeyStr_T& iDemandStreamKeyStr,
             const NbOfRequests_T& iExpectedTotalNbOfEvents) {

    /**
     * \note After the initialisation of the event queue (e.g., by a
     * call to the TRADEMGEN_Service::generateFirstRequests() method),
     * there are, by construction, exactly as many events as distinct
     * demand streams. Indeed, the event queue contains a single event
     * structure for every demand stream.
     */

    // Initialise the progress status object for the current demand stream
    const Count_T lExpectedTotalNbOfEventsInt =
      std::floor (iExpectedTotalNbOfEvents);
    const NbOfEventsPair_T lNbOfEventsPair (1, lExpectedTotalNbOfEventsInt);

    // Insert the (Boost) progress display object into the dedicated map
    const bool hasInsertBeenSuccessful =
      _nbOfEvents.insert (NbOfEventsByDemandStreamMap_T::
                          value_type (iDemandStreamKeyStr,
                                      lNbOfEventsPair)).second;

    if (hasInsertBeenSuccessful == false) {
      STDAIR_LOG_ERROR ("No progress_status can be inserted "
                        << "for the following DemandStream: "
                        << iDemandStreamKeyStr
                        << ". EventQueue: " << toString());
      throw EventException ("No progress_status can be inserted for the "
                            "following DemandStream: " + iDemandStreamKeyStr
                            + ". EventQueue: " + toString());
    }

    // Update the overall progress status
    _progressStatus.second += iExpectedTotalNbOfEvents;
  }

  // //////////////////////////////////////////////////////////////////////
  void EventQueue::
  initProgressDisplays (ProgressDisplayMap_T& ioProgressDisplayMap) {

    ProgressDisplayMap_T::iterator itProgressDisplayMap =
      ioProgressDisplayMap.begin();
    for (NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
           _nbOfEvents.begin();  itNbOfEventsMap != _nbOfEvents.end();
          ++itProgressDisplayMap, ++itNbOfEventsMap) {
      // Demand stream
      const DemandStreamKeyStr_T& lDemandStreamKeyStr = itNbOfEventsMap->first;

      // Expected total number of events for the current demand stream
      const NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      const Count_T& lExpectedTotalNbOfEvents = lNbOfEventsPair.second;

      // Initialise the (Boost) progress display object for the
      // current demand stream
      ProgressDisplayPtr lProgressDisplayPtr =
        boost::make_shared<boost::progress_display> (lExpectedTotalNbOfEvents);

      // Insert the (Boost) progress display object into the dedicated map
      const bool hasInsertBeenSuccessful =
        ioProgressDisplayMap.insert (ProgressDisplayMap_T::
                                     value_type (lDemandStreamKeyStr,
                                                 lProgressDisplayPtr)).second;

      if (hasInsertBeenSuccessful == false) {
        STDAIR_LOG_ERROR ("No Boost progress_display can be inserted "
                          << "for the following DemandStream: "
                          << lDemandStreamKeyStr
                          << ". EventQueue: " << toString());
        throw EventException ("No Boost progress_display can be inserted for "
                              "the following DemandStream: "
                              + lDemandStreamKeyStr + ". EventQueue: "
                              + toString());
      }
    }
  }

  // //////////////////////////////////////////////////////////////////////
  NbOfEventsPair_T EventQueue::
  getStatus (const DemandStreamKeyStr_T& iDemandStreamKey) const {

    NbOfEventsByDemandStreamMap_T::const_iterator itNbOfEventsMap =
      _nbOfEvents.find (iDemandStreamKey);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      const NbOfEventsPair_T& oNbOfEventsPair = itNbOfEventsMap->second;
      return oNbOfEventsPair;
    }

    return NbOfEventsPair_T (stdair::DEFAULT_PROGRESS_STATUS,
                             stdair::DEFAULT_PROGRESS_STATUS);
  }

  // //////////////////////////////////////////////////////////////////////
  EventStruct EventQueue::popEvent() {
    assert (_eventList.empty() == false);

    // Get an iterator on the first event (sorted by date-time stamps)
    EventList_T::iterator itEvent = _eventList.begin();

    // Extract the corresponding Event structure
    EventStruct lEventStruct = itEvent->second;

    // Extract the key of the demand stream
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      lEventStruct.getDemandStreamKey();

    // Retrieve the progress status specific to that demand stream
    const NbOfEventsPair_T& lNbOfEventsPair = getStatus (lDemandStreamKeyStr);

    // Update the progress status of the event structure, specific to
    // the demand stream
    lEventStruct.setSpecificStatus (lNbOfEventsPair);

    // Update the overall progress status, to account for the event
    // that is being popped out of the event queue
    ++_progressStatus.first;

    // Update the overall progress status of the event structure
    lEventStruct.setOverallStatus (_progressStatus);

    // Remove the event, which has just been retrieved
    _eventList.erase (itEvent);

    //
    return lEventStruct;
  }

  // //////////////////////////////////////////////////////////////////////
  bool EventQueue::addEvent (EventStruct& ioEventStruct) {
    bool insertionSucceeded =
      _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                             ioEventStruct)).second;

    /**
       If the insertion has not been successful, try repeatedly until the
       insertion becomes successful.
       <br>The date-time is counted in milliseconds (1e-3 second). Hence,
       one thousand (1e3) of attempts correspond to 1 second.
    */
    const unsigned int idx = 0;
    while (insertionSucceeded == false && idx != 1e3) {
      // Retrieve the date-time stamp (expressed in milliseconds)
      LongDuration_T& lEventTimeStamp (ioEventStruct._eventTimeStamp);
      ++lEventTimeStamp;

      // Retry to insert into the event queue
      insertionSucceeded =
        _eventList.insert (EventListElement_T (ioEventStruct._eventTimeStamp,
                                               ioEventStruct)).second;
    }

    // Extract the corresponding demand stream key
    const DemandStreamKeyStr_T& lDemandStreamKeyStr =
      ioEventStruct.getDemandStreamKey();

    // Update the progress status for the corresponding demand stream
    NbOfEventsByDemandStreamMap_T::iterator itNbOfEventsMap =
      _nbOfEvents.find (lDemandStreamKeyStr);
    if (itNbOfEventsMap != _nbOfEvents.end()) {
      NbOfEventsPair_T& lNbOfEventsPair = itNbOfEventsMap->second;
      stdair::Count_T& lCurrentNbOfEvents = lNbOfEventsPair.first;
      ++lCurrentNbOfEvents;
    }

    return insertionSucceeded;
  }

}
<|endoftext|>


<commit_before>//
// Created by Miguel Rentes on 19/01/2017.
//

#include "STL.h"

int main(void) {
    unsigned int number_elements;
    unsigned int number_queries;
    unsigned int element;
    vector <unsigned int> elements;
    vector<unsigned int>::iterator it;
    cin >> number_elements;
    for (int i = 0; i < number_elements; i++) {
        if (cin >> element) {
            elements.push_back(element);
        }
    }
    cin >> number_queries;
    for (int i = 0; i < number_queries; i++) {
        cin >> element;
        it = find(elements.begin(), elements.end(), element);
        if (it != elements.end()) {
            cout << "Yes " << it - elements.begin() + 1 << endl;
        }
        else {
            it = lower_bound(elements.begin(), elements.end(), element);
            cout << "No " << it - elements.begin() + 1 << endl;
        }
    }

    return EXIT_SUCCESS;
}<commit_msg>Refactors solution for the Lower Bound-STL challenge.<commit_after>//
// Created by Miguel Rentes on 19/01/2017.
//

#include "STL.h"

int main(void) {
    unsigned int number_elements;
    unsigned int number_queries;
    unsigned int element;
    vector <unsigned int> elements;
    vector<unsigned int>::iterator it;
    cin >> number_elements;
    for (int i = 0; i < number_elements; i++) {
        if (cin >> element) {
            elements.push_back(element);
        }
    }
    cin >> number_queries;
    for (int i = 0; i < number_queries; i++) {
        cin >> element;
        it = lower_bound(elements.begin(), elements.end(), element);
        if (elements.begin() != elements.end() && !(element<*elements.begin()) && element == *it) {
            cout << "Yes " << it - elements.begin() + 1 << endl;
        }
        else {
            cout << "No " << it - elements.begin() + 1 << endl;
        }
    }

    return EXIT_SUCCESS;
}<|endoftext|>


<commit_before>#include "corrcheck.h"

int create_database(const Options& opts)
{
    Directory dir;
    dir.set_path(opts.directory);
    dir.checksum_files();

    Database db;
    const std::vector<File*>& files = dir.get_files();
    for(auto it = files.begin(); it != files.end(); it++)
	db.insert(*it);
    db.write(opts.directory);

    return CORRCHECK_SUCCESS;
}

int verify_database(const Options& opts)
{
    bool needs_updating = false;

    Directory dir;
    dir.set_path(opts.directory);

    Database db;
    db.load(opts.directory);

    // find new files
    std::set<std::string> found_new_files;
    const std::vector<File*>& current_files = dir.get_files();
    for(auto it = current_files.begin(); it != current_files.end(); it++)
    {
	if(db.get((*it)->name) == nullptr)
	    found_new_files.insert((*it)->name);
    }

    if(found_new_files.size() > 0)
    {
	std::cout << "Found " << found_new_files.size() << " new file(s):" << std::endl;
	for(auto it = found_new_files.begin(); it != found_new_files.end(); it++)
	    std::cout << *it << std::endl;
	std::cout << "The database should be updated." << std::endl;
    }
    else
	std::cout << "No new files found." << std::endl;

    // verify checksums
    // check against files in directory; need to be checksummed first
    dir.checksum_files();
    std::set<std::string> found_changed_files;
    for(auto it = current_files.begin(); it != current_files.end(); it++)
    {
	// if it's a new file, no point in going further
	if(found_new_files.find((*it)->name) != found_new_files.end())
	    continue;

	const unsigned char* const current_sum = db.get((*it)->name);
	assert(current_sum != nullptr);
	unsigned int i = 0;
	for(; i < SHA256_DIGEST_LENGTH; i++)
	{
	    if(current_sum[i] != (*it)->checksum[i])
		break;
	}
	if(i < SHA256_DIGEST_LENGTH) // changed checksum
	    found_changed_files.insert((*it)->name);
    }

    if(found_changed_files.size() > 0)
    {
	std::cout << "Found " << found_changed_files.size() << " changed file(s):" << std::endl;
	for(auto it = found_changed_files.begin(); it != found_changed_files.end(); it++)
	    std::cout << *it << std::endl;
	std::cout << "The databases needs to be updated or the file(s) have become corrupt." << std::endl;
    }
    else
	std::cout << "All files are consistent." << std::endl;

    return CORRCHECK_SUCCESS;
}

<commit_msg>Fix typo.<commit_after>#include "corrcheck.h"

int create_database(const Options& opts)
{
    Directory dir;
    dir.set_path(opts.directory);
    dir.checksum_files();

    Database db;
    const std::vector<File*>& files = dir.get_files();
    for(auto it = files.begin(); it != files.end(); it++)
	db.insert(*it);
    db.write(opts.directory);

    return CORRCHECK_SUCCESS;
}

int verify_database(const Options& opts)
{
    bool needs_updating = false;

    Directory dir;
    dir.set_path(opts.directory);

    Database db;
    db.load(opts.directory);

    // find new files
    std::set<std::string> found_new_files;
    const std::vector<File*>& current_files = dir.get_files();
    for(auto it = current_files.begin(); it != current_files.end(); it++)
    {
	if(db.get((*it)->name) == nullptr)
	    found_new_files.insert((*it)->name);
    }

    if(found_new_files.size() > 0)
    {
	std::cout << "Found " << found_new_files.size() << " new file(s):" << std::endl;
	for(auto it = found_new_files.begin(); it != found_new_files.end(); it++)
	    std::cout << *it << std::endl;
	std::cout << "The database should be updated." << std::endl;
    }
    else
	std::cout << "No new files found." << std::endl;

    // verify checksums
    // check against files in directory; need to be checksummed first
    dir.checksum_files();
    std::set<std::string> found_changed_files;
    for(auto it = current_files.begin(); it != current_files.end(); it++)
    {
	// if it's a new file, no point in going further
	if(found_new_files.find((*it)->name) != found_new_files.end())
	    continue;

	const unsigned char* const current_sum = db.get((*it)->name);
	assert(current_sum != nullptr);
	unsigned int i = 0;
	for(; i < SHA256_DIGEST_LENGTH; i++)
	{
	    if(current_sum[i] != (*it)->checksum[i])
		break;
	}
	if(i < SHA256_DIGEST_LENGTH) // changed checksum
	    found_changed_files.insert((*it)->name);
    }

    if(found_changed_files.size() > 0)
    {
	std::cout << "Found " << found_changed_files.size() << " changed file(s):" << std::endl;
	for(auto it = found_changed_files.begin(); it != found_changed_files.end(); it++)
	    std::cout << *it << std::endl;
	std::cout << "The database needs to be updated or the file(s) have become corrupt." << std::endl;
    }
    else
	std::cout << "All files are consistent." << std::endl;

    return CORRCHECK_SUCCESS;
}

<|endoftext|>