Skip to content

Commit 0cf5dc2

Browse files
committed
use binary search for timestamps and canceled txs
1 parent 9d75a95 commit 0cf5dc2

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

contracts/FlowTransactionScheduler.cdc

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)