╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ PatchRev.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
138 record.event_oid = existing.event_oid; 139 } 140 141 const cursor = try records.putCursor(record_key); 142 try evt.upsert(Record, DB, hash_kind, try DB.HashMap(.read_write).init(cursor), record); 143 try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .patchrev, record.created_order, record.removed); 144 145 if (existing_cursor_maybe == null) { 146 const ids = try DB.SortedSet(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, id_set_key))); 147 try ids.put(&evt.orderKeyDesc(record.created_order, event_id)); 148 } 149 } 150 151 pub fn validateOid(comptime hash_kind: hash.HashKind, oid: []const u8) !void { 152 var bytes: [hash.byteLen(hash_kind)]u8 = undefined; 153 _ = try std.fmt.hexToBytes(&bytes, oid); 154 if (!std.mem.eql(u8, oid, &std.fmt.bytesToHex(bytes, .lower))) return error.InvalidOid; 155 } 156 157 pub fn validateTarget(target_ref: []const u8) !void { 158 if (!std.mem.startsWith(u8, target_ref, "refs/heads/") or 159 !xit.ref.validateName(target_ref["refs/".len..])) return error.InvalidTarget; 160 } 161 162 pub fn readById( 163 comptime DB: type, 164 comptime hash_kind: hash.HashKind, 165 haxy_moment: DB.HashMap(.read_only), 166 arena: *std.heap.ArenaAllocator, 167 id: *const [evt.event_id_size]u8, 168 ) !?Record { 169 const records_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, record_map_key)) orelse return null; 170 const records = try DB.HashMap(.read_only).init(records_cursor); 171 const record_cursor = try records.getCursor(hash.hashInt(hash_kind, id)) orelse return null; 172 return try evt.read(Record, DB, hash_kind, arena, try DB.HashMap(.read_only).init(record_cursor)); 173 } 174 175 pub const WithId = struct { 176 id: [evt.event_id_size]u8, 177 record: Record, 178 }; 179 180 pub fn readNewest( 181 comptime DB: type, 182 comptime hash_kind: hash.HashKind, 183 haxy_moment: DB.HashMap(.read_only), 184 arena: *std.heap.ArenaAllocator, 185 ) !?WithId { 186 const ids_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, id_set_key)) orelse return null; 187 const ids = try DB.SortedSet(.read_only).init(ids_cursor); 188 var iter = try ids.iteratorFromIndex(0); 189 while (try iter.next()) |cursor| { 190 const id = try evt.readOrderKeyId(DB, cursor); 191 const record = (try readById(DB, hash_kind, haxy_moment, arena, &id)) orelse continue; 192 if (!record.removed) return .{ .id = id, .record = record }; 193 } 194 return null; 195 } 196 197 // squash commits referenced only by patch revision records 198 pub fn gcRoots( 199 comptime DB: type, 200 comptime hash_kind: hash.HashKind, 201 allocator: std.mem.Allocator, 202 haxy_moment: DB.HashMap(.read_only), 203 ) ![][hash.hexLen(hash_kind)]u8 { 204 var roots: std.ArrayList([hash.hexLen(hash_kind)]u8) = .empty; 205 errdefer roots.deinit(allocator); 206 var arena = std.heap.ArenaAllocator.init(allocator); 207 defer arena.deinit(); 208 209 const ids_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, id_set_key)) orelse return try roots.toOwnedSlice(allocator); 210 const ids = try DB.SortedSet(.read_only).init(ids_cursor); 211 var iter = try ids.iteratorFromIndex(0); 212 while (try iter.next()) |cursor| { 213 _ = arena.reset(.retain_capacity); 214 const id = try evt.readOrderKeyId(DB, cursor); 215 const record = (try readById(DB, hash_kind, haxy_moment, &arena, &id)) orelse continue; 216 var oid: [hash.hexLen(hash_kind)]u8 = undefined; 217 if (record.patch_oid.len != oid.len) return error.InvalidOid; 218 @memcpy(&oid, record.patch_oid); 219 try roots.append(allocator, oid); 220 } 221 222 return try roots.toOwnedSlice(allocator); 223 } 224