| ... | @@ -146,7 +146,7 @@ pub const Node = extern struct { | ... | @@ -146,7 +146,7 @@ pub const Node = extern struct { |
| 146 | | 146 | |
| 147 | pub fn hasMoved(ni: Node.Index, mf: *const MappedFile) bool { | 147 | pub fn hasMoved(ni: Node.Index, mf: *const MappedFile) bool { |
| 148 | var parent_ni = ni; | 148 | var parent_ni = ni; |
| 149 | while (parent_ni != .none) { | 149 | while (parent_ni != Node.Index.root) { |
| 150 | const parent = parent_ni.get(mf); | 150 | const parent = parent_ni.get(mf); |
| 151 | if (parent.flags.moved) return true; | 151 | if (parent.flags.moved) return true; |
| 152 | parent_ni = parent.parent; | 152 | parent_ni = parent.parent; |
| ... | @@ -164,7 +164,7 @@ pub const Node = extern struct { | ... | @@ -164,7 +164,7 @@ pub const Node = extern struct { |
| 164 | } | 164 | } |
| 165 | fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void { | 165 | fn movedAssumeCapacity(ni: Node.Index, mf: *MappedFile) void { |
| 166 | var parent_ni = ni; | 166 | var parent_ni = ni; |
| 167 | while (parent_ni != .none) { | 167 | while (parent_ni != Node.Index.root) { |
| 168 | const parent_node = parent_ni.get(mf); | 168 | const parent_node = parent_ni.get(mf); |
| 169 | if (parent_node.flags.moved) return; | 169 | if (parent_node.flags.moved) return; |
| 170 | parent_ni = parent_node.parent; | 170 | parent_ni = parent_node.parent; |
| ... | @@ -550,9 +550,9 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested | ... | @@ -550,9 +550,9 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 550 | const new_size = node.flags.alignment.forward(@intCast(requested_size)); | 550 | const new_size = node.flags.alignment.forward(@intCast(requested_size)); |
| 551 | // Resize the entire file | 551 | // Resize the entire file |
| 552 | if (ni == Node.Index.root) { | 552 | if (ni == Node.Index.root) { |
| | 553 | try mf.ensureCapacityForSetLocation(gpa); |
| 553 | try mf.file.setEndPos(new_size); | 554 | try mf.file.setEndPos(new_size); |
| 554 | try mf.ensureTotalCapacity(@intCast(new_size)); | 555 | try mf.ensureTotalCapacity(@intCast(new_size)); |
| 555 | try mf.ensureCapacityForSetLocation(gpa); | | |
| 556 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); | 556 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); |
| 557 | return; | 557 | return; |
| 558 | } | 558 | } |
| ... | @@ -585,56 +585,56 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested | ... | @@ -585,56 +585,56 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 585 | continue; | 585 | continue; |
| 586 | } | 586 | } |
| 587 | const range_file_offset = ni.fileLocation(mf, false).offset + old_size; | 587 | const range_file_offset = ni.fileLocation(mf, false).offset + old_size; |
| 588 | retry: while (true) { | 588 | while (true) switch (linux.E.init(linux.fallocate( |
| 589 | switch (linux.E.init(linux.fallocate( | 589 | mf.file.handle, |
| 590 | mf.file.handle, | 590 | linux.FALLOC.FL_INSERT_RANGE, |
| 591 | linux.FALLOC.FL_INSERT_RANGE, | 591 | @intCast(range_file_offset), |
| 592 | @intCast(range_file_offset), | 592 | @intCast(range_size), |
| 593 | @intCast(range_size), | 593 | ))) { |
| 594 | ))) { | 594 | .SUCCESS => { |
| 595 | .SUCCESS => { | 595 | var enclosing_ni = ni; |
| 596 | var enclosing_ni = ni; | 596 | while (true) { |
| 597 | while (enclosing_ni != .none) { | 597 | try mf.ensureCapacityForSetLocation(gpa); |
| | 598 | const enclosing = enclosing_ni.get(mf); |
| | 599 | const enclosing_offset, const old_enclosing_size = |
| | 600 | enclosing.location().resolve(mf); |
| | 601 | const new_enclosing_size = old_enclosing_size + range_size; |
| | 602 | enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size); |
| | 603 | if (enclosing_ni == Node.Index.root) { |
| | 604 | assert(enclosing_offset == 0); |
| | 605 | try mf.ensureTotalCapacity(@intCast(new_enclosing_size)); |
| | 606 | break; |
| | 607 | } |
| | 608 | var after_ni = enclosing.next; |
| | 609 | while (after_ni != .none) { |
| 598 | try mf.ensureCapacityForSetLocation(gpa); | 610 | try mf.ensureCapacityForSetLocation(gpa); |
| 599 | const enclosing = enclosing_ni.get(mf); | 611 | const after = after_ni.get(mf); |
| 600 | const enclosing_offset, const enclosing_size = | 612 | const after_offset, const after_size = after.location().resolve(mf); |
| 601 | enclosing.location().resolve(mf); | 613 | after_ni.setLocationAssumeCapacity( |
| 602 | enclosing_ni.setLocationAssumeCapacity( | | |
| 603 | mf, | 614 | mf, |
| 604 | enclosing_offset, | 615 | range_size + after_offset, |
| 605 | enclosing_size + range_size, | 616 | after_size, |
| 606 | ); | 617 | ); |
| 607 | var after_ni = enclosing.next; | 618 | after_ni = after.next; |
| 608 | while (after_ni != .none) { | | |
| 609 | try mf.ensureCapacityForSetLocation(gpa); | | |
| 610 | const after = after_ni.get(mf); | | |
| 611 | const after_offset, const after_size = after.location().resolve(mf); | | |
| 612 | after_ni.setLocationAssumeCapacity( | | |
| 613 | mf, | | |
| 614 | range_size + after_offset, | | |
| 615 | after_size, | | |
| 616 | ); | | |
| 617 | after_ni = after.next; | | |
| 618 | } | | |
| 619 | enclosing_ni = enclosing.parent; | | |
| 620 | } | 619 | } |
| 621 | return; | 620 | enclosing_ni = enclosing.parent; |
| 622 | }, | 621 | } |
| 623 | .INTR => continue :retry, | 622 | return; |
| 624 | .BADF, .FBIG, .INVAL => unreachable, | 623 | }, |
| 625 | .IO => return error.InputOutput, | 624 | .INTR => continue, |
| 626 | .NODEV => return error.NotFile, | 625 | .BADF, .FBIG, .INVAL => unreachable, |
| 627 | .NOSPC => return error.NoSpaceLeft, | 626 | .IO => return error.InputOutput, |
| 628 | .NOSYS, .OPNOTSUPP => { | 627 | .NODEV => return error.NotFile, |
| 629 | mf.flags.fallocate_insert_range_unsupported = true; | 628 | .NOSPC => return error.NoSpaceLeft, |
| 630 | break :insert_range; | 629 | .NOSYS, .OPNOTSUPP => { |
| 631 | }, | 630 | mf.flags.fallocate_insert_range_unsupported = true; |
| 632 | .PERM => return error.PermissionDenied, | 631 | break :insert_range; |
| 633 | .SPIPE => return error.Unseekable, | 632 | }, |
| 634 | .TXTBSY => return error.FileBusy, | 633 | .PERM => return error.PermissionDenied, |
| 635 | else => |e| return std.posix.unexpectedErrno(e), | 634 | .SPIPE => return error.Unseekable, |
| 636 | } | 635 | .TXTBSY => return error.FileBusy, |
| 637 | } | 636 | else => |e| return std.posix.unexpectedErrno(e), |
| | 637 | }; |
| 638 | } | 638 | } |
| 639 | switch (node.next) { | 639 | switch (node.next) { |
| 640 | .none => { | 640 | .none => { |
| ... | @@ -728,7 +728,6 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: | ... | @@ -728,7 +728,6 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 728 | // delete the copy of this node at the old location | 728 | // delete the copy of this node at the old location |
| 729 | if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and | 729 | if (is_linux and !mf.flags.fallocate_punch_hole_unsupported and |
| 730 | size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true) | 730 | size >= mf.flags.block_size.toByteUnits() * 2 - 1) while (true) |
| 731 | { | | |
| 732 | switch (linux.E.init(linux.fallocate( | 731 | switch (linux.E.init(linux.fallocate( |
| 733 | mf.file.handle, | 732 | mf.file.handle, |
| 734 | linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE, | 733 | linux.FALLOC.FL_PUNCH_HOLE | linux.FALLOC.FL_KEEP_SIZE, |
| ... | @@ -749,8 +748,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: | ... | @@ -749,8 +748,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 749 | .SPIPE => return error.Unseekable, | 748 | .SPIPE => return error.Unseekable, |
| 750 | .TXTBSY => return error.FileBusy, | 749 | .TXTBSY => return error.FileBusy, |
| 751 | else => |e| return std.posix.unexpectedErrno(e), | 750 | else => |e| return std.posix.unexpectedErrno(e), |
| 752 | } | 751 | }; |
| 753 | }; | | |
| 754 | @memset(mf.contents[@intCast(old_file_offset)..][0..@intCast(size)], 0); | 752 | @memset(mf.contents[@intCast(old_file_offset)..][0..@intCast(size)], 0); |
| 755 | } | 753 | } |
| 756 | | 754 | |