Add linked list and benchmarks.
This commit is contained in:
		
							parent
							
								
									e5d93a083f
								
							
						
					
					
						commit
						afc2413568
					
				| 
						 | 
				
			
			@ -1,2 +1,5 @@
 | 
			
		|||
ACLOCAL_AMFLAGS =       -I m4
 | 
			
		||||
SUBDIRS =               src data
 | 
			
		||||
 | 
			
		||||
benchmarks:
 | 
			
		||||
	cd src && make benchmarks
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
cd src && make benchmarks
 | 
			
		||||
make[1]: Entering directory '/home/build/ods/src'
 | 
			
		||||
LIST BENCHMARKS
 | 
			
		||||
SimpList @ 1000000 ops: 1.96438s
 | 
			
		||||
VList @ 1000000 ops: 1.91541s
 | 
			
		||||
LinkedList @ 1000000 ops: 4.02349s
 | 
			
		||||
 | 
			
		||||
USET BENCHMARKS
 | 
			
		||||
SimpUSet @ 1000000 ops: 1.19608s
 | 
			
		||||
 | 
			
		||||
SSET BENCHMARKS
 | 
			
		||||
SimpSSet @ 1000000 ops: 1.29316s
 | 
			
		||||
make[1]: Leaving directory '/home/build/ods/src'
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,8 @@ AC_CONFIG_SRCDIR([src/ch01ex01.cc])
 | 
			
		|||
AC_CONFIG_FILES([Makefile src/Makefile data/Makefile])
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
: ${CXXFLAGS=""}
 | 
			
		||||
 | 
			
		||||
PKG_PROG_PKG_CONFIG
 | 
			
		||||
AC_CHECK_HEADERS
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
AM_CPPFLAGS  =  -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align
 | 
			
		||||
AM_CPPFLAGS +=  -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror
 | 
			
		||||
AM_CPPFLAGS +=  -Wunused-variable -std=c++17 -D_XOPEN_SOURCE -O0 -g -I.
 | 
			
		||||
AM_CPPFLAGS +=  -fno-elide-constructors -Weffc++
 | 
			
		||||
AM_CPPFLAGS +=  -fno-elide-constructors -Weffc++ -fPIC
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS :=		ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \
 | 
			
		||||
			list_bench uset_bench sset_bench
 | 
			
		||||
| 
						 | 
				
			
			@ -13,3 +13,15 @@ ch01ex06_SOURCES :=	ch01ex06.cc
 | 
			
		|||
list_bench_SOURCES :=	list_bench.cc
 | 
			
		||||
uset_bench_SOURCES :=	uset_bench.cc
 | 
			
		||||
sset_bench_SOURCES :=	sset_bench.cc
 | 
			
		||||
 | 
			
		||||
BENCH_OPS ?=	1000000
 | 
			
		||||
 | 
			
		||||
benchmarks: list_bench uset_bench sset_bench
 | 
			
		||||
	@echo "LIST BENCHMARKS"
 | 
			
		||||
	@./list_bench $(BENCH_OPS) > /dev/null
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "USET BENCHMARKS"
 | 
			
		||||
	@./uset_bench $(BENCH_OPS) > /dev/null
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "SSET BENCHMARKS"
 | 
			
		||||
	@./sset_bench $(BENCH_OPS) > /dev/null
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
#include <iostream>
 | 
			
		||||
#include <ods/simplist.h>
 | 
			
		||||
#include <ods/simpuset.h>
 | 
			
		||||
#include <ods/simpsset.h>
 | 
			
		||||
#include <ods/linked_list.h>
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,10 +81,67 @@ check_simpuset(void)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_simpsset(void)
 | 
			
		||||
{
 | 
			
		||||
	ods::SimpSSet<int>	ss;
 | 
			
		||||
	
 | 
			
		||||
	assert(ss.add(2));
 | 
			
		||||
	assert(ss.size() == 1);
 | 
			
		||||
	assert(ss.find(2));
 | 
			
		||||
	assert(!ss.add(2));
 | 
			
		||||
	assert(ss.size() == 1);
 | 
			
		||||
	assert(ss.add(1));
 | 
			
		||||
	assert(ss.find(1));
 | 
			
		||||
	assert(ss.size() == 2);
 | 
			
		||||
	assert(ss.add(3));
 | 
			
		||||
	assert(ss.size() == 3);
 | 
			
		||||
	assert(ss.find(3));
 | 
			
		||||
	
 | 
			
		||||
	auto removed = ss.remove(2);
 | 
			
		||||
	assert(removed == 2);
 | 
			
		||||
	assert(ss.size() == 2);
 | 
			
		||||
	assert(!ss.find(2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void check_linkedlist(void);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
check_linkedlist()
 | 
			
		||||
{
 | 
			
		||||
	ods::LinkedList<int>	ll;
 | 
			
		||||
	
 | 
			
		||||
	ll.add(0, 1);
 | 
			
		||||
	assert(ll.size() == 1);
 | 
			
		||||
	assert(ll.get(0) == 1);
 | 
			
		||||
	ll.add(0, 2);
 | 
			
		||||
	assert(ll.size() == 2);
 | 
			
		||||
	assert(ll.get(0) == 2);
 | 
			
		||||
	ll.add(2, 4);
 | 
			
		||||
	assert(ll.get(2) == 4);
 | 
			
		||||
	assert(ll.size() == 3);
 | 
			
		||||
	
 | 
			
		||||
	ll.set(1, 5);
 | 
			
		||||
	assert(ll.get(1) == 5);
 | 
			
		||||
	
 | 
			
		||||
	ll.remove(1);
 | 
			
		||||
	assert(ll.size() == 2);
 | 
			
		||||
	assert(ll.get(1) == 4);
 | 
			
		||||
	ll.remove(1);
 | 
			
		||||
	assert(ll.size() == 1);
 | 
			
		||||
	ll.remove(0);
 | 
			
		||||
	assert(ll.size() == 0);
 | 
			
		||||
	
 | 
			
		||||
	ll.add(0, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(void)
 | 
			
		||||
{
 | 
			
		||||
	check_simplist();
 | 
			
		||||
	check_simpuset();
 | 
			
		||||
	check_simpsset();
 | 
			
		||||
	check_linkedlist();
 | 
			
		||||
	cout << "OK" << endl;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
#include <ods/list.h>
 | 
			
		||||
#include <ods/simplist.h>
 | 
			
		||||
#include <ods/vlist.h>
 | 
			
		||||
#include <ods/linked_list.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -128,4 +129,7 @@ main(int argc, char *argv[])
 | 
			
		|||
	
 | 
			
		||||
	ods::VList<int>		vl;
 | 
			
		||||
	run("VList", vl, ops);
 | 
			
		||||
	
 | 
			
		||||
	ods::LinkedList<int>	ll;
 | 
			
		||||
	run("LinkedList", ll, ops);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,151 @@
 | 
			
		|||
#ifndef __ODS_ODS_LINKED_LIST__
 | 
			
		||||
#define __ODS_ODS_LINKED_LIST__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <ods/list.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace ods {
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct Node {
 | 
			
		||||
	struct Node	*next;
 | 
			
		||||
	T		 value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
class LinkedList : public List<T> {
 | 
			
		||||
public:
 | 
			
		||||
	LinkedList();
 | 
			
		||||
	~LinkedList();
 | 
			
		||||
	std::size_t size(void);
 | 
			
		||||
	T get(std::size_t);
 | 
			
		||||
	T set(std::size_t, T);
 | 
			
		||||
	void add(std::size_t, T);
 | 
			
		||||
	T remove(std::size_t);
 | 
			
		||||
private:
 | 
			
		||||
	struct Node<T>	*head;
 | 
			
		||||
	std::size_t	 len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
LinkedList<T>::LinkedList() : head(nullptr), len(0) {}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
LinkedList<T>::~LinkedList()
 | 
			
		||||
{
 | 
			
		||||
	struct Node<T>	*cursor = this->head;
 | 
			
		||||
	while (cursor != nullptr) {
 | 
			
		||||
		if (this->head != nullptr) {
 | 
			
		||||
			cursor = this->head->next;
 | 
			
		||||
		}
 | 
			
		||||
		delete this->head;
 | 
			
		||||
		this->head = cursor;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
std::size_t
 | 
			
		||||
LinkedList<T>::size()
 | 
			
		||||
{
 | 
			
		||||
	return this->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
void
 | 
			
		||||
LinkedList<T>::add(std::size_t i, T value)
 | 
			
		||||
{
 | 
			
		||||
	assert(i <= this->size());
 | 
			
		||||
	struct Node<T>	*node = new struct Node<T>;
 | 
			
		||||
	node->value = value;
 | 
			
		||||
	node->next = nullptr;
 | 
			
		||||
	
 | 
			
		||||
	auto cursor = this->head;
 | 
			
		||||
	if (i == 0) {
 | 
			
		||||
		node->next = this->head;
 | 
			
		||||
		this->head = node;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		for (size_t j = 0; j < (i-1); j++) {
 | 
			
		||||
			cursor = cursor->next;
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		if (cursor != nullptr) {
 | 
			
		||||
			node->next = cursor->next;
 | 
			
		||||
			cursor->next = node;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			this->head = node;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	this->len++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T
 | 
			
		||||
LinkedList<T>::get(std::size_t i)
 | 
			
		||||
{
 | 
			
		||||
	assert(i < this->size());
 | 
			
		||||
	if (i == 0) {
 | 
			
		||||
		return this->head->value;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	auto cursor = this->head;
 | 
			
		||||
	for (size_t j = 0; j < i; j++) {
 | 
			
		||||
		cursor = cursor->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cursor->value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T
 | 
			
		||||
LinkedList<T>::set(std::size_t i, T value)
 | 
			
		||||
{
 | 
			
		||||
	auto cursor = this->head;
 | 
			
		||||
	for (std::size_t j = 0; j < i; j++) {
 | 
			
		||||
		cursor = cursor->next;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	T prev = cursor->value;
 | 
			
		||||
	cursor->value = value;
 | 
			
		||||
	return prev;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
T
 | 
			
		||||
LinkedList<T>::remove(std::size_t i)
 | 
			
		||||
{
 | 
			
		||||
	if (i == 0) {
 | 
			
		||||
		auto old = this->head->value;
 | 
			
		||||
		auto target = this->head;
 | 
			
		||||
		this->head = this->head->next;
 | 
			
		||||
		delete target;
 | 
			
		||||
		this->len--;
 | 
			
		||||
		return old;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	auto cursor = this->head;
 | 
			
		||||
	for (std::size_t j = 0; j < (i-1); j++) {
 | 
			
		||||
		cursor = cursor->next;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	auto target = cursor->next;
 | 
			
		||||
	cursor->next = target->next;
 | 
			
		||||
	auto old = target->value;
 | 
			
		||||
	delete target;
 | 
			
		||||
	this->len--;
 | 
			
		||||
	return old;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace ods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // __ODS_ODS_LINKED_LIST__
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,10 @@ SimpSSet<T>::add(T value)
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		this->list.add(i, value);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	this->list.add(this->list.size(), value);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue