From 6614dc2b99fc100730266111b254e43c44cd92d8 Mon Sep 17 00:00:00 2001
From: Pietro Incardona <i-bird@localhost.localdomain>
Date: Fri, 18 Mar 2016 22:30:53 +0100
Subject: [PATCH] Added buffered heap memory

---
 src/memory/BHeapMemory.hpp           | 139 +++++++++++++++++++++++++++
 src/memory/HeapMemory.cpp            |   1 -
 src/memory/HeapMemory.hpp            |  32 +++---
 src/memory/HeapMemory_unit_tests.hpp |  65 ++++++++++++-
 4 files changed, 220 insertions(+), 17 deletions(-)
 create mode 100644 src/memory/BHeapMemory.hpp

diff --git a/src/memory/BHeapMemory.hpp b/src/memory/BHeapMemory.hpp
new file mode 100644
index 0000000..71a54c6
--- /dev/null
+++ b/src/memory/BHeapMemory.hpp
@@ -0,0 +1,139 @@
+/*
+ * RHeapMempory.hpp
+ *
+ *  Created on: Aug 17, 2014
+ *      Author: Pietro Incardona
+ */
+
+
+#ifndef BHEAP_MEMORY_HPP
+#define BHEAP_MEMORY_HPP
+
+#include "config.h"
+#include "memory.hpp"
+#include <cstddef>
+#include <cstdint>
+#include <iostream>
+
+typedef unsigned char byte;
+
+#define MEM_ALIGNMENT 32
+
+/**
+ * \brief It is like HeapMemory but buffered
+ *
+ * The concept of buffer is different from allocated memory. The buffer size can be <= the allocated memory
+ *
+ * It differs from HeapMemory in resize behavior.
+ *
+ * In the case of HeapMemory if you try to shrink the memory nothing happen to the allocated memory.
+ * To destroy the internal memory you must use destroy.
+ *
+ * BHeapMemory does not shrink the memory, but it shrink the buffer size. size will always return the buffer size
+ *
+ * ### Allocate memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp BAllocate some memory and fill with data
+ *
+ * ### Resize memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp BResize the memory
+ *
+ * ### Shrink memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp BShrink memory
+ *
+ */
+class BHeapMemory : public HeapMemory
+{
+	size_t buf_sz;
+
+public:
+
+	// Copy the Heap memory
+	BHeapMemory(const BHeapMemory & mem)
+	:HeapMemory(mem)
+	{
+	}
+
+	BHeapMemory(BHeapMemory && mem) noexcept
+	:HeapMemory((HeapMemory &&)mem)
+	{
+		buf_sz = mem.buf_sz;
+	}
+
+	//! Constructor, we choose a default alignment of 32 for avx
+	BHeapMemory()
+	:HeapMemory()
+	{};
+
+	virtual ~BHeapMemory()
+	{
+	};
+
+	/*! \brief allocate the memory
+	 *
+	 * Resize the allocated memory, if request is smaller than the allocated memory
+	 * is not resized
+	 *
+	 * \param sz size
+	 * \return true if the resize operation complete correctly
+	 *
+	 */
+	virtual bool allocate(size_t sz)
+	{
+		bool ret = HeapMemory::allocate(sz);
+
+		if (ret == true)
+			buf_sz = sz;
+
+		return ret;
+	}
+
+	/*! \brief Resize the allocated memory
+	 *
+	 * Resize the allocated memory, if request is smaller than the allocated memory
+	 * is not resized
+	 *
+	 * \param sz size
+	 * \return true if the resize operation complete correctly
+	 *
+	 */
+	virtual bool resize(size_t sz)
+	{
+		bool ret = HeapMemory::resize(sz);
+
+		// if the allocated memory is enough, do not resize
+		if (ret == true)
+			buf_sz = sz;
+
+		return ret;
+	}
+
+	/*! \brief Resize the buffer size
+	 *
+	 * Resize the buffer size,
+	 *
+	 * \param sz size
+	 * \return true if the resize operation complete correctly
+	 *
+	 */
+	virtual size_t size()
+	{
+		return buf_sz;
+	}
+
+	/*! \brief Return the memory size
+	 *
+	 *
+	 * \return The allocated memory size
+	 *
+	 */
+	size_t msize()
+	{
+		return HeapMemory::size();
+	}
+};
+
+
+#endif
diff --git a/src/memory/HeapMemory.cpp b/src/memory/HeapMemory.cpp
index 4dd71c9..1901fa7 100644
--- a/src/memory/HeapMemory.cpp
+++ b/src/memory/HeapMemory.cpp
@@ -163,7 +163,6 @@ size_t HeapMemory::size() const
  * \return true if the resize operation complete correctly
  *
  */
-
 bool HeapMemory::resize(size_t sz)
 {
 	// if the allocated memory is enough, do not resize
diff --git a/src/memory/HeapMemory.hpp b/src/memory/HeapMemory.hpp
index 5238f5e..82fba22 100644
--- a/src/memory/HeapMemory.hpp
+++ b/src/memory/HeapMemory.hpp
@@ -5,21 +5,6 @@
  *      Author: Pietro Incardona
  */
 
-/**
- * \brief This class allocate, and destroy CPU memory
- *
- * Usage:
- *
- * HeapMemory m = new HeapMemory();
- *
- * m.allocate(1000*sizeof(int));
- * int * ptr = m.getPointer();
- * ptr[999] = 1000;
- * ....
- *
- *
- */
-
 #ifndef HEAP_MEMORY_HPP
 #define HEAP_MEMORY_HPP
 
@@ -34,6 +19,23 @@ typedef unsigned char byte;
 #define MEM_ALIGNMENT 32
 
 
+/**
+ * \brief This class allocate, and destroy CPU memory
+ *
+ *
+ * ### Allocate memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp Allocate some memory and fill with data
+ *
+ * ### Resize memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp Resize the memory
+ *
+ * ### Shrink memory
+ *
+ * \snippet HeapMemory_unit_tests.hpp Shrink memory
+ *
+ */
 class HeapMemory : public memory
 {
 	//! memory alignment
diff --git a/src/memory/HeapMemory_unit_tests.hpp b/src/memory/HeapMemory_unit_tests.hpp
index 447da6c..54df299 100644
--- a/src/memory/HeapMemory_unit_tests.hpp
+++ b/src/memory/HeapMemory_unit_tests.hpp
@@ -11,6 +11,7 @@
 #include "config.h"
 
 #include "memory/HeapMemory.hpp"
+#include "memory/BHeapMemory.hpp"
 #ifdef NVCC
 #include "memory/CudaMemory.cuh"
 #endif
@@ -56,6 +57,14 @@ template<typename T> void test()
 		BOOST_REQUIRE_EQUAL(ptr2[i],c);
 	}
 
+	//! [Shrink memory]
+
+	mem.resize(1);
+	BOOST_REQUIRE_EQUAL(mem.size(),SECOND_ALLOCATION);
+
+	//! [Shrink memory]
+
+
 	{
 	//! [Copy memory]
 	T src;
@@ -101,7 +110,49 @@ template<typename T> void test()
 	}
 }
 
-BOOST_AUTO_TEST_CASE( use )
+template<typename T> void Btest()
+{
+	//! [BAllocate some memory and fill with data]
+	T mem;
+
+	mem.allocate(FIRST_ALLOCATION);
+
+	BOOST_REQUIRE_EQUAL(mem.size(),FIRST_ALLOCATION);
+
+	// get the pointer of the allocated memory and fill
+
+	unsigned char * ptr = (unsigned char *)mem.getPointer();
+	for (size_t i = 0 ; i < mem.size() ; i++)
+		ptr[i] = i;
+
+	//! [BAllocate some memory and fill with data]
+
+	//! [BResize the memory]
+	mem.resize(SECOND_ALLOCATION);
+
+	unsigned char * ptr2 = (unsigned char *)mem.getPointer();
+
+	BOOST_REQUIRE_EQUAL(mem.size(),SECOND_ALLOCATION);
+	BOOST_REQUIRE_EQUAL(mem.isInitialized(),false);
+
+	//! [BResize the memory]
+
+	// check that the data are retained
+	for (size_t i = 0 ; i < FIRST_ALLOCATION ; i++)
+	{
+		unsigned char c = i;
+		BOOST_REQUIRE_EQUAL(ptr2[i],c);
+	}
+
+	//! [BShrink memory]
+
+	mem.resize(1);
+	BOOST_REQUIRE_EQUAL(mem.size(),1ul);
+
+	//! [BShrink memory]
+}
+
+BOOST_AUTO_TEST_CASE( use_heap_memory )
 {
 	test<HeapMemory>();
 #ifdef CUDA_GPU
@@ -109,6 +160,18 @@ BOOST_AUTO_TEST_CASE( use )
 #endif
 }
 
+BOOST_AUTO_TEST_CASE( use_cuda_memory )
+{
+	test<HeapMemory>();
+#ifdef CUDA_GPU
+	test<CudaMemory>();
+#endif
+}
+
+BOOST_AUTO_TEST_CASE( use_bheap_memory )
+{
+	Btest<BHeapMemory>();
+}
 
 BOOST_AUTO_TEST_SUITE_END()
 
-- 
GitLab