<commit_before>/**
 * @file typed_subgroup_test.cpp
 *
 * @date Mar 1, 2017
 * @author edward
 */

#include <chrono>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include "derecho/derecho.h"
#include "initialize.h"
#include <mutils-serialization/SerializationSupport.hpp>
#include <persistent/Persistent.hpp>

/**
 * Example for replicated object with Persistent<T>
 */
class PFoo : public mutils::ByteRepresentable, public derecho::PersistsFields {
    Persistent<int> pint;

public:
    virtual ~PFoo() noexcept(true) {
    }
    int read_state(int64_t ver) {
        return *pint[ver];
    }
    bool change_state(int new_int) {
        if(new_int == *pint) {
            return false;
        }
        *pint = new_int;
        return true;
    }
    int64_t get_latest_version() {
        return pint.getLatestVersion();
    }

    enum Functions { READ_STATE,
                     CHANGE_STATE,
                     GET_LATEST_VERSION };

    static auto register_functions() {
        return std::make_tuple(derecho::rpc::tag<READ_STATE>(&PFoo::read_state),
                               derecho::rpc::tag<CHANGE_STATE>(&PFoo::change_state),
                               derecho::rpc::tag<GET_LATEST_VERSION>(&PFoo::get_latest_version));
    }

    // constructor for PersistentRegistry
    PFoo(PersistentRegistry* pr) : pint(nullptr, pr) {}
    PFoo(Persistent<int>& init_pint) : pint(std::move(init_pint)) {}
    DEFAULT_SERIALIZATION_SUPPORT(PFoo, pint);
};

using derecho::ExternalCaller;
using derecho::Replicated;
using std::cout;
using std::endl;

int main(int argc, char** argv) {
    derecho::node_id_t node_id;
    derecho::ip_addr my_ip;
    derecho::ip_addr leader_ip;

    query_node_info(node_id, my_ip, leader_ip);

    //Derecho message parameters
    //Where do these come from? What do they mean? Does the user really need to supply them?
    long long unsigned int max_msg_size = 100;
    long long unsigned int block_size = 100000;
    const long long unsigned int sst_max_msg_size = (max_msg_size < 17000 ? max_msg_size : 0);
    derecho::DerechoParams derecho_params{max_msg_size, sst_max_msg_size, block_size};

    // derecho::message_callback_t stability_callback{};
    // derecho::CallbackSet callback_set{stability_callback, {}};
    derecho::CallbackSet callback_set{
            nullptr,
            [](derecho::subgroup_id_t subgroup, persistent::version_t ver) {
                std::cout << "Subgroup " << subgroup << ", version " << ver << "is persisted." << std::endl;
            }};

    derecho::SubgroupInfo subgroup_info{{{std::type_index(typeid(PFoo)), [](const derecho::View& curr_view, int& next_unassigned_rank, bool previous_was_successful) {
                                              if(curr_view.num_members < 2) {
                                                  std::cout << "PFoo function throwing subgroup_provisioning_exception" << std::endl;
                                                  throw derecho::subgroup_provisioning_exception();
                                              }
                                              derecho::subgroup_shard_layout_t subgroup_vector(1);
                                              //Put the desired SubView at subgroup_vector[0][0] since there's one subgroup with one shard
                                              subgroup_vector[0].emplace_back(curr_view.make_subview({0, 1}));
                                              next_unassigned_rank = std::max(next_unassigned_rank, 2);
                                              return subgroup_vector;
                                          }}},
                                        {std::type_index(typeid(PFoo))}};

    auto pfoo_factory = [](PersistentRegistry* pr) { return std::make_unique<PFoo>(pr); };

    std::unique_ptr<derecho::Group<PFoo>> group;
    if(my_ip == leader_ip) {
        group = std::make_unique<derecho::Group<PFoo>>(
                node_id, my_ip, callback_set, subgroup_info, derecho_params,
                std::vector<derecho::view_upcall_t>{},
                pfoo_factory);
    } else {
        group = std::make_unique<derecho::Group<PFoo>>(
                node_id, my_ip, leader_ip, callback_set, subgroup_info,
                std::vector<derecho::view_upcall_t>{},
                pfoo_factory);
    }

    cout << "Finished constructing/joining Group" << endl;

    // Update the states:<commit_msg>Fixed new experiment to compile with my changes<commit_after>/**
 * @file typed_subgroup_test.cpp
 *
 * @date Mar 1, 2017
 * @author edward
 */

#include <chrono>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <thread>
#include <vector>

#include "derecho/derecho.h"
#include "initialize.h"
#include <mutils-serialization/SerializationSupport.hpp>
#include <persistent/Persistent.hpp>

/**
 * Example for replicated object with Persistent<T>
 */
class PFoo : public mutils::ByteRepresentable, public derecho::PersistsFields {
    Persistent<int> pint;

public:
    virtual ~PFoo() noexcept(true) {
    }
    int read_state(int64_t ver) {
        return *pint[ver];
    }
    bool change_state(int new_int) {
        if(new_int == *pint) {
            return false;
        }
        *pint = new_int;
        return true;
    }
    int64_t get_latest_version() {
        return pint.getLatestVersion();
    }

    enum Functions { READ_STATE,
                     CHANGE_STATE,
                     GET_LATEST_VERSION };

    static auto register_functions() {
        return std::make_tuple(derecho::rpc::tag<READ_STATE>(&PFoo::read_state),
                               derecho::rpc::tag<CHANGE_STATE>(&PFoo::change_state),
                               derecho::rpc::tag<GET_LATEST_VERSION>(&PFoo::get_latest_version));
    }

    // constructor for PersistentRegistry
    PFoo(PersistentRegistry* pr) : pint(nullptr, pr) {}
    PFoo(Persistent<int>& init_pint) : pint(std::move(init_pint)) {}
    DEFAULT_SERIALIZATION_SUPPORT(PFoo, pint);
};

using derecho::ExternalCaller;
using derecho::Replicated;
using std::cout;
using std::endl;

int main(int argc, char** argv) {
    derecho::node_id_t node_id;
    derecho::ip_addr my_ip;
    derecho::ip_addr leader_ip;

    query_node_info(node_id, my_ip, leader_ip);

    //Derecho message parameters
    //Where do these come from? What do they mean? Does the user really need to supply them?
    long long unsigned int max_msg_size = 100;
    long long unsigned int block_size = 100000;
    const long long unsigned int sst_max_msg_size = (max_msg_size < 17000 ? max_msg_size : 0);
    derecho::DerechoParams derecho_params{max_msg_size, sst_max_msg_size, block_size};

    // derecho::message_callback_t stability_callback{};
    // derecho::CallbackSet callback_set{stability_callback, {}};
    derecho::CallbackSet callback_set{
            nullptr,
            [](derecho::subgroup_id_t subgroup, persistent::version_t ver) {
                std::cout << "Subgroup " << subgroup << ", version " << ver << "is persisted." << std::endl;
            }};

    derecho::SubgroupInfo subgroup_info{{{std::type_index(typeid(PFoo)), [](const derecho::View& curr_view, int& next_unassigned_rank) {
                                              if(curr_view.num_members < 2) {
                                                  std::cout << "PFoo function throwing subgroup_provisioning_exception" << std::endl;
                                                  throw derecho::subgroup_provisioning_exception();
                                              }
                                              derecho::subgroup_shard_layout_t subgroup_vector(1);
                                              //Put the desired SubView at subgroup_vector[0][0] since there's one subgroup with one shard
                                              subgroup_vector[0].emplace_back(curr_view.make_subview({0, 1}));
                                              next_unassigned_rank = std::max(next_unassigned_rank, 2);
                                              return subgroup_vector;
                                          }}},
                                        {std::type_index(typeid(PFoo))}};

    auto pfoo_factory = [](PersistentRegistry* pr) { return std::make_unique<PFoo>(pr); };

    std::unique_ptr<derecho::Group<PFoo>> group;
    if(my_ip == leader_ip) {
        group = std::make_unique<derecho::Group<PFoo>>(
                node_id, my_ip, callback_set, subgroup_info, derecho_params,
                std::vector<derecho::view_upcall_t>{},
                pfoo_factory);
    } else {
        group = std::make_unique<derecho::Group<PFoo>>(
                node_id, my_ip, leader_ip, callback_set, subgroup_info,
                std::vector<derecho::view_upcall_t>{},
                pfoo_factory);
    }

    cout << "Finished constructing/joining Group" << endl;

    // Update the states:
{'fraction_non_alphanumeric': 0.11104923145466697, 'fraction_numerical': 0.007128536422365783, 'mean_word_length': 2.253260869565217, 'pattern_counts': {'":': 0, '<': 95, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5775134', 'n_tokens_mistral': 2693, 'n_tokens_neox': 2553, 'n_words': 522}