mirror of
https://github.com/corda/corda.git
synced 2024-12-23 14:52:29 +00:00
core: Make topological sort more efficient
This commit is contained in:
parent
d6f82637ad
commit
5596ced5c3
@ -33,40 +33,36 @@ class ResolveTransactionsProtocol(private val txHashes: Set<SecureHash>,
|
|||||||
companion object {
|
companion object {
|
||||||
private fun dependencyIDs(wtx: WireTransaction) = wtx.inputs.map { it.txhash }.toSet()
|
private fun dependencyIDs(wtx: WireTransaction) = wtx.inputs.map { it.txhash }.toSet()
|
||||||
|
|
||||||
private fun topologicalSort(transactions: Iterable<SignedTransaction>): List<SignedTransaction> {
|
private fun topologicalSort(transactions: Collection<SignedTransaction>): List<SignedTransaction> {
|
||||||
|
|
||||||
// Construct txhash -> dependent-txhashes map
|
// Construct txhash -> dependent-txhashes map
|
||||||
val forwardGraph = HashMap<SecureHash, HashSet<SecureHash>>()
|
val forwardGraph = HashMap<SecureHash, HashSet<SignedTransaction>>()
|
||||||
transactions.forEach { tx ->
|
transactions.forEach { tx ->
|
||||||
tx.tx.inputs.forEach { input ->
|
tx.tx.inputs.forEach { input ->
|
||||||
forwardGraph.getOrPut(input.txhash) { HashSet() }.add(tx.id)
|
forwardGraph.getOrPut(input.txhash) { HashSet() }.add(tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct txhash -> tx map
|
val visited = HashSet<SecureHash>(transactions.size)
|
||||||
val transactionMap = HashMap<SecureHash, SignedTransaction>()
|
val result = ArrayList<SignedTransaction>(transactions.size)
|
||||||
transactions.forEach { transactionMap[it.tx.id] = it }
|
|
||||||
|
|
||||||
val visited = HashSet<SecureHash>()
|
fun visit(transaction: SignedTransaction) {
|
||||||
val result = LinkedList<SignedTransaction>()
|
if (transaction.id in visited) {
|
||||||
|
|
||||||
fun visit(transactionHash: SecureHash) {
|
|
||||||
if (transactionHash in visited) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
visited.add(transactionHash)
|
visited.add(transaction.id)
|
||||||
forwardGraph[transactionHash]?.forEach {
|
forwardGraph[transaction.id]?.forEach {
|
||||||
visit(it)
|
visit(it)
|
||||||
}
|
}
|
||||||
result.addFirst(transactionMap[transactionHash]!!)
|
result.add(transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
transactions.forEach {
|
transactions.forEach {
|
||||||
visit(it.tx.id)
|
visit(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
require(result.size == transactionMap.size)
|
require(result.size == transactions.size)
|
||||||
require(visited.size == transactionMap.size)
|
result.reverse()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +130,7 @@ class ResolveTransactionsProtocol(private val txHashes: Set<SecureHash>,
|
|||||||
override val topic: String get() = throw UnsupportedOperationException()
|
override val topic: String get() = throw UnsupportedOperationException()
|
||||||
|
|
||||||
@Suspendable
|
@Suspendable
|
||||||
private fun downloadDependencies(depsToCheck: Set<SecureHash>): List<SignedTransaction> {
|
private fun downloadDependencies(depsToCheck: Set<SecureHash>): Collection<SignedTransaction> {
|
||||||
// Maintain a work queue of all hashes to load/download, initialised with our starting set. Then do a breadth
|
// Maintain a work queue of all hashes to load/download, initialised with our starting set. Then do a breadth
|
||||||
// first traversal across the dependency graph.
|
// first traversal across the dependency graph.
|
||||||
//
|
//
|
||||||
@ -184,7 +180,7 @@ class ResolveTransactionsProtocol(private val txHashes: Set<SecureHash>,
|
|||||||
throw ExcessivelyLargeTransactionGraph()
|
throw ExcessivelyLargeTransactionGraph()
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultQ.values.reversed()
|
return resultQ.values
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user