╭ changed ─────────╮ │src/event/Repo.zig│ ╰──────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │19 removed: bool = false, │ │20 created_order: u64 = 0, │ │21 updated_order: u64 = 0, │ │22 - │ │23 - // a repo's key in the name index. it's unique per owner, so the read side │ │24 - // resolves the url's username to its user id first. │ │25 - pub fn indexKey(self: Record, allocator: std.mem.Allocator) ![]const u8 { │ │26 - return std.fmt.allocPrint(allocator, "{s}/{s}", .{ self.event.user_id, self.event.name });│ │27 - } │ │22 }; │ │23 │ │24 const Self = @This(); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │129 try validateUserIds(record_to_write.event.owner_user_ids); │ │130 } │ │131 │ │138 - const user_id_to_repo_id_set_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, "user-id->repo-id-set"));│ │139 - const user_id_to_repo_id_set = try DB.HashMap(.read_write).init(user_id_to_repo_id_set_cursor); │ │140 - │ │132 if (existing_record_maybe) |existing_record| { │ │133 // updates preserve the original creation metadata │ │134 record_to_write.created_order = existing_record.created_order; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │144 - const order_key = evt.orderKeyDesc(existing_record.created_order, event_id); │ │135 │ │146 - // drop the old active indexes; active values are re-added below │ │136 + // drop the old active index; active values are re-added below │ │137 if (!existing_record.removed) { │ │148 - const existing_path = try existing_record.indexKey(arena.allocator()); │ │149 - _ = try name_to_repo_id.remove(hash.hashInt(hash_kind, existing_path)); │ │150 - │ │151 - const old_user_repos_cursor = try user_id_to_repo_id_set.putCursor(hash.hashInt(hash_kind, existing_record.event.user_id));│ │152 - const old_user_repos = try DB.SortedSet(.read_write).init(old_user_repos_cursor); │ │153 - _ = try old_user_repos.remove(&order_key); │ │138 + _ = try name_to_repo_id.remove(hash.hashInt(hash_kind, existing_record.event.name)); │ │139 } │ │140 } │ │141 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │153 try repo_id_set.put(&order_key); │ │154 } │ │155 │ │156 + // the user's repos, ordered by creation time, newest first │ │157 const active = try DB.SortedSet(.read_write).init(try haxy_moment.putCursor(hash.hashInt(hash_kind, active_id_set_key)));│ │158 if (record_to_write.removed) { │ │159 _ = try active.remove(&order_key); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │160 } else { │ │161 try active.put(&order_key); │ │176 - const repo_path = try record_to_write.indexKey(arena.allocator()); │ │177 - try name_to_repo_id.put(hash.hashInt(hash_kind, repo_path), .{ .bytes = event_id }); │ │178 - │ │179 - // each user's repos are ordered by creation time, newest first │ │180 - const user_repos_cursor = try user_id_to_repo_id_set.putCursor(hash.hashInt(hash_kind, record_to_write.event.user_id));│ │181 - const user_repos = try DB.SortedSet(.read_write).init(user_repos_cursor); │ │182 - try user_repos.put(&order_key); │ │162 + try name_to_repo_id.put(hash.hashInt(hash_kind, record_to_write.event.name), .{ .bytes = event_id }); │ │163 } │ │164 } │ │165 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │170 event_id: [evt.event_id_size]u8, │ │171 }; │ │172 │ │193 -// read a repo by its owner's name and repo name. the owner name is resolved to │ │194 -// a user id via name->user-id (the repo index is keyed by "user-id/repo-name"), │ │195 -// matching the /repo/username/reponame url. │ │196 -pub fn readByOwnerAndName( │ │173 +// read a repo by its name from its owner's user repo │ │174 +pub fn readByName( │ │175 comptime DB: type, │ │176 comptime hash_kind: hash.HashKind, │ │199 - haxy_moment: DB.HashMap(.read_only), │ │177 + user_moment: DB.HashMap(.read_only), │ │178 arena: *std.heap.ArenaAllocator, │ │201 - owner_name: []const u8, │ │202 - repo_name: []const u8, │ │179 + name: []const u8, │ │180 ) !?RepoWithId { │ │204 - // owner name -> user id │ │205 - const name_to_user_id_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, "name->user-id")) orelse return null; │ │206 - const name_to_user_id = try DB.HashMap(.read_only).init(name_to_user_id_cursor); │ │207 - const user_id_cursor = try name_to_user_id.getCursor(hash.hashInt(hash_kind, owner_name)) orelse return null; │ │208 - var user_id: [evt.event_id_size]u8 = undefined; │ │209 - _ = try user_id_cursor.readBytes(&user_id); │ │210 - │ │211 - // "user-id/repo-name" -> repo event id │ │212 - const repo_path = try (Record{ .event = .{ .user_id = user_id[0..], .name = repo_name, .description = "" } }).indexKey(arena.allocator());│ │213 - const name_to_repo_id_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, "name->repo-id")) orelse return null; │ │181 + const name_to_repo_id_cursor = try user_moment.getCursor(hash.hashInt(hash_kind, name_index_key)) orelse return null; │ │182 const name_to_repo_id = try DB.HashMap(.read_only).init(name_to_repo_id_cursor); │ │215 - const repo_id_cursor = try name_to_repo_id.getCursor(hash.hashInt(hash_kind, repo_path)) orelse return null; │ │183 + const repo_id_cursor = try name_to_repo_id.getCursor(hash.hashInt(hash_kind, name)) orelse return null; │ │184 var repo_id: [evt.event_id_size]u8 = undefined; │ │185 _ = try repo_id_cursor.readBytes(&repo_id); │ │218 - │ │219 - const event_id_to_repo_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, "event-id->repo")) orelse return null; │ │220 - const event_id_to_repo = try DB.HashMap(.read_only).init(event_id_to_repo_cursor); │ │221 - const repo_cursor = try event_id_to_repo.getCursor(hash.hashInt(hash_kind, &repo_id)) orelse return null; │ │222 - const repo_map = try DB.HashMap(.read_only).init(repo_cursor); │ │223 - return .{ .repo = try evt.read(Record, DB, hash_kind, arena, repo_map), .event_id = repo_id }; │ │186 + const repo = (try readById(DB, hash_kind, user_moment, arena, &repo_id)) orelse return null; │ │187 + return .{ .repo = repo, .event_id = repo_id }; │ │188 } │ │189 │ │190 pub fn readById( │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯