╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ event.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
639 else => @compileError("unsupported upsert field type: " ++ @typeName(Field)), 640 } 641 } 642 643 fn upsertBytes( 644 comptime DB: type, 645 comptime hash_kind: hash.HashKind, 646 map: DB.HashMap(.read_write), 647 key: hash.HashInt(hash_kind), 648 value: []const u8, 649 ) !void { 650 var existing_cursor_maybe = try map.getCursor(key); 651 if (existing_cursor_maybe) |*existing_cursor| { 652 if (try bytesEqual(DB, existing_cursor, value)) { 653 return; 654 } 655 } 656 657 var value_cursor = try map.putCursor(key); 658 var write_buffer: [1024]u8 = undefined; 659 var writer = try value_cursor.writer(&write_buffer); 660 try writer.interface.writeAll(value); 661 try writer.finish(); 662 } 663 664 fn bytesEqual( 665 comptime DB: type, 666 cursor: *DB.Cursor(.read_only), 667 value: []const u8, 668 ) !bool { 669 var read_buffer: [1024]u8 = undefined; 670 var reader = try cursor.reader(&read_buffer); 671 if (reader.size != value.len) { 672 return false; 673 } 674 675 var chunk_buffer: [1024]u8 = undefined; 676 var offset: usize = 0; 677 while (offset < value.len) { 678 const chunk_len = @min(chunk_buffer.len, value.len - offset); 679 try reader.interface.readSliceAll(chunk_buffer[0..chunk_len]); 680 if (!std.mem.eql(u8, chunk_buffer[0..chunk_len], value[offset .. offset + chunk_len])) { 681 return false; 682 } 683 offset += chunk_len; 684 } 685 686 return true; 687 } 688