summaryrefslogtreecommitdiff
path: root/libsolv-0.4.0/src/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsolv-0.4.0/src/queue.c')
-rw-r--r--libsolv-0.4.0/src/queue.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/libsolv-0.4.0/src/queue.c b/libsolv-0.4.0/src/queue.c
new file mode 100644
index 0000000..37ea381
--- /dev/null
+++ b/libsolv-0.4.0/src/queue.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007, Novell Inc.
+ *
+ * This program is licensed under the BSD license, read LICENSE.BSD
+ * for further information
+ */
+
+/*
+ * queue.c
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "queue.h"
+#include "util.h"
+
+#define EXTRA_SPACE 8
+#define EXTRA_SPACE_HEAD 8
+
+void
+queue_init(Queue *q)
+{
+ q->alloc = q->elements = 0;
+ q->count = q->left = 0;
+}
+
+void
+queue_init_clone(Queue *t, Queue *s)
+{
+ if (!s->elements)
+ {
+ t->alloc = t->elements = 0;
+ t->count = t->left = 0;
+ return;
+ }
+ t->alloc = t->elements = solv_malloc2(s->count + EXTRA_SPACE, sizeof(Id));
+ if (s->count)
+ memcpy(t->alloc, s->elements, s->count * sizeof(Id));
+ t->count = s->count;
+ t->left = EXTRA_SPACE;
+}
+
+void
+queue_init_buffer(Queue *q, Id *buf, int size)
+{
+ q->alloc = 0;
+ q->elements = buf;
+ q->count = 0;
+ q->left = size;
+}
+
+void
+queue_free(Queue *q)
+{
+ if (q->alloc)
+ solv_free(q->alloc);
+ q->alloc = q->elements = 0;
+ q->count = q->left = 0;
+}
+
+void
+queue_alloc_one(Queue *q)
+{
+ if (!q->alloc)
+ {
+ q->alloc = solv_malloc2(q->count + EXTRA_SPACE, sizeof(Id));
+ if (q->count)
+ memcpy(q->alloc, q->elements, q->count * sizeof(Id));
+ q->elements = q->alloc;
+ q->left = EXTRA_SPACE;
+ }
+ else if (q->alloc != q->elements)
+ {
+ int l = q->elements - q->alloc;
+ if (q->count)
+ memmove(q->alloc, q->elements, q->count * sizeof(Id));
+ q->elements -= l;
+ q->left += l;
+ }
+ else
+ {
+ q->elements = q->alloc = solv_realloc2(q->alloc, q->count + EXTRA_SPACE, sizeof(Id));
+ q->left = EXTRA_SPACE;
+ }
+}
+
+/* make room for an element in front of queue */
+void
+queue_alloc_one_head(Queue *q)
+{
+ int l;
+ if (!q->alloc || !q->left)
+ queue_alloc_one(q);
+ l = q->left > EXTRA_SPACE_HEAD ? EXTRA_SPACE_HEAD : q->left;
+ if (q->count)
+ memmove(q->elements + l, q->elements, q->count * sizeof(Id));
+ q->elements += l;
+ q->left -= l;
+}
+
+void
+queue_insert(Queue *q, int pos, Id id)
+{
+ queue_push(q, id); /* make room */
+ if (pos < q->count - 1)
+ {
+ memmove(q->elements + pos + 1, q->elements + pos, (q->count - 1 - pos) * sizeof(Id));
+ q->elements[pos] = id;
+ }
+}
+
+void
+queue_delete(Queue *q, int pos)
+{
+ if (pos >= q->count)
+ return;
+ if (pos < q->count - 1)
+ memmove(q->elements + pos, q->elements + pos + 1, (q->count - 1 - pos) * sizeof(Id));
+ q->left++;
+ q->count--;
+}
+
+void
+queue_insert2(Queue *q, int pos, Id id1, Id id2)
+{
+ queue_push(q, id1); /* make room */
+ queue_push(q, id2); /* make room */
+ if (pos < q->count - 2)
+ {
+ memmove(q->elements + pos + 2, q->elements + pos, (q->count - 2 - pos) * sizeof(Id));
+ q->elements[pos] = id1;
+ q->elements[pos + 1] = id2;
+ }
+}
+
+void
+queue_delete2(Queue *q, int pos)
+{
+ if (pos >= q->count)
+ return;
+ if (pos == q->count - 1)
+ {
+ q->left++;
+ q->count--;
+ return;
+ }
+ if (pos < q->count - 2)
+ memmove(q->elements + pos, q->elements + pos + 2, (q->count - 2 - pos) * sizeof(Id));
+ q->left += 2;
+ q->count -= 2;
+}
+
+void
+queue_insertn(Queue *q, int pos, int n, Id *elements)
+{
+ if (n <= 0)
+ return;
+ if (pos > q->count)
+ pos = q->count;
+ if (q->left < n)
+ {
+ int off;
+ if (!q->alloc)
+ queue_alloc_one(q);
+ off = q->elements - q->alloc;
+ q->alloc = solv_realloc2(q->alloc, off + q->count + n + EXTRA_SPACE, sizeof(Id));
+ q->elements = q->alloc + off;
+ q->left = n + EXTRA_SPACE;
+ }
+ if (pos < q->count)
+ memmove(q->elements + pos + n, q->elements + pos, (q->count - pos) * sizeof(Id));
+ if (elements)
+ memcpy(q->elements + pos, elements, n * sizeof(Id));
+ else
+ memset(q->elements + pos, 0, n * sizeof(Id));
+ q->left -= n;
+ q->count += n;
+}
+
+void
+queue_deleten(Queue *q, int pos, int n)
+{
+ if (n <= 0 || pos >= q->count)
+ return;
+ if (pos + n >= q->count)
+ n = q->count - pos;
+ else
+ memmove(q->elements + pos, q->elements + pos + n, (q->count - n - pos) * sizeof(Id));
+ q->left += n;
+ q->count -= n;
+}
+
+/* allocate room for n more elements */
+void
+queue_prealloc(Queue *q, int n)
+{
+ int off;
+ if (n <= 0 || q->left >= n)
+ return;
+ if (!q->alloc)
+ queue_alloc_one(q);
+ off = q->elements - q->alloc;
+ q->alloc = solv_realloc2(q->alloc, off + q->count + n + EXTRA_SPACE, sizeof(Id));
+ q->elements = q->alloc + off;
+ q->left = n + EXTRA_SPACE;
+}
+