Commit 886d391288d124a845ee1a32fa82571cc8d3d04a

Authored by Georg Hopp
1 parent 26d6138c

Created new queue implementation based on dynamically growing arrays

1 /** 1 /**
2 * \file 2 * \file
3 * Holds requests ready for processing. 3 * Holds requests ready for processing.
4 - * 4 + *
5 * \todo change this to a real queue. 5 * \todo change this to a real queue.
6 * 6 *
7 * \author Georg Hopp 7 * \author Georg Hopp
@@ -32,34 +32,23 @@ @@ -32,34 +32,23 @@
32 32
33 33
34 TR_CLASS(TR_Queue) { 34 TR_CLASS(TR_Queue) {
35 - void * msg;  
36 - TR_Queue next;  
37 -  
38 - /**  
39 - * first and last are only available in the initial queue  
40 - * element (the root). This elelment does not contain any message  
41 - * and exists only for organizational purpose.  
42 - *  
43 - * \todo next and first always have to be the same...so get rid  
44 - * of first.  
45 - */  
46 - TR_Queue first;  
47 - TR_Queue last;  
48 - size_t nmsg; 35 + size_t size;
  36 + size_t start;
  37 + size_t end;
  38 + void ** data;
49 int free_msgs; 39 int free_msgs;
50 }; 40 };
51 TR_INSTANCE_INIT(TR_Queue); 41 TR_INSTANCE_INIT(TR_Queue);
52 TR_CLASSVARS_DECL(TR_Queue) {}; 42 TR_CLASSVARS_DECL(TR_Queue) {};
53 43
54 -void TR_queuePut(TR_Queue, void *);  
55 -void TR_queuePutFirst(TR_Queue, void *);  
56 -void * TR_queueGet(TR_Queue);  
57 -TR_Queue TR_queueFind(TR_Queue, void *);  
58 -TR_Queue TR_queueFindParent(TR_Queue, void *);  
59 -void TR_queueDelete(TR_Queue, void *);  
60 -void TR_queueDestroy(TR_Queue); 44 +void TR_queuePut(TR_Queue, void *);
  45 +void TR_queuePutFirst(TR_Queue, void *);
  46 +void * TR_queueGet(TR_Queue);
61 47
62 -#define TR_queueEmpty(this) (0 >= (this)->nmsg) 48 +#define TR_queueEmpty(this) (this->start == this->end)
  49 +#define TR_queueFirst(this) ((this)->start)
  50 +#define TR_queueLast(this) ((this)->end - 1)
  51 +#define TR_queueSize(this) ((this)->size)
63 52
64 #endif // __TR_QUEUE_H__ 53 #endif // __TR_QUEUE_H__
65 54
@@ -6,12 +6,7 @@ AM_LDFLAGS += @@ -6,12 +6,7 @@ AM_LDFLAGS +=
6 6
7 QUEUE = queue.c \ 7 QUEUE = queue.c \
8 get.c \ 8 get.c \
9 - put.c \  
10 - put_first.c \  
11 - find.c \  
12 - find_parent.c \  
13 - delete.c \  
14 - destroy.c 9 + put.c
15 10
16 noinst_LTLIBRARIES = libqueue.la 11 noinst_LTLIBRARIES = libqueue.la
17 12
1 -/**  
2 - * \file  
3 - *  
4 - * \author Georg Hopp  
5 - *  
6 - * \copyright  
7 - * Copyright © 2014 Georg Hopp  
8 - *  
9 - * This program is free software: you can redistribute it and/or modify  
10 - * it under the terms of the GNU General Public License as published by  
11 - * the Free Software Foundation, either version 3 of the License, or  
12 - * (at your option) any later version.  
13 - *  
14 - * This program is distributed in the hope that it will be useful,  
15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - * GNU General Public License for more details.  
18 - *  
19 - * You should have received a copy of the GNU General Public License  
20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.  
21 - */  
22 -  
23 -#include "trbase.h"  
24 -#include "tr/queue.h"  
25 -  
26 -void  
27 -TR_queueDelete(TR_Queue this, void * msg)  
28 -{  
29 - TR_Queue node, parent;  
30 -  
31 - parent = TR_queueFindParent(this, msg);  
32 -  
33 - if (! parent) {  
34 - return;  
35 - }  
36 -  
37 - node = parent->next;  
38 - parent->next = node->next;  
39 - if (node == this->last) {  
40 - this->last = parent;  
41 - }  
42 - if (node == this->first) {  
43 - this->first = node->next;  
44 - }  
45 - TR_delete(node);  
46 - this->nmsg--;  
47 -}  
48 -  
49 -// vim: set ts=4 sw=4:  
1 -/**  
2 - * \file  
3 - *  
4 - * \author Georg Hopp  
5 - *  
6 - * \copyright  
7 - * Copyright © 2014 Georg Hopp  
8 - *  
9 - * This program is free software: you can redistribute it and/or modify  
10 - * it under the terms of the GNU General Public License as published by  
11 - * the Free Software Foundation, either version 3 of the License, or  
12 - * (at your option) any later version.  
13 - *  
14 - * This program is distributed in the hope that it will be useful,  
15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - * GNU General Public License for more details.  
18 - *  
19 - * You should have received a copy of the GNU General Public License  
20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.  
21 - */  
22 -  
23 -#include <stdarg.h>  
24 -  
25 -#include "trbase.h"  
26 -#include "tr/queue.h"  
27 -  
28 -void  
29 -TR_queueDestroy(TR_Queue this)  
30 -{  
31 - TR_Queue node;  
32 -  
33 - node = this->first;  
34 -  
35 - while (NULL != node) {  
36 - TR_Queue next = node->next;  
37 - if (this->free_msgs) {  
38 - TR_delete(node->msg);  
39 - }  
40 - TR_delete(node);  
41 - node = next;  
42 - }  
43 -  
44 - this->first = this->next = this->last = NULL;  
45 - this->nmsg = 0;  
46 -}  
47 -  
48 -// vim: set ts=4 sw=4:  
1 -/**  
2 - * \file  
3 - *  
4 - * \author Georg Hopp  
5 - *  
6 - * \copyright  
7 - * Copyright © 2014 Georg Hopp  
8 - *  
9 - * This program is free software: you can redistribute it and/or modify  
10 - * it under the terms of the GNU General Public License as published by  
11 - * the Free Software Foundation, either version 3 of the License, or  
12 - * (at your option) any later version.  
13 - *  
14 - * This program is distributed in the hope that it will be useful,  
15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - * GNU General Public License for more details.  
18 - *  
19 - * You should have received a copy of the GNU General Public License  
20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.  
21 - */  
22 -  
23 -#include "trbase.h"  
24 -#include "tr/queue.h"  
25 -  
26 -TR_Queue  
27 -TR_queueFind(TR_Queue this, void * msg)  
28 -{  
29 - TR_Queue node;  
30 -  
31 - for (node = this->first; node && node->msg != msg; node = node->next);  
32 -  
33 - return node;  
34 -}  
35 -  
36 -// vim: set ts=4 sw=4:  
1 -/**  
2 - * \file  
3 - *  
4 - * \author Georg Hopp  
5 - *  
6 - * \copyright  
7 - * Copyright © 2014 Georg Hopp  
8 - *  
9 - * This program is free software: you can redistribute it and/or modify  
10 - * it under the terms of the GNU General Public License as published by  
11 - * the Free Software Foundation, either version 3 of the License, or  
12 - * (at your option) any later version.  
13 - *  
14 - * This program is distributed in the hope that it will be useful,  
15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - * GNU General Public License for more details.  
18 - *  
19 - * You should have received a copy of the GNU General Public License  
20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.  
21 - */  
22 -  
23 -#include "trbase.h"  
24 -#include "tr/queue.h"  
25 -  
26 -TR_Queue  
27 -TR_queueFindParent(TR_Queue this, void * msg)  
28 -{  
29 - TR_Queue node;  
30 -  
31 - for (node = this; node->next && node->next->msg != msg; node = node->next);  
32 -  
33 - return node->next ? node : NULL;  
34 -}  
35 -  
36 -// vim: set ts=4 sw=4:  
@@ -26,26 +26,16 @@ @@ -26,26 +26,16 @@
26 void * 26 void *
27 TR_queueGet(TR_Queue this) 27 TR_queueGet(TR_Queue this)
28 { 28 {
29 - TR_Queue first;  
30 - void * msg; 29 + void * retval;
31 30
32 - if (NULL == this->first) { 31 + if (TR_queueEmpty(this)) {
33 return NULL; 32 return NULL;
34 } 33 }
35 34
36 - msg = this->first->msg;  
37 - first = this->first->next; 35 + retval = this->data[this->start];
  36 + this->start = this->start + 1 == this->size ? 0 : this->start + 1;
38 37
39 - if (this->first == this->last) {  
40 - this->last = NULL;  
41 - }  
42 - TR_delete(this->first);  
43 -  
44 - this->next = first;  
45 - this->first = first;  
46 - this->nmsg--;  
47 -  
48 - return msg; 38 + return retval;
49 } 39 }
50 40
51 // vim: set ts=4 sw=4: 41 // vim: set ts=4 sw=4:
@@ -23,22 +23,49 @@ @@ -23,22 +23,49 @@
23 #include "trbase.h" 23 #include "trbase.h"
24 #include "tr/queue.h" 24 #include "tr/queue.h"
25 25
  26 +static
  27 +inline
26 void 28 void
27 -TR_queuePut(TR_Queue this, void * msg) 29 +_TR_queueResize(TR_Queue this, size_t split)
28 { 30 {
29 - TR_Queue node; 31 +#define VPSIZE(elem) ((elem) * sizeof(void*))
  32 +
  33 + void ** new = TR_malloc(VPSIZE(this->size + 1));
  34 + size_t new_size = TR_getUsableSize(new) / sizeof(void *);
30 35
31 - node = (this->last)? this->last : this; 36 +#define GROWTH (new_size - this->size)
  37 +
  38 + memcpy(new, this->data, VPSIZE(split));
  39 + memcpy(
  40 + new + GROWTH + this->start,
  41 + &(this->data[this->start]),
  42 + VPSIZE(this->size - this->start));
  43 + this->start = GROWTH + this->start;
  44 + this->size = new_size;
  45 +}
  46 +
  47 +void
  48 +TR_queuePutFirst(TR_Queue this, void * msg)
  49 +{
  50 + size_t next = this->start == 0 ? this->size - 1: this->start - 1;
32 51
33 - node->next = TR_new(TR_Queue);  
34 - this->last = node->next; 52 + this->data[next] = msg;
  53 + this->start = next;
35 54
36 - if (node == this) {  
37 - this->first = node->next; 55 + if (next == this->end) {
  56 + _TR_queueResize(this, this->end);
38 } 57 }
  58 +}
  59 +
  60 +void
  61 +TR_queuePut(TR_Queue this, void * msg)
  62 +{
  63 + this->data[this->end] = msg;
  64 + this->end = this->end + 1 == this->size ? 0 : this->end + 1;
39 65
40 - node->next->msg = msg;  
41 - this->nmsg++; 66 + if (this->end == this->start) {
  67 + _TR_queueResize(this, this->end);
  68 + }
42 } 69 }
43 70
44 // vim: set ts=4 sw=4: 71 // vim: set ts=4 sw=4:
1 -/**  
2 - * \file  
3 - *  
4 - * \author Georg Hopp  
5 - *  
6 - * \copyright  
7 - * Copyright © 2014 Georg Hopp  
8 - *  
9 - * This program is free software: you can redistribute it and/or modify  
10 - * it under the terms of the GNU General Public License as published by  
11 - * the Free Software Foundation, either version 3 of the License, or  
12 - * (at your option) any later version.  
13 - *  
14 - * This program is distributed in the hope that it will be useful,  
15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
17 - * GNU General Public License for more details.  
18 - *  
19 - * You should have received a copy of the GNU General Public License  
20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.  
21 - */  
22 -  
23 -#include "trbase.h"  
24 -#include "tr/queue.h"  
25 -  
26 -void  
27 -TR_queuePutFirst(TR_Queue this, void * msg)  
28 -{  
29 - TR_Queue current_first;  
30 -  
31 - current_first = this->first;  
32 -  
33 - this->first = this->next = TR_new(TR_Queue);  
34 - this->first->next = current_first;  
35 - this->first->msg = msg;  
36 - this->last = this->last ? this->last : this->first;  
37 - this->nmsg++;  
38 -}  
39 -  
40 -// vim: set ts=4 sw=4:  
@@ -31,6 +31,9 @@ queueCtor(void * _this, va_list * params) @@ -31,6 +31,9 @@ queueCtor(void * _this, va_list * params)
31 { 31 {
32 TR_Queue this = _this; 32 TR_Queue this = _this;
33 33
  34 + this->data = (void **)TR_malloc(32 * sizeof(void *));
  35 + this->size = TR_getUsableSize(this->data) / sizeof(void *);
  36 + this->start = this->end = 0;
34 this->free_msgs = 1; 37 this->free_msgs = 1;
35 38
36 return 0; 39 return 0;
@@ -41,8 +44,20 @@ void @@ -41,8 +44,20 @@ void
41 queueDtor(void * _this) 44 queueDtor(void * _this)
42 { 45 {
43 TR_Queue this = _this; 46 TR_Queue this = _this;
  47 + size_t i;
44 48
45 - TR_queueDestroy(this); 49 + if (this->free_msgs) {
  50 + for (
  51 + i = this->start;
  52 + i != this->end;
  53 + i = i + 1 == this->size ? 0 : i + 1) {
  54 + if (this->data[i]) {
  55 + TR_delete(this->data[i]);
  56 + }
  57 + }
  58 + }
  59 +
  60 + TR_MEM_FREE(this->data);
46 } 61 }
47 62
48 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL); 63 TR_INIT_IFACE(TR_Class, queueCtor, queueDtor, NULL);
Please register or login to post a comment