Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory,Utility: use binary search #64

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 25 additions & 33 deletions NOnion/Directory/TorDirectory.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ open NOnion.Crypto
open NOnion.Network
open NOnion.Http
open NOnion.Utility
open NOnion.Utility.ByteArrayUtil

type RouterType =
| Normal
Expand Down Expand Up @@ -456,33 +457,6 @@ type TorDirectory =

let! networkStatus = self.GetLiveNetworkStatus()

let ByteArrayCompare (x: array<byte>) (y: array<byte>) =
let xlen = x.Length
let ylen = y.Length

let len =
if xlen < ylen then
xlen
else
ylen

let mutable index = 0
let mutable result = 0

while index < len do
let diff = (int(x.[index])) - int(y.[index])

if diff <> 0 then
index <- len + 1 // breaks out of the loop, and signals that result is valid
result <- diff
else
index <- index + 1

if index > len then
result
else
(xlen - ylen)

let directories =
networkStatus.GetHiddenServiceDirectories()
|> List.choose(fun node ->
Expand Down Expand Up @@ -528,13 +502,31 @@ type TorDirectory =
]
|> HiddenServicesCipher.SHA3256

//FIXME: binary serach idx here
let start =
directories
|> Seq.tryFindIndex(fun (_, index) ->
ByteArrayCompare index hsIndex >= 0
)
|> Option.defaultValue 0
let maybeStart =
let hsIndexes =
directories
|> Array.ofList
|> Array.map(fun (_, hsIndex) -> hsIndex)

Array.BinarySearch(
hsIndexes,
hsIndex,
ByteArrayComparer()
)

if maybeStart < 0 then
let complement = ~~~maybeStart

// Getting the length of the list if no member is greater than the key we
// are looking for so start at the first element.
if complement >= directories.Length then
let arrayStartIndex = 0
arrayStartIndex
else
complement
else
maybeStart

let rec pickNodes startIndex nToAdd state =
if nToAdd = 0 then
Expand Down
1 change: 1 addition & 0 deletions NOnion/NOnion.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<Compile Include="RelayIntroduceStatus.fs" />
<Compile Include="Exceptions.fs" />
<Compile Include="HandshakeType.fs" />
<Compile Include="Utility\ByteArrayUtil.fs" />
<Compile Include="Utility\FSharpUtil.fs" />
<Compile Include="Utility\ResultUtil.fs" />
<Compile Include="Utility\MailboxUtil.fs" />
Expand Down
36 changes: 36 additions & 0 deletions NOnion/Utility/ByteArrayUtil.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace NOnion.Utility

open System.Collections.Generic

module ByteArrayUtil =
let ByteArrayCompare (x: array<byte>) (y: array<byte>) =
let xlen = x.Length
let ylen = y.Length

let len =
if xlen < ylen then
xlen
else
ylen

let mutable index = 0
let mutable result = 0

while index < len do
let diff = (int(x.[index])) - int(y.[index])

if diff <> 0 then
index <- len + 1 // breaks out of the loop, and signals that result is valid
result <- diff
else
index <- index + 1

if index > len then
result
else
(xlen - ylen)

type ByteArrayComparer() =
interface IComparer<array<byte>> with
member __.Compare(first, second) =
ByteArrayCompare first second