mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
* @min and @max * builtins and some trivial ones * Most of them * more * more! * More Progress * wip * Update tagged_pointer.zig * Update http_client_async.zig * Most of the iterable dir changes * alright * Remove usages of deprecated formatters * 📷 * fmt * Update shimmer.zig * wip * wip * wip * progress * more * Latest * stuck on error * latest * workaround stage2 * wip * Update string_immutable.zig * wip * Migrate `Dirent` and `require("fs')` to use JSC<>Zig bindings * Fix build errors * Fixup most of the test failures * Fix `make headers` * Fix "outside package path" error * Fixup aligned alloc * Add missing file * linux * More linux fixes * use latest peechy * Fix transpiler test failure * Forgot about these * Fixup test failure * Update node-timers.test.ts * [node:htt] Fix `undefined is not an object` error Fixes https://github.com/oven-sh/bun/issues/1618 * Update http.exports.js * Make this test less flaky * fix hashes * Fix hex formatting and zls issues * Download zig version * Update Dockerfile * Update Dockerfile * Update uws * Update Dockerfile * Set llvm version * Update README.md * Update uws * Update Dockerfile * Update io_linux.zig * Update bun.zig * Log output * workaround strange @cInclude error * Make ffi tests better * Don't use cImport * Update c.zig * Update c-bindings.cpp * call setOutputDir * Update Dockerfile * Use a longer name * latest * Update serve.test.ts Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Co-authored-by: Veikka Tuominen <git@vexu.eu>
96 lines
2.6 KiB
Zig
96 lines
2.6 KiB
Zig
/// Rope-like data structure for joining many small strings into one big string.
|
|
const Joiner = @This();
|
|
|
|
const string = @import("string_types.zig").string;
|
|
const Allocator = @import("std").mem.Allocator;
|
|
const assert = @import("std").debug.assert;
|
|
const copy = @import("std").mem.copy;
|
|
const Env = @import("./env.zig");
|
|
const ObjectPool = @import("./pool.zig").ObjectPool;
|
|
|
|
const default_allocator = @import("bun").default_allocator;
|
|
|
|
const Joinable = struct {
|
|
offset: u31 = 0,
|
|
needs_deinit: bool = false,
|
|
allocator: std.mem.Allocator = undefined,
|
|
slice: []const u8 = "",
|
|
|
|
pub const Pool = ObjectPool(Joinable, null, true, 4);
|
|
};
|
|
|
|
last_byte: u8 = 0,
|
|
len: usize = 0,
|
|
use_pool: bool = true,
|
|
node_allocator: std.mem.Allocator = undefined,
|
|
|
|
head: ?*Joinable.Pool.Node = null,
|
|
tail: ?*Joinable.Pool.Node = null,
|
|
|
|
pub fn done(this: *Joiner, allocator: std.mem.Allocator) ![]u8 {
|
|
if (this.head == null) {
|
|
var out: []u8 = &[_]u8{};
|
|
return out;
|
|
}
|
|
|
|
var slice = try allocator.alloc(u8, this.len);
|
|
var remaining = slice;
|
|
var el_ = this.head;
|
|
while (el_) |join| {
|
|
const to_join = join.data.slice[join.data.offset..];
|
|
@memcpy(remaining.ptr, to_join.ptr, to_join.len);
|
|
|
|
remaining = remaining[@min(remaining.len, to_join.len)..];
|
|
|
|
var prev = join;
|
|
el_ = join.next;
|
|
if (prev.data.needs_deinit) {
|
|
prev.data.allocator.free(prev.data.slice);
|
|
prev.data = Joinable{};
|
|
}
|
|
|
|
if (this.use_pool) prev.release();
|
|
}
|
|
|
|
return slice[0 .. slice.len - remaining.len];
|
|
}
|
|
|
|
pub fn lastByte(this: *const Joiner) u8 {
|
|
if (this.tail) |tail| {
|
|
const slice = tail.data.slice[tail.data.offset..];
|
|
return if (slice.len > 0) slice[slice.len - 1] else 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
pub fn append(this: *Joiner, slice: string, offset: u32, allocator: ?std.mem.Allocator) void {
|
|
const data = slice[offset..];
|
|
this.len += @truncate(u32, data.len);
|
|
|
|
var new_tail = if (this.use_pool)
|
|
Joinable.Pool.get(default_allocator)
|
|
else
|
|
(this.node_allocator.create(Joinable.Pool.Node) catch unreachable);
|
|
|
|
new_tail.* = .{
|
|
.allocator = default_allocator,
|
|
.data = Joinable{
|
|
.offset = @truncate(u31, offset),
|
|
.allocator = allocator orelse undefined,
|
|
.needs_deinit = allocator != null,
|
|
.slice = slice,
|
|
},
|
|
};
|
|
|
|
var tail = this.tail orelse {
|
|
this.tail = new_tail;
|
|
this.head = new_tail;
|
|
return;
|
|
};
|
|
tail.next = new_tail;
|
|
this.tail = new_tail;
|
|
}
|
|
|
|
const std = @import("std");
|