<commit_before>#include "clustering/administration/persist.hpp"

#include <sys/stat.h>
#include <sys/types.h>

#include "arch/runtime/thread_pool.hpp"
#include "buffer_cache/blob.hpp"
#include "containers/archive/string_stream.hpp"
#include "clustering/immediate_consistency/branch/history.hpp"
#include "serializer/config.hpp"

namespace metadata_persistence {

struct metadata_superblock_t {
    block_magic_t magic;

    machine_id_t machine_id;

    static const int METADATA_BLOB_MAXREFLEN = 1500;
    char metadata_blob[METADATA_BLOB_MAXREFLEN];

    static const int BRANCH_HISTORY_BLOB_MAXREFLEN = 500;
    char dummy_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];
    char memcached_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];
    char rdb_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];

    static const block_magic_t expected_magic;
};

/* Etymology: (R)ethink(D)B (m)eta(d)ata */
const block_magic_t metadata_superblock_t::expected_magic = { { 'R', 'D', 'm', 'd' } };

template <class T>
static void write_blob(transaction_t *txn, char *ref, int maxreflen, const T &value) {
    write_message_t msg;
    msg << value;
    intrusive_list_t<write_buffer_t> *buffers = msg.unsafe_expose_buffers();
    size_t slen = 0;
    for (write_buffer_t *p = buffers->head(); p != NULL; p = buffers->next(p)) {
        slen += p->size;
    }
    std::string str;
    str.reserve(slen);
    for (write_buffer_t *p = buffers->head(); p != NULL; p = buffers->next(p)) {
        str.append(p->data, p->size);
    }
    guarantee(str.size() == slen);
    blob_t blob(ref, maxreflen);
    blob.clear(txn);
    blob.append_region(txn, str.size());
    blob.write_from_string(str, txn, 0);
    guarantee(blob.valuesize() == static_cast<int64_t>(slen));
}

template<class T>
static void read_blob(transaction_t *txn, const char *ref, int maxreflen, T *value_out) {
    blob_t blob(const_cast<char *>(ref), maxreflen);
    std::string str = blob.read_to_string(txn, 0, blob.valuesize());
    read_string_stream_t ss(str);
    int res = deserialize(&ss, value_out);
    guarantee(res == 0);
}

persistent_file_t::persistent_file_t(io_backender_t *io_backender, const std::string &filename, perfmon_collection_t *perfmon_parent) {
    construct_serializer_and_cache(io_backender, false, filename, perfmon_parent);
    construct_branch_history_managers(false);
}

persistent_file_t::persistent_file_t(io_backender_t *io_backender, const std::string& filename, perfmon_collection_t *perfmon_parent, const machine_id_t &machine_id, const cluster_semilattice_metadata_t &initial_metadata) {
    construct_serializer_and_cache(io_backender, true, filename, perfmon_parent);

    transaction_t txn(cache.get(), rwi_write, 1, repli_timestamp_t::distant_past, cache_order_source.check_in("persistent_file_t"));
    buf_lock_t superblock(&txn, SUPERBLOCK_ID, rwi_write);
    metadata_superblock_t *sb = static_cast<metadata_superblock_t *>(superblock.get_data_major_write());

    bzero(sb, cache->get_block_size().value());
    sb->magic = metadata_superblock_t::expected_magic;
    sb->machine_id = machine_id;
    write_blob(&txn, sb->metadata_blob, metadata_superblock_t::METADATA_BLOB_MAXREFLEN, initial_metadata);
    write_blob(&txn, sb->dummy_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<mock::dummy_protocol_t>());
    write_blob(&txn, sb->memcached_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<memcached_protocol_t>());
    write_blob(&txn, sb->rdb_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<rdb_protocol_t>());

    construct_branch_history_managers(true);
}

persistent_file_t::~persistent_file_t() {
    /* This destructor is defined here so that the compiler won't try to
    generate a destructor in the header file. In the header file, it can't see
    the definition of `persistent_branch_history_manager_t`, so any attempt to<commit_msg>Made the read_blob function of persist.cc not use read_to_string.<commit_after>#include "clustering/administration/persist.hpp"

#include <sys/stat.h>
#include <sys/types.h>

#include "arch/runtime/thread_pool.hpp"
#include "buffer_cache/blob.hpp"
#include "containers/archive/buffer_group_stream.hpp"
#include "clustering/immediate_consistency/branch/history.hpp"
#include "serializer/config.hpp"

namespace metadata_persistence {

struct metadata_superblock_t {
    block_magic_t magic;

    machine_id_t machine_id;

    static const int METADATA_BLOB_MAXREFLEN = 1500;
    char metadata_blob[METADATA_BLOB_MAXREFLEN];

    static const int BRANCH_HISTORY_BLOB_MAXREFLEN = 500;
    char dummy_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];
    char memcached_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];
    char rdb_branch_history_blob[BRANCH_HISTORY_BLOB_MAXREFLEN];

    static const block_magic_t expected_magic;
};

/* Etymology: (R)ethink(D)B (m)eta(d)ata */
const block_magic_t metadata_superblock_t::expected_magic = { { 'R', 'D', 'm', 'd' } };

template <class T>
static void write_blob(transaction_t *txn, char *ref, int maxreflen, const T &value) {
    write_message_t msg;
    msg << value;
    intrusive_list_t<write_buffer_t> *buffers = msg.unsafe_expose_buffers();
    size_t slen = 0;
    for (write_buffer_t *p = buffers->head(); p != NULL; p = buffers->next(p)) {
        slen += p->size;
    }
    std::string str;
    str.reserve(slen);
    for (write_buffer_t *p = buffers->head(); p != NULL; p = buffers->next(p)) {
        str.append(p->data, p->size);
    }
    guarantee(str.size() == slen);
    blob_t blob(ref, maxreflen);
    blob.clear(txn);
    blob.append_region(txn, str.size());
    blob.write_from_string(str, txn, 0);
    guarantee(blob.valuesize() == static_cast<int64_t>(slen));
}

template<class T>
static void read_blob(transaction_t *txn, const char *ref, int maxreflen, T *value_out) {
    blob_t blob(const_cast<char *>(ref), maxreflen);
    blob_acq_t acq_group;
    buffer_group_t group;
    blob.expose_all(txn, rwi_read, &group, &acq_group);
    buffer_group_read_stream_t ss(const_view(&group));
    int res = deserialize(&ss, value_out);
    guarantee(res == 0);
}

persistent_file_t::persistent_file_t(io_backender_t *io_backender, const std::string &filename, perfmon_collection_t *perfmon_parent) {
    construct_serializer_and_cache(io_backender, false, filename, perfmon_parent);
    construct_branch_history_managers(false);
}

persistent_file_t::persistent_file_t(io_backender_t *io_backender, const std::string& filename, perfmon_collection_t *perfmon_parent, const machine_id_t &machine_id, const cluster_semilattice_metadata_t &initial_metadata) {
    construct_serializer_and_cache(io_backender, true, filename, perfmon_parent);

    transaction_t txn(cache.get(), rwi_write, 1, repli_timestamp_t::distant_past, cache_order_source.check_in("persistent_file_t"));
    buf_lock_t superblock(&txn, SUPERBLOCK_ID, rwi_write);
    metadata_superblock_t *sb = static_cast<metadata_superblock_t *>(superblock.get_data_major_write());

    bzero(sb, cache->get_block_size().value());
    sb->magic = metadata_superblock_t::expected_magic;
    sb->machine_id = machine_id;
    write_blob(&txn, sb->metadata_blob, metadata_superblock_t::METADATA_BLOB_MAXREFLEN, initial_metadata);
    write_blob(&txn, sb->dummy_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<mock::dummy_protocol_t>());
    write_blob(&txn, sb->memcached_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<memcached_protocol_t>());
    write_blob(&txn, sb->rdb_branch_history_blob, metadata_superblock_t::BRANCH_HISTORY_BLOB_MAXREFLEN, branch_history_t<rdb_protocol_t>());

    construct_branch_history_managers(true);
}

persistent_file_t::~persistent_file_t() {
    /* This destructor is defined here so that the compiler won't try to
    generate a destructor in the header file. In the header file, it can't see
    the definition of `persistent_branch_history_manager_t`, so any attempt to
{'fraction_non_alphanumeric': 0.11229022704837117, 'fraction_numerical': 0.0033316880552813426, 'mean_word_length': 6.047826086956522, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 53, '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': '1547254', 'n_tokens_mistral': 2951, 'n_tokens_neox': 2887, 'n_words': 504}