From afc24135686b17e57d868434b0be702d5aa30152 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Thu, 21 Dec 2017 22:26:04 -0800 Subject: [PATCH] Add linked list and benchmarks. --- Makefile.am | 3 + benchmarks.txt | 13 ++++ configure.ac | 2 + src/Makefile.am | 14 +++- src/ch01ex06.cc | 59 +++++++++++++++++ src/list_bench.cc | 4 ++ src/ods/linked_list.h | 151 ++++++++++++++++++++++++++++++++++++++++++ src/ods/simpsset.h | 3 + 8 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 benchmarks.txt create mode 100644 src/ods/linked_list.h diff --git a/Makefile.am b/Makefile.am index 11c2cc1..bc31d7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,5 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src data + +benchmarks: + cd src && make benchmarks \ No newline at end of file diff --git a/benchmarks.txt b/benchmarks.txt new file mode 100644 index 0000000..5a4b5b9 --- /dev/null +++ b/benchmarks.txt @@ -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' diff --git a/configure.ac b/configure.ac index 1888319..866c5d3 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index 6e863e6..b1f2881 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ No newline at end of file diff --git a/src/ch01ex06.cc b/src/ch01ex06.cc index a83b0e5..fce753a 100644 --- a/src/ch01ex06.cc +++ b/src/ch01ex06.cc @@ -2,6 +2,8 @@ #include #include #include +#include +#include using namespace std; @@ -79,10 +81,67 @@ check_simpuset(void) } +static void +check_simpsset(void) +{ + ods::SimpSSet 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 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; } diff --git a/src/list_bench.cc b/src/list_bench.cc index 802f072..9ff8eb9 100644 --- a/src/list_bench.cc +++ b/src/list_bench.cc @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std; @@ -128,4 +129,7 @@ main(int argc, char *argv[]) ods::VList vl; run("VList", vl, ops); + + ods::LinkedList ll; + run("LinkedList", ll, ops); } \ No newline at end of file diff --git a/src/ods/linked_list.h b/src/ods/linked_list.h new file mode 100644 index 0000000..d4c1878 --- /dev/null +++ b/src/ods/linked_list.h @@ -0,0 +1,151 @@ +#ifndef __ODS_ODS_LINKED_LIST__ +#define __ODS_ODS_LINKED_LIST__ + + +#include +#include +#include + + +namespace ods { + +template +struct Node { + struct Node *next; + T value; +}; + +template +class LinkedList : public List { +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 *head; + std::size_t len; +}; + + +template +LinkedList::LinkedList() : head(nullptr), len(0) {} + +template +LinkedList::~LinkedList() +{ + struct Node *cursor = this->head; + while (cursor != nullptr) { + if (this->head != nullptr) { + cursor = this->head->next; + } + delete this->head; + this->head = cursor; + } +} + + +template +std::size_t +LinkedList::size() +{ + return this->len; +} + + +template +void +LinkedList::add(std::size_t i, T value) +{ + assert(i <= this->size()); + struct Node *node = new struct Node; + 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 +T +LinkedList::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 +T +LinkedList::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 +T +LinkedList::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__ \ No newline at end of file diff --git a/src/ods/simpsset.h b/src/ods/simpsset.h index ae24a55..8c3ec4d 100644 --- a/src/ods/simpsset.h +++ b/src/ods/simpsset.h @@ -53,7 +53,10 @@ SimpSSet::add(T value) continue; } this->list.add(i, value); + return true; } + + this->list.add(this->list.size(), value); return true; }