mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
std.Build.Cache: write manifest without heap allocating
Now that the buffered writing interface is not generic.
This commit is contained in:
parent
d6ac04c478
commit
4bca5faca6
@ -2,6 +2,18 @@
|
||||
//! This is not a general-purpose cache. It is designed to be fast and simple,
|
||||
//! not to withstand attacks using specially-crafted input.
|
||||
|
||||
const Cache = @This();
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const crypto = std.crypto;
|
||||
const fs = std.fs;
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
const fmt = std.fmt;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const log = std.log.scoped(.cache);
|
||||
|
||||
gpa: Allocator,
|
||||
manifest_dir: fs.Dir,
|
||||
hash: HashHelper = .{},
|
||||
@ -21,18 +33,6 @@ pub const Path = @import("Cache/Path.zig");
|
||||
pub const Directory = @import("Cache/Directory.zig");
|
||||
pub const DepTokenizer = @import("Cache/DepTokenizer.zig");
|
||||
|
||||
const Cache = @This();
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const crypto = std.crypto;
|
||||
const fs = std.fs;
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const mem = std.mem;
|
||||
const fmt = std.fmt;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const log = std.log.scoped(.cache);
|
||||
|
||||
pub fn addPrefix(cache: *Cache, directory: Directory) void {
|
||||
cache.prefixes_buffer[cache.prefixes_len] = directory;
|
||||
cache.prefixes_len += 1;
|
||||
@ -1118,25 +1118,12 @@ pub const Manifest = struct {
|
||||
if (self.manifest_dirty) {
|
||||
self.manifest_dirty = false;
|
||||
|
||||
const gpa = self.cache.gpa;
|
||||
var contents: std.ArrayListUnmanaged(u8) = .empty;
|
||||
defer contents.deinit(gpa);
|
||||
|
||||
try contents.appendSlice(gpa, manifest_header ++ "\n");
|
||||
for (self.files.keys()) |file| {
|
||||
try contents.print(gpa, "{d} {d} {d} {x} {d} {s}\n", .{
|
||||
file.stat.size,
|
||||
file.stat.inode,
|
||||
file.stat.mtime,
|
||||
&file.bin_digest,
|
||||
file.prefixed_path.prefix,
|
||||
file.prefixed_path.sub_path,
|
||||
});
|
||||
}
|
||||
|
||||
try manifest_file.setEndPos(contents.items.len);
|
||||
var pos: usize = 0;
|
||||
while (pos < contents.items.len) pos += try manifest_file.pwrite(contents.items[pos..], pos);
|
||||
var buffer: [4000]u8 = undefined;
|
||||
var fw = manifest_file.writer(&buffer);
|
||||
writeDirtyManifestToStream(self, &fw) catch |err| switch (err) {
|
||||
error.WriteFailed => return fw.err.?,
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
|
||||
if (self.want_shared_lock) {
|
||||
@ -1144,6 +1131,21 @@ pub const Manifest = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn writeDirtyManifestToStream(self: *Manifest, fw: *fs.File.Writer) !void {
|
||||
try fw.interface.writeAll(manifest_header ++ "\n");
|
||||
for (self.files.keys()) |file| {
|
||||
try fw.interface.print("{d} {d} {d} {x} {d} {s}\n", .{
|
||||
file.stat.size,
|
||||
file.stat.inode,
|
||||
file.stat.mtime,
|
||||
&file.bin_digest,
|
||||
file.prefixed_path.prefix,
|
||||
file.prefixed_path.sub_path,
|
||||
});
|
||||
}
|
||||
try fw.end();
|
||||
}
|
||||
|
||||
fn downgradeToSharedLock(self: *Manifest) !void {
|
||||
if (!self.have_exclusive_lock) return;
|
||||
|
||||
|
||||
@ -1894,6 +1894,20 @@ pub const Writer = struct {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub const EndError = SetEndPosError || std.io.Writer.Error;
|
||||
|
||||
/// Flushes any buffered data and sets the end position of the file.
|
||||
///
|
||||
/// If not overwriting existing contents, then calling `interface.flush`
|
||||
/// directly is sufficient.
|
||||
///
|
||||
/// Flush failure is handled by setting `err` so that it can be handled
|
||||
/// along with other write failures.
|
||||
pub fn end(w: *Writer) EndError!void {
|
||||
try w.interface.flush();
|
||||
return w.file.setEndPos(w.pos);
|
||||
}
|
||||
};
|
||||
|
||||
/// Defaults to positional reading; falls back to streaming.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user