diff --git a/configure.ac b/configure.ac
index 7d6a738..9c0c695 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,5 +65,6 @@ AC_CONFIG_FILES([Makefile
src/queue/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 77bec2d..fca79c9 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -5,4 +5,5 @@ nobase_include_HEADERS = trdata.h \
tr/queue.h \
tr/tree.h \
tr/dynarray.h \
+ tr/heap.h \
tr/interface/hashable.h
diff --git a/include/tr/dynarray.h b/include/tr/dynarray.h
index a5db29b..f2b751d 100644
--- a/include/tr/dynarray.h
+++ b/include/tr/dynarray.h
@@ -36,7 +36,7 @@ TR_CLASSVARS_DECL(TR_Dynarray) {};
size_t TR_darrPut(TR_Dynarray, const void *);
void TR_darrPutAt(TR_Dynarray, const void *, size_t);
-size_t TR_darrFindLastIndex(TR_Dynarray);
+size_t TR_darrFindFirstFree(TR_Dynarray);
#define TR_darrGet(this, idx) ((this)->data[(idx)])
diff --git a/include/tr/heap.h b/include/tr/heap.h
new file mode 100644
index 0000000..c456b5f
--- /dev/null
+++ b/include/tr/heap.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_HEAP_H__
+#define __TR_HEAP_H__
+
+#include
+
+#include "trbase.h"
+#include "tr/dynarray.h"
+
+typedef int (*TR_HeapComp)(const void *, const void *);
+
+TR_CLASS(TR_Heap) {
+ TR_EXTENDS(TR_Dynarray);
+ TR_HeapComp comp;
+};
+TR_INSTANCE_INIT(TR_Heap);
+TR_CLASSVARS_DECL(TR_Heap) {};
+
+void TR_heapPut(TR_Heap, const void *);
+const void * TR_heapGet(TR_Heap);
+
+#endif // __TR_HEAP_H__
+
+// vim: set ts=4 sw=4:
diff --git a/include/trdata.h b/include/trdata.h
index ff10164..98887fb 100644
--- a/include/trdata.h
+++ b/include/trdata.h
@@ -7,6 +7,7 @@
#include "tr/queue.h"
#include "tr/tree.h"
#include "tr/dynarray.h"
+#include "tr/heap.h"
#include "tr/interface/hashable.h"
#endif // __TR_DATA_H__
diff --git a/src/Makefile.am b/src/Makefile.am
index 5440ac8..c333558 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,7 +8,8 @@ TRDATALIBS = cbuf/libcbuf.la \
hash/libhash.la \
queue/libqueue.la \
tree/libtree.la \
- dynarray/libdynarray.la
+ dynarray/libdynarray.la \
+ heap/libheap.la
lib_LTLIBRARIES = libtrdata.la
@@ -17,4 +18,4 @@ libtrdata_la_CFLAGS = $(AM_CFLAGS)
libtrdata_la_LIBADD = $(TRDATALIBS)
libtrdata_la_LDFLAGS = -version-info 0:0:0 $(AM_LDFLAGS)
-SUBDIRS = cbuf hash queue tree dynarray
+SUBDIRS = cbuf hash queue tree dynarray heap
diff --git a/src/dynarray/Makefile.am b/src/dynarray/Makefile.am
index ad60394..43e81d8 100644
--- a/src/dynarray/Makefile.am
+++ b/src/dynarray/Makefile.am
@@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = subdir-objects
AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
AM_LDFLAGS += -lpthread
-DYNARRAY = dynarray.c put.c find_last_index.c
+DYNARRAY = dynarray.c put.c find_first_free.c
noinst_LTLIBRARIES = libdynarray.la
diff --git a/src/dynarray/dynarray.c b/src/dynarray/dynarray.c
index dca554a..e7c7642 100644
--- a/src/dynarray/dynarray.c
+++ b/src/dynarray/dynarray.c
@@ -41,7 +41,7 @@ _darrResize(TR_Dynarray this, size_t index)
static
int
-darrCtor(void * _this)
+darrCtor(void * _this, va_list * params)
{
return 0;
}
diff --git a/src/dynarray/find_last_index.c b/src/dynarray/find_first_free.c
similarity index 96%
rename from src/dynarray/find_last_index.c
rename to src/dynarray/find_first_free.c
index 1815586..716a2d6 100644
--- a/src/dynarray/find_last_index.c
+++ b/src/dynarray/find_first_free.c
@@ -26,7 +26,7 @@
#include "tr/dynarray.h"
size_t
-TR_darrFindLastIndex(TR_Dynarray this)
+TR_darrFindFirstFree(TR_Dynarray this)
{
size_t i = this->size;
diff --git a/src/dynarray/put.c b/src/dynarray/put.c
index 27e4af4..67cbf88 100644
--- a/src/dynarray/put.c
+++ b/src/dynarray/put.c
@@ -42,7 +42,7 @@ _darrResize(TR_Dynarray this, size_t index)
size_t
TR_darrPut(TR_Dynarray this, const void * data)
{
- size_t i = TR_darrFindLastIndex(this);
+ size_t i = TR_darrFindFirstFree(this);
TR_darrPutAt(this, data, i);
diff --git a/src/heap/Makefile.am b/src/heap/Makefile.am
new file mode 100644
index 0000000..c3b57c5
--- /dev/null
+++ b/src/heap/Makefile.am
@@ -0,0 +1,13 @@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CFLAGS += -I../../include/ -std=c99 -DREENTRANT -lpthread
+AM_LDFLAGS += -lpthread
+
+HEAP = heap.c put.c get.c
+
+noinst_LTLIBRARIES = libheap.la
+
+libheap_la_SOURCES = $(HEAP)
+libheap_la_CFLAGS = $(AM_CFLAGS)
+libheap_la_LIBADD = $(AM_LDFLAGS)
diff --git a/src/heap/get.c b/src/heap/get.c
new file mode 100644
index 0000000..65c5b7a
--- /dev/null
+++ b/src/heap/get.c
@@ -0,0 +1,85 @@
+/**
+ * \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
+
+#include "trbase.h"
+#include "tr/heap.h"
+#include "tr/dynarray.h"
+
+const void *
+TR_heapGet(TR_Heap this)
+{
+ const void * value = TR_darrGet((TR_Dynarray)this, 0);
+ size_t left = 1;
+ size_t right = 2;
+ size_t idx;
+
+ if (! value) {
+ return NULL;
+ }
+
+ idx = TR_darrFindFirstFree((TR_Dynarray)this) - 1;
+ TR_darrGet((TR_Dynarray)this, 0) = NULL;
+
+ if (0 == idx) {
+ return value;
+ }
+
+ SWAP(
+ void *,
+ TR_darrGet((TR_Dynarray)this, 0),
+ TR_darrGet((TR_Dynarray)this, idx));
+ idx = 0;
+
+ while (left < ((TR_Dynarray)this)->size &&
+ TR_darrGet((TR_Dynarray)this, left)) {
+ size_t change = left;
+
+ if (right < ((TR_Dynarray)this)->size &&
+ TR_darrGet((TR_Dynarray)this, right) &&
+ 0 > this->comp (
+ TR_darrGet((TR_Dynarray)this, left),
+ TR_darrGet((TR_Dynarray)this, right))) {
+ change = right;
+ }
+
+ if (0 > this->comp(
+ TR_darrGet((TR_Dynarray)this, idx),
+ TR_darrGet((TR_Dynarray)this, change))) {
+ SWAP(
+ void *,
+ TR_darrGet((TR_Dynarray)this, idx),
+ TR_darrGet((TR_Dynarray)this, change));
+ idx = change;
+ left = (idx << 1) + 1;
+ right = left + 1;
+ } else {
+ break;
+ }
+ }
+
+ return value;
+}
+
+// vim: set ts=4 sw=4:
diff --git a/src/heap/heap.c b/src/heap/heap.c
new file mode 100644
index 0000000..e5cbb71
--- /dev/null
+++ b/src/heap/heap.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
+
+#include "trbase.h"
+#include "tr/heap.h"
+
+static
+int
+heapCtor(void * _this, va_list * params)
+{
+ TR_Heap this = _this;
+
+ this->comp = va_arg(*params, TR_HeapComp);
+
+ return 0;
+}
+
+static
+void
+heapDtor(void * _this)
+{
+ TR_PARENTCALL(TR_Heap, _this, TR_Class, dtor);
+}
+
+TR_INIT_IFACE(TR_Class, heapCtor, heapDtor, NULL);
+TR_CREATE_CLASS(TR_Heap, TR_Dynarray, NULL, TR_IF(TR_Class));
+
+// vim: set ts=4 sw=4:
diff --git a/src/heap/put.c b/src/heap/put.c
new file mode 100644
index 0000000..3555cfd
--- /dev/null
+++ b/src/heap/put.c
@@ -0,0 +1,52 @@
+/**
+ * \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
+
+#include "trbase.h"
+#include "tr/heap.h"
+#include "tr/dynarray.h"
+
+void
+TR_heapPut(TR_Heap this, const void * data)
+{
+ size_t idx = TR_darrPut((TR_Dynarray)this, data);
+
+ while (idx) {
+ size_t parent = (idx - 1) >> 1;
+
+ if (0 > this->comp(
+ TR_darrGet((TR_Dynarray)this, parent),
+ TR_darrGet((TR_Dynarray)this, idx))) {
+ SWAP(
+ void *,
+ TR_darrGet((TR_Dynarray)this, parent),
+ TR_darrGet((TR_Dynarray)this, idx));
+ idx = parent;
+ } else {
+ break;
+ }
+ }
+}
+
+// vim: set ts=4 sw=4: