Browse Source

Created new queue implementation based on dynamically growing arrays

1.0.0
Georg Hopp 10 years ago
parent
commit
886d391288
  1. 33
      include/tr/queue.h
  2. 7
      src/queue/Makefile.am
  3. 49
      src/queue/delete.c
  4. 48
      src/queue/destroy.c
  5. 36
      src/queue/find.c
  6. 36
      src/queue/find_parent.c
  7. 20
      src/queue/get.c
  8. 45
      src/queue/put.c
  9. 40
      src/queue/put_first.c
  10. 17
      src/queue/queue.c

33
include/tr/queue.h

@ -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__

7
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

49
src/queue/delete.c

@ -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 <http://www.gnu.org/licenses/>.
*/
#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:

48
src/queue/destroy.c

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#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:

36
src/queue/find.c

@ -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 <http://www.gnu.org/licenses/>.
*/
#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:

36
src/queue/find_parent.c

@ -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 <http://www.gnu.org/licenses/>.
*/
#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:

20
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:

45
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:

40
src/queue/put_first.c

@ -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 <http://www.gnu.org/licenses/>.
*/
#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:

17
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);

Loading…
Cancel
Save