╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ event.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
485 .pointer => |pointer_info| { 486 if (pointer_info.size == .slice and pointer_info.child == u8) { 487 try upsertBytes(DB, hash_kind, map, key, value); 488 } else { 489 @compileError("unsupported upsert field type: " ++ @typeName(Field)); 490 } 491 }, 492 .array => |array_info| { 493 if (array_info.child == u8) { 494 try upsertBytes(DB, hash_kind, map, key, &value); 495 } else { 496 @compileError("unsupported upsert field type: " ++ @typeName(Field)); 497 } 498 }, 499 .int => |int_info| switch (int_info.signedness) { 500 .unsigned => { 501 if (try map.getCursor(key)) |value_cursor| { 502 if (try value_cursor.readUint() == value) { 503 return; 504 } 505 } 506 507 try map.put(key, .{ .uint = value }); 508 }, 509 .signed => { 510 if (try map.getCursor(key)) |value_cursor| { 511 if (try value_cursor.readInt() == value) { 512 return; 513 } 514 } 515 516 try map.put(key, .{ .int = value }); 517 }, 518 }, 519 .bool => { 520 const bytes = if (value) "true" else "false"; 521 if (try map.getCursor(key)) |value_cursor| { 522 var buffer: [5]u8 = undefined; 523 const existing = try value_cursor.readBytesObject(&buffer); 524 if (existing.format_tag != null and 525 std.mem.eql(u8, &existing.format_tag.?, "bl") and 526 std.mem.eql(u8, existing.value, bytes)) 527 { 528 return; 529 } 530 } 531 532 try map.put(key, .{ .bytes_object = .{ .value = bytes, .format_tag = "bl".* } }); 533 }, 534 else => @compileError("unsupported upsert field type: " ++ @typeName(Field)), 535 } 536 } 537 538 fn upsertBytes( 539 comptime DB: type, 540 comptime hash_kind: hash.HashKind, 541 map: DB.HashMap(.read_write), 542 key: hash.HashInt(hash_kind), 543 value: []const u8, 544 ) !void { 545 var existing_cursor_maybe = try map.getCursor(key); 546 if (existing_cursor_maybe) |*existing_cursor| { 547 if (try bytesEqual(DB, existing_cursor, value)) { 548 return; 549 } 550 } 551 552 var value_cursor = try map.putCursor(key); 553 var write_buffer: [1024]u8 = undefined; 554 var writer = try value_cursor.writer(&write_buffer); 555 try writer.interface.writeAll(value); 556 try writer.finish(); 557 } 558 559 fn bytesEqual( 560 comptime DB: type, 561 cursor: *DB.Cursor(.read_only), 562 value: []const u8, 563 ) !bool { 564 var read_buffer: [1024]u8 = undefined; 565 var reader = try cursor.reader(&read_buffer); 566 if (reader.size != value.len) { 567 return false; 568 } 569 570 var chunk_buffer: [1024]u8 = undefined; 571 var offset: usize = 0; 572 while (offset < value.len) { 573 const chunk_len = @min(chunk_buffer.len, value.len - offset); 574 try reader.interface.readSliceAll(chunk_buffer[0..chunk_len]); 575 if (!std.mem.eql(u8, chunk_buffer[0..chunk_len], value[offset .. offset + chunk_len])) { 576 return false; 577 } 578 offset += chunk_len; 579 } 580 581 return true; 582 } 583