╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Fork.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
43 arena: *std.heap.ArenaAllocator, 44 _: ?[]const u8, 45 ) !void { 46 const fork_key = hash.hashInt(hash_kind, event_id); 47 const records = try DB.HashMap(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, record_map_key))); 48 const active = try DB.SortedSet(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, active_id_set_key))); 49 const drafts = try DB.HashMap(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, repo_to_draft_id_set_key))); 50 51 var existing_maybe: ?Record = null; 52 const existing_cursor_maybe = try records.getCursor(fork_key); 53 if (existing_cursor_maybe) |cursor| { 54 existing_maybe = try evt.read(Record, DB, hash_kind, arena, try DB.HashMap(.read_only).init(cursor)); 55 } 56 57 var record = record_maybe orelse try evt.removedRecord(Record, DB, hash_kind, haxy_moment.readOnly(), existing_maybe); 58 59 if (!record.removed) try validate(record); 60 61 if (existing_maybe) |existing| { 62 if (!std.mem.eql(u8, existing.event.repo_id, record.event.repo_id) or 63 !std.mem.eql(u8, existing.event.repo_user_id, record.event.repo_user_id)) return error.ForkChanged; 64 if (existing.event.stage == .publish and record.event.stage != .publish) return error.ForkAlreadyPublished; 65 record.created_order = existing.created_order; 66 if (!existing.removed) { 67 const order_key = evt.orderKeyDesc(existing.created_order, event_id); 68 _ = try active.remove(&order_key); 69 if (existing.event.stage == .draft) { 70 try removeFromParentSet(DB, hash_kind, drafts, existing.event.repo_id, &order_key); 71 } 72 } 73 } 74 75 const fork_cursor = try records.putCursor(fork_key); 76 try evt.upsert(Record, DB, hash_kind, try DB.HashMap(.read_write).init(fork_cursor), record); 77 try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .fork, existing_maybe, record); 78 79 const order_key = evt.orderKeyDesc(record.created_order, event_id); 80 if (existing_cursor_maybe == null) { 81 const ids = try DB.SortedSet(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, all_id_set_key))); 82 try ids.put(&order_key); 83 } 84 85 if (!record.removed) { 86 try active.put(&order_key); 87 if (record.event.stage == .draft) { 88 const by_repo = try DB.SortedSet(.read_write).init(try drafts.putCursor(hash.hashInt(hash_kind, record.event.repo_id))); 89 try by_repo.put(&order_key); 90 } 91 } 92 } 93 94 fn removeFromParentSet( 95 comptime DB: type, 96 comptime hash_kind: hash.HashKind, 97 index: DB.HashMap(.read_write), 98 parent_id: []const u8, 99 order_key: *const [@sizeOf(u64) + evt.event_id_size]u8, 100 ) !void { 101 const cursor = try index.putCursor(hash.hashInt(hash_kind, parent_id)); 102 const ids = try DB.SortedSet(.read_write).init(cursor); 103 _ = try ids.remove(order_key); 104 } 105 106 pub fn readById( 107 comptime DB: type, 108 comptime hash_kind: hash.HashKind, 109 haxy_moment: DB.HashMap(.read_only), 110 arena: *std.heap.ArenaAllocator, 111 fork_id: []const u8, 112 ) !?Record { 113 const records_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, record_map_key)) orelse return null; 114 const records = try DB.HashMap(.read_only).init(records_cursor); 115 const fork_cursor = try records.getCursor(hash.hashInt(hash_kind, fork_id)) orelse return null; 116 return try evt.read(Record, DB, hash_kind, arena, try DB.HashMap(.read_only).init(fork_cursor)); 117 } 118