shithub: sce

Download patch

ref: fd50731b43864c9e2e7dcaf1a8aae4d3a3c7c8fb
parent: 88d10fd7cc9f47e67c1813b98984e8b3393a71b3
author: qwx <qwx@sciops.net>
date: Tue Feb 22 21:26:49 EST 2022

add simple quadtree implementation

--- a/dat.h
+++ b/dat.h
@@ -18,6 +18,7 @@
 typedef struct Cbuf Cbuf;
 typedef struct Msg Msg;
 typedef struct Vector Vector;
+typedef struct QNode QNode;
 
 enum{
 	Nresource = 3,
@@ -44,6 +45,17 @@
 	ulong bufsz;
 	ulong totsz;
 	int firstempty;
+};
+
+struct QNode{
+	QNode *left;
+	QNode *right;
+	QNode *up;
+	QNode *down;
+	void *aux;
+
+	QNode *prev;
+	QNode *next;
 };
 
 struct Pairheap{
--- /dev/null
+++ b/qtree.c
@@ -1,0 +1,79 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+enum{
+	Ninc = 128,
+};
+
+/* no nodes are ever freed */
+static QNode freeq = { .next = &freeq, .prev = &freeq };
+
+static void
+qtlink(QNode *q)
+{
+	assert(q != nil);
+	q->prev = freeq.prev;
+	q->next = &freeq;
+	freeq.prev->next = q;
+	freeq.prev = q;
+}
+
+void
+qtfree(QNode *q)
+{
+	if(q == nil)
+		return;
+	free(q->aux);
+	memset(q, 0, sizeof *q);
+	qtlink(q);
+}
+
+static QNode *
+qtalloc(void)
+{
+	QNode *q, *fq;
+
+	if(freeq.next == &freeq){
+		q = emalloc(Ninc * sizeof *q);
+		for(fq=q; fq<q+Ninc; fq++)
+			qtlink(fq);
+	}
+	q = freeq.next;
+	q->next->prev = &freeq;
+	freeq.next = q->next;
+	q->prev = q->next = nil;
+	return q;
+}
+
+QNode *
+qtmerge(QNode *q)
+{
+	if(q == nil)
+		return nil;
+	qtmerge(q->left);
+	qtmerge(q->right);
+	qtmerge(q->up);
+	qtmerge(q->down);
+	qtfree(q->left);
+	qtfree(q->right);
+	qtfree(q->up);
+	qtfree(q->down);
+	q->left = q->right = q->up = q->down = nil;
+	dprint("qtmerge %#p\n", q);
+	return q;
+}
+
+QNode *
+qtsplit(QNode *q)
+{
+	assert(q->left == nil && q->right == nil && q->up == nil && q->down == nil);
+	dprint("qtsplit %#p\n", q);
+	q->left = qtalloc();
+	q->right = qtalloc();
+	q->up = qtalloc();
+	q->down = qtalloc();
+	return q;
+}