╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1288 return try DB.HashMap(.read_only).init(haxy_moment_cursor); │ │1289 } │ │1290 │ │1277 -// build the key for SortedSets sorted by timestamp. the big-endian timestamp │ │1278 -// makes byte order match creation order; the event id breaks ties and keeps │ │1279 -// keys unique within the same timestamp. │ │1280 -pub fn orderKey(timestamp: u64, event_id: *const [event_id_size]u8) [@sizeOf(u64) + event_id_size]u8 {│ │1291 +// build a sorted-set key from an order and event id. big-endian order makes │ │1292 +// byte order match numeric order; the event id breaks ties. │ │1293 +pub fn orderKey(order: u64, event_id: *const [event_id_size]u8) [@sizeOf(u64) + event_id_size]u8 { │ │1294 var key: [@sizeOf(u64) + event_id_size]u8 = undefined; │ │1282 - std.mem.writeInt(u64, key[0..@sizeOf(u64)], timestamp, .big); │ │1295 + std.mem.writeInt(u64, key[0..@sizeOf(u64)], order, .big); │ │1296 @memcpy(key[@sizeOf(u64)..], event_id); │ │1297 return key; │ │1298 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1299 │ │1287 -pub fn orderKeyDesc(timestamp: u64, event_id: *const [event_id_size]u8) [@sizeOf(u64) + event_id_size]u8 {│ │1288 - return orderKey(std.math.maxInt(u64) - timestamp, event_id); │ │1300 +pub fn orderKeyDesc(order: u64, event_id: *const [event_id_size]u8) [@sizeOf(u64) + event_id_size]u8 { │ │1301 + return orderKey(std.math.maxInt(u64) - order, event_id); │ │1302 } │ │1303 │ │1304 // add or refresh one entry in the global logical-event index. updates and │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │1292 -// removed records preserve created_ts, so the key never moves. │ │1305 +// removed records preserve created_order, so the key never moves.│ │1306 pub fn indexEvent( │ │1307 comptime DB: type, │ │1308 comptime hash_kind: hash.HashKind, │ ╰────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1309 haxy_moment: DB.HashMap(.read_write), │ │1310 event_id: *const [event_id_size]u8, │ │1311 kind: EventKind, │ │1299 - created_ts: u64, │ │1312 + created_order: u64, │ │1313 removed: bool, │ │1314 ) !void { │ │1315 const kind_map_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, event_index_key));│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1320 const active = try DB.SortedSet(.read_write).init(active_cursor); │ │1321 const removed_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, removed_event_id_set_key));│ │1322 const removed_set = try DB.SortedSet(.read_write).init(removed_cursor); │ │1310 - const order_key = orderKeyDesc(created_ts, event_id); │ │1323 + const order_key = orderKeyDesc(created_order, event_id); │ │1324 if (removed) { │ │1325 _ = try active.remove(&order_key); │ │1326 try removed_set.put(&order_key); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1330 } │ │1331 } │ │1332 │ │1333 +pub fn touchThread( │ │1334 + comptime DB: type, │ │1335 + comptime hash_kind: hash.HashKind, │ │1336 + haxy_moment: DB.HashMap(.read_write), │ │1337 + thread_id: *const [event_id_size]u8, │ │1338 + order: u64, │ │1339 + arena: *std.heap.ArenaAllocator, │ │1340 +) !void { │ │1341 + const kind_map_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, event_index_key)) orelse return;│ │1342 + const kind_map = try DB.HashMap(.read_only).init(kind_map_cursor); │ │1343 + const kind = (try readEventKind(hash_kind, kind_map, thread_id)) orelse return; │ │1344 + switch (kind) { │ │1345 + .discuss => try Discussion.touch(DB, hash_kind, haxy_moment, thread_id, order, arena), │ │1346 + else => {}, │ │1347 + } │ │1348 +} │ │1349 + │ │1350 pub fn readEventKind( │ │1351 comptime hash_kind: hash.HashKind, │ │1352 kind_map: anytype, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/event/Attachment.zig│ ╰────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │13 event: Self, │ │14 removed: bool = false, │ │15 author_email: ?[]const u8 = null, │ │16 - created_ts: u64 = 0, // the commit timestamp of the event that created this attachment│ │16 + created_order: u64 = 0, │ │17 name: []const u8, │ │18 blob_oid: []const u8, │ │19 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │ 94 if (existing_record_maybe) |existing_record| { │ │ 95 // the file never changes, so an update preserves everything the original│ │ 96 // commit determined │ │ 97 - record_to_write.created_ts = existing_record.created_ts; │ │ 97 + record_to_write.created_order = existing_record.created_order; │ │ 98 record_to_write.author_email = existing_record.author_email; │ │ 99 record_to_write.name = existing_record.name; │ │100 record_to_write.blob_oid = existing_record.blob_oid; │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │106 const attachment_cursor = try event_id_to_attachment.putCursor(attachment_key); │ │107 const attachment = try DB.HashMap(.read_write).init(attachment_cursor); │ │108 try evt.upsert(Record, DB, hash_kind, attachment, record_to_write); │ │109 - try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .attach, record_to_write.created_ts, record_to_write.removed); │ │109 + try evt.indexEvent(DB, hash_kind, haxy_moment, event_id, .attach, record_to_write.created_order, record_to_write.removed);│ │110 │ │111 if (existing_cursor_maybe == null) { │ │112 const attachment_id_set_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, id_set_key)); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────╮ │113 const attachment_id_set = try DB.SortedSet(.read_write).init(attachment_id_set_cursor);│ │114 - try attachment_id_set.put(&evt.orderKeyDesc(record_to_write.created_ts, event_id)); │ │114 + try attachment_id_set.put(&evt.orderKeyDesc(record_to_write.created_order, event_id)); │ │115 } │ │116 │ │117 // removed attachments stay in the parent's set; the views skip them │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯