diff --git a/ring/ring.odin b/ring/ring.odin index 4a3ad13..382e408 100644 --- a/ring/ring.odin +++ b/ring/ring.odin @@ -7,13 +7,13 @@ import "core:fmt" ODIN_BOUNDS_CHECK :: !ODIN_NO_BOUNDS_CHECK Ring :: struct($E: typeid) { - data: []E, - _end_index, len: int, + data: []E, + next_write_index, len: int, } Ring_Soa :: struct($E: typeid) { - data: #soa[]E, - _end_index, len: int, + data: #soa[]E, + next_write_index, len: int, } destroy_aos :: #force_inline proc(ring: ^Ring($E)) -> runtime.Allocator_Error { @@ -38,7 +38,6 @@ create_aos :: #force_inline proc( err: runtime.Allocator_Error, ) #optional_allocator_error { ring.data, err = make([]E, capacity, allocator) - ring._end_index = -1 return ring, err } @@ -51,21 +50,20 @@ create_soa :: #force_inline proc( err: runtime.Allocator_Error, ) #optional_allocator_error { ring.data, err = make(#soa[]E, capacity, allocator) - ring._end_index = -1 return ring, err } init_from_slice_aos :: #force_inline proc(ring: ^Ring($E), data: $T/[]E) { ring.data = data ring.len = 0 - ring._end_index = -1 + ring.next_write_index = 0 return } init_from_slice_soa :: #force_inline proc(ring: ^Ring_Soa($E), data: $T/#soa[]E) { ring.data = data ring.len = 0 - ring._end_index = -1 + ring.next_write_index = 0 return } @@ -74,46 +72,32 @@ init_from_slice :: proc { init_from_slice_soa, } +// Internal // Index in the backing array where the ring starts -_start_index_aos :: #force_inline proc(ring: Ring($E)) -> int { - if ring.len < len(ring.data) { - return 0 - } else { - start_index := ring._end_index + 1 - return 0 if start_index == len(ring.data) else start_index - } +start_index_aos :: #force_inline proc(ring: Ring($E)) -> int { + return ring.len < len(ring.data) ? 0 : ring.next_write_index } +// Internal // Index in the backing array where the ring starts -_start_index_soa :: #force_inline proc(ring: Ring_Soa($E)) -> int { - if ring.len < len(ring.data) { - return 0 - } else { - start_index := ring._end_index + 1 - return 0 if start_index == len(ring.data) else start_index - } +start_index_soa :: #force_inline proc(ring: Ring_Soa($E)) -> int { + return ring.len < len(ring.data) ? 0 : ring.next_write_index } advance_aos :: #force_inline proc(ring: ^Ring($E)) { // Length if ring.len != len(ring.data) do ring.len += 1 - // End index - if ring._end_index == len(ring.data) - 1 { // If we are at the end of the backing array - ring._end_index = 0 // Overflow end to 0 - } else { - ring._end_index += 1 - } + // Write index + ring.next_write_index += 1 + if ring.next_write_index == len(ring.data) do ring.next_write_index = 0 } advance_soa :: #force_inline proc(ring: ^Ring_Soa($E)) { // Length if ring.len != len(ring.data) do ring.len += 1 - // End index - if ring._end_index == len(ring.data) - 1 { // If we are at the end of the backing array - ring._end_index = 0 // Overflow end to 0 - } else { - ring._end_index += 1 - } + // Write index + ring.next_write_index += 1 + if ring.next_write_index == len(ring.data) do ring.next_write_index = 0 } advance :: proc { @@ -122,13 +106,13 @@ advance :: proc { } append_aos :: #force_inline proc(ring: ^Ring($E), element: E) { + ring.data[ring.next_write_index] = element advance(ring) - ring.data[ring._end_index] = element } append_soa :: #force_inline proc(ring: ^Ring_Soa($E), element: E) { + ring.data[ring.next_write_index] = element advance(ring) - ring.data[ring._end_index] = element } append :: proc { @@ -141,7 +125,7 @@ get_aos :: #force_inline proc(ring: Ring($E), index: int) -> ^E { fmt.assertf(index < ring.len, "Ring index %i out of bounds for length %i", index, ring.len) } - array_index := _start_index_aos(ring) + index + array_index := start_index_aos(ring) + index if array_index < len(ring.data) { return &ring.data[array_index] } else { @@ -156,7 +140,7 @@ get_soa :: #force_inline proc(ring: Ring_Soa($E), index: int) -> E { fmt.assertf(index < ring.len, "Ring index %i out of bounds for length %i", index, ring.len) } - array_index := _start_index_soa(ring) + index + array_index := start_index_soa(ring) + index if array_index < len(ring.data) { return ring.data[array_index] } else { @@ -185,12 +169,12 @@ get_last :: proc { clear_aos :: #force_inline proc "contextless" (ring: ^Ring($E)) { ring.len = 0 - ring._end_index = -1 + ring.next_write_index = 0 } clear_soa :: #force_inline proc "contextless" (ring: ^Ring_Soa($E)) { ring.len = 0 - ring._end_index = -1 + ring.next_write_index = 0 } clear :: proc { @@ -212,21 +196,21 @@ test_ring_aos :: proc(t: ^testing.T) { for i in 1 ..= 5 { append(&ring, i) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_aos(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_aos(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0)^, 1) testing.expect_value(t, get(ring, 4)^, 5) testing.expect_value(t, ring.len, 5) - testing.expect_value(t, ring._end_index, 4) - testing.expect_value(t, _start_index_aos(ring), 0) + testing.expect_value(t, ring.next_write_index, 5) + testing.expect_value(t, start_index_aos(ring), 0) for i in 6 ..= 15 { append(&ring, i) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_aos(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_aos(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0)^, 6) @@ -234,18 +218,18 @@ test_ring_aos :: proc(t: ^testing.T) { testing.expect_value(t, get(ring, 9)^, 15) testing.expect_value(t, get_last(ring)^, 15) testing.expect_value(t, ring.len, 10) - testing.expect_value(t, ring._end_index, 4) - testing.expect_value(t, _start_index_aos(ring), 5) + testing.expect_value(t, ring.next_write_index, 5) + testing.expect_value(t, start_index_aos(ring), 5) for i in 15 ..= 25 { append(&ring, i) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_aos(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_aos(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0)^, 16) - testing.expect_value(t, ring._end_index, 5) + testing.expect_value(t, ring.next_write_index, 6) testing.expect_value(t, get_last(ring)^, 25) clear(&ring) @@ -266,21 +250,21 @@ test_ring_soa :: proc(t: ^testing.T) { for i in 1 ..= 5 { append(&ring, Ints{i, i}) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_soa(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_soa(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0), Ints{1, 1}) testing.expect_value(t, get(ring, 4), Ints{5, 5}) testing.expect_value(t, ring.len, 5) - testing.expect_value(t, ring._end_index, 4) - testing.expect_value(t, _start_index_soa(ring), 0) + testing.expect_value(t, ring.next_write_index, 5) + testing.expect_value(t, start_index_soa(ring), 0) for i in 6 ..= 15 { append(&ring, Ints{i, i}) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_soa(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_soa(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0), Ints{6, 6}) @@ -288,18 +272,18 @@ test_ring_soa :: proc(t: ^testing.T) { testing.expect_value(t, get(ring, 9), Ints{15, 15}) testing.expect_value(t, get_last(ring), Ints{15, 15}) testing.expect_value(t, ring.len, 10) - testing.expect_value(t, ring._end_index, 4) - testing.expect_value(t, _start_index_soa(ring), 5) + testing.expect_value(t, ring.next_write_index, 5) + testing.expect_value(t, start_index_soa(ring), 5) for i in 15 ..= 25 { append(&ring, Ints{i, i}) log.debug("Length:", ring.len) - log.debug("Start index:", _start_index_soa(ring)) - log.debug("End index:", ring._end_index) + log.debug("Start index:", start_index_soa(ring)) + log.debug("Next write index:", ring.next_write_index) log.debug(ring.data) } testing.expect_value(t, get(ring, 0), Ints{16, 16}) - testing.expect_value(t, ring._end_index, 5) + testing.expect_value(t, ring.next_write_index, 6) testing.expect_value(t, get_last(ring), Ints{25, 25}) clear(&ring)