Skip to content

Instantly share code, notes, and snippets.

@thebirk
Last active September 29, 2017 14:37
Show Gist options
  • Save thebirk/ec7f2ca66ee1950bede82029614d7844 to your computer and use it in GitHub Desktop.
Save thebirk/ec7f2ca66ee1950bede82029614d7844 to your computer and use it in GitHub Desktop.
Non-working queue written in Odin
// IMPORTANT: THIS IS A NON WORKING EXAMPLE
// ATTENTION: THIS IS NOT WORKING
import "core:fmt.odin";
QueueNode :: struct(T: type) {
data: T,
prev: int,
used: bool = false,
}
Queue :: struct(T: type) {
nodes: []QueueNode(T),
cap: int = -1,
size: int,
head: int,
tail: int,
}
queue_init :: proc(using queue: ^Queue($T)) {
if cap != -1 do return;
cap = 16;
size = 0;
nodes = make([]QueueNode(T), cap);
head = 0;
tail = -1;
}
queue_clear :: proc(using queue: ^Queue($T)) {
size = 0;
head = 0;
tail = -1;
}
queue_expand :: proc(using queue: ^Queue($T)) {
if size <= cap do return;
old_cap := cap;
cap *= 2;
new_nodes := make([]QueueNode(T), cap);
if tail < head {
// The queue has gone full circle
// so we move everything right of the head to end of the array
// We have:
// [1, 1, tail, head, rest of queue]
// We want:
// [1, 1, tail, more empty, head, rest of queue]
for i := 0; i <= tail; i += 1 {
new_nodes[i] = nodes[i];
}
for i := 0; i < old_cap - head; i += 1 {
new_nodes[cap-1-(old_cap-head)+i] = nodes[head + i];
}
head = cap-head;
} else {
// The queue has not gone full circle
// so we dont have to move anything
// We have:
// [head, 1, 1, 1, 1, tail]
// We want:
// [head, 1, 1, 1, 1, tail, new space]
for i := 0; i < old_cap; i += 1 {
new_nodes[i] = nodes[i];
}
}
free(nodes);
nodes = new_nodes;
}
enqueue :: proc(using queue: ^Queue($T), el: T) {
if cap == -1 do queue_init(queue);
size += 1;
queue_expand(queue);
prev := tail;
if tail == cap-1 {
tail = 0;
} else {
tail += 1;
}
nodes[tail].used = true;
nodes[tail].data = el;
nodes[tail].prev = prev;
}
dequeue :: proc(using queue: ^Queue($T)) -> T {
result := nodes[head].data;
nodes[head].used = false;
head += 1;
if head == cap {
head = 0;
}
size -= 1;
return result;
}
expand_test :: proc() {
test: Queue(int);
for i := 0; i < 16; i += 1 {
enqueue(&test, i);
}
// cause expand
fmt.println("Before 17th element:", test.cap);
enqueue(&test, 255);
fmt.println("After 17th element:", test.cap);
dequeue(&test);
}
normal_expand_then_wrap_test :: proc() {
test: Queue(int);
for i in 0..16 {
enqueue(&test, i);
}
dequeue(&test);
dequeue(&test);
dequeue(&test);
pretty :: proc(using queue: ^Queue($T)) {
fmt.printf("[");
for i := 0; i < cap-1; i += 1 {
val := 0;
if nodes[i].used do val = 1;
fmt.printf("%d, ", val);
}
val := 0;
if nodes[cap-1].used do val = 1;
fmt.printf("%d]\n", val);
}
pretty(&test);
for i in 0..18 {
enqueue(&test, i);
}
pretty(&test);
}
main :: proc() {
test: Queue(int);
pretty :: proc(using queue: ^Queue($T)) {
fmt.printf("[");
for i := 0; i < cap-1; i += 1 {
val := 0;
if nodes[i].used do val = 1;
fmt.printf("%d, ", val);
}
val := 0;
if nodes[cap-1].used do val = 1;
fmt.printf("%d]\n", val);
}
for i in 0..16 {
enqueue(&test, i);
}
dequeue(&test);
dequeue(&test);
dequeue(&test);
enqueue(&test, 1);
//enqueue(&test, 2);
pretty(&test);
for i in 0..200 {
enqueue(&test, i);
fmt.printf("after #%d: ", i);
pretty(&test);
}
pretty(&test);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment