@@ -460,28 +460,39 @@ access(all) contract FlowTransactionScheduler {
460460 self .timestamps = []
461461 }
462462
463+ // bisect is a function that finds the index to insert a new timestamp in the sorted array.
464+ // taken from bisect_right in pthon https://stackoverflow.com/questions/2945017/javas-equivalent-to-bisect-in-python
465+ access (all) fun bisect (new : UFix64 ): Int ? {
466+ var high = self .timestamps.length
467+ var low = 0
468+ while low < high {
469+ let mid = (low+ high)/ 2
470+ let midTimestamp = self .timestamps[mid]
471+
472+ if midTimestamp == new {
473+ return nil
474+ } else if midTimestamp > new {
475+ high = mid
476+ } else {
477+ low = mid + 1
478+ }
479+ }
480+ return low
481+ }
482+
463483 /// Add a timestamp to the sorted array maintaining sorted order
464484 access (all) fun add (timestamp : UFix64 ) {
465-
466- var insertIndex = 0
467- for i, ts in self .timestamps {
468- if timestamp < ts {
469- insertIndex = i
470- break
471- } else if timestamp == ts {
472- return
473- }
474- insertIndex = i + 1
485+ // Only insert if the timestamp is not already in the array
486+ if let insertIndex = self .bisect (new : timestamp) {
487+ self .timestamps.insert (at : insertIndex, timestamp)
475488 }
476- self .timestamps.insert (at : insertIndex, timestamp)
477489 }
478490
479491 /// Remove a timestamp from the sorted array
480492 access (all) fun remove (timestamp : UFix64 ) {
481-
482- let index = self .timestamps.firstIndex (of : timestamp)
483- if index ! = nil {
484- self .timestamps.remove (at : index! )
493+ // Only remove if the timestamp is in the array
494+ if let index = self .timestamps.firstIndex (of : timestamp) {
495+ self .timestamps.remove (at : index)
485496 }
486497 }
487498
@@ -1336,15 +1347,21 @@ access(all) contract FlowTransactionScheduler {
13361347
13371348 // if the transaction was canceled, add it to the canceled transactions array
13381349 // maintain sorted order by inserting at the correct position
1339- var insertIndex = 0
1340- for i, canceledID in self .canceledTransactions {
1341- if id < canceledID {
1342- insertIndex = i
1343- break
1344- }
1345- insertIndex = i + 1
1346- }
1347- self .canceledTransactions.insert (at : insertIndex, id)
1350+ var high = self .canceledTransactions.length
1351+ var low = 0
1352+ while low < high {
1353+ let mid = (low+ high)/ 2
1354+ let midCanceledID = self .canceledTransactions[mid]
1355+
1356+ if midCanceledID == id {
1357+ emit CriticalIssue (message : " Invalid ID: \(id) transaction already in canceled transactions array" )
1358+ } else if midCanceledID > id {
1359+ high = mid
1360+ } else {
1361+ low = mid + 1
1362+ }
1363+ }
1364+ self .canceledTransactions.insert (at : low, id)
13481365
13491366 // keep the array under the limit
13501367 if UInt (self .canceledTransactions.length) > self .config.canceledTransactionsLimit {
0 commit comments