diff --git a/net/include/ftl/net/protocol.hpp b/net/include/ftl/net/protocol.hpp new file mode 100644 index 0000000000000000000000000000000000000000..59de85de039fc56e47a459ffb527b82bf619870b --- /dev/null +++ b/net/include/ftl/net/protocol.hpp @@ -0,0 +1,6 @@ +#ifndef _FTL_NET_PROTOCOL_HPP_ +#define _FTL_NET_PROTOCOL_HPP_ + +#define FTL_PROTOCOL_P2P 0x1000 + +#endif // _FTL_NET_PROTOCOL_HPP_ diff --git a/p2p-rm/CMakeLists.txt b/p2p-rm/CMakeLists.txt index 6046cecdf3c88fdcc8c3f276ef5f893704b9c86e..f13d00cef1fd2f847c8976434535ded1c5db6608 100644 --- a/p2p-rm/CMakeLists.txt +++ b/p2p-rm/CMakeLists.txt @@ -23,7 +23,7 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O3") SET(CMAKE_USE_RELATIVE_PATHS ON) set(FTLSOURCE - src/blob.cpp + src/cluster.cpp src/p2prm.cpp ) add_library(ftl-p2prm ${FTLSOURCE}) diff --git a/p2p-rm/include/ftl/p2p-rm.hpp b/p2p-rm/include/ftl/p2p-rm.hpp index 9c94e5db2be2d551a5b9fa5a2bbfa85c236e8683..00ea8d20eec849dd2d6ec3d36e06cec575cd07c1 100644 --- a/p2p-rm/include/ftl/p2p-rm.hpp +++ b/p2p-rm/include/ftl/p2p-rm.hpp @@ -1,87 +1,15 @@ -#ifndef _FTL_P2P_RA_HPP_ -#define _FTL_P2P_RA_HPP_ +#ifndef _FTL_P2P_RM_HPP_ +#define _FTL_P2P_RM_HPP_ -#include "ftl/p2p-rm/mapped_ptr.hpp" -#include "ftl/p2p-rm/internal.hpp" - -#include <type_traits> +#include <ftl/p2p-rm/cluster.hpp> namespace ftl { namespace rm { - void reset(); - inline void destroy() { reset(); } - - /** - * Obtain a remote pointer from a URI. A nullptr is returned if the URI is - * not valid. If the URI is actually local then a remote pointer is still - * returned and may be used normally, although it will possibly result in - * unwanted memory copies. - */ - template <typename T> - ftl::mapped_ptr<T> get(const char *uri) { - auto b = _lookup(uri); - // TODO Verify type and size - return ftl::mapped_ptr<T>{b,0}; - } - - /** - * Get a read-only memory reference from a URI. - */ - template <typename T> - ftl::read_ref<T> getReadable(const char *uri) { - return get<T>(uri).readable(); - } + std::shared_ptr<Cluster> cluster(const char *uri); - /** - * Get a read/writable memory reference from a URI. - */ - template <typename T> - ftl::write_ref<T> getWritable(const char *uri) { - return get<T>(uri).writable(); - } - - /** - * Register a memory area locally mapped to a given URI. The URI - * must not already exist within the peer group. - */ - template <typename T> - ftl::mapped_ptr<T> map(const char *uri, T *addr, size_t size=1) { - if (std::is_pointer<T>::value) return ftl::null_ptr<T>; - if (std::is_function<T>::value) return ftl::null_ptr<T>; - if (std::is_void<T>::value) return ftl::null_ptr<T>; - - if (addr == NULL) return ftl::null_ptr<T>; - - return ftl::mapped_ptr<T>{_create(uri, (char*)addr, sizeof(T), size, - static_cast<flags_t>(std::is_integral<T>::value * ftl::rm::FLAG_INTEGER | - std::is_signed<T>::value * ftl::rm::FLAG_SIGNED | - std::is_trivial<T>::value * ftl::rm::FLAG_TRIVIAL), - typeid(T).name()),0}; - } - - void unmap(const char *uri); - - template <typename T> - void unmap(ftl::mapped_ptr<T> ptr) {} - - /** - * Obtain a list or URI memory blocks in the current peer group that match - * the provided base URI. - */ - std::vector<std::string> search(const char *partial_uri); - - /** - * Connect to a new peer node using the specified socket. - */ - void addPeer(ftl::net::Socket *s); - - /** - * Connect to a new peer using a URL string. - */ - void addPeer(const char *url); } } -#endif // _FTL_P2P_RA_HPP_ +#endif // _FTL_P2P_RM_HPP_ diff --git a/p2p-rm/include/ftl/p2p-rm/cluster.hpp b/p2p-rm/include/ftl/p2p-rm/cluster.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b60de3f99655e6d315cf52485929d13ca24be4dd --- /dev/null +++ b/p2p-rm/include/ftl/p2p-rm/cluster.hpp @@ -0,0 +1,107 @@ +#ifndef _FTL_P2P_RM_CLUSTER_HPP_ +#define _FTL_P2P_RM_CLUSTER_HPP_ + +#include "ftl/p2p-rm/mapped_ptr.hpp" +#include "ftl/p2p-rm/internal.hpp" + +#include <type_traits> +#include <memory> +#include <vector> + +namespace ftl { +namespace net { + class Socket; + class Listener; +}; + +namespace rm { + +class Cluster { + public: + Cluster(const char *uri, std::shared_ptr<ftl::net::Listener> l); + ~Cluster(); + + void reset(); + inline void destroy() { reset(); } + + /** + * Obtain a remote pointer from a URI. A nullptr is returned if the URI is + * not valid. If the URI is actually local then a remote pointer is still + * returned and may be used normally, although it will possibly result in + * unwanted memory copies. + */ + template <typename T> + ftl::mapped_ptr<T> get(const char *uri) { + auto b = _lookup(uri); + // TODO Verify type and size + return ftl::mapped_ptr<T>{b,0}; + } + + /** + * Get a read-only memory reference from a URI. + */ + template <typename T> + ftl::read_ref<T> getReadable(const char *uri) { + return get<T>(uri).readable(); + } + + /** + * Get a read/writable memory reference from a URI. + */ + template <typename T> + ftl::write_ref<T> getWritable(const char *uri) { + return get<T>(uri).writable(); + } + + /** + * Register a memory area locally mapped to a given URI. The URI + * must not already exist within the peer group. + */ + template <typename T> + ftl::mapped_ptr<T> map(const char *uri, T *addr, size_t size=1) { + if (std::is_pointer<T>::value) return ftl::null_ptr<T>; + if (std::is_function<T>::value) return ftl::null_ptr<T>; + if (std::is_void<T>::value) return ftl::null_ptr<T>; + + if (addr == NULL) return ftl::null_ptr<T>; + + return ftl::mapped_ptr<T>{_create(this, uri, (char*)addr, sizeof(T), size, + static_cast<flags_t>(std::is_integral<T>::value * ftl::rm::FLAG_INTEGER | + std::is_signed<T>::value * ftl::rm::FLAG_SIGNED | + std::is_trivial<T>::value * ftl::rm::FLAG_TRIVIAL), + typeid(T).name()),0}; + } + + void unmap(const char *uri); + + template <typename T> + void unmap(ftl::mapped_ptr<T> ptr) {} + + /** + * Obtain a list or URI memory blocks in the current peer group that match + * the provided base URI. + */ + std::vector<std::string> search(const char *partial_uri); + + /** + * Connect to a new peer node using the specified socket. + */ + void addPeer(std::shared_ptr<ftl::net::Socket> s); + + /** + * Connect to a new peer using a URL string. + */ + void addPeer(const char *url); + + private: + std::string uri_; + std::string root_; + std::shared_ptr<ftl::net::Listener> listener_; + std::vector<std::shared_ptr<ftl::net::Socket>> peers_; +}; + +}; +}; + +#endif // _FTL_P2P_RM_CLUSTER_HPP_ + diff --git a/p2p-rm/include/ftl/p2p-rm/internal.hpp b/p2p-rm/include/ftl/p2p-rm/internal.hpp index 8519b942b1ea48bde33354a1d05553e2c0d95287..5d35fdac7417924dd5c14f68b095b2a6ca5e326c 100644 --- a/p2p-rm/include/ftl/p2p-rm/internal.hpp +++ b/p2p-rm/include/ftl/p2p-rm/internal.hpp @@ -5,6 +5,7 @@ namespace ftl { namespace rm { class Blob; +class Cluster; enum flags_t : uint32_t { FLAG_INTEGER = 1, @@ -13,7 +14,7 @@ enum flags_t : uint32_t { }; ftl::rm::Blob *_lookup(const char *uri); -ftl::rm::Blob *_create(const char *uri, char *addr, size_t size, size_t count, flags_t flags, const std::string &tname); +ftl::rm::Blob *_create(Cluster *c, const char *uri, char *addr, size_t size, size_t count, flags_t flags, const std::string &tname); }; // namespace rm }; // namespace ftl diff --git a/p2p-rm/src/cluster.cpp b/p2p-rm/src/cluster.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/p2p-rm/test/CMakeLists.txt b/p2p-rm/test/CMakeLists.txt index 17dd869af271582c34c9319ccb25e4d8b6b08186..82c07480af28c7fac5aa2f89d686e16eab6a5919 100644 --- a/p2p-rm/test/CMakeLists.txt +++ b/p2p-rm/test/CMakeLists.txt @@ -9,7 +9,7 @@ add_executable(mapped_ptr EXCLUDE_FROM_ALL add_executable(p2p_rm EXCLUDE_FROM_ALL ./tests.cpp ../src/p2prm.cpp - ../src/blob.cpp + ../src/cluster.cpp ./p2p-rm.cpp ) target_link_libraries(p2p_rm uriparser) diff --git a/p2p-rm/test/peer.cpp b/p2p-rm/test/peer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3cf2321bed5c5308b117ba62bcaba4b2103ab106 --- /dev/null +++ b/p2p-rm/test/peer.cpp @@ -0,0 +1,37 @@ +#include "ftl/p2p-rm.hpp" +#include <ftl/net.hpp> + +#include <gflags/gflags.h> + +DEFINE_string(listen, "tcp://*:9000", "Listen URI"); +DEFINE_string(peer, "", "Peer to connect to"); + +using namespace ftl; + +int main(int argc, char *argv) { + gflags::ParseCommandLineFlags(&argc, &argv, true); + + auto net = net::listen(FLAGS_listen); + auto cluster = rm::cluster("ftl://utu.fi", net); + + int data = 20; + auto ptr = cluster->map<int>("ftl://utu.fi/memory/test1", &data); + + if (FLAGS_peer) { + cluster->addPeer(FLAGS_peer); + std::cout << "Value = " << *ptr << std::endl; // 25. + std::cout << "Raw = " << data << std::endl; // 25. + + *ptr = 30; + } else { + *ptr = 25; + + ptr.onChange(()=> { + std::cout << "Value changed = " << *ptr << std::endl; // 30 + }); + } + + while (net()); + return 0; +} +