summaryrefslogtreecommitdiff
path: root/src/datastruct
diff options
context:
space:
mode:
Diffstat (limited to 'src/datastruct')
-rw-r--r--src/datastruct/array_list_collection.zig44
-rw-r--r--src/datastruct/cache_table.zig2
-rw-r--r--src/datastruct/circ_buf.zig35
3 files changed, 56 insertions, 25 deletions
diff --git a/src/datastruct/array_list_collection.zig b/src/datastruct/array_list_collection.zig
new file mode 100644
index 000000000..d3fbddb13
--- /dev/null
+++ b/src/datastruct/array_list_collection.zig
@@ -0,0 +1,44 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+
+/// A collection of ArrayLists with methods for bulk operations.
+pub fn ArrayListCollection(comptime T: type) type {
+ return struct {
+ const Self = ArrayListCollection(T);
+ const ArrayListT = std.ArrayListUnmanaged(T);
+
+ // An array containing the lists that belong to this collection.
+ lists: []ArrayListT,
+
+ // The collection will be initialized with empty ArrayLists.
+ pub fn init(
+ alloc: Allocator,
+ list_count: usize,
+ initial_capacity: usize,
+ ) Allocator.Error!Self {
+ const self: Self = .{
+ .lists = try alloc.alloc(ArrayListT, list_count),
+ };
+
+ for (self.lists) |*list| {
+ list.* = try .initCapacity(alloc, initial_capacity);
+ }
+
+ return self;
+ }
+
+ pub fn deinit(self: *Self, alloc: Allocator) void {
+ for (self.lists) |*list| {
+ list.deinit(alloc);
+ }
+ alloc.free(self.lists);
+ }
+
+ /// Clear all lists in the collection, retaining capacity.
+ pub fn reset(self: *Self) void {
+ for (self.lists) |*list| {
+ list.clearRetainingCapacity();
+ }
+ }
+ };
+}
diff --git a/src/datastruct/cache_table.zig b/src/datastruct/cache_table.zig
index 40d36cc24..fbfb30d71 100644
--- a/src/datastruct/cache_table.zig
+++ b/src/datastruct/cache_table.zig
@@ -70,7 +70,7 @@ pub fn CacheTable(
/// become a pointless check, but hopefully branch prediction picks
/// up on it at that point. The memory cost isn't too bad since it's
/// just bytes, so should be a fraction the size of the main table.
- lengths: [bucket_count]u8 = [_]u8{0} ** bucket_count,
+ lengths: [bucket_count]u8 = @splat(0),
/// An instance of the context structure.
/// Must be initialized before calling any operations.
diff --git a/src/datastruct/circ_buf.zig b/src/datastruct/circ_buf.zig
index 065bf6a1d..646a00940 100644
--- a/src/datastruct/circ_buf.zig
+++ b/src/datastruct/circ_buf.zig
@@ -152,7 +152,7 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
/// If larger, new values will be set to the default value.
pub fn resize(self: *Self, alloc: Allocator, size: usize) Allocator.Error!void {
// Rotate to zero so it is aligned.
- try self.rotateToZero(alloc);
+ try self.rotateToZero();
// Reallocate, this adds to the end so we're ready to go.
const prev_len = self.len();
@@ -173,29 +173,16 @@ pub fn CircBuf(comptime T: type, comptime default: T) type {
}
/// Rotate the data so that it is zero-aligned.
- fn rotateToZero(self: *Self, alloc: Allocator) Allocator.Error!void {
- // TODO: this does this in the worst possible way by allocating.
- // rewrite to not allocate, its possible, I'm just lazy right now.
-
+ fn rotateToZero(self: *Self) Allocator.Error!void {
// If we're already at zero then do nothing.
if (self.tail == 0) return;
- var buf = try alloc.alloc(T, self.storage.len);
- defer {
- self.head = if (self.full) 0 else self.len();
- self.tail = 0;
- alloc.free(self.storage);
- self.storage = buf;
- }
+ // We use std.mem.rotate to rotate our storage in-place.
+ std.mem.rotate(T, self.storage, self.tail);
- if (!self.full and self.head >= self.tail) {
- fastmem.copy(T, buf, self.storage[self.tail..self.head]);
- return;
- }
-
- const middle = self.storage.len - self.tail;
- fastmem.copy(T, buf, self.storage[self.tail..]);
- fastmem.copy(T, buf[middle..], self.storage[0..self.head]);
+ // Then fix up our head and tail.
+ self.head = self.len() % self.storage.len;
+ self.tail = 0;
}
/// Returns if the buffer is currently empty. To check if its
@@ -589,7 +576,7 @@ test "CircBuf rotateToZero" {
defer buf.deinit(alloc);
_ = buf.getPtrSlice(0, 11);
- try buf.rotateToZero(alloc);
+ try buf.rotateToZero();
}
test "CircBuf rotateToZero offset" {
@@ -611,7 +598,7 @@ test "CircBuf rotateToZero offset" {
try testing.expect(buf.tail > 0 and buf.head >= buf.tail);
// Rotate to zero
- try buf.rotateToZero(alloc);
+ try buf.rotateToZero();
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 1), buf.head);
}
@@ -645,7 +632,7 @@ test "CircBuf rotateToZero wraps" {
}
// Rotate to zero
- try buf.rotateToZero(alloc);
+ try buf.rotateToZero();
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 3), buf.head);
{
@@ -681,7 +668,7 @@ test "CircBuf rotateToZero full no wrap" {
}
// Rotate to zero
- try buf.rotateToZero(alloc);
+ try buf.rotateToZero();
try testing.expect(buf.full);
try testing.expectEqual(@as(usize, 0), buf.tail);
try testing.expectEqual(@as(usize, 0), buf.head);