#include "erf_mem.h"

#include <saas/rtyserver/factors/factors_abstract.h>
#include <saas/rtyserver/factors/factor.h>

TRTYErfMemoryManager::TRTYErfMemoryManager(ui32 blocksCountStart, const IRTYStaticFactors* fDescription, const TString& componentName)
    : IRTYErfManager(componentName)
    , FDescription(fDescription)
    , Remapper(*fDescription)
{
    VERIFY_WITH_LOG(FDescription, "empty factors description");
    Storage.Resize(static_cast<ui64>(blocksCountStart) * BlockSizeBytes());
}

bool TRTYErfMemoryManager::Write(const TBasicFactorStorage& data, ui32 docId) const {
    if (docId >= Size())
        return false;

    Y_ASSERT(FDescription->GetStaticFactorsCount() == data.Size());
    Remapper.PackSimple(data, reinterpret_cast<ui8*>(Storage.Data() + (ui64)docId * BlockSizeBytes()));
    return true;
}

bool TRTYErfMemoryManager::Read(TFactorView& data, ui32 docId) const {
    if (docId >= Size())
        return false;
    Remapper.UnpackFormula(data, reinterpret_cast<const ui8*>(Storage.Data() + (ui64)docId * BlockSizeBytes()));
    return true;
}

bool TRTYErfMemoryManager::ReadRaw(TBasicFactorStorage& erfBlock, ui32 docId) const {
    if (docId >= Size())
        return false;
    Remapper.UnpackSimple(erfBlock, reinterpret_cast<const ui8*>(Storage.Data() + (ui64)docId * BlockSizeBytes()));
    return true;
}

bool TRTYErfMemoryManager::Resize() {
    const size_t oldSize = Storage.Size();
    Storage.Resize(oldSize ? oldSize * 2 : 1);
    return true;
}

ui32 TRTYErfMemoryManager::Size() const {
    Y_ASSERT(Storage.Size() % BlockSizeBytes() == 0);
    return  Storage.Size() / BlockSizeBytes();
}

ui32 TRTYErfMemoryManager::BlockSizeBytes() const {
    return FDescription->GetStaticFactorsCount() * sizeof(float);
}

