in cassovary-core/src/main/scala/com/twitter/cassovary/graph/bipartite/IterativeLinkAnalyzer.scala [55:92]
private def iterate(nodeInfos: Seq[mutable.HashMap[Int, NodeInfo]],
resetProb: Double, neighborsProvider: Node => Seq[Int],
flowReverse: Boolean,
isRightUninitialized: Boolean, isLastIter: Boolean) {
def flowWeight(source: NodeInfo, dest: NodeInfo) {
dest.weight += (source.weight / source.numNeighbors) * (1 - resetProb)
if (isLastIter) dest.contributors += source
}
// flow weights from sourceInfos to destInfos
val left = nodeInfos(0)
val right = nodeInfos(1)
var (sourceInfos, destInfos) = if (flowReverse) (right, left) else (left, right)
// initialize dest
destInfos.values foreach { destInfo =>
destInfo.weight = resetProb * destInfo.initialIterationWeight
if (isLastIter) destInfo.contributors.clear()
}
// actual iteration: always go from left to right
left.values foreach { leftInfo =>
neighborsProvider(leftInfo.node) foreach { rightNode =>
// create rightInfo, calculate number of neighbors of rightNode in this subgraph
val rightInfo = right.getOrElseUpdate(rightNode, {
assert(isRightUninitialized)
NodeInfo(graphUtils.graph.getNodeById(rightNode).get, 0.0, 0.0, 0)
})
if (isRightUninitialized) { rightInfo.numNeighbors += 1 }
if (flowReverse)
flowWeight(rightInfo, leftInfo)
else
flowWeight(leftInfo, rightInfo)
}
}
}