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: