From 886d391288d124a845ee1a32fa82571cc8d3d04a Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Thu, 22 Oct 2015 16:14:32 +0200 Subject: [PATCH] Created new queue implementation based on dynamically growing arrays --- include/tr/queue.h | 35 ++++++++++------------------- src/queue/Makefile.am | 7 +----- src/queue/delete.c | 49 ----------------------------------------- src/queue/destroy.c | 48 ---------------------------------------- src/queue/find.c | 36 ------------------------------ src/queue/find_parent.c | 36 ------------------------------ src/queue/get.c | 20 +++++------------ src/queue/put.c | 45 +++++++++++++++++++++++++++++-------- src/queue/put_first.c | 40 --------------------------------- src/queue/queue.c | 17 +++++++++++++- 10 files changed, 70 insertions(+), 263 deletions(-) delete mode 100644 src/queue/delete.c delete mode 100644 src/queue/destroy.c delete mode 100644 src/queue/find.c delete mode 100644 src/queue/find_parent.c delete mode 100644 src/queue/put_first.c diff --git a/include/tr/queue.h b/include/tr/queue.h index 1240d34..19ff11c 100644 --- a/include/tr/queue.h +++ b/include/tr/queue.h @@ -1,7 +1,7 @@ /** * \file * Holds requests ready for processing. - * + * * \todo change this to a real queue. * * \author Georg Hopp @@ -32,34 +32,23 @@ TR_CLASS(TR_Queue) { - void * msg; - TR_Queue next; - - /** - * first and last are only available in the initial queue - * element (the root). This elelment does not contain any message - * and exists only for organizational purpose. - * - * \todo next and first always have to be the same...so get rid - * of first. - */ - TR_Queue first; - TR_Queue last; - size_t nmsg; + size_t size; + size_t start; + size_t end; + void ** data; int free_msgs; }; TR_INSTANCE_INIT(TR_Queue); TR_CLASSVARS_DECL(TR_Queue) {}; -void TR_queuePut(TR_Queue, void *); -void TR_queuePutFirst(TR_Queue, void *); -void * TR_queueGet(TR_Queue); -TR_Queue TR_queueFind(TR_Queue, void *); -TR_Queue TR_queueFindParent(TR_Queue, void *); -void TR_queueDelete(TR_Queue, void *); -void TR_queueDestroy(TR_Queue); +void TR_queuePut(TR_Queue, void *); +void TR_queuePutFirst(TR_Queue, void *); +void * TR_queueGet(TR_Queue); -#define TR_queueEmpty(this) (0 >= (this)->nmsg) +#define TR_queueEmpty(this) (this->start == this->end) +#define TR_queueFirst(this) ((this)->start) +#define TR_queueLast(this) ((this)->end - 1) +#define TR_queueSize(this) ((this)->size) #endif // __TR_QUEUE_H__ diff --git a/src/queue/Makefile.am b/src/queue/Makefile.am index 0bd8013..b0c7ea3 100644 --- a/src/queue/Makefile.am +++ b/src/queue/Makefile.am @@ -6,12 +6,7 @@ AM_LDFLAGS += QUEUE = queue.c \ get.c \ - put.c \ - put_first.c \ - find.c \ - find_parent.c \ - delete.c \ - destroy.c + put.c noinst_LTLIBRARIES = libqueue.la diff --git a/src/queue/delete.c b/src/queue/delete.c deleted file mode 100644 index c9ecc51..0000000 --- a/src/queue/delete.c +++ /dev/null @@ -1,49 +0,0 @@ -/** - * \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/queue.h" - -void -TR_queueDelete(TR_Queue this, void * msg) -{ - TR_Queue node, parent; - - parent = TR_queueFindParent(this, msg); - - if (! parent) { - return; - } - - node = parent->next; - parent->next = node->next; - if (node == this->last) { - this->last = parent; - } - if (node == this->first) { - this->first = node->next; - } - TR_delete(node); - this->nmsg--; -} - -// vim: set ts=4 sw=4: diff --git a/src/queue/destroy.c b/src/queue/destroy.c deleted file mode 100644 index 16f2c2a..0000000 --- a/src/queue/destroy.c +++ /dev/null @@ -1,48 +0,0 @@ -/** - * \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/queue.h" - -void -TR_queueDestroy(TR_Queue this) -{ - TR_Queue node; - - node = this->first; - - while (NULL != node) { - TR_Queue next = node->next; - if (this->free_msgs) { - TR_delete(node->msg); - } - TR_delete(node); - node = next; - } - - this->first = this->next = this->last = NULL; - this->nmsg = 0; -} - -// vim: set ts=4 sw=4: diff --git a/src/queue/find.c b/src/queue/find.c deleted file mode 100644 index 67f51d3..0000000 --- a/src/queue/find.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * \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/queue.h" - -TR_Queue -TR_queueFind(TR_Queue this, void * msg) -{ - TR_Queue node; - - for (node = this->first; node && node->msg != msg; node = node->next); - - return node; -} - -// vim: set ts=4 sw=4: diff --git a/src/queue/find_parent.c b/src/queue/find_parent.c deleted file mode 100644 index 707c29b..0000000 --- a/src/queue/find_parent.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * \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/queue.h" - -TR_Queue -TR_queueFindParent(TR_Queue this, void * msg) -{ - TR_Queue node; - - for (node = this; node->next && node->next->msg != msg; node = node->next); - - return node->next ? node : NULL; -} - -// vim: set ts=4 sw=4: diff --git a/src/queue/get.c b/src/queue/get.c index 0eea544..f115ac8 100644 --- a/src/queue/get.c +++ b/src/queue/get.c @@ -26,26 +26,16 @@ void * TR_queueGet(TR_Queue this) { - TR_Queue first; - void * msg; + void * retval; - if (NULL == this->first) { + if (TR_queueEmpty(this)) { return NULL; } - msg = this->first->msg; - first = this->first->next; + retval = this->data[this->start]; + this->start = this->start + 1 == this->size ? 0 : this->start + 1; - if (this->first == this->last) { - this->last = NULL; - } - TR_delete(this->first); - - this->next = first; - this->first = first; - this->nmsg--; - - return msg; + return retval; } // vim: set ts=4 sw=4: diff --git a/src/queue/put.c b/src/queue/put.c index f5969c3..e91aa1b 100644 --- a/src/queue/put.c +++ b/src/queue/put.c @@ -23,22 +23,49 @@ #include "trbase.h" #include "tr/queue.h" +static +inline void -TR_queuePut(TR_Queue this, void * msg) +_TR_queueResize(TR_Queue this, size_t split) { - TR_Queue node; +#define VPSIZE(elem) ((elem) * sizeof(void*)) + + void ** new = TR_malloc(VPSIZE(this->size + 1)); + size_t new_size = TR_getUsableSize(new) / sizeof(void *); - node = (this->last)? this->last : this; +#define GROWTH (new_size - this->size) + + memcpy(new, this->data, VPSIZE(split)); + memcpy( + new + GROWTH + this->start, + &(this->data[this->start]), + VPSIZE(this->size - this->start)); + this->start = GROWTH + this->start; + this->size = new_size; +} + +void +TR_queuePutFirst(TR_Queue this, void * msg) +{ + size_t next = this->start == 0 ? this->size - 1: this->start - 1; - node->next = TR_new(TR_Queue); - this->last = node->next; + this->data[next] = msg; + this->start = next; - if (node == this) { - this->first = node->next; + if (next == this->end) { + _TR_queueResize(this, this->end); } +} + +void +TR_queuePut(TR_Queue this, void * msg) +{ + this->data[this->end] = msg; + this->end = this->end + 1 == this->size ? 0 : this->end + 1; - node->next->msg = msg; - this->nmsg++; + if (this->end == this->start) { + _TR_queueResize(this, this->end); + } } // vim: set ts=4 sw=4: diff --git a/src/queue/put_first.c b/src/queue/put_first.c deleted file mode 100644 index c52ea9d..0000000 --- a/src/queue/put_first.c +++ /dev/null @@ -1,40 +0,0 @@ -/** - * \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/queue.h" - -void -TR_queuePutFirst(TR_Queue this, void * msg) -{ - TR_Queue current_first; - - current_first = this->first; - - this->first = this->next = TR_new(TR_Queue); - this->first->next = current_first; - this->first->msg = msg; - this->last = this->last ? this->last : this->first; - this->nmsg++; -} - -// vim: set ts=4 sw=4: diff --git a/src/queue/queue.c b/src/queue/queue.c index 79ec171..2db6eaa 100644 --- a/src/queue/queue.c +++ b/src/queue/queue.c @@ -31,6 +31,9 @@ queueCtor(void * _this, va_list * params) { TR_Queue this = _this; + this->data = (void **)TR_malloc(32 * sizeof(void *)); + this->size = TR_getUsableSize(this->data) / sizeof(void *); + this->start = this->end = 0; this->free_msgs = 1; return 0; @@ -41,8 +44,20 @@ void queueDtor(void * _this) { TR_Queue this = _this; + size_t i; - TR_queueDestroy(this); + if (this->free_msgs) { + for ( + i = this->start; + i != this->end; + i = i + 1 == this->size ? 0 : i + 1) { + if (this->data[i]) { + TR_delete(this->data[i]); + } + } + } + + TR_MEM_FREE(this->data); } TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);