#pragma once #include #include "remote_loopback.hpp" #include "transfer.hpp" namespace saw { template<> class remote; template class data_server final : public i_data_server { private: //typename using type = std::unordered_map>; type values_; ptr> remote_; remote_address rmt_address_; public: static constexpr std::pair class_id{schema_hash::apply(), schema_hash::apply()}; data_server(ptr> remote__, const remote_address& addr): remote_{remote__}, rmt_address_{addr} { remote_().register_data_server(addr, *this); } ~data_server(){ remote_().deregister_data_server(rmt_address_, *this); } SAW_FORBID_COPY(data_server); SAW_FORBID_MOVE(data_server); /** * Return the schema id */ std::pair get_class_id() const override { return class_id; } error_or send(const data& dat, id store_id){ try { auto insert_res = values_.emplace(std::make_pair(store_id.get_value(), dat)); if(!insert_res.second){ return make_error(); } }catch(std::exception& ){ return make_error(); } return void_t{}; } error_or allocate(data::MetaSchema, Encoding> meta, id store_id){ try{ auto insert_res = values_.emplace(std::make_pair(store_id.get_value(), data::MetaSchema, Encoding>{std::move(meta)})); if(!insert_res.second){ return make_error(); } }catch(const std::exception&){ return make_error(); } return make_void(); } error_or> receive(id store_id){ auto find_res = values_.find(store_id.get_value()); if(find_res == values_.end()){ return make_error(); } auto& dat = find_res->second; // here return dat;// boy } error_or erase(id store_id){ auto erase_res = values_.erase(store_id.get_value()); if(erase_res == 0u){ return make_error(); } return make_void(); } error_or>> find(id store_id){ auto find_res = values_.find(store_id.get_value()); if(find_res == values_.end()){ return make_error(); } auto& dat = find_res->second; return ptr>{dat}; } }; /* template class data_server, Encoding, rmt::Loopback> final { private: ptr> remote_; remote_address rmt_address_; std::tuple>...> values_; struct inner_register_helper { template static error_or reg_i(ptr> rmt, ref> addr, ref...>> vals){ { auto eov = rmt().register_data_server(addr,std::get(vals)); if(eov.is_error()){ return i; } } if constexpr ( (i+1u) < sizeof...(Schema) ){ return reg_i(rmt, addr, vals); } // This only happens if we reached the last element return i+1u; } static error_or reg(ptr> rmt, ref> addr, ref...>> vals){ if ( 0u < sizeof...(Schema) ){ return reg_i<0u>(rmt,addr,vals); } return 1u; } static error_or dereg(ptr> rmt, ref> addr, ref...>> vals){ return 1u; } }; public: data_server(ptr> remote__, const remote_address& addr, std::tuple>...>&& values__): remote_{remote__}, rmt_address_{addr}, values_{std::move(values__)} { } ~data_server(){ remote_().deregister_data_server(rmt_address_,*this); } SAW_FORBID_COPY(data_server); SAW_FORBID_MOVE(data_server); template error_or send(const data& dat, id store_id){ auto& vals = std::get>>(values_); try { auto insert_res = vals.emplace(std::make_pair(store_id.get_value(), std::move(dat))); if(!insert_res.second){ return make_error(); } }catch(std::exception& ){ return make_error(); } return void_t{}; } template error_or allocate(data::MetaSchema, Encoding> meta, id store_id){ auto& vals = std::get>>(values_); try { auto insert_res = vals.emplace(std::make_pair(store_id.get_value(), data::MetaSchema, Encoding>{std::move(meta)})); if(!insert_res.second){ return make_error(); } }catch(std::exception& ){ return make_error(); } return make_void(); } template error_or> receive(id store_id){ auto& vals = std::get>>(values_); auto find_res = vals.find(store_id.get_value()); if(find_res == vals.end()){ return make_error(); } auto& dat = find_res->second; return dat; } template error_or erase(id store_id){ auto& vals = std::get>>(values_); auto erase_op = vals.erase(store_id.get_value()); if(erase_op == 0u){ return make_error(); } return make_void(); } template error_or*> find(id store_id){ auto& vals = std::get>>(values_); auto find_res = vals.find(store_id.get_value()); if(find_res == vals.end()){ return make_error(); } auto& dat = find_res->second; return &dat; } }; */ template class data_client final { private: ptr> srv_; uint64_t next_id_; public: data_client(ptr> srv__): srv_{srv__}, next_id_{0u} {} /** * Send data to the remote. */ error_or> send(const data& dat){ id dat_id{next_id_}; auto eov = srv_().send(dat, dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } ++next_id_; return dat_id; } /** * Preallocate data */ error_or> allocate(const data::MetaSchema, Encoding>& meta){ id dat_id{next_id_}; auto eov = srv_().allocate(meta, dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } ++next_id_; return dat_id; } /** * Receive data */ conveyor> receive(id dat_id){ auto eov = srv_().receive(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto& val = eov.get_value(); return std::move(val); } /** * Erase data */ error_or erase(id dat_id){ return srv_().erase(dat_id); } /** * An exception for the Loopback backend. Here we can safely use find from * the client side. */ error_or>> find(id dat_id){ auto eov = srv_().find(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto val = eov.get_value(); return val; } }; /* template class data_client, Encoding, rmt::Loopback> { private: ptr, Encoding, rmt::Loopback>> srv_; uint64_t next_id_; public: data_client(ptr, Encoding, rmt::Loopback>> srv__): srv_{srv__}, next_id_{0u} {} SAW_FORBID_COPY(data_client); SAW_DEFAULT_MOVE(data_client); template error_or> send(const data& dat){ id dat_id{next_id_}; auto eov = srv_().send(dat, dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } ++next_id_; return dat_id; } template error_or> allocate(const data::MetaSchema, Encoding>& meta){ id dat_id{next_id_}; auto eov = srv_().allocate(meta, dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } ++next_id_; return dat_id; } template conveyor> receive(id dat_id){ auto eov = srv_().receive(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto& val = eov.get_value(); return std::move(val); } template error_or erase(id dat_id){ return srv_().erase(dat_id); } template error_or*> find(id dat_id){ auto eov = srv_().find(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto val = eov.get_value(); return val; } }; */ }