summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsteven-na <noreply.github@stvnc.dev>2026-08-06 02:36:01 -0700
committersteven-na <noreply.github@stvnc.dev>2026-08-06 02:36:01 -0700
commit5d575f8cd99e9bc064b3d998f17b194a818e3546 (patch)
tree8a8e1485dda924aeefb5428e26dbcca74f74721e /src
parentd07b96b9914e706630dc1d2807ecfa9e104945d5 (diff)
Sliding window array implementation
Diffstat (limited to 'src')
-rw-r--r--src/slidingwindow.c43
-rw-r--r--src/slidingwindow.h19
-rw-r--r--src/vec2sw.c23
-rw-r--r--src/vec2sw.h16
4 files changed, 101 insertions, 0 deletions
diff --git a/src/slidingwindow.c b/src/slidingwindow.c
new file mode 100644
index 0000000..883e852
--- /dev/null
+++ b/src/slidingwindow.c
@@ -0,0 +1,43 @@
+#include "slidingwindow.h"
+#include "common.h"
+#include "smrt_arena.h"
+
+#include <string.h>
+
+sliding_window_array_t *sw_create(smrt_arena_t *arena, u64 elem_size, u64 size) {
+ sliding_window_array_t *sw = smrt_arena_push(arena, sizeof(sliding_window_array_t) + 2 * elem_size * size, true);
+ sw->size = size;
+ sw->element_size_bytes = elem_size;
+
+ return sw;
+}
+
+void sw_insert(sliding_window_array_t *sw, void *x) {
+ if (sw->num_elements == sw->size) {
+ sw->start_idx++;
+ }
+
+ if ((sw->start_idx + sw->size) > (2 * sw->size)) {
+ u64 src_offset = SLIDING_WINDOW_BASE_POS + (sw->start_idx * sw->element_size_bytes);
+ u64 bytes_to_copy = (sw->size - 1) * sw->element_size_bytes;
+ memmove(
+ ((u8*)sw + SLIDING_WINDOW_BASE_POS),
+ ((u8*)sw + src_offset),
+ bytes_to_copy
+ );
+
+ sw->start_idx = 0;
+ }
+
+ u64 new_pos = sw->start_idx + sw->num_elements;
+
+ if (new_pos >= sw->start_idx + sw->size) {
+ new_pos = sw->start_idx + sw->size - 1;
+ }
+
+ memcpy(((u8*)sw + SLIDING_WINDOW_BASE_POS + (new_pos * sw->element_size_bytes)), x, sw->element_size_bytes);
+
+ if (sw->num_elements < sw->size) {
+ sw->num_elements++;
+ }
+}
diff --git a/src/slidingwindow.h b/src/slidingwindow.h
new file mode 100644
index 0000000..3cfe821
--- /dev/null
+++ b/src/slidingwindow.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "common.h"
+#include "smrt_arena.h"
+
+#define SLIDING_WINDOW_BASE_POS (sizeof(sliding_window_array_t))
+
+typedef struct {
+ u64 size;
+ u64 num_elements;
+ u64 start_idx;
+ u64 element_size_bytes;
+} sliding_window_array_t;
+
+#define SMRTA_ALLOC_SLIDINGWINDOW(arena, T, n) (sliding_window_array_t*)sw_create(arena, sizeof(T), (n))
+#define SLIDINGWINDOW_GET(w, T) ((T*)((u8*)(w) + SLIDING_WINDOW_BASE_POS) + (w)->start_idx)
+
+sliding_window_array_t *sw_create(smrt_arena_t *arena, u64 elem_size, u64 size);
+void sw_insert(sliding_window_array_t *sw, void *x);
diff --git a/src/vec2sw.c b/src/vec2sw.c
new file mode 100644
index 0000000..0e1aec0
--- /dev/null
+++ b/src/vec2sw.c
@@ -0,0 +1,23 @@
+#include "vec2sw.h"
+#include "slidingwindow.h"
+#include "vec2.h"
+
+vec2d_sw_soa_t vec2d_sw_soa(smrt_arena_t *arena, u64 size) {
+ vec2d_sw_soa_t vs = { .size=size };
+ vs.xs = SMRTA_ALLOC_SLIDINGWINDOW(arena, f64, size);
+ vs.ys = SMRTA_ALLOC_SLIDINGWINDOW(arena, f64, size);
+ return vs;
+}
+
+void vec2d_sw_soa_insert(vec2d_sw_soa_t sw_vs, vec2d_t v) {
+ sw_insert(sw_vs.xs, (void*)&v.x);
+ sw_insert(sw_vs.ys, (void*)&v.y);
+}
+
+vec2d_soa_t vec2d_sw_soa_get(vec2d_sw_soa_t sw_vs) {
+ return (vec2d_soa_t){
+ .size = sw_vs.xs->num_elements,
+ .xs = SLIDINGWINDOW_GET(sw_vs.xs, f64),
+ .ys = SLIDINGWINDOW_GET(sw_vs.ys, f64),
+ };
+}
diff --git a/src/vec2sw.h b/src/vec2sw.h
new file mode 100644
index 0000000..cbf8e6d
--- /dev/null
+++ b/src/vec2sw.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "common.h"
+#include "smrt_arena.h"
+#include "vec2.h"
+#include "slidingwindow.h"
+
+typedef struct {
+ sliding_window_array_t *xs;
+ sliding_window_array_t *ys;
+ u64 size;
+} vec2d_sw_soa_t;
+
+vec2d_sw_soa_t vec2d_sw_soa(smrt_arena_t *arena, u64 size);
+ void vec2d_sw_soa_insert(vec2d_sw_soa_t sw_vs, vec2d_t v);
+ vec2d_soa_t vec2d_sw_soa_get(vec2d_sw_soa_t sw_vs);