Skip to content

Commit

Permalink
feat: pre-allocated buffer resizing
Browse files Browse the repository at this point in the history
Removed `resizeIfNeeded`, since `realloc` effectively that for us.
Exposed the `resize` functions to the public `Ascii` and `Unicode`
interfaces to make them available to users.
  • Loading branch information
fjebaker committed Aug 12, 2024
1 parent ad33235 commit 967df94
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 37 deletions.
67 changes: 30 additions & 37 deletions src/root.zig
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ pub fn AlgorithmType(
max_haystack: usize,
max_needle: usize,
) !Self {

// init to a min size, and resize after if needed
const rows = max_needle + 1;
const cols = max_haystack + 1;

Expand Down Expand Up @@ -171,48 +169,35 @@ pub fn AlgorithmType(
};
}

/// Resize matrixs and buffer if it is needed
pub fn resizeIfNeeded(self: *Self, max_haystack: usize, max_needle: usize) !void {
/// Resize pre-allocated buffers to fit a new maximum haystack and
/// needle size
pub fn resize(self: *Self, max_haystack: usize, max_needle: usize) !void {
const new_rows = max_needle + 1;
const new_cols = max_haystack + 1;

if (new_rows <= self.m.rows and new_cols <= self.m.cols) {
return;
}

if (new_rows > self.first_match_buffer.len) {
self.first_match_buffer = try self.allocator.realloc(self.first_match_buffer, new_rows);
}
if (new_cols > self.role_bonus.len) {
self.role_bonus = try self.allocator.realloc(self.role_bonus, new_cols);
self.bonus_buffer = try self.allocator.realloc(self.bonus_buffer, new_cols);
self.traceback_buffer = try self.allocator.realloc(self.traceback_buffer, new_cols);
}

if (new_rows * new_cols > self.m.matrix.len) {
try self.m.resizeAlloc(new_rows, new_cols);
try self.x.resizeAlloc(new_rows, new_cols);
try self.m_skip.resizeAlloc(new_rows, new_cols);
}
return;
}
self.first_match_buffer = try self.allocator.realloc(
self.first_match_buffer,
new_rows,
);

/// Force to resize all matrixs and buffer
pub fn resize(self: *Self, max_haystack: usize, max_needle: usize) !void {
const new_rows = max_needle + 1;
const new_cols = max_haystack + 1;
self.role_bonus = try self.allocator.realloc(
self.role_bonus,
new_cols,
);

self.first_match_buffer = try self.allocator.realloc(self.first_match_buffer, new_rows);
self.bonus_buffer = try self.allocator.realloc(
self.bonus_buffer,
new_cols,
);

self.role_bonus = try self.allocator.realloc(self.role_bonus, new_cols);
self.bonus_buffer = try self.allocator.realloc(self.bonus_buffer, new_cols);
self.traceback_buffer = try self.allocator.realloc(self.traceback_buffer, new_cols);
self.traceback_buffer = try self.allocator.realloc(
self.traceback_buffer,
new_cols,
);

try self.m.resizeAlloc(new_rows, new_cols);
try self.x.resizeAlloc(new_rows, new_cols);
try self.m_skip.resizeAlloc(new_rows, new_cols);

return;
}

/// Compute matching score
Expand Down Expand Up @@ -546,9 +531,6 @@ pub const Ascii = struct {
.isEqual = eqlFunc,
};

alg: Algorithm,
opts: Options,

fn eqlFunc(self: *Ascii, h: u8, n: u8) bool {
if (n == ' ' and self.opts.wildcard_spaces) {
return switch (h) {
Expand Down Expand Up @@ -603,6 +585,9 @@ pub const Ascii = struct {
penalty_case_mistmatch: i32 = -2,
};

alg: Algorithm,
opts: Options,

// public interface

pub fn init(
Expand All @@ -619,6 +604,7 @@ pub const Ascii = struct {
self.alg.deinit();
}

/// Compute matching score
pub fn score(
self: *Ascii,
haystack: []const u8,
Expand All @@ -627,13 +613,20 @@ pub const Ascii = struct {
return self.alg.score(self, FunctionTable, haystack, needle);
}

/// Compute the score and the indices of the matched characters
pub fn scoreMatches(
self: *Ascii,
haystack: []const u8,
needle: []const u8,
) Algorithm.Matches {
return self.alg.scoreMatches(self, FunctionTable, haystack, needle);
}

/// Resize pre-allocated buffers to fit a new maximum haystack and
/// needle size
pub fn resize(self: *Ascii, max_haystack: usize, max_needle: usize) !void {
try self.alg.resize(max_haystack, max_needle);
}
};

fn doTestScore(alg: *Ascii, haystack: []const u8, needle: []const u8, comptime score: i32) !void {
Expand Down
12 changes: 12 additions & 0 deletions src/unicode.zig
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ pub const Unicode = struct {
self.alg.deinit();
}

/// Compute matching score. Recasts the `u8` array to `u21` to properly
/// encode unicode characters
pub fn score(
self: *Unicode,
haystack: []const u8,
Expand All @@ -191,22 +193,32 @@ pub const Unicode = struct {
);
}

/// Compute the score and the indices of the matched characters. Recasts
/// the `u8` array to `u21` to properly encode unicode characters
pub fn scoreMatches(
self: *Unicode,
haystack: []const u8,
needle: []const u8,
) Algorithm.Matches {
const haystack_normal = self.convertString(haystack);
defer self.allocator.free(haystack_normal);

const needle_normal = self.convertString(needle);
defer self.allocator.free(needle_normal);

return self.alg.scoreMatches(
self,
FunctionTable,
haystack_normal,
needle_normal,
);
}

/// Resize pre-allocated buffers to fit a new maximum haystack and
/// needle size
pub fn resize(self: *Unicode, max_haystack: usize, max_needle: usize) !void {
try self.alg.resize(max_haystack, max_needle);
}
};

fn doTestScoreUnicode(
Expand Down

0 comments on commit 967df94

Please sign in to comment.