From 379d79f53bc44b23f7cbb97fe19263a3160d066f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Radovan=20=C4=8Cerven=C3=BD?= <radovan.cerveny@gmail.com>
Date: Mon, 1 Feb 2016 21:50:40 +0100
Subject: [PATCH] added memory measurement tests, fixed bugs in memory
 measurement

---
 .../src/measurements/MeasurementEngine.cpp    | 11 +++++++--
 .../src/measurements/MeasurementEngine.hpp    |  1 +
 .../src/measurements/MeasurementFrames.hpp    |  8 +++----
 .../src/measurements/MemoryDataFrame.cpp      | 23 +++++++++++++++----
 alib2algo/src/measurements/measurements.hpp   |  4 ++++
 .../measurements/MeasurementsTest.cpp         | 22 +++++++++++++++++-
 .../test-src/measurements/MeasurementsTest.h  |  6 +++--
 7 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/alib2algo/src/measurements/MeasurementEngine.cpp b/alib2algo/src/measurements/MeasurementEngine.cpp
index c805f77983..c33e023013 100644
--- a/alib2algo/src/measurements/MeasurementEngine.cpp
+++ b/alib2algo/src/measurements/MeasurementEngine.cpp
@@ -9,8 +9,7 @@ namespace measurements {
 MeasurementEngine MeasurementEngine::INSTANCE;
 
 MeasurementEngine::MeasurementEngine ( ) {
-	frames.emplace_back ( std::move ( "Root" ), measurements::Type::ROOT, 0 );
-	frame_idx_stack.push_back ( 0 );
+	reset_measurements ( );
 }
 
 void MeasurementEngine::push_measurement_frame ( std::string frame_name, measurements::Type frame_type ) {
@@ -36,6 +35,14 @@ void MeasurementEngine::pop_measurement_frame ( ) {
 	MemoryDataFrame::update ( current_idx, frames );
 }
 
+void MeasurementEngine::reset_measurements ( ) {
+	frames.clear ( );
+	frame_idx_stack.clear ( );
+
+	frames.emplace_back ( std::move ( "Root" ), measurements::Type::ROOT, 0 );
+	frame_idx_stack.push_back ( 0 );
+}
+
 void MeasurementEngine::memory_hint ( MemoryHint mh ) {
 	if ( ( frame_idx_stack.size ( ) == 0 ) || ( frames[frame_idx_stack.back ( )].type == measurements::Type::ROOT ) ) return;
 
diff --git a/alib2algo/src/measurements/MeasurementEngine.hpp b/alib2algo/src/measurements/MeasurementEngine.hpp
index 69590f048f..f45419bda9 100644
--- a/alib2algo/src/measurements/MeasurementEngine.hpp
+++ b/alib2algo/src/measurements/MeasurementEngine.hpp
@@ -22,6 +22,7 @@ class MeasurementEngine {
 public:
 	void push_measurement_frame ( std::string, measurements::Type );
 	void pop_measurement_frame ( );
+	void reset_measurements ( );
 
 	void memory_hint ( MemoryHint );
 
diff --git a/alib2algo/src/measurements/MeasurementFrames.hpp b/alib2algo/src/measurements/MeasurementFrames.hpp
index 016aaf24cc..65c91d98c3 100644
--- a/alib2algo/src/measurements/MeasurementFrames.hpp
+++ b/alib2algo/src/measurements/MeasurementFrames.hpp
@@ -23,11 +23,11 @@ struct MemoryHint {
 };
 
 struct MemoryDataFrame {
-	unsigned start_heap_usage;
-	unsigned end_heap_usage;
-	unsigned high_watermark;
+	size_t start_heap_usage;
+	size_t end_heap_usage;
+	size_t high_watermark;
 
-	unsigned current_heap_usage;
+	size_t current_heap_usage;
 
 	std::string to_string ( );
 	// void		to_xml ( );
diff --git a/alib2algo/src/measurements/MemoryDataFrame.cpp b/alib2algo/src/measurements/MemoryDataFrame.cpp
index d45f20f861..7356331580 100644
--- a/alib2algo/src/measurements/MemoryDataFrame.cpp
+++ b/alib2algo/src/measurements/MemoryDataFrame.cpp
@@ -4,6 +4,8 @@
 
 #include "MeasurementFrames.hpp"
 
+#include <iostream>
+
 using namespace std::chrono;
 
 namespace measurements {
@@ -12,17 +14,25 @@ void MemoryDataFrame::init ( unsigned frame_idx, std::vector < MeasurementFrame
 	MeasurementFrame & current_frame = frames[frame_idx];
 	MeasurementFrame & parent_frame	 = frames[current_frame.parent_idx];
 
-	current_frame.memory.start_heap_usage = parent_frame.memory.current_heap_usage;
-	current_frame.memory.current_heap_usage = parent_frame.memory.current_heap_usage;
-	current_frame.memory.high_watermark = parent_frame.memory.current_heap_usage;
+	if ( parent_frame.type != measurements::Type::ROOT ) {
+		current_frame.memory.start_heap_usage = parent_frame.memory.current_heap_usage;
+		current_frame.memory.current_heap_usage = parent_frame.memory.current_heap_usage;
+		current_frame.memory.high_watermark = parent_frame.memory.current_heap_usage;
+	}
 }
 
 void MemoryDataFrame::update ( unsigned frame_idx, std::vector < MeasurementFrame > & frames ) {
 	MeasurementFrame & current_frame = frames[frame_idx];
 	MeasurementFrame & parent_frame	 = frames[current_frame.parent_idx];
 
-	parent_frame.memory.current_heap_usage = current_frame.memory.current_heap_usage;
 	current_frame.memory.end_heap_usage = current_frame.memory.current_heap_usage;
+
+	 // if we end up with more memory from children, adjust watermark
+	if ( current_frame.memory.current_heap_usage > current_frame.memory.high_watermark )
+		current_frame.memory.high_watermark = current_frame.memory.current_heap_usage;
+
+	if ( parent_frame.type != measurements::Type::ROOT )
+		parent_frame.memory.current_heap_usage = current_frame.memory.current_heap_usage;
 }
 
 void MemoryDataFrame::hint ( unsigned frame_idx, std::vector < MeasurementFrame > & frames, MemoryHint hint ) {
@@ -32,7 +42,10 @@ void MemoryDataFrame::hint ( unsigned frame_idx, std::vector < MeasurementFrame
 	switch ( hint.type ) {
 	case MemoryHint::Type::NEW:
 		current_frame.memory.current_heap_usage += hint.size;
-		current_frame.memory.high_watermark = std::max ( current_frame.memory.high_watermark, current_frame.memory.current_heap_usage );
+
+		if ( current_frame.memory.current_heap_usage > current_frame.memory.high_watermark )
+			current_frame.memory.high_watermark = current_frame.memory.current_heap_usage;
+
 		break;
 
 	case MemoryHint::Type::DELETE:
diff --git a/alib2algo/src/measurements/measurements.hpp b/alib2algo/src/measurements/measurements.hpp
index ccd80db859..47c7cba0e1 100644
--- a/alib2algo/src/measurements/measurements.hpp
+++ b/alib2algo/src/measurements/measurements.hpp
@@ -17,6 +17,10 @@ void end ( ) {
 	MeasurementEngine::INSTANCE.pop_measurement_frame ( );
 }
 
+void reset ( ) {
+	MeasurementEngine::INSTANCE.reset_measurements ( );
+}
+
 void memory_hint ( MemoryHint mh ) {
 	MeasurementEngine::INSTANCE.memory_hint ( std::move ( mh ) );
 }
diff --git a/alib2algo/test-src/measurements/MeasurementsTest.cpp b/alib2algo/test-src/measurements/MeasurementsTest.cpp
index 253c94cfb5..5a93d292f9 100644
--- a/alib2algo/test-src/measurements/MeasurementsTest.cpp
+++ b/alib2algo/test-src/measurements/MeasurementsTest.cpp
@@ -7,12 +7,13 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( MeasurementsTest, "measurements" );
 CPPUNIT_TEST_SUITE_REGISTRATION ( MeasurementsTest );
 
 void MeasurementsTest::setUp ( ) {
+	measurements::reset ( );
 }
 
 void MeasurementsTest::tearDown ( ) {
 }
 
-void MeasurementsTest::testMeasurements ( ) {
+void MeasurementsTest::testTimeMeasurements ( ) {
 	measurements::start ( "global", measurements::Type::OVERALL );
 		measurements::start ( "init", measurements::Type::INIT );
 		std::this_thread::sleep_for ( std::chrono::milliseconds ( 100 ) );
@@ -40,3 +41,22 @@ void MeasurementsTest::testMeasurements ( ) {
 	measurements::print_as_list ( std::cout );
 	std::cout << std::endl;
 }
+
+void MeasurementsTest::testMemoryMeasurements ( ) {
+
+	measurements::start ( "chunk1", measurements::Type::MAIN );
+	measurements::end ( );
+
+	measurements::start ( "chunk2", measurements::Type::MAIN );
+		int * foo = new int[500];
+		measurements::start ( "chunk21", measurements::Type::MAIN );
+			int * bar = new int[500];
+		measurements::end ( );
+		delete foo;
+		delete bar;
+	measurements::end ( );
+
+	measurements::print_as_list ( std::cout );
+	std::cout << std::endl;
+}
+
diff --git a/alib2algo/test-src/measurements/MeasurementsTest.h b/alib2algo/test-src/measurements/MeasurementsTest.h
index 067898bf10..a5782b1518 100644
--- a/alib2algo/test-src/measurements/MeasurementsTest.h
+++ b/alib2algo/test-src/measurements/MeasurementsTest.h
@@ -5,14 +5,16 @@
 
 class MeasurementsTest : public CppUnit::TestFixture {
   CPPUNIT_TEST_SUITE ( MeasurementsTest );
-  CPPUNIT_TEST ( testMeasurements );
+  CPPUNIT_TEST ( testTimeMeasurements );
+  CPPUNIT_TEST ( testMemoryMeasurements );
   CPPUNIT_TEST_SUITE_END ( );
 
 public:
   void setUp ( );
   void tearDown ( );
 
-  void testMeasurements ( );
+  void testTimeMeasurements ( );
+  void testMemoryMeasurements ( );
 };
 
 #endif // MEASUREMENTS_TEST_H_
-- 
GitLab