Randomized pieces to download

This commit is contained in:
Ben Davis
2017-08-29 12:34:02 +01:00
parent dba46bf8a7
commit 91c8e44d48
9 changed files with 73 additions and 23 deletions
+4
View File
@@ -10,6 +10,7 @@
0434EAB818A3C318E433338A /* Pods_BitTorrentTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A8680B0EA21B5A20E03DEE6D /* Pods_BitTorrentTests.framework */; };
34D4082D0E0A2C899857DC89 /* Pods_BitTorrent.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B47AE52A67ECE61259FCDAD /* Pods_BitTorrent.framework */; };
867491B4C409A91D4D72CCE7 /* Pods_BitTorrent_BitTorrentExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D97F9FB9F74204574FF6840B /* Pods_BitTorrent_BitTorrentExample.framework */; };
B501A5581F557E9E00B87911 /* RandomEnumeration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501A5571F557E9E00B87911 /* RandomEnumeration.swift */; };
B50B24F71F0A553F00C23E7C /* UDPConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50B24F61F0A553B00C23E7C /* UDPConnectionTests.swift */; };
B50B24F91F0A554A00C23E7C /* UDPConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50B24F81F0A554A00C23E7C /* UDPConnection.swift */; };
B514DD7B1F40971D00C932F8 /* TorrentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B514DD7A1F40971D00C932F8 /* TorrentViewController.swift */; };
@@ -168,6 +169,7 @@
8B47AE52A67ECE61259FCDAD /* Pods_BitTorrent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BitTorrent.framework; sourceTree = BUILT_PRODUCTS_DIR; };
99A91AD4708288B297A8B700 /* Pods-BitTorrentTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BitTorrentTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-BitTorrentTests/Pods-BitTorrentTests.debug.xcconfig"; sourceTree = "<group>"; };
A8680B0EA21B5A20E03DEE6D /* Pods_BitTorrentTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_BitTorrentTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B501A5571F557E9E00B87911 /* RandomEnumeration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomEnumeration.swift; sourceTree = "<group>"; };
B50B24F61F0A553B00C23E7C /* UDPConnectionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDPConnectionTests.swift; sourceTree = "<group>"; };
B50B24F81F0A554A00C23E7C /* UDPConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDPConnection.swift; sourceTree = "<group>"; };
B514DD7A1F40971D00C932F8 /* TorrentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TorrentViewController.swift; sourceTree = "<group>"; };
@@ -407,6 +409,7 @@
B514DDA31F40E96100C932F8 /* CombinedNetworkSpeedTracker.swift */,
B514DD8E1F40C53C00C932F8 /* NetworkSpeedTrackerTests.swift */,
B514DD9B1F40DD1B00C932F8 /* URL.swift */,
B501A5571F557E9E00B87911 /* RandomEnumeration.swift */,
);
path = Utilities;
sourceTree = "<group>";
@@ -982,6 +985,7 @@
B558F4831F0A647D00438BB4 /* InternetProtocol.swift in Sources */,
B527F62B1F1BD5FA001F06AF /* TorrentPieceDownloadBuffer.swift in Sources */,
B5BFD9CC1F3FAF9A00CE0186 /* TorrentTrackerManager.swift in Sources */,
B501A5581F557E9E00B87911 /* RandomEnumeration.swift in Sources */,
B54D0C7A1CA69FAD004343BD /* TorrentMetaInfo.swift in Sources */,
B5C06F131F12CDD8005730B3 /* TorrentPeer.swift in Sources */,
B5F81E4B1F04399800B25C70 /* TorrentTrackerResponse.swift in Sources */,
+19 -10
View File
@@ -92,15 +92,24 @@ public struct BitField: Equatable {
}
}
extension BitField: Sequence {
public func makeIterator() -> AnyIterator<(index: Int, isSet: Bool)> {
var index = 0
return AnyIterator {
guard index < self.size else { return nil }
defer {
index += 1
}
return (index, self.isSet(at: index))
}
extension BitField: Collection {
public typealias Index = Array<Bool>.Index
public var startIndex: Index {
return value.startIndex
}
public var endIndex: Index {
return value.endIndex
}
public subscript(position: Index) -> (index: Int, isSet: Bool) {
precondition(indices.contains(position), "out of bounds")
return (index: position, isSet: value[position])
}
public func index(after i: Index) -> Index {
return value.index(after: i)
}
}
@@ -73,6 +73,4 @@ class TorrentPieceDownloadBuffer {
pendingRequests.remove(at: pendingIndex)
}
}
@@ -43,7 +43,7 @@ class TorrentProgressManager {
}
func getNextPieceToDownload(from availablePieces: BitField) -> TorrentPieceRequest? {
for (i, isSet) in availablePieces where isSet {
for (i, isSet) in availablePieces.pseudoRandomized where isSet {
if !progress.hasPiece(i) && !progress.isCurrentlyDownloading(piece: i) {
progress.setCurrentlyDownloading(piece: i)
return (i, metaInfo.info.lengthOfPiece(at: i), metaInfo.info.pieces[i])
@@ -12,10 +12,10 @@ import CocoaAsyncSocket
class GCDAsyncSocketStub: GCDAsyncSocket {
var connectToHostCalled = false
var connectToHostParameters: (host: String, port: UInt16)?
override func connect(toHost host: String, onPort port: UInt16) throws {
var connectToHostParameters: (host: String, port: UInt16, timeout: TimeInterval)?
override func connect(toHost host: String, onPort port: UInt16, withTimeout timeout: TimeInterval) throws {
connectToHostCalled = true
connectToHostParameters = (host, port)
connectToHostParameters = (host, port, timeout)
}
var readDataCalled = false
@@ -61,7 +61,7 @@ class TCPConnection: NSObject, TCPConnectionProtocol {
}
func connect(to host: String, onPort port: UInt16) throws {
try socket.connect(toHost: host, onPort: port)
try socket.connect(toHost: host, onPort: port, withTimeout: 15)
}
func disconnect() {
@@ -0,0 +1,38 @@
//
// RandomEnumeration.swift
// BitTorrent
//
// Created by Ben Davis on 29/08/2017.
// Copyright © 2017 Ben Davis. All rights reserved.
//
import Foundation
struct PseudoRandomizedSequence<Col, Elem>: Sequence
where Col: Collection, Col.Element == Elem, Col.Index == Int, Col.IndexDistance == Int {
fileprivate let orderedSequence: Col
func makeIterator() -> AnyIterator<Elem> {
let length = orderedSequence.count
let seed = Int(arc4random()) % length
let increment = 13 // prime as the step
var generatedNumber = seed
var count = 0
return AnyIterator {
guard count != length else { return nil }
count += 1
generatedNumber = (generatedNumber + increment) % length
return self.orderedSequence[generatedNumber]
}
}
}
extension Collection where Index == Int, IndexDistance == Int {
var pseudoRandomized: PseudoRandomizedSequence<Self, Element> {
return PseudoRandomizedSequence(orderedSequence: self)
}
}
+3 -2
View File
@@ -42,6 +42,7 @@ enum TorrentInfoRowData: Int {
func value(using client: TorrentClient) -> String {
let speedSampleSize: TimeInterval = 5
let etaSampleSize: TimeInterval = 30
switch self {
@@ -73,8 +74,8 @@ enum TorrentInfoRowData: Int {
return "????"
case .eta:
let speed = client.downloadSpeedTracker.numberOfBytesDownloaded(over: speedSampleSize)
let speedPerSecond = Double(speed) / speedSampleSize
let speed = client.downloadSpeedTracker.numberOfBytesDownloaded(over: etaSampleSize)
let speedPerSecond = Double(speed) / etaSampleSize
guard speed > 0 else { return "" }
let remaining = client.progress.remaining * client.metaInfo.info.pieceLength
@@ -92,10 +92,10 @@ extension TorrentViewController: UITableViewDataSource {
return startCell
} else {
let reCheckCell = UITableViewCell(style: .default, reuseIdentifier: nil)
startCell.textLabel?.text = "Start"
startCell.textLabel?.textAlignment = .center
startCell.textLabel?.textColor = .blue
return startCell
reCheckCell.textLabel?.text = "Start"
reCheckCell.textLabel?.textAlignment = .center
reCheckCell.textLabel?.textColor = .blue
return reCheckCell
}
}
}