Skip to content

Commit 79dfaaf

Browse files
committed
Replace PackedIntArray with std.mem packed reads and writes
1 parent b79f9b8 commit 79dfaaf

1 file changed

Lines changed: 23 additions & 14 deletions

File tree

src/main.zig

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,14 @@ pub fn StateMachineFromTable(
9595
// Events are organized into a packed 2D array. Indexing by state and event yields the next state (where 0 means no transition)
9696
// Add 1 to bit_count because zero is used to indicates absence of transition (no target state defined for a source state/event combination)
9797
// Cell values must thus be adjusted accordingly when added or queried.
98-
const CellType = std.meta.Int(.unsigned, @as(u16, @max(state_enum_bits, event_enum_bits)) + 1);
99-
const EventPackedIntArray = if (EventType != null) std.PackedIntArray(CellType, state_type_count * @max(event_type_count, 1)) else void;
98+
const bits_per_cell = @as(u16, @max(state_enum_bits, event_enum_bits)) + 1;
99+
const total_bits = (bits_per_cell * state_type_count * @max(event_type_count, 1));
100+
const total_bytes = total_bits / 8 + 1;
101+
const CellType = std.meta.Int(.unsigned, bits_per_cell);
102+
const EventPackedIntArray = if (EventType != null)
103+
[total_bytes]u8
104+
else
105+
void;
100106

101107
return struct {
102108
internal: struct {
@@ -125,7 +131,9 @@ pub fn StateMachineFromTable(
125131
instance.internal.final_states = FinalStatesType.initEmpty();
126132
instance.internal.transition_handlers = &.{};
127133
instance.internal.state_map = TransitionBitSet.initEmpty();
128-
if (comptime EventType != null) instance.internal.events = EventPackedIntArray.initAllTo(0);
134+
if (comptime EventType != null) {
135+
instance.internal.events = .{0} ** total_bytes;
136+
}
129137

130138
for (transitions) |t| {
131139
const offset = (@intFromEnum(t.from) * state_type_count) + @intFromEnum(t.to);
@@ -134,7 +142,7 @@ pub fn StateMachineFromTable(
134142
if (comptime EventType != null) {
135143
if (t.event) |event| {
136144
const slot = computeEventSlot(event, t.from);
137-
instance.internal.events.set(slot, @intFromEnum(t.to) + @as(CellType, 1));
145+
std.mem.writePackedIntNative(CellType, &instance.internal.events, slot * bits_per_cell, @intFromEnum(t.to) + @as(CellType, 1));
138146
}
139147
}
140148
}
@@ -219,8 +227,9 @@ pub fn StateMachineFromTable(
219227
if (comptime EventType != null) {
220228
if (self.canTransitionFromTo(from, to)) {
221229
const slot = computeEventSlot(event, from);
222-
if (self.internal.events.get(slot) != 0) return StateError.AlreadyDefined;
223-
self.internal.events.set(slot, @as(CellType, @intCast(@intFromEnum(to))) + 1);
230+
const slot_val = std.mem.readPackedIntNative(CellType, &self.internal.events, slot * bits_per_cell);
231+
if (slot_val != 0) return StateError.AlreadyDefined;
232+
std.mem.writePackedIntNative(CellType, &self.internal.events, slot * bits_per_cell, @as(CellType, @intCast(@intFromEnum(to))) + 1);
224233
} else return StateError.Invalid;
225234
}
226235
}
@@ -231,7 +240,7 @@ pub fn StateMachineFromTable(
231240
if (comptime EventType != null) {
232241
const from_state = self.internal.current_state;
233242
const slot = computeEventSlot(event, self.internal.current_state);
234-
const to_state = self.internal.events.get(slot);
243+
const to_state = std.mem.readPackedIntNative(CellType, &self.internal.events, slot * bits_per_cell);
235244
if (to_state != 0) {
236245
try self.transitionToInternal(event, @as(StateType, @enumFromInt(to_state - 1)));
237246
return .{ .event = event, .from = from_state, .to = @as(StateType, @enumFromInt(to_state - 1)) };
@@ -391,7 +400,7 @@ pub fn StateMachineFromTable(
391400
var transition_name_buf: [4096]u8 = undefined;
392401
var transition_name = std.io.fixedBufferStream(&transition_name_buf);
393402
for (0..event_type_count) |event_index| {
394-
const slot_val = self.internal.events.get(events_start_offset + event_index);
403+
const slot_val = std.mem.readPackedIntNative(CellType, &self.internal.events, (events_start_offset + event_index) * bits_per_cell);
395404
if (slot_val > 0 and (slot_val - 1) == @intFromEnum(to)) {
396405
if ((try transition_name.getPos()) == 0) {
397406
try writer.print(" [label = \"", .{});
@@ -500,11 +509,11 @@ pub fn StateMachineFromTable(
500509
fsm.setTransitionHandlers(&handlers);
501510

502511
var line_no: usize = 1;
503-
var lines = std.mem.split(u8, input, "\n");
512+
var lines = std.mem.splitAny(u8, input, "\n");
504513

505514
while (lines.next()) |line| {
506515
if (std.mem.indexOf(u8, line, "->") == null and std.mem.indexOf(u8, line, "start:") == null and std.mem.indexOf(u8, line, "end:") == null) continue;
507-
var parts = std.mem.tokenize(u8, line, " \t='\";,");
516+
var parts = std.mem.tokenizeAny(u8, line, " \t='\";,");
508517
while (parts.next()) |part| {
509518
if (anyStringsEqual(&.{ "->", "[label", "]", "||" }, part)) {
510519
continue;
@@ -551,11 +560,11 @@ pub fn FsmFromText(comptime input: []const u8) type {
551560
var event_enum_fields: []const EnumField = &[_]EnumField{};
552561

553562
var line_no: usize = 1;
554-
var lines = std.mem.split(u8, input, "\n");
563+
var lines = std.mem.splitAny(u8, input, "\n");
555564
var start_state_index: usize = 0;
556565
while (lines.next()) |line| {
557566
if (std.mem.indexOf(u8, line, "->") == null and std.mem.indexOf(u8, line, "start:") == null and std.mem.indexOf(u8, line, "end:") == null) continue;
558-
var parts = std.mem.tokenize(u8, line, " \t='\";,");
567+
var parts = std.mem.tokenizeAny(u8, line, " \t='\";,");
559568
part_loop: while (parts.next()) |part| {
560569
if (anyStringsEqual(&.{ "->", "[label", "]", "||" }, part)) {
561570
continue;
@@ -602,14 +611,14 @@ pub fn FsmFromText(comptime input: []const u8) type {
602611
}
603612
_ = fsm.do(.newline) catch unreachable;
604613

605-
const StateEnum = @Type(.{ .Enum = .{
614+
const StateEnum = @Type(.{ .@"enum" = .{
606615
.fields = state_enum_fields,
607616
.tag_type = std.math.IntFittingRange(0, state_enum_fields.len),
608617
.decls = &[_]std.builtin.Type.Declaration{},
609618
.is_exhaustive = false,
610619
} });
611620

612-
const EventEnum = if (event_enum_fields.len > 0) @Type(.{ .Enum = .{
621+
const EventEnum = if (event_enum_fields.len > 0) @Type(.{ .@"enum" = .{
613622
.fields = event_enum_fields,
614623
.tag_type = std.math.IntFittingRange(0, event_enum_fields.len),
615624
.decls = &[_]std.builtin.Type.Declaration{},

0 commit comments

Comments
 (0)