From 5592c0ff1429d4d63bc344046789d4d0b0b6c74c Mon Sep 17 00:00:00 2001
From: whh8b <whh8b@git.zephyr-software.com>
Date: Fri, 24 Oct 2014 17:36:29 +0000
Subject: [PATCH] Track free ranges with a std::set.

---
 .gitattributes         |   1 -
 include/memory_space.h |  25 ++++-----
 src/memory_space.cpp   | 112 ++++++-----------------------------------
 src/zipr.cpp           |   4 +-
 test/MemorySpace.cpp   |   7 +--
 test/MemorySpace.o     |   0
 6 files changed, 31 insertions(+), 118 deletions(-)
 delete mode 100644 test/MemorySpace.o

diff --git a/.gitattributes b/.gitattributes
index 7f14fc898..e98d7ba81 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -33,7 +33,6 @@ src/zipr.cpp -text
 src/zipr_options.cpp -text
 src/zipr_stats.cpp -text
 test/MemorySpace.cpp -text
-test/MemorySpace.o -text
 third_party/ELFIO/elfio-2.2/AUTHORS -text
 third_party/ELFIO/elfio-2.2/COPYING -text
 third_party/ELFIO/elfio-2.2/ChangeLog -text
diff --git a/include/memory_space.h b/include/memory_space.h
index 1b466bdc5..3c1bc4489 100644
--- a/include/memory_space.h
+++ b/include/memory_space.h
@@ -33,38 +33,39 @@
 
 class Options_t;
 
+struct Range_tCompare
+{
+	bool operator()(const Range_t first, const Range_t second)
+	{
+		return first.GetEnd() < second.GetStart();
+	}
+};
+
 class MemorySpace_t
 {
 	public:
-		MemorySpace_t():m_opts(NULL),m_is_sorted(false),free_ranges_ptrs(NULL) { }
-		MemorySpace_t(Options_t *opts):m_opts(opts),m_is_sorted(false),free_ranges_ptrs(NULL) { }
+		MemorySpace_t():m_opts(NULL) { }
+		MemorySpace_t(Options_t *opts):m_opts(opts) { }
 
 		// range operatations
 		void SplitFreeRange(RangeAddress_t addr);
 		void MergeFreeRange(RangeAddress_t addr);
-		std::list<Range_t>::iterator FindFreeRange(RangeAddress_t addr);
+		std::set<Range_t>::iterator FindFreeRange(RangeAddress_t addr);
 		Range_t GetFreeRange(int size);
 		void AddFreeRange(Range_t newRange);
 
 		// queries about free areas.
 		bool AreBytesFree(RangeAddress_t addr, int num_bytes);
 		bool IsByteFree(RangeAddress_t addr);
-		bool IsValidRange(std::list<Range_t>::iterator it);
+		bool IsValidRange(std::set<Range_t>::iterator it);
 
 		int GetRangeCount();
 
-		void Sort();
-
 		void PrintMemorySpace(std::ostream &out);
 	protected:
-		std::list<Range_t> free_ranges;   // keep ordered
+		std::set<Range_t, Range_tCompare> free_ranges;   // keep ordered
 		Options_t *m_opts;
-		bool m_is_sorted;
 	private:
-		std::list<Range_t>::iterator FindFreeRangeB(int startIndex, int stopIndex,
-			RangeAddress_t addr);
-		std::list<Range_t>::iterator **free_ranges_ptrs;
-		int free_ranges_ptrs_size;
 };
 
 #endif
diff --git a/src/memory_space.cpp b/src/memory_space.cpp
index 6195896f6..7c16f9bec 100644
--- a/src/memory_space.cpp
+++ b/src/memory_space.cpp
@@ -6,44 +6,12 @@
 using namespace zipr;
 using namespace std;
 
-static bool range_compare(const Range_t first, const Range_t second)
-{
-	return first.GetStart() < second.GetStart();
-}
-
-void MemorySpace_t::Sort()
-{
-	int i = 0;
-	list<Range_t>::iterator it;
-
-	if (free_ranges_ptrs != NULL)
-	{
-		for (int j = 0; j<free_ranges_ptrs_size; j++)
-			delete free_ranges_ptrs[j];
-		free(free_ranges_ptrs);
-	}
-
-	free_ranges.sort(range_compare);
-
-	free_ranges_ptrs = (std::list<Range_t>::iterator**)malloc(sizeof(std::list<Range_t>::iterator*)*free_ranges.size());
-	for(i=0,it=free_ranges.begin();it!=free_ranges.end();++it,++i)
-	{
-		free_ranges_ptrs[i] = new std::list<Range_t>::iterator(it);
-	}
-
-	m_is_sorted = true;
-	free_ranges_ptrs_size = free_ranges.size();
-}
-
 void MemorySpace_t::SplitFreeRange(RangeAddress_t addr)
 {
-	list<Range_t>::iterator it=FindFreeRange(addr);
+	std::set<Range_t>::iterator it=FindFreeRange(addr);
 	assert(IsValidRange(it));
 
 	Range_t r=*it;
-
-	m_is_sorted = false;
-
 	if(r.GetStart()==r.GetEnd())
 	{
 		assert(addr==r.GetEnd());
@@ -51,19 +19,19 @@ void MemorySpace_t::SplitFreeRange(RangeAddress_t addr)
 	}
 	else if(addr==r.GetStart())
 	{
-		free_ranges.insert(it, Range_t(r.GetStart()+1, r.GetEnd()));
 		free_ranges.erase(it);
+		free_ranges.insert(Range_t(r.GetStart()+1, r.GetEnd()));
 	}
 	else if(addr==r.GetEnd())
 	{
-		free_ranges.insert(it, Range_t(r.GetStart(), r.GetEnd()-1));
 		free_ranges.erase(it);
+		free_ranges.insert(Range_t(r.GetStart(), r.GetEnd()-1));
 	}
 	else // split range 
 	{
-		free_ranges.insert(it, Range_t(r.GetStart(), addr-1));
-		free_ranges.insert(it, Range_t(addr+1, r.GetEnd()));
 		free_ranges.erase(it);
+		free_ranges.insert(Range_t(r.GetStart(), addr-1));
+		free_ranges.insert(Range_t(addr+1, r.GetEnd()));
 	}
 }
 
@@ -80,9 +48,7 @@ void MemorySpace_t::MergeFreeRange(RangeAddress_t addr)
 
 	Range_t nr(addr, addr);
 	bool merged = false;
-	list<Range_t>::iterator it=free_ranges.begin();
-
-	m_is_sorted = false;
+	std::set<Range_t>::iterator it=free_ranges.begin();
 
 	for(;it!=free_ranges.end();++it)
 	{
@@ -164,8 +130,8 @@ void MemorySpace_t::MergeFreeRange(RangeAddress_t addr)
 				printf("nr: %p to %p\n", (void*)nr.GetStart(), (void*)nr.GetEnd());
 				printf("to: %p to %p\n", (void*)merged_range.GetStart(), (void*)merged_range.GetEnd());
 			}
-			free_ranges.insert(it, merged_range);
 			free_ranges.erase(it);
+			free_ranges.insert(merged_range);
 			merged = true;
 			break;
 		}
@@ -173,13 +139,13 @@ void MemorySpace_t::MergeFreeRange(RangeAddress_t addr)
 
 	if (!merged)
 	{
-		free_ranges.push_back(nr);
+		free_ranges.insert(nr);
 	}
 }
 
 void MemorySpace_t::PrintMemorySpace(std::ostream &out)
 {
-	for( list<Range_t>::iterator it=free_ranges.begin();
+	for( std::set<Range_t>::iterator it=free_ranges.begin();
 		it!=free_ranges.end();
 		++it)
 	{
@@ -188,67 +154,20 @@ void MemorySpace_t::PrintMemorySpace(std::ostream &out)
 	}
 }
 
-std::list<Range_t>::iterator MemorySpace_t::FindFreeRangeB(
-	int startIndex,
-	int stopIndex,
-	RangeAddress_t addr)
+std::set<Range_t>::iterator MemorySpace_t::FindFreeRange(RangeAddress_t addr)
 {
-	std::list<Range_t>::iterator *start = free_ranges_ptrs[startIndex];
-	std::list<Range_t>::iterator *stop = free_ranges_ptrs[stopIndex];
-	Range_t startRange = **start;
-	Range_t stopRange = **stop;
-	if (startIndex == stopIndex)
-		return free_ranges.end();
-	else if (startRange.GetStart() <= addr && addr <=startRange.GetEnd())
-		return *start;
-	else if (stopRange.GetStart() <= addr && addr <=stopRange.GetEnd())
-		return *stop;
-	else
-	{
-		/*
-		 * mid startIndex - stopIndex 
-		 */
-		int midIndex = startIndex + ((stopIndex-startIndex)/2);
-		Range_t mid = **(free_ranges_ptrs[midIndex]);
-
-		if (mid.GetStart() <= addr && addr <=mid.GetEnd())
-			return *free_ranges_ptrs[midIndex];
-		else if (addr <= mid.GetStart()) {
-			return FindFreeRangeB(startIndex, std::max(0, std::max(--midIndex, startIndex)), addr);
-		}
-		else
-		{
-			return FindFreeRangeB(std::min(++midIndex, stopIndex), stopIndex, addr);
-		}
-	}
-}
-
-std::list<Range_t>::iterator MemorySpace_t::FindFreeRange(RangeAddress_t addr)
-{
-	if (m_is_sorted)
-	{
-		return FindFreeRangeB(0, free_ranges.size()-1, addr);
-	}
-
-	for( list<Range_t>::iterator it=free_ranges.begin();
-		it!=free_ranges.end();
-		++it)
-	{
-		Range_t r=*it;
-		if(r.GetStart() <= addr && addr <=r.GetEnd())
-			return it;
-	}
-	return free_ranges.end();
+	std::set<Range_t>::iterator freer = free_ranges.find(Range_t(addr, addr)); 
+	return freer;
 }
 
-bool MemorySpace_t::IsValidRange(std::list<Range_t>::iterator it)
+bool MemorySpace_t::IsValidRange(std::set<Range_t>::iterator it)
 {
 	return it!=free_ranges.end();
 }
 
 Range_t MemorySpace_t::GetFreeRange(int size)
 {
-	for( list<Range_t>::iterator it=free_ranges.begin();
+	for( std::set<Range_t>::iterator it=free_ranges.begin();
 		it!=free_ranges.end();
 		++it)
 	{
@@ -277,8 +196,7 @@ bool MemorySpace_t::IsByteFree(RangeAddress_t addr)
 
 void MemorySpace_t::AddFreeRange(Range_t newRange)
 {
-	m_is_sorted = false;
-	free_ranges.push_back(Range_t(newRange.GetStart(), newRange.GetEnd()));
+	free_ranges.insert(Range_t(newRange.GetStart(), newRange.GetEnd()));
 }
 int MemorySpace_t::GetRangeCount()
 {
diff --git a/src/zipr.cpp b/src/zipr.cpp
index 55591c68e..5ebcfe0db 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -95,7 +95,6 @@ void Zipr_t::CreateBinaryFile(const std::string &name)
 			printf("Going to Re PreReserve2ByteJumpTargets.\n");
 			PreReserve2ByteJumpTargets();
 		}
-		memory_space.Sort();
 	}
 
 
@@ -110,7 +109,6 @@ void Zipr_t::CreateBinaryFile(const std::string &name)
 	UpdateCallbacks();
 
 	m_stats->total_free_ranges = memory_space.GetRangeCount();
-	memory_space.Sort();
 
 	// write binary file to disk 
 	OutputBinaryFile(name);
@@ -1267,7 +1265,7 @@ void Zipr_t::OutputBinaryFile(const string &name)
 		perror( "void Zipr_t::OutputBinaryFile(const string &name)");
 
 	// first byte of this range is the last used byte.
-	list<Range_t>::iterator it=memory_space.FindFreeRange((RangeAddress_t) -1);
+	std::set<Range_t>::iterator it=memory_space.FindFreeRange((RangeAddress_t) -1);
 	assert(memory_space.IsValidRange(it));
 
 	RangeAddress_t end_of_new_space=it->GetStart();
diff --git a/test/MemorySpace.cpp b/test/MemorySpace.cpp
index 0ec450bbb..88d9101cc 100644
--- a/test/MemorySpace.cpp
+++ b/test/MemorySpace.cpp
@@ -33,7 +33,7 @@ bool TestSplitMemorySpace()
 
 bool TestBinarySearchMaxRange()
 {
-	std::list<Range_t>::iterator foundRange;
+	std::set<Range_t>::iterator foundRange;
 	Options_t opts;
 	opts.SetVerbose(true);
 	MemorySpace_t m(&opts);
@@ -46,7 +46,6 @@ bool TestBinarySearchMaxRange()
 	m.SplitFreeRange(375);
 	m.SplitFreeRange(385);
 
-	m.Sort();
 
 	cout << "Looking for 0x" << std::hex << (RangeAddress_t)-1 << ":" << endl;
 	foundRange = m.FindFreeRange(RangeAddress_t((RangeAddress_t)-1));
@@ -59,7 +58,7 @@ bool TestBinarySearchMaxRange()
 
 bool TestBinarySearch()
 {
-	std::list<Range_t>::iterator foundRange;
+	std::set<Range_t>::iterator foundRange;
 	Options_t opts;
 	opts.SetVerbose(true);
 	MemorySpace_t m(&opts);
@@ -72,7 +71,6 @@ bool TestBinarySearch()
 	m.SplitFreeRange(400);
 
 	m.PrintMemorySpace(cout);
-	m.Sort();
 	m.PrintMemorySpace(cout);
 	
 	cout << "Looking for 0x" << std::hex << 258 << ":" << endl;
@@ -142,7 +140,6 @@ bool TestSort()
 	m.MergeFreeRange(315);
 
 	m.PrintMemorySpace(cout);
-	m.Sort();
 	m.PrintMemorySpace(cout);
 
 	return true;
diff --git a/test/MemorySpace.o b/test/MemorySpace.o
deleted file mode 100644
index e69de29bb..000000000
-- 
GitLab