<commit_before>/**
 * @file storageMapper.cc
 * @author <NAME>
 * @author <NAME>
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "storageMapper.h"

#include "context.h"
#include "fslogicProxy.h"
#include "fuse_messages.pb.h"
#include "helpers/storageHelperFactory.h"
#include "jobScheduler.h"
#include "logging.h"
#include "veilException.h"
#include "veilfs.h"

#include <boost/any.hpp>

#include <ctime>
#include <arpa/inet.h>

using namespace std;
using namespace veil::protocol::fuse_messages;

namespace veil {
namespace client {

StorageMapper::StorageMapper(std::weak_ptr<Context> context, std::shared_ptr<FslogicProxy> fslogicProxy)
    : m_fslogic(fslogicProxy)
    , m_context{std::move(context)}
{
}

pair<locationInfo, storageInfo> StorageMapper::getLocationInfo(const string &logicalName, bool useCluster)
{
    AutoLock lock(m_fileMappingLock, READ_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it == m_fileMapping.end())
    {
        if(!useCluster)
            throw VeilException(VEIO, "cannot find file mapping in cache but using cluster is not allowed in this context");

        lock.release();
        string status = findLocation(logicalName);
        lock.lock();

        it = m_fileMapping.find(logicalName);
        if(it == m_fileMapping.end())
            throw VeilException(VEIO, "cannot find file mapping (cluster was used)");
    }

    locationInfo location = it->second;

    AutoLock sLock(m_storageMappingLock, READ_LOCK);

    // Find matching storage info
    auto it1 = m_storageMapping.find(location.storageId);
    if(it1 == m_storageMapping.end())
        throw VeilException(VEIO, "cannot find storage information");

    // Check for helper overrides for this file
    auto it0 = m_fileHelperOverride.find(logicalName);
    if(it0 != m_fileHelperOverride.end())
    {

        // BEGIN HACK
        /*
         * @todo
         * If override changes helper to "ClusterProxy", we need to tuneup fileId since "ClusterProxy" handles
         * it differently. Right now logic that format fileId for "ClusterProxy" is both on server and client side which is
         * unacceptable. Easiest fix would be moving storageId to "ClusterProxy"'s arguments map, so that
         * "ClusterProxy" could accept standard fileId.
        */

        if(it1->second.storageHelperName != it0->second.storageHelperName && it0->second.storageHelperName == CLUSTER_PROXY_HELPER)
        {
            location.fileId = std::to_string(location.storageId) + "///" + location.fileId;
        }
        // END HACK

        DLOG(INFO) << "Default helper / fileId: " << it1->second.storageHelperName << " / " << it->second.fileId << " "
                   << "Overriden helper / fileId: " << it0->second.storageHelperName << " / " << location.fileId;

        return make_pair(location, it0->second);
    }

    return make_pair(location, it1->second);
}

string StorageMapper::findLocation(const string &logicalName, const string &openMode)
{
    LOG(INFO) << "quering cluster about storage mapping for file: " << logicalName;
    FileLocation location;
    if(m_fslogic->getFileLocation(logicalName, location, openMode))
    {
        if(location.answer() == VOK)
            addLocation(logicalName, location);
        else
            LOG(WARNING) << "Cannot get storage mapping for file: " << logicalName << " due to error: " << location.answer();
        return location.answer();
    }
    else<commit_msg>VFS-759: fix ClusterProxy's fileId<commit_after>/**
 * @file storageMapper.cc
 * @author <NAME>
 * @author <NAME>
 * @copyright (C) 2013 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in 'LICENSE.txt'
 */

#include "storageMapper.h"

#include "context.h"
#include "fslogicProxy.h"
#include "fuse_messages.pb.h"
#include "helpers/storageHelperFactory.h"
#include "jobScheduler.h"
#include "logging.h"
#include "veilException.h"
#include "veilfs.h"

#include <boost/any.hpp>

#include <ctime>
#include <arpa/inet.h>

using namespace std;
using namespace veil::protocol::fuse_messages;

namespace veil {
namespace client {

StorageMapper::StorageMapper(std::weak_ptr<Context> context, std::shared_ptr<FslogicProxy> fslogicProxy)
    : m_fslogic(fslogicProxy)
    , m_context{std::move(context)}
{
}

pair<locationInfo, storageInfo> StorageMapper::getLocationInfo(const string &logicalName, bool useCluster)
{
    AutoLock lock(m_fileMappingLock, READ_LOCK);
    map<string, locationInfo>::iterator it = m_fileMapping.find(logicalName);
    if(it == m_fileMapping.end())
    {
        if(!useCluster)
            throw VeilException(VEIO, "cannot find file mapping in cache but using cluster is not allowed in this context");

        lock.release();
        string status = findLocation(logicalName);
        lock.lock();

        it = m_fileMapping.find(logicalName);
        if(it == m_fileMapping.end())
            throw VeilException(VEIO, "cannot find file mapping (cluster was used)");
    }

    locationInfo location = it->second;

    AutoLock sLock(m_storageMappingLock, READ_LOCK);

    // Find matching storage info
    auto it1 = m_storageMapping.find(location.storageId);
    if(it1 == m_storageMapping.end())
        throw VeilException(VEIO, "cannot find storage information");

    // Check for helper overrides for this file
    auto it0 = m_fileHelperOverride.find(logicalName);
    if(it0 != m_fileHelperOverride.end())
    {

        // BEGIN HACK
        /*
         * @todo
         * If override changes helper to "ClusterProxy", we need to tuneup fileId since "ClusterProxy" handles
         * it differently. Right now logic that format fileId for "ClusterProxy" is both on server and client side which is
         * unacceptable. Easiest fix would be moving storageId to "ClusterProxy"'s arguments map, so that
         * "ClusterProxy" could accept standard fileId.
        */

        if(it1->second.storageHelperName != it0->second.storageHelperName && it0->second.storageHelperName == CLUSTER_PROXY_HELPER)
        {
            location.fileId = std::to_string(location.storageId) + "///" + location.fileId;
        }
        // END HACK

        DLOG(INFO) << "Default helper / fileId: " << it1->second.storageHelperName << " / " << it->second.fileId << " "
                   << "Overriden helper / fileId: " << it0->second.storageHelperName << " / " << location.fileId;

        return make_pair(std::move(location), it0->second);
    }

    return make_pair(std::move(location), it1->second);
}

string StorageMapper::findLocation(const string &logicalName, const string &openMode)
{
    LOG(INFO) << "quering cluster about storage mapping for file: " << logicalName;
    FileLocation location;
    if(m_fslogic->getFileLocation(logicalName, location, openMode))
    {
        if(location.answer() == VOK)
            addLocation(logicalName, location);
        else
            LOG(WARNING) << "Cannot get storage mapping for file: " << logicalName << " due to error: " << location.answer();
        return location.answer();
    }
    else
{'fraction_non_alphanumeric': 0.11847417513573716, 'fraction_numerical': 0.004594180704441042, 'mean_word_length': 3.3460375075620084, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7351179', 'n_tokens_mistral': 2173, 'n_tokens_neox': 2108, 'n_words': 552}