Add linked list and benchmarks.

This commit is contained in:
Kyle Isom 2017-12-21 22:26:04 -08:00
parent e5d93a083f
commit afc2413568
8 changed files with 248 additions and 1 deletions

View File

@ -1,2 +1,5 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src data SUBDIRS = src data
benchmarks:
cd src && make benchmarks

13
benchmarks.txt Normal file
View File

@ -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'

View File

@ -12,6 +12,8 @@ AC_CONFIG_SRCDIR([src/ch01ex01.cc])
AC_CONFIG_FILES([Makefile src/Makefile data/Makefile]) AC_CONFIG_FILES([Makefile src/Makefile data/Makefile])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
: ${CXXFLAGS=""}
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
AC_CHECK_HEADERS AC_CHECK_HEADERS

View File

@ -1,7 +1,7 @@
AM_CPPFLAGS = -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align AM_CPPFLAGS = -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align
AM_CPPFLAGS += -Wwrite-strings -Wmissing-declarations -Wno-long-long -Werror 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 += -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 \ bin_PROGRAMS := ch01ex01 ch01ex03 ch01ex04 ch01ex05 ch01ex06 \
list_bench uset_bench sset_bench list_bench uset_bench sset_bench
@ -13,3 +13,15 @@ ch01ex06_SOURCES := ch01ex06.cc
list_bench_SOURCES := list_bench.cc list_bench_SOURCES := list_bench.cc
uset_bench_SOURCES := uset_bench.cc uset_bench_SOURCES := uset_bench.cc
sset_bench_SOURCES := sset_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

View File

@ -2,6 +2,8 @@
#include <iostream> #include <iostream>
#include <ods/simplist.h> #include <ods/simplist.h>
#include <ods/simpuset.h> #include <ods/simpuset.h>
#include <ods/simpsset.h>
#include <ods/linked_list.h>
using namespace std; 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 int
main(void) main(void)
{ {
check_simplist(); check_simplist();
check_simpuset(); check_simpuset();
check_simpsset();
check_linkedlist();
cout << "OK" << endl; cout << "OK" << endl;
} }

View File

@ -7,6 +7,7 @@
#include <ods/list.h> #include <ods/list.h>
#include <ods/simplist.h> #include <ods/simplist.h>
#include <ods/vlist.h> #include <ods/vlist.h>
#include <ods/linked_list.h>
using namespace std; using namespace std;
@ -128,4 +129,7 @@ main(int argc, char *argv[])
ods::VList<int> vl; ods::VList<int> vl;
run("VList", vl, ops); run("VList", vl, ops);
ods::LinkedList<int> ll;
run("LinkedList", ll, ops);
} }

151
src/ods/linked_list.h Normal file
View File

@ -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__

View File

@ -53,7 +53,10 @@ SimpSSet<T>::add(T value)
continue; continue;
} }
this->list.add(i, value); this->list.add(i, value);
return true;
} }
this->list.add(this->list.size(), value);
return true; return true;
} }