Picking peers weighted by the number of rare blocks they have. A block is rare if there are at most 2 copies in the neighborhood. Better number can be used (some function of neighborhood size)
This commit is contained in:
parent
cf81da9485
commit
0416cc22d2
|
@ -444,7 +444,13 @@ extends Broadcast[T] with Logging {
|
||||||
threadPool.getActiveCount
|
threadPool.getActiveCount
|
||||||
|
|
||||||
while (hasBlocks < totalBlocks && numThreadsToCreate > 0) {
|
while (hasBlocks < totalBlocks && numThreadsToCreate > 0) {
|
||||||
var peerToTalkTo = pickPeerToTalkTo
|
var peerToTalkTo = pickPeerToTalkToRarestFirst
|
||||||
|
|
||||||
|
if (peerToTalkTo != null)
|
||||||
|
logInfo ("Peer chosen: " + peerToTalkTo + " with " + peerToTalkTo.hasBlocksBitVector)
|
||||||
|
else
|
||||||
|
logInfo ("No peer chosen...")
|
||||||
|
|
||||||
if (peerToTalkTo != null) {
|
if (peerToTalkTo != null) {
|
||||||
threadPool.execute (new TalkToPeer (peerToTalkTo))
|
threadPool.execute (new TalkToPeer (peerToTalkTo))
|
||||||
|
|
||||||
|
@ -467,7 +473,7 @@ extends Broadcast[T] with Logging {
|
||||||
|
|
||||||
// Right now picking the one that has the most blocks this peer wants
|
// Right now picking the one that has the most blocks this peer wants
|
||||||
// Also picking peer randomly if no one has anything interesting
|
// Also picking peer randomly if no one has anything interesting
|
||||||
private def pickPeerToTalkTo: SourceInfo = {
|
private def pickPeerToTalkToRandom: SourceInfo = {
|
||||||
var curPeer: SourceInfo = null
|
var curPeer: SourceInfo = null
|
||||||
var curMax = 0
|
var curMax = 0
|
||||||
|
|
||||||
|
@ -475,10 +481,13 @@ extends Broadcast[T] with Logging {
|
||||||
|
|
||||||
// Find peers that are not connected right now
|
// Find peers that are not connected right now
|
||||||
var peersNotInUse = ListBuffer[SourceInfo] ()
|
var peersNotInUse = ListBuffer[SourceInfo] ()
|
||||||
synchronized {
|
listOfSources.synchronized {
|
||||||
peersNotInUse = listOfSources -- peersNowTalking
|
peersNowTalking.synchronized {
|
||||||
|
peersNotInUse = listOfSources -- peersNowTalking
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select the peer that has the most blocks that this receiver does not
|
||||||
peersNotInUse.foreach { eachSource =>
|
peersNotInUse.foreach { eachSource =>
|
||||||
var tempHasBlocksBitVector: BitSet = null
|
var tempHasBlocksBitVector: BitSet = null
|
||||||
hasBlocksBitVector.synchronized {
|
hasBlocksBitVector.synchronized {
|
||||||
|
@ -493,7 +502,7 @@ extends Broadcast[T] with Logging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always pick randomly or randomly pick randomly?
|
// TODO: Always pick randomly or randomly pick randomly?
|
||||||
// Now always picking randomly
|
// Now always picking randomly
|
||||||
if (curPeer == null && peersNotInUse.size > 0) {
|
if (curPeer == null && peersNotInUse.size > 0) {
|
||||||
// Pick uniformly the i'th required peer
|
// Pick uniformly the i'th required peer
|
||||||
|
@ -508,14 +517,86 @@ extends Broadcast[T] with Logging {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curPeer != null)
|
|
||||||
logInfo ("Peer chosen: " + curPeer + " with " + curPeer.hasBlocksBitVector)
|
|
||||||
else
|
|
||||||
logInfo ("No peer chosen...")
|
|
||||||
|
|
||||||
return curPeer
|
return curPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Picking peer with the weight of rare blocks it has
|
||||||
|
private def pickPeerToTalkToRarestFirst: SourceInfo = {
|
||||||
|
// Find peers that are not connected right now
|
||||||
|
var peersNotInUse = ListBuffer[SourceInfo] ()
|
||||||
|
listOfSources.synchronized {
|
||||||
|
peersNowTalking.synchronized {
|
||||||
|
peersNotInUse = listOfSources -- peersNowTalking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of copies of each block in the neighborhood
|
||||||
|
var numCopiesPerBlock = Array.tabulate [Int] (totalBlocks) (_ => 0)
|
||||||
|
|
||||||
|
listOfSources.synchronized {
|
||||||
|
listOfSources.foreach { eachSource =>
|
||||||
|
for (i <- 0 until totalBlocks) {
|
||||||
|
numCopiesPerBlock(i) +=
|
||||||
|
( if (eachSource.hasBlocksBitVector.get (i)) 1 else 0 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: A block is rare if there are at most 2 copies of that block
|
||||||
|
// TODO: This CONSTANT could be a function of the neighborhood size
|
||||||
|
var rareBlocksIndices = ListBuffer[Int] ()
|
||||||
|
for (i <- 0 until totalBlocks) {
|
||||||
|
if (numCopiesPerBlock(i) > 0 && numCopiesPerBlock(i) <= 2) {
|
||||||
|
rareBlocksIndices += i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find peers with rare blocks
|
||||||
|
var peersWithRareBlocks = ListBuffer[(SourceInfo, Int)] ()
|
||||||
|
var totalRareBlocks = 0
|
||||||
|
|
||||||
|
peersNotInUse.foreach { eachPeer =>
|
||||||
|
var hasRareBlocks = 0
|
||||||
|
rareBlocksIndices.foreach { rareBlock =>
|
||||||
|
if (eachPeer.hasBlocksBitVector.get (rareBlock)) {
|
||||||
|
hasRareBlocks += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasRareBlocks > 0) {
|
||||||
|
peersWithRareBlocks += ((eachPeer, hasRareBlocks))
|
||||||
|
}
|
||||||
|
totalRareBlocks += hasRareBlocks
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select a peer from peersWithRareBlocks based on weight calculated from
|
||||||
|
// unique rare blocks
|
||||||
|
var selectedPeerToTalkTo: SourceInfo = null
|
||||||
|
|
||||||
|
if (peersWithRareBlocks.size > 0) {
|
||||||
|
// Sort the peers based on how many rare blocks they have
|
||||||
|
peersWithRareBlocks.sortBy(_._2)
|
||||||
|
|
||||||
|
var randomNumber = BitTorrentBroadcast.ranGen.nextDouble
|
||||||
|
var tempSum = 0.0
|
||||||
|
|
||||||
|
var i = 0
|
||||||
|
do {
|
||||||
|
tempSum += (1.0 * peersWithRareBlocks(i)._2 / totalRareBlocks)
|
||||||
|
if (tempSum >= randomNumber) {
|
||||||
|
selectedPeerToTalkTo = peersWithRareBlocks(i)._1
|
||||||
|
}
|
||||||
|
i += 1
|
||||||
|
} while (i < peersWithRareBlocks.size && selectedPeerToTalkTo == null)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPeerToTalkTo == null) {
|
||||||
|
selectedPeerToTalkTo = pickPeerToTalkToRandom
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedPeerToTalkTo
|
||||||
|
}
|
||||||
|
|
||||||
class TalkToPeer (peerToTalkTo: SourceInfo)
|
class TalkToPeer (peerToTalkTo: SourceInfo)
|
||||||
extends Thread with Logging {
|
extends Thread with Logging {
|
||||||
private var peerSocketToSource: Socket = null
|
private var peerSocketToSource: Socket = null
|
||||||
|
|
Loading…
Reference in a new issue