Last active
September 29, 2017 14:37
-
-
Save thebirk/ec7f2ca66ee1950bede82029614d7844 to your computer and use it in GitHub Desktop.
Non-working queue written in Odin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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