feature. See also
. The project being documented here (as the example) is the Zig library itself.
Fetch.queueJobsForDeps
fn queueJobsForDeps(f: *Fetch) RunError!void
File
Code
fn queueJobsForDeps(f: *Fetch) RunError!void {
const io = f.job_queue.io;
assert(f.job_queue.recursive);
if (!f.have_manifest) return;
const manifest = &f.manifest;
const new_fetches, const prog_names = nf: {
const parent_arena = f.arena.allocator();
const gpa = f.arena.child_allocator;
const cache_root = f.job_queue.global_cache;
const dep_names = manifest.dependencies.keys();
const deps = manifest.dependencies.values();
// as fast as possible.
// This overallocates any fetches that get skipped by the `continue` in the
// loop below.
const new_fetches = try parent_arena.alloc(Fetch, deps.len);
const prog_names = try parent_arena.alloc([]const u8, deps.len);
var new_fetch_index: usize = 0;
try f.job_queue.mutex.lock(io);
defer f.job_queue.mutex.unlock(io);
try f.job_queue.all_fetches.ensureUnusedCapacity(gpa, new_fetches.len);
try f.job_queue.table.ensureUnusedCapacity(gpa, @intCast(new_fetches.len));
// * Correct hash is provided by manifest.
// - Hash map already has the entry, no need to add it again.
// * Incorrect hash is provided by manifest.
// - Hash mismatch error emitted; `queueJobsForDeps` is not called.
// * Hash is not provided by manifest.
// - Hash missing error emitted; `queueJobsForDeps` is not called.
// * path-based location is used without a hash.
// - Hash is added to the table based on the path alone before
// calling run(); no need to add it again.
//
// If we add a dep as lazy and then later try to add the same dep as eager,
// eagerness takes precedence and the existing entry is updated and re-scheduled
// for fetching.
for (dep_names, deps) |dep_name, dep| {
var promoted_existing_to_eager = false;
const new_fetch = &new_fetches[new_fetch_index];
const location: Location = switch (dep.location) {
.url => |url| .{
.remote = .{
.url = url,
.hash = h: {
const h = dep.hash orelse break :h null;
const pkg_hash: Package.Hash = .fromSlice(h);
if (h.len == 0) break :h pkg_hash;
const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
if (gop.found_existing) {
if (!dep.lazy and gop.value_ptr.*.lazy_status != .eager) {
gop.value_ptr.*.lazy_status = .eager;
promoted_existing_to_eager = true;
} else {
continue;
}
}
gop.value_ptr.* = new_fetch;
break :h pkg_hash;
},
},
},
.path => |rel_path| l: {
// at the beginning of run().
const new_root = try f.package_root.resolvePosix(parent_arena, rel_path);
const pkg_hash = relativePathDigest(new_root, cache_root);
const gop = f.job_queue.table.getOrPutAssumeCapacity(pkg_hash);
if (gop.found_existing) {
if (!dep.lazy and gop.value_ptr.*.lazy_status != .eager) {
gop.value_ptr.*.lazy_status = .eager;
promoted_existing_to_eager = true;
} else {
continue;
}
}
gop.value_ptr.* = new_fetch;
break :l .{ .relative_path = new_root };
},
};
prog_names[new_fetch_index] = dep_name;
new_fetch_index += 1;
if (!promoted_existing_to_eager) {
f.job_queue.all_fetches.appendAssumeCapacity(new_fetch);
}
new_fetch.* = .{
.arena = std.heap.ArenaAllocator.init(gpa),
.location = location,
.location_tok = dep.location_tok,
.hash_tok = dep.hash_tok,
.name_tok = dep.name_tok,
.lazy_status = switch (f.job_queue.mode) {
.needed => if (dep.lazy) .available else .eager,
.all => .eager,
},
.parent_package_root = f.package_root,
.remote_package_root = f.remote_package_root,
.parent_manifest_ast = &f.manifest_ast,
.prog_node = f.prog_node,
.job_queue = f.job_queue,
.omit_missing_hash_error = false,
.allow_missing_paths_field = true,
.use_latest_commit = false,
.package_root = undefined,
.error_bundle = undefined,
.manifest = undefined,
.manifest_ast = undefined,
.have_manifest = false,
.computed_hash = undefined,
.has_build_zig = false,
.oom_flag = false,
.latest_commit = null,
.cli_module = null,
};
}
f.prog_node.increaseEstimatedTotalItems(new_fetch_index);
break :nf .{ new_fetches[0..new_fetch_index], prog_names[0..new_fetch_index] };
};
for (new_fetches, prog_names) |*new_fetch, prog_name| {
f.job_queue.group.async(io, workerRun, .{ new_fetch, prog_name });
}
}