authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-03 16:02:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-03 22:58:52-07:00
log810f70ef42fa013dc31b13445dd2910a43f8a0f7
treea3bfb745f1de2ad9c9e523cf18a1a0ec7a7220b2
parent337e1109f5c2894aad9519ee9f7ff1f1f4c65b56

update compiler usage of DoublyLinkedList API


1 files changed, 17 insertions(+), 10 deletions(-)

src/Package/Fetch/git.zig+17-10
...@@ -473,14 +473,18 @@ const Object = struct {...@@ -473,14 +473,18 @@ const Object = struct {
473/// objects remaining in the cache will be freed when the cache itself is freed.473/// objects remaining in the cache will be freed when the cache itself is freed.
474const ObjectCache = struct {474const ObjectCache = struct {
475 objects: std.AutoHashMapUnmanaged(u64, CacheEntry) = .empty,475 objects: std.AutoHashMapUnmanaged(u64, CacheEntry) = .empty,
476 lru_nodes: LruList = .{},476 lru_nodes: std.DoublyLinkedList = .{},
477 lru_nodes_len: usize = 0,
477 byte_size: usize = 0,478 byte_size: usize = 0,
478479
479 const max_byte_size = 128 * 1024 * 1024; // 128MiB480 const max_byte_size = 128 * 1024 * 1024; // 128MiB
480 /// A list of offsets stored in the cache, with the most recently used481 /// A list of offsets stored in the cache, with the most recently used
481 /// entries at the end.482 /// entries at the end.
482 const LruList = std.DoublyLinkedList(u64);483 const LruListNode = struct {
483 const CacheEntry = struct { object: Object, lru_node: *LruList.Node };484 data: u64,
485 node: std.DoublyLinkedList.Node,
486 };
487 const CacheEntry = struct { object: Object, lru_node: *LruListNode };
484488
485 fn deinit(cache: *ObjectCache, allocator: Allocator) void {489 fn deinit(cache: *ObjectCache, allocator: Allocator) void {
486 var object_iterator = cache.objects.iterator();490 var object_iterator = cache.objects.iterator();
...@@ -496,8 +500,8 @@ const ObjectCache = struct {...@@ -496,8 +500,8 @@ const ObjectCache = struct {
496 /// position if it is present.500 /// position if it is present.
497 fn get(cache: *ObjectCache, offset: u64) ?Object {501 fn get(cache: *ObjectCache, offset: u64) ?Object {
498 if (cache.objects.get(offset)) |entry| {502 if (cache.objects.get(offset)) |entry| {
499 cache.lru_nodes.remove(entry.lru_node);503 cache.lru_nodes.remove(&entry.lru_node.node);
500 cache.lru_nodes.append(entry.lru_node);504 cache.lru_nodes.append(&entry.lru_node.node);
501 return entry.object;505 return entry.object;
502 } else {506 } else {
503 return null;507 return null;
...@@ -510,26 +514,29 @@ const ObjectCache = struct {...@@ -510,26 +514,29 @@ const ObjectCache = struct {
510 /// will not be evicted before the next call to `put` or `deinit` even if514 /// will not be evicted before the next call to `put` or `deinit` even if
511 /// it exceeds the maximum cache size.515 /// it exceeds the maximum cache size.
512 fn put(cache: *ObjectCache, allocator: Allocator, offset: u64, object: Object) !void {516 fn put(cache: *ObjectCache, allocator: Allocator, offset: u64, object: Object) !void {
513 const lru_node = try allocator.create(LruList.Node);517 const lru_node = try allocator.create(LruListNode);
514 errdefer allocator.destroy(lru_node);518 errdefer allocator.destroy(lru_node);
515 lru_node.data = offset;519 lru_node.data = offset;
516520
517 const gop = try cache.objects.getOrPut(allocator, offset);521 const gop = try cache.objects.getOrPut(allocator, offset);
518 if (gop.found_existing) {522 if (gop.found_existing) {
519 cache.byte_size -= gop.value_ptr.object.data.len;523 cache.byte_size -= gop.value_ptr.object.data.len;
520 cache.lru_nodes.remove(gop.value_ptr.lru_node);524 cache.lru_nodes.remove(&gop.value_ptr.lru_node.node);
525 cache.lru_nodes_len -= 1;
521 allocator.destroy(gop.value_ptr.lru_node);526 allocator.destroy(gop.value_ptr.lru_node);
522 allocator.free(gop.value_ptr.object.data);527 allocator.free(gop.value_ptr.object.data);
523 }528 }
524 gop.value_ptr.* = .{ .object = object, .lru_node = lru_node };529 gop.value_ptr.* = .{ .object = object, .lru_node = lru_node };
525 cache.byte_size += object.data.len;530 cache.byte_size += object.data.len;
526 cache.lru_nodes.append(lru_node);531 cache.lru_nodes.append(&lru_node.node);
532 cache.lru_nodes_len += 1;
527533
528 while (cache.byte_size > max_byte_size and cache.lru_nodes.len > 1) {534 while (cache.byte_size > max_byte_size and cache.lru_nodes_len > 1) {
529 // The > 1 check is to make sure that we don't evict the most535 // The > 1 check is to make sure that we don't evict the most
530 // recently added node, even if it by itself happens to exceed the536 // recently added node, even if it by itself happens to exceed the
531 // maximum size of the cache.537 // maximum size of the cache.
532 const evict_node = cache.lru_nodes.popFirst().?;538 const evict_node: *LruListNode = @alignCast(@fieldParentPtr("node", cache.lru_nodes.popFirst().?));
539 cache.lru_nodes_len -= 1;
533 const evict_offset = evict_node.data;540 const evict_offset = evict_node.data;
534 allocator.destroy(evict_node);541 allocator.destroy(evict_node);
535 const evict_object = cache.objects.get(evict_offset).?.object;542 const evict_object = cache.objects.get(evict_offset).?.object;