@@ -438,9 +438,6 @@ isQueued = \ds -> case ds of DsQueued {} -> True {}; _ -> False {}
438nextSeqTs : Timestamp -> Timestamp -> Timestamp
438nextSeqTs : Timestamp -> Timestamp -> Timestamp
439nextSeqTs = \t seqCounter -> if t > seqCounter then t else seqCounter + 1
439nextSeqTs = \t seqCounter -> if t > seqCounter then t else seqCounter + 1
441−takeN : [a] -> Int -> [a]
442−takeN = \items n -> (fold (\acc e -> if acc.n >= n then acc else {n: acc.n + 1, items: union acc.items [e]}) {n: 0, items: []} items).items
444dedupMessageIds : [MessageIdHex] -> [MessageIdHex]
441dedupMessageIds : [MessageIdHex] -> [MessageIdHex]
445dedupMessageIds = \messageIds ->
442dedupMessageIds = \messageIds ->
446 fold (\acc mid ->
443 fold (\acc mid ->
@@ -448,39 +445,11 @@ dedupMessageIds = \messageIds ->
448 else if any acc (\a -> a == mid) then acc
445 else if any acc (\a -> a == mid) then acc
449 else union acc [mid]) [] messageIds
446 else union acc [mid]) [] messageIds
451−boundedSmallest = \items n getKey ->
456− let newHeap = union acc.heap [a] in
457− let newSize = count newHeap in
458− if newSize > acc.size
459− then {size: newSize, heap: newHeap, heapMax: Just {value: case acc.heapMax of
461− Just {value: v} -> max k v
464− else case acc.heapMax of
466− Just {value: maxVal} ->
469− let removed = fold (\r x ->
470− if not r.done && getKey x == maxVal
471− then {done: True {}, items: r.items}
472− else {done: r.done, items: union r.items [x]}) {done: False {}, items: []} acc.heap in
473− let newHeap = union removed.items [a] in
474− let newMax = fold (\best x -> Just {value: case best of
475− Nothing {} -> getKey x
476− Just {value: v} -> max (getKey x) v
477− }) Nothing {} newHeap in
478− {size: acc.size, heap: newHeap, heapMax: newMax}
479− else acc) {size: 0, heap: [], heapMax: Nothing {}} items).heap
481evictOldestAckedIds = \items n ->
448evictOldestAckedIds = \items n ->
482 if n <= 0 then items
449 if n <= 0 then items
483− else diff items (boundedSmallest items n (\a -> a.ackedAt))
452+ diff items (takeRelation n ( sortBy (\a -> a.ackedAt) items))
485safeCompareLoop : Text -> Text -> Int -> Int -> Int
454safeCompareLoop : Text -> Text -> Int -> Int -> Int
486safeCompareLoop = \s1 s2 n result ->
455safeCompareLoop = \s1 s2 n result ->
@@ -553,7 +522,7 @@ capGossipPresence = \args ->
553 let updatesOnlyAfterOffline = removeOffline updatesOnlyMerged args.trustedOffline args.t in
522 let updatesOnlyAfterOffline = removeOffline updatesOnlyMerged args.trustedOffline args.t in
554 let reclaimSlots = maxPresenceEntries - count updatesOnlyAfterOffline in
523 let reclaimSlots = maxPresenceEntries - count updatesOnlyAfterOffline in
555 let newEntries = do e <- args.trustedDeduped; where none args.presence (\p -> samePubkeyServer p e); yield e in
524 let newEntries = do e <- args.trustedDeduped; where none args.presence (\p -> samePubkeyServer p e); yield e in
556− let reclaimedEntries = takeN newEntries reclaimSlots in
525+ let reclaimedEntries = takeRelation reclaimSlots newEntries in
557 {finalPresence: union updatesOnlyAfterOffline reclaimedEntries,
526 {finalPresence: union updatesOnlyAfterOffline reclaimedEntries,
558 appliedOnline: union
527 appliedOnline: union
559 (do e <- updatesOnly; where none args.presence (\p -> samePubkeyServer p e && p.expiresAt >= e.expiresAt); yield (pubkeyServer e))
528 (do e <- updatesOnly; where none args.presence (\p -> samePubkeyServer p e && p.expiresAt >= e.expiresAt); yield (pubkeyServer e))
@@ -751,7 +720,7 @@ forwardQueuedMessages = \targets t -> do
751 where none forwards (\f -> f.messageId == m.messageId && f.toServer == target.server)
720 where none forwards (\f -> f.messageId == m.messageId && f.toServer == target.server)
752 yield {messageId: m.messageId, toServer: target.server, createdAt: t,
721 yield {messageId: m.messageId, toServer: target.server, createdAt: t,
753 toKey: m.toKey, encryptedBlob: m.encryptedBlob, timestamp: m.timestamp}
722 toKey: m.toKey, encryptedBlob: m.encryptedBlob, timestamp: m.timestamp}
754− let capped = takeN candidates (maxForwardsEntries - count forwards)
723+ let capped = takeRelation (maxForwardsEntries - count forwards) candidates
755 let updatedForwards = union forwards capped
724 let updatedForwards = union forwards capped
756 set *forwards = updatedForwards
725 set *forwards = updatedForwards
757 yield capped
726 yield capped
@@ -832,11 +801,10 @@ pollOnce = \token cursor startWakeup -> do
832 atomic do
801 atomic do
833 wakeup <- *pollWakeup
802 wakeup <- *pollWakeup
834 allMessages <- *messages
803 allMessages <- *messages
835− let matchingMsgs = do
804+ let limitedMsgs = takeRelation maxPollEvents (sortBy (\m -> m.receivedAt) (do
836 m <- allMessages
805 m <- allMessages
837 where m.toKey == pubkey && m.receivedAt >= t - messageMaxAge && m.receivedAt > clampedCursor
806 where m.toKey == pubkey && m.receivedAt >= t - messageMaxAge && m.receivedAt > clampedCursor
838− yield m
807+ yield m))
839− let limitedMsgs = boundedSmallest matchingMsgs maxPollEvents (\m -> m.receivedAt)
840 if count limitedMsgs > 0
808 if count limitedMsgs > 0
842 let evts = do
810 let evts = do
@@ -945,15 +913,14 @@ serve = \req -> case req of
945 seqCounter <- *seqCounter
913 seqCounter <- *seqCounter
946 let seqTs = nextSeqTs t seqCounter
914 let seqTs = nextSeqTs t seqCounter
947 set *seqCounter = seqTs
915 set *seqCounter = seqTs
948− let updatedMessages = union messages
916+ set *messages = union messages
949 [{messageId: msgId, toKey: to,
917 [{messageId: msgId, toKey: to,
950 encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: "", receivedAt: seqTs}]
918 encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: "", receivedAt: seqTs}]
951− set *messages = updatedMessages
952 let toPresence = do p <- presence; where p.pubkey == to && p.expiresAt > t; yield p
919 let toPresence = do p <- presence; where p.pubkey == to && p.expiresAt > t; yield p
953 let localOnline = any toPresence (\p -> isLocalServer p.server)
920 let localOnline = any toPresence (\p -> isLocalServer p.server)
954 let remoteServers = collectPeerServers toPresence (\p -> p.server)
921 let remoteServers = collectPeerServers toPresence (\p -> p.server)
955 forwards <- *forwards
922 forwards <- *forwards
956− let forwardServers = takeN remoteServers (maxForwardsEntries - count forwards)
923+ let forwardServers = takeRelation (maxForwardsEntries - count forwards) remoteServers
957 let shouldForward = federationEnabled && count forwardServers > 0
924 let shouldForward = federationEnabled && count forwardServers > 0
958 let delivery = if localOnline then DsDelivered {}
925 let delivery = if localOnline then DsDelivered {}
959 else if shouldForward then DsFederated {}
926 else if shouldForward then DsFederated {}
@@ -1004,7 +971,7 @@ serve = \req -> case req of
1004 ackedIds <- *ackedIds
971 ackedIds <- *ackedIds
1005 let combinedAckedIds = union ackedIds ackedFederated
972 let combinedAckedIds = union ackedIds ackedFederated
1006 let evictedEntries = let excessCount = count combinedAckedIds - maxAckedIds in
973 let evictedEntries = let excessCount = count combinedAckedIds - maxAckedIds in
1007− if excessCount <= 0 then [] else boundedSmallest combinedAckedIds excessCount (\a -> a.ackedAt)
974+ if excessCount <= 0 then [] else takeRelation excessCount (sortBy (\a -> a.ackedAt) combinedAckedIds)
1008 let remainingAckedIds = diff combinedAckedIds evictedEntries
975 let remainingAckedIds = diff combinedAckedIds evictedEntries
1009 set *ackedIds = remainingAckedIds
976 set *ackedIds = remainingAckedIds
1010 yield {pr: pr, ack: AckDone {pendingAcks: ackedFederated, evictedEntries: evictedEntries}})
977 yield {pr: pr, ack: AckDone {pendingAcks: ackedFederated, evictedEntries: evictedEntries}})