diff --git a/configure.ac b/configure.ac
index ac723b6..0b3626e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,11 +71,12 @@ AC_CONFIG_FILES([Makefile
tests/Makefile
src/Makefile
src/cbuf/Makefile
+ src/dynarray/Makefile
src/hash/Makefile
+ src/heap/Makefile
src/list/Makefile
src/queue/Makefile
+ src/set/Makefile
src/tree/Makefile
- src/dynarray/Makefile
- src/heap/Makefile
include/Makefile])
AC_OUTPUT
diff --git a/include/Makefile.am b/include/Makefile.am
index 094f5ab..b8c59de 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,11 +1,12 @@
nobase_include_HEADERS = trdata.h \
tr/cbuf.h \
+ tr/dynarray.h \
tr/hash.h \
+ tr/heap.h \
tr/hash_value.h \
tr/list.h \
tr/queue.h \
+ tr/set.h \
tr/tree.h \
- tr/dynarray.h \
- tr/heap.h \
tr/interface/hashable.h \
tr/interface/iterable.h
diff --git a/include/tr/set.h b/include/tr/set.h
new file mode 100644
index 0000000..eaf8d86
--- /dev/null
+++ b/include/tr/set.h
@@ -0,0 +1,55 @@
+/**
+ * \file
+ * Holds requests ready for processing.
+ *
+ * \todo change this to a real queue.
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __TR_SET_H__
+#define __TR_SET_H__
+
+#include
+
+#include "trbase.h"
+
+
+TR_CLASS(TR_Set) {
+ size_t size;
+ size_t used;
+ void ** data;
+ int free_msgs;
+
+ // for iterable interface
+ size_t current;
+};
+TR_INSTANCE_INIT(TR_Set);
+TR_CLASSVARS_DECL(TR_Set) {};
+
+void TR_setAdd(TR_Set, void *);
+size_t TR_setFind(TR_Set, void *);
+void TR_setDelete(TR_Set, void *);
+
+#define TR_setEmpty(this) (this->used == 0)
+#define TR_setSize(this) ((this)->used)
+
+#endif // __TR_SET_H__
+
+// vim: set ts=4 sw=4:
diff --git a/include/trdata.h b/include/trdata.h
index d489a4f..f006bd4 100644
--- a/include/trdata.h
+++ b/include/trdata.h
@@ -2,13 +2,14 @@
#define __TR_DATA_H__
#include "tr/cbuf.h"
+#include "tr/dynarray.h"
#include "tr/hash.h"
#include "tr/hash_value.h"
+#include "tr/heap.h"
#include "tr/list.h"
#include "tr/queue.h"
+#include "tr/set.h"
#include "tr/tree.h"
-#include "tr/dynarray.h"
-#include "tr/heap.h"
#include "tr/interface/hashable.h"
#include "tr/interface/iterable.h"
diff --git a/src/Makefile.am b/src/Makefile.am
index 523f0c9..e4bee0e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,12 +5,13 @@ AM_CFLAGS += -I../include/ -std=c99
AM_LDFLAGS +=
TRDATALIBS = cbuf/libcbuf.la \
+ dynarray/libdynarray.la \
hash/libhash.la \
+ heap/libheap.la \
list/liblist.la \
queue/libqueue.la \
- tree/libtree.la \
- dynarray/libdynarray.la \
- heap/libheap.la
+ set/libset.la \
+ tree/libtree.la
ITERABLE = interface/iterable.c
@@ -21,4 +22,4 @@ libtrdata_la_CFLAGS = $(AM_CFLAGS)
libtrdata_la_LIBADD = $(TRDATALIBS)
libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS)
-SUBDIRS = cbuf hash list queue tree dynarray heap
+SUBDIRS = cbuf dynarray hash heap list queue set tree
diff --git a/src/set/Makefile.am b/src/set/Makefile.am
new file mode 100644
index 0000000..c52022f
--- /dev/null
+++ b/src/set/Makefile.am
@@ -0,0 +1,16 @@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CFLAGS += -I../../include/ -std=c99
+AM_LDFLAGS +=
+
+SET = set.c \
+ add.c \
+ find.c \
+ delete.c
+
+noinst_LTLIBRARIES = libset.la
+
+libset_la_SOURCES = $(SET)
+libset_la_CFLAGS = $(AM_CFLAGS)
+libset_la_LIBADD = $(AM_LDFLAGS)
diff --git a/src/set/_resize.h b/src/set/_resize.h
new file mode 100644
index 0000000..d4cb4eb
--- /dev/null
+++ b/src/set/_resize.h
@@ -0,0 +1,45 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef __TR_SET_RESIZE_H__
+#define __TR_SET_RESIZE_H__
+
+#include "trbase.h"
+#include "tr/set.h"
+
+inline
+void
+_TR_setResize(TR_Set this)
+{
+ void ** new = TR_calloc(this->size+1, sizeof(void*));
+ size_t new_size = TR_getUsableSize(new) / sizeof(void *);
+
+#define GROWTH (new_size - this->size)
+
+ memcpy(new, this->data, this->size * sizeof(void*));
+ TR_MEM_FREE(this->data);
+ this->size = new_size;
+ this->data = new;
+}
+
+#endif // __TR_SET_RESIZE_H__
+
+// vim: set ts=4 sw=4:
diff --git a/src/set/add.c b/src/set/add.c
new file mode 100644
index 0000000..0433029
--- /dev/null
+++ b/src/set/add.c
@@ -0,0 +1,54 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "trbase.h"
+#include "tr/set.h"
+
+#include "_resize.h"
+
+extern inline void _TR_setResize(TR_Set);
+
+void
+TR_setAdd(TR_Set this, void * msg)
+{
+ size_t pos = TR_setFind(this, msg);
+
+ if (this->data[pos] == msg) {
+ return;
+ }
+
+ if (this->used == this->size) {
+ _TR_setResize(this);
+ }
+
+ if (pos != this->used) {
+ memmove(
+ this->data+pos+1,
+ this->data+pos,
+ (this->used-pos)*sizeof(void*));
+ }
+
+ this->data[pos] = msg;
+ ++this->used;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/set/delete.c b/src/set/delete.c
new file mode 100644
index 0000000..166c771
--- /dev/null
+++ b/src/set/delete.c
@@ -0,0 +1,48 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "trbase.h"
+#include "tr/set.h"
+
+#include "_resize.h"
+
+void
+TR_setDelete(TR_Set this, void * msg)
+{
+ size_t pos = TR_setFind(this, msg);
+
+ if (this->data[pos] != msg) {
+ return;
+ }
+
+ if (pos != this->used - 1) {
+ memmove(
+ this->data+pos,
+ this->data+pos+1,
+ (this->used-pos-1)*sizeof(void*));
+ }
+
+ this->data[this->used-1] = NULL;
+ --this->used;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/set/find.c b/src/set/find.c
new file mode 100644
index 0000000..3edd558
--- /dev/null
+++ b/src/set/find.c
@@ -0,0 +1,49 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include "trbase.h"
+#include "tr/set.h"
+
+size_t
+TR_setFind(TR_Set this, void * search)
+{
+#define MID(a, b) (((b)-(a))/2)
+
+ size_t start = 0;
+ size_t end = this->used > 0 ? this->used-1 : 0;
+ size_t i = MID(start, end);
+
+ while (this->data[i] != search && start < end) {
+ if (this->data[i] < search) {
+ start = i+1 > end ? end : i+1;
+ } else {
+ end = i <= start || i-1 < start ? start : i-1;
+ }
+ i = start+MID(start, end);
+ }
+
+ if (this->data[i] < search && this->used != 0) ++i;
+
+ return i;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/set/set.c b/src/set/set.c
new file mode 100644
index 0000000..6106a92
--- /dev/null
+++ b/src/set/set.c
@@ -0,0 +1,96 @@
+/**
+ * \file
+ *
+ * \author Georg Hopp
+ *
+ * \copyright
+ * Copyright © 2014 Georg Hopp
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+
+#include "trbase.h"
+#include "tr/set.h"
+#include "tr/interface/iterable.h"
+
+static
+int
+setCtor(void * _this, va_list * params)
+{
+ TR_Set this = _this;
+
+ this->data = (void **)TR_calloc(32, sizeof(void *));
+ this->size = TR_getUsableSize(this->data) / sizeof(void *);
+ this->free_msgs = 1;
+
+ return 0;
+}
+
+static
+void
+setDtor(void * _this)
+{
+ TR_Set this = _this;
+ size_t i;
+
+ if (this->free_msgs) {
+ for (i = 0; i < this->used; i++) {
+ if (this->data[i]) {
+ TR_delete(this->data[i]);
+ }
+ }
+ }
+
+ TR_MEM_FREE(this->data);
+}
+
+static
+void *
+setCurrent(void * _this)
+{
+ TR_Set this = _this;
+ return this->data[this->current];
+}
+
+static
+void
+setNext(void * _this)
+{
+ TR_Set this = _this;
+ ++this->current;
+}
+
+static
+void
+setRewind(void * _this)
+{
+ TR_Set this = _this;
+ this->current = 0;
+}
+
+static
+int
+setValid(void * _this)
+{
+ TR_Set this = _this;
+ return this->current < this->used;
+}
+
+TR_INIT_IFACE(TR_Class, setCtor, setDtor, NULL);
+TR_INIT_IFACE(TR_Iterable, setCurrent, setNext, setRewind, setValid);
+TR_CREATE_CLASS(TR_Set, NULL, NULL, TR_IF(TR_Class), TR_IF(TR_Iterable));
+
+// vim: set ts=4 sw=4: