#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(), std::move(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 : public i_data_server { private: typename impl::data_server_redux>::type>::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; } /** * Get data from client */ 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; } }; /** * Client for transporting data to remote and receiving data back */ template class data_client, Encoding, rmt::Loopback> { private: /** * Corresponding server for this client */ ptr, Encoding, rmt::Loopback>> srv_; /** * The next id for identifying issues on the remote side. */ uint64_t next_id_; public: /** * Main constructor */ data_client(ptr, Encoding, rmt::Loopback>> srv__): srv_{srv__}, next_id_{0u} {} SAW_FORBID_COPY(data_client); SAW_DEFAULT_MOVE(data_client); /** * Send data to the remote. */ 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; } /** * Preallocate data */ 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; } /** * Receive data */ 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); } /** * Erase data */ template 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. */ 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; } }; }