From d008509da46a6a662ea5e05adcba4443f9391d71 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Wed, 20 Feb 2019 13:40:59 +0200
Subject: [PATCH] Converted remote_ptr to mapped_ptr

---
 p2p-rm/include/ftl/p2p-rm.hpp                 | 81 +++++++++++--------
 p2p-rm/include/ftl/p2p-rm/blob.hpp            | 29 +++----
 p2p-rm/include/ftl/p2p-rm/internal.hpp        | 22 +++++
 .../p2p-rm/{remote_ptr.hpp => mapped_ptr.hpp} | 57 +++++++------
 p2p-rm/src/blob.cpp                           | 42 ++++++++--
 p2p-rm/src/p2prm.cpp                          | 19 +++--
 p2p-rm/test/CMakeLists.txt                    |  8 +-
 .../test/{remote_ptr.cpp => mapped_ptr.cpp}   | 22 ++---
 p2p-rm/test/p2p-rm.cpp                        | 58 ++++++++-----
 9 files changed, 209 insertions(+), 129 deletions(-)
 create mode 100644 p2p-rm/include/ftl/p2p-rm/internal.hpp
 rename p2p-rm/include/ftl/p2p-rm/{remote_ptr.hpp => mapped_ptr.hpp} (61%)
 rename p2p-rm/test/{remote_ptr.cpp => mapped_ptr.cpp} (73%)

diff --git a/p2p-rm/include/ftl/p2p-rm.hpp b/p2p-rm/include/ftl/p2p-rm.hpp
index 5e0e2ff85..9c94e5db2 100644
--- a/p2p-rm/include/ftl/p2p-rm.hpp
+++ b/p2p-rm/include/ftl/p2p-rm.hpp
@@ -1,70 +1,85 @@
 #ifndef _FTL_P2P_RA_HPP_
 #define _FTL_P2P_RA_HPP_
 
-#include "ftl/p2p-rm/remote_ptr.hpp"
+#include "ftl/p2p-rm/mapped_ptr.hpp"
+#include "ftl/p2p-rm/internal.hpp"
+
+#include <type_traits>
 
 namespace ftl {
 namespace rm {
 
 	void reset();
-	void destroy() { reset(); }
-
-	ftl::rm::Blob *_lookupBlob(const char *uri);
-	ftl::rm::Blob *_createBlob(const char *uri, size_t size);
+	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::remote_ptr<T> getPointer(const char *uri) {
-		auto b = _lookupBlob(uri);
+	ftl::mapped_ptr<T> get(const char *uri) {
+		auto b = _lookup(uri);
 		// TODO Verify type and size
-		return ftl::remote_ptr<T>{b,0};
+		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 getPointer<T>(uri).readable();
+		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 getPointer<T>(uri).writable();
+		return get<T>(uri).writable();
 	}
 	
-	//template <typename T>
-	//ftl::rw_ref<T> getReadWrite(const char *uri);
-	
 	/**
-	 * Get a remote write only reference filled with a provided empty value
-	 * rather than first performing a remote read to populate.
-	 */
-	//template <typename T>
-	//ftl::write_ref<T> getWritable(const char *uri, T nullvalue);
-	
-	/**
-	 * Make a new memory allocation locally mapped to a given URI. The URI
-	 * must not already exist within the peer group, otherwise a nullptr is
-	 * returned.
+	 * Register a memory area locally mapped to a given URI. The URI
+	 * must not already exist within the peer group.
 	 */
 	template <typename T>
-	ftl::remote_ptr<T> alloc(const char *uri, size_t size) {
-		auto b = _createBlob(uri, size*sizeof(T));
-		return ftl::remote_ptr<T>{b,0};
+	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 free(const char *uri);
-	
+	void unmap(const char *uri);
+
 	template <typename T>
-	void free(ftl::remote_ptr<T> p) {
-		
-	}
+	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> list(const char *partial_uri);
+	std::vector<std::string> search(const char *partial_uri);
 	
-	void addPeer(ftl::net::raw::Socket *s);
+	/**
+	 * 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);
 }
 }
 
diff --git a/p2p-rm/include/ftl/p2p-rm/blob.hpp b/p2p-rm/include/ftl/p2p-rm/blob.hpp
index 3b72fb172..8dbe537f8 100644
--- a/p2p-rm/include/ftl/p2p-rm/blob.hpp
+++ b/p2p-rm/include/ftl/p2p-rm/blob.hpp
@@ -1,33 +1,30 @@
-#ifndef _FTL_P2P_RA_BLOB_HPP_
-#define _FTL_P2P_RA_BLOB_HPP_
+#ifndef _FTL_P2P_RM_BLOB_HPP_
+#define _FTL_P2P_RM_BLOB_HPP_
 
 #include <mutex>
 #include <shared_mutex>
 #include <ftl/net.hpp>
+#include <string>
+#include <vector>
 
 namespace ftl {
 namespace rm {
 
-struct Header {
-	char magic[4];
-	uint32_t version;
-	size_t size;
-	uint32_t format;
-	uint32_t blobid;
-};
-
 /* NOT TO BE USED DIRECTLY */
 struct Blob {
-	Blob();
-	~Blob();
+	//Blob();
+	//~Blob();
 
-	ftl::net::raw::Socket *socket_;
+	std::vector<ftl::net::Socket*> sockets_;
 	char *data_;
 	size_t size_;
+	std::string uri_;
+	uint32_t blobid_;
 	
 	void finished();
-	void write(size_t offset, const char *data, size_t size);
-	void read(size_t offset, char *data, size_t size);
+	//void write(size_t offset, const char *data, size_t size);
+	//void read(size_t offset, char *data, size_t size);
+	void sync(size_t offset, size_t size);
 	
 	mutable std::shared_mutex mutex_;
 };
@@ -35,5 +32,5 @@ struct Blob {
 }
 }
 
-#endif // _FTL_P2P_RA_CACHE_HPP_
+#endif // _FTL_P2P_RM_CACHE_HPP_
 
diff --git a/p2p-rm/include/ftl/p2p-rm/internal.hpp b/p2p-rm/include/ftl/p2p-rm/internal.hpp
new file mode 100644
index 000000000..8519b942b
--- /dev/null
+++ b/p2p-rm/include/ftl/p2p-rm/internal.hpp
@@ -0,0 +1,22 @@
+#ifndef _FTL_P2P_RM_INTERNAL_HPP_
+#define _FTL_P2P_RM_INTERNAL_HPP_
+
+namespace ftl {
+namespace rm {
+
+class Blob;
+
+enum flags_t : uint32_t {
+	FLAG_INTEGER = 1,
+	FLAG_SIGNED = 2,
+	FLAG_TRIVIAL = 4
+};
+
+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);
+
+}; // namespace rm
+}; // namespace ftl
+
+#endif // _FTL_P2P_RM_INTERNAL_HPP_
+
diff --git a/p2p-rm/include/ftl/p2p-rm/remote_ptr.hpp b/p2p-rm/include/ftl/p2p-rm/mapped_ptr.hpp
similarity index 61%
rename from p2p-rm/include/ftl/p2p-rm/remote_ptr.hpp
rename to p2p-rm/include/ftl/p2p-rm/mapped_ptr.hpp
index f7821b525..c6cc04224 100644
--- a/p2p-rm/include/ftl/p2p-rm/remote_ptr.hpp
+++ b/p2p-rm/include/ftl/p2p-rm/mapped_ptr.hpp
@@ -1,5 +1,5 @@
-#ifndef _FTL_P2P_RA_REMOTE_PTR_HPP_
-#define _FTL_P2P_RA_REMOTE_PTR_HPP_
+#ifndef _FTL_P2P_RM_MAPPED_PTR_HPP_
+#define _FTL_P2P_RM_MAPPED_PTR_HPP_
 
 #include "ftl/p2p-rm/blob.hpp"
 
@@ -10,7 +10,7 @@ namespace ftl {
 	template <typename T> struct read_ptr;
 	
 	template <typename T>
-	struct remote_ptr {
+	struct mapped_ptr {
 		rm::Blob *blob;
 		size_t offset;
 		
@@ -31,9 +31,9 @@ namespace ftl {
 		read_ref<T> operator[](ptrdiff_t idx) const;
 		read_ref<T> readable() { return ftl::read_ref<T>(*this); }
 		
-		remote_ptr<T> operator+(std::ptrdiff_t diff) const {
+		mapped_ptr<T> operator+(std::ptrdiff_t diff) const {
 			size_t new_offset = offset + sizeof(T)*diff;
-			return remote_ptr<T>{blob, new_offset};
+			return mapped_ptr<T>{blob, new_offset};
 		}
 		
 		/** Allow pointer casting if a local blob */
@@ -43,24 +43,28 @@ namespace ftl {
 			return NULL;
 		}
 	};
+
+	template <typename T>
+	static const mapped_ptr<T> null_ptr = mapped_ptr<T>{0,0};
 	
 	template <typename T>
 	struct read_ref {
-		remote_ptr<T> ptr_;
+		mapped_ptr<T> ptr_;
 		
 		// Constructor
-		read_ref(remote_ptr<T> ptr) : ptr_(ptr), rlock_(ptr.blob->mutex_) {}
+		read_ref(mapped_ptr<T> ptr) : ptr_(ptr), rlock_(ptr.blob->mutex_) {}
 		
 		bool is_valid() const { return !ptr_.is_null(); }
-		remote_ptr<T> pointer() const { return ptr_; }
+		mapped_ptr<T> pointer() const { return ptr_; }
 		void reset() { rlock_.unlock(); }
 		void finish() { reset(); }
 		
 		operator T() const {
 			//return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
-			T t;
-			ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
-			return t;
+			return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
+			//T t;
+			//ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
+			//return t;
 		}
 		
 		read_ref &operator=(const T &value) {
@@ -73,27 +77,30 @@ namespace ftl {
 	
 	template <typename T>
 	struct write_ref {
-		remote_ptr<T> ptr_;
+		mapped_ptr<T> ptr_;
 		
 		// Constructor
-		write_ref(remote_ptr<T> ptr) : ptr_(ptr), wlock_(ptr.blob->mutex_) {}
+		write_ref(mapped_ptr<T> ptr) : ptr_(ptr), wlock_(ptr.blob->mutex_) {}
 		~write_ref() { ptr_.blob->finished(); }
 		
 		bool is_valid() const { return !ptr_.is_null(); }
-		remote_ptr<T> pointer() const { return ptr_; }
+		mapped_ptr<T> pointer() const { return ptr_; }
 		void reset() { ptr_.blob->finished(); wlock_.unlock(); }
-		void finish() { reset(); }
+		void end() { reset(); }
+		void begin() { wlock_.lock(); }
 		
 		/** Cast to type reads the value */
 		operator T() const {
-			//return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
-			T t;
-			ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
-			return t;
+			return static_cast<T>(ptr_.blob->data_[ptr_.offset]);
+			//T t;
+			//ptr_.blob->read(ptr_.offset, (char*)&t, sizeof(T));
+			//return t;
 		}
 		
 		write_ref &operator=(const T &value) {
-			ptr_.blob->write(ptr_.offset, (char*)(&value), sizeof(T));
+			//ptr_.blob->write(ptr_.offset, (char*)(&value), sizeof(T));
+			*((T*)&ptr_.blob->data_[ptr_.offset]) = value;
+			ptr_.blob->sync(ptr_.offset, sizeof(T));
 			return *this;
 		}
 		
@@ -102,24 +109,24 @@ namespace ftl {
 }
 
 template <typename T>
-ftl::read_ref<T> ftl::remote_ptr<T>::operator*() const {
+ftl::read_ref<T> ftl::mapped_ptr<T>::operator*() const {
 	return ftl::read_ref<T>(*this);
 }
 
 template <typename T>
-ftl::read_ref<T> ftl::remote_ptr<T>::operator[](ptrdiff_t idx) const {
+ftl::read_ref<T> ftl::mapped_ptr<T>::operator[](ptrdiff_t idx) const {
 	return ftl::read_ref<T>(*this + idx);
 }
 
 template <typename T>
-ftl::write_ref<T> ftl::remote_ptr<T>::operator*() {
+ftl::write_ref<T> ftl::mapped_ptr<T>::operator*() {
 	return ftl::write_ref<T>(*this);
 }
 
 template <typename T>
-ftl::write_ref<T> ftl::remote_ptr<T>::operator[](ptrdiff_t idx) {
+ftl::write_ref<T> ftl::mapped_ptr<T>::operator[](ptrdiff_t idx) {
 	return ftl::write_ref<T>(*this + idx);
 }
 
-#endif // _FTL_P2P_RA_REMOTE_PTR_HPP_
+#endif // _FTL_P2P_RM_MAPPED_PTR_HPP_
 
diff --git a/p2p-rm/src/blob.cpp b/p2p-rm/src/blob.cpp
index 89321564a..3b8b1beef 100644
--- a/p2p-rm/src/blob.cpp
+++ b/p2p-rm/src/blob.cpp
@@ -3,31 +3,59 @@
 
 #include "ftl/p2p-rm/blob.hpp"
 
-void ftl::rm::Blob::write(size_t offset, const char *data, size_t size) {
+#define MEMORY_SYNC		0x1000
+
+struct Header {
+	uint32_t blobid;
+	uint32_t offset;
+	uint32_t size;
+};
+
+void ftl::rm::Blob::sync(size_t offset, size_t size) {
+	// Sanity check
+	if (offset + size > size_) throw -1;
+
+	// TODO Delay send to collate many write operations?
+
+	if (sockets_.size() > 0) {
+		Header header{blobid_,static_cast<uint32_t>(offset),static_cast<uint32_t>(size)};
+	
+		// If local, write direct to data_, otherwise send over network
+		for (auto s : sockets_) {
+			// Send over network
+			s->send2(MEMORY_SYNC, std::string((const char*)&header,sizeof(header)),
+				std::string(&data_[offset],size));
+		}
+	}
+}
+
+/*void ftl::rm::Blob::write(size_t offset, const char *data, size_t size) {
 	// Sanity check
 	if (offset + size > size_) throw -1;
 	
 	// If local, write direct to data_, otherwise send over network
 	if (socket_ != NULL) {
+		Header header{blobid_,static_cast<uint32_t>(offset),static_cast<uint32_t>(size)};
+
 		// Send over network
-		//socket_->send(ftl::rm::MEMORY_WRITE, std::string(data,size));
+		socket_->send2(MEMORY_WRITE, std::string((const char*)&header,sizeof(header)),
+			std::string(data,size));
 	} else {
 		// Copy locally
 		memcpy(data_+offset, data, size);
 	}
-}
+}*/
 
-void ftl::rm::Blob::read(size_t offset, char *data, size_t size) {
+/*void ftl::rm::Blob::read(size_t offset, char *data, size_t size) {
 	// Sanity check
 	if (offset + size > size_) throw -1;
 	
 	// If local, write direct to data_, otherwise send over network
 	if (socket_ != NULL) {
-		// Send over network
-		//socket_->send(ftl::rm::MEMORY_WRITE, std::string(data,size));
+		
 	} else {
 		// Copy locally
 		memcpy(data,data_+offset, size);
 	}
-}
+}*/
 
diff --git a/p2p-rm/src/p2prm.cpp b/p2p-rm/src/p2prm.cpp
index 59edc3a8a..1281c51ea 100644
--- a/p2p-rm/src/p2prm.cpp
+++ b/p2p-rm/src/p2prm.cpp
@@ -2,17 +2,18 @@
 
 #include <ftl/uri.hpp>
 #include <map>
+#include <string>
 
 static std::map<std::string, ftl::rm::Blob*> blobs;
 
 void ftl::rm::reset() {
 	for (auto x : blobs) {
-		delete x;
+		delete x.second;
 	}
 	blobs.clear();
 }
 
-ftl::rm::Blob *ftl::rm::_lookupBlob(const char *uri) {
+ftl::rm::Blob *ftl::rm::_lookup(const char *uri) {
 	URI u(uri);
 	if (!u.isValid()) return NULL;
 	if (u.getScheme() != ftl::URI::SCHEME_FTL) return NULL;
@@ -21,7 +22,8 @@ ftl::rm::Blob *ftl::rm::_lookupBlob(const char *uri) {
 	return blobs[u.getBaseURI()];
 }
 
-ftl::rm::Blob *ftl::rm::_createBlob(const char *uri, size_t size) {
+ftl::rm::Blob *ftl::rm::_create(const char *uri, char *addr, size_t size, size_t count,
+		ftl::rm::flags_t flags, const std::string &tname) {
 	URI u(uri);
 	if (!u.isValid()) return NULL;
 	if (u.getScheme() != ftl::URI::SCHEME_FTL) return NULL;
@@ -31,15 +33,12 @@ ftl::rm::Blob *ftl::rm::_createBlob(const char *uri, size_t size) {
 	
 	ftl::rm::Blob *b = new ftl::rm::Blob;
 
-	char *raw = new char[size+sizeof(ftl::rm::Header)];
-
-	b->raw_ = raw;
-	b->header_ = (ftl::rm::Header*)raw;
-	b->data_ = raw+sizeof(ftl::rm::Header);
+	b->data_ = addr;
 	b->size_ = size;
-	b->rawsize = size++sizeof(ftl::rm::Header);
-	b->socket_ = NULL;
+	b->uri_ = std::string(uri);
 	blobs[u.getBaseURI()] = b;
+
+	// TODO : Perhaps broadcast this new allocation?
 	return b;
 }
 
diff --git a/p2p-rm/test/CMakeLists.txt b/p2p-rm/test/CMakeLists.txt
index 25895fabf..17dd869af 100644
--- a/p2p-rm/test/CMakeLists.txt
+++ b/p2p-rm/test/CMakeLists.txt
@@ -1,9 +1,9 @@
 include(CTest)
 enable_testing()
 
-add_executable(remote_ptr EXCLUDE_FROM_ALL
+add_executable(mapped_ptr EXCLUDE_FROM_ALL
 	./tests.cpp
-	./remote_ptr.cpp
+	./mapped_ptr.cpp
 )
 
 add_executable(p2p_rm EXCLUDE_FROM_ALL
@@ -14,9 +14,9 @@ add_executable(p2p_rm EXCLUDE_FROM_ALL
 )
 target_link_libraries(p2p_rm uriparser)
 
-add_test(Remote_ptr remote_ptr)
+add_test(Mapped_ptr mapped_ptr)
 add_test(RM_API p2p_rm)
 
 add_custom_target(tests)
-add_dependencies(tests remote_ptr p2p_rm)
+add_dependencies(tests mapped_ptr p2p_rm)
 
diff --git a/p2p-rm/test/remote_ptr.cpp b/p2p-rm/test/mapped_ptr.cpp
similarity index 73%
rename from p2p-rm/test/remote_ptr.cpp
rename to p2p-rm/test/mapped_ptr.cpp
index 23e20f205..72aaef8a4 100644
--- a/p2p-rm/test/remote_ptr.cpp
+++ b/p2p-rm/test/mapped_ptr.cpp
@@ -1,5 +1,5 @@
 #include "catch.hpp"
-#include <ftl/p2p-rm/remote_ptr.hpp>
+#include <ftl/p2p-rm/mapped_ptr.hpp>
 #include <memory.h>
 
 // Mock the BLOB
@@ -8,16 +8,10 @@ void ftl::rm::Blob::finished() {
 	is_finished = true;
 }
 
-static bool blob_size;
-static const int *blob_data;
-void ftl::rm::Blob::write(size_t offset, const char *data, size_t size) {
-	blob_size = size;
-	blob_data = (const int*)data;
-	memcpy(data_+offset,data,size);
-}
+static bool blob_sync = false;
 
-void ftl::rm::Blob::read(size_t offset, char *data, size_t size) {
-	memcpy(data,data_+offset,size);
+void ftl::rm::Blob::sync(size_t offset, size_t size) {
+	blob_sync = true;
 }
 
 SCENARIO( "Reading from a remote pointer", "[remote_ptr]" ) {
@@ -28,7 +22,7 @@ SCENARIO( "Reading from a remote pointer", "[remote_ptr]" ) {
 	((int*)(blob->data_))[1] = 66;
 	
 	GIVEN( "a valid POD const remote pointer" ) {
-		const ftl::remote_ptr<int> pa{blob,0};
+		const ftl::mapped_ptr<int> pa{blob,0};
 		REQUIRE( *pa == 55 );
 		REQUIRE( pa[0] == 55 );
 		REQUIRE( pa[1] == 66 );
@@ -43,7 +37,7 @@ SCENARIO( "Writing to a remote pointer", "[remote_ptr]" ) {
 	((int*)(blob->data_))[1] = 66;
 	
 	GIVEN( "a valid POD remote pointer" ) {
-		ftl::remote_ptr<int> pa{blob,0};
+		ftl::mapped_ptr<int> pa{blob,0};
 		is_finished = false;
 		*pa = 23;
 		REQUIRE( *pa == 23 );
@@ -54,7 +48,7 @@ SCENARIO( "Writing to a remote pointer", "[remote_ptr]" ) {
 	}
 	
 	GIVEN( "a persistent write_ref" ) {
-		ftl::remote_ptr<int> pa{blob,0};
+		ftl::mapped_ptr<int> pa{blob,0};
 		is_finished = false;
 		auto ra = *pa;
 		
@@ -74,7 +68,7 @@ SCENARIO( "Writing to readonly pointer fails", "[remote_ptr]" ) {
 	((int*)(blob->data_))[1] = 66;
 	
 	GIVEN( "a valid POD const remote pointer" ) {
-		const ftl::remote_ptr<int> pa{blob,0};
+		const ftl::mapped_ptr<int> pa{blob,0};
 		*pa = 23;
 		REQUIRE( *pa == 55 );
 	}
diff --git a/p2p-rm/test/p2p-rm.cpp b/p2p-rm/test/p2p-rm.cpp
index 31a3c9a6c..d124341a3 100644
--- a/p2p-rm/test/p2p-rm.cpp
+++ b/p2p-rm/test/p2p-rm.cpp
@@ -1,59 +1,77 @@
 #include "catch.hpp"
 #include <ftl/p2p-rm.hpp>
 
-SCENARIO( "ftl::rm::alloc()", "[alloc]" ) {
+// --- Mock Socket Send
+
+int ftl::net::raw::Socket::send2(uint32_t service, const std::string &data1, const std::string &data2) {
+	return 0;
+}
+
+// --- End Mock Socket Send
+
+SCENARIO( "ftl::rm::map()", "[map]" ) {
 	ftl::rm::reset();
 	
-	GIVEN( "a valid URI and size" ) {
-		auto r = ftl::rm::alloc<int>("ftl://uti.fi/memory/test0", 10);
+	GIVEN( "a valid URI and array datatype" ) {
+		int data[10];
+		auto m = ftl::rm::map<int[10]>("ftl://uti.fi/memory/test0", &data);
+		REQUIRE( m.is_valid() );
+
+		auto r = ftl::rm::get<int[10]>("ftl://uti.fi/memory/test0");
 		REQUIRE( r.is_valid() );
 		REQUIRE( r.size() == 10*sizeof(int) );
 		REQUIRE( r.is_local() );
 	}
 	
-	GIVEN( "a valid URI and invalid size" ) {
-		auto r = ftl::rm::alloc<int>("ftl://uti.fi/memory/test0", 0);
-		REQUIRE( !r.is_valid() );
+	GIVEN( "a valid URI and invalid data" ) {
+		auto m = ftl::rm::map<int>("ftl://uti.fi/memory/test0", NULL);
+		REQUIRE( !m.is_valid() );
 	}
 	
 	GIVEN( "an empty URI" ) {
-		auto r = ftl::rm::alloc<int>("", 10);
-		REQUIRE( !r.is_valid() );
+		int data;
+		auto m = ftl::rm::map<int>("", &data);
+		REQUIRE( !m.is_valid() );
 	}
 	
 	GIVEN( "an invalid URI" ) {
-		auto r = ftl::rm::alloc<int>("noschema/test", 10);
-		REQUIRE( !r.is_valid() );
+		int data;
+		auto m = ftl::rm::map<int>("noschema/test", &data);
+		REQUIRE( !m.is_valid() );
 	}
 	
 	GIVEN( "an invalid URI schema" ) {
-		auto r = ftl::rm::alloc<int>("http://uti.fi/memory/test0", 10);
-		REQUIRE( !r.is_valid() );
+		int data;
+		auto m = ftl::rm::map<int>("http://uti.fi/memory/test0", &data);
+		REQUIRE( !m.is_valid() );
 	}
 	
 	GIVEN( "an invalid URI path segment" ) {
-		auto r = ftl::rm::alloc<int>("ftl://uti.fi/wrong/test0", 10);
-		REQUIRE( !r.is_valid() );
+		int data;
+		auto m = ftl::rm::map<int>("ftl://uti.fi/wrong/test0", &data);
+		REQUIRE( !m.is_valid() );
 	}
 	
 	GIVEN( "a duplicate URI" ) {
-		auto a = ftl::rm::alloc<int>("ftl://uti.fi/memory/test0", 10);
-		auto b = ftl::rm::alloc<int>("ftl://uti.fi/memory/test0", 10);
-		REQUIRE( a.is_valid() );
+		int data;
+		auto a = ftl::rm::map<int>("ftl://uti.fi/memory/test0", &data);
+		auto b = ftl::rm::map<int>("ftl://uti.fi/memory/test0", &data);
 		REQUIRE( !b.is_valid() );
+		REQUIRE( a.is_valid() );
 	}
 }
 
 SCENARIO( "Getting a read_ref", "[get]" ) {
 	ftl::rm::reset();
-	auto a = ftl::rm::alloc<int>("ftl://uti.fi/memory/test1", 10);
-	REQUIRE( a.is_valid() );
+	int data = 89;
+	auto m = ftl::rm::map<int>("ftl://uti.fi/memory/test1", &data);
+	REQUIRE( m.is_valid() );
 	
 	GIVEN( "a valid URI to local memory" ) {
 		const auto r = ftl::rm::getReadable<int>("ftl://uti.fi/memory/test1");
 		REQUIRE( r.is_valid() );
 		REQUIRE( r.pointer().is_local() );
-		REQUIRE( r.pointer().blob == a.blob );
+		REQUIRE( r == 89 );
 	}
 }
 
-- 
GitLab