Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: build

on: [push, pull_request]
on:
push:
branches:
- main
pull_request:

jobs:
build:
Expand All @@ -14,7 +18,9 @@ jobs:
with:
submodules: recursive
fetch-depth: 0
- uses: mlugg/setup-zig@v2
- uses: zed-industries/setup-zig@node24
with:
version: 0.17.0

- name: Testing
run: zig run runall.zig
Expand All @@ -23,5 +29,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: mlugg/setup-zig@v2
- uses: zed-industries/setup-zig@node24
with:
version: 0.17.0
- run: zig fmt --check --ast-check */*.zig
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
### How to build

**Require:**
- [Zig v0.16.0 or higher](https://ziglang.org/download), self-hosting (stage3) compiler.
- [Zig v0.17.0 or higher](https://ziglang.org/download), self-hosting (stage3) compiler.

### Test all

Expand Down
60 changes: 49 additions & 11 deletions search/binarySearchTree.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ pub fn BinarySearchTree(comptime T: type) type {
// Arguments:
// key: T - the key to be removed from the tree
pub fn remove(self: *Self, key: T) !void {
if (self.root == null) {
return;
var removed = false;
self.root = try self._remove(self.root, key, &removed);
if (removed) {
self.size -= 1;
}
self.root = try self._remove(self.root, key);
self.size -= 1;
}

// Function to search if a key exists in the tree
Expand Down Expand Up @@ -84,10 +84,8 @@ pub fn BinarySearchTree(comptime T: type) type {
// Function that destroys the allocated memory of the whole tree
// Uses the _destroy helper private function
pub fn destroy(self: *Self) void {
if (self.root == null) {
return;
}
self._destroy(self.root);
self.root = null;
self.size = 0;
}

Expand All @@ -114,16 +112,17 @@ pub fn BinarySearchTree(comptime T: type) type {
return root;
}

fn _remove(self: *Self, root: ?*node, key: T) !?*node {
fn _remove(self: *Self, root: ?*node, key: T, removed: *bool) !?*node {
if (root == null) {
return root;
}

if (root.?.info < key) {
root.?.right = try self._remove(root.?.right, key);
root.?.right = try self._remove(root.?.right, key, removed);
} else if (root.?.info > key) {
root.?.left = try self._remove(root.?.left, key);
root.?.left = try self._remove(root.?.left, key, removed);
} else {
removed.* = true;
if (root.?.left == null and root.?.right == null) {
self.allocator.destroy(root.?);
return null;
Expand All @@ -139,7 +138,7 @@ pub fn BinarySearchTree(comptime T: type) type {
var curr: ?*node = root.?.right;
while (curr.?.left != null) : (curr = curr.?.left) {}
root.?.info = curr.?.info;
root.?.right = try self._remove(root.?.right, curr.?.info);
root.?.right = try self._remove(root.?.right, curr.?.info, removed);
}
}

Expand Down Expand Up @@ -282,4 +281,43 @@ test "Testing operations on empty trees" {
try testing.expect(t.search(10) == false);
try t.remove(10);
try testing.expect(t.search(10) == false);
try testing.expect(t.size == 0);
}

test "Testing removal of absent keys keeps size" {
var gpa = std.heap.DebugAllocator(.{}){};
defer assert(gpa.deinit() == .ok);
var allocator = gpa.allocator();

var t = BinarySearchTree(i32){ .allocator = &allocator };
defer t.destroy();

try t.insert(10);
try t.insert(5);
try t.insert(15);

try t.remove(7);
try testing.expect(t.size == 3);
try t.remove(7);
try testing.expect(t.size == 3);
try testing.expect(t.search(10) == true);

try t.remove(10);
try testing.expect(t.size == 2);
}

test "Testing destroy leaves an empty reusable tree" {
var gpa = std.heap.DebugAllocator(.{}){};
defer assert(gpa.deinit() == .ok);
var allocator = gpa.allocator();

var t = BinarySearchTree(i32){ .allocator = &allocator };
defer t.destroy();

try t.insert(10);
t.destroy();
try testing.expect(t.size == 0);
try testing.expect(t.root == null);
try t.insert(5);
try testing.expect(t.size == 1);
}
2 changes: 1 addition & 1 deletion tiger_style/raft_consensus.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub const NodeState = enum(u8) {

pub fn validate(self: NodeState) void {
// Ensure state is valid
assert(@intFromEnum(self) <= 2);
assert(@backingInt(self) <= 2);
}
};

Expand Down
4 changes: 2 additions & 2 deletions tiger_style/two_phase_commit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub const CoordinatorState = enum(u8) {
aborted,

pub fn validate(self: CoordinatorState) void {
assert(@intFromEnum(self) <= 3);
assert(@backingInt(self) <= 3);
}
};

Expand All @@ -39,7 +39,7 @@ pub const ParticipantVote = enum(u8) {
no_response,

pub fn validate(self: ParticipantVote) void {
assert(@intFromEnum(self) <= 2);
assert(@backingInt(self) <= 2);
}
};

Expand Down
2 changes: 1 addition & 1 deletion tiger_style/vsr_consensus.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub const ReplicaState = enum(u8) {
recovering, // Replica recovering

pub fn validate(self: ReplicaState) void {
assert(@intFromEnum(self) <= 2);
assert(@backingInt(self) <= 2);
}
};

Expand Down
Loading