The Close List and the Search Entries are termed the \texttt{Node Lists} of
the DHT State.
\begin{code}
{-# LANGUAGE StrictData #-}
module Tox.DHT.NodeList where
import Control.Applicative (Const (..), getConst)
import Control.Monad (guard)
import Data.Maybe (listToMaybe)
import Data.Monoid (Dual (..), Endo (..), appEndo, getDual)
import Tox.Core.Time (Timestamp)
import Tox.Crypto.Core.Key (PublicKey)
import Tox.DHT.ClientList (ClientList)
import qualified Tox.DHT.ClientList as ClientList
import Tox.DHT.Distance (Distance)
import Tox.DHT.KBuckets (KBuckets)
import qualified Tox.DHT.KBuckets as KBuckets
import Tox.Network.Core.NodeInfo (NodeInfo)
class NodeList l where
addNode :: Timestamp -> NodeInfo -> l -> l
removeNode :: PublicKey -> l -> l
viable :: NodeInfo -> l -> Bool
baseKey :: l -> PublicKey
traverseClientLists ::
Applicative f => (ClientList -> f ClientList) -> l -> f l
closeNodes :: PublicKey -> l -> [(Distance, NodeInfo)]
foldMapClientLists :: Monoid m => (ClientList -> m) -> l -> m
foldMapClientLists ClientList -> m
f = Const m l -> m
forall a k (b :: k). Const a b -> a
getConst (Const m l -> m) -> (l -> Const m l) -> l -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ClientList -> Const m ClientList) -> l -> Const m l
forall l (f :: * -> *).
(NodeList l, Applicative f) =>
(ClientList -> f ClientList) -> l -> f l
traverseClientLists (m -> Const m ClientList
forall k a (b :: k). a -> Const a b
Const (m -> Const m ClientList)
-> (ClientList -> m) -> ClientList -> Const m ClientList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClientList -> m
f)
foldlClientLists :: (a -> ClientList -> a) -> a -> l -> a
foldlClientLists a -> ClientList -> a
f a
z l
t =
Endo a -> a -> a
forall a. Endo a -> a -> a
appEndo (Dual (Endo a) -> Endo a
forall a. Dual a -> a
getDual ((ClientList -> Dual (Endo a)) -> l -> Dual (Endo a)
forall l m. (NodeList l, Monoid m) => (ClientList -> m) -> l -> m
foldMapClientLists (Endo a -> Dual (Endo a)
forall a. a -> Dual a
Dual (Endo a -> Dual (Endo a))
-> (ClientList -> Endo a) -> ClientList -> Dual (Endo a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Endo ((a -> a) -> Endo a)
-> (ClientList -> a -> a) -> ClientList -> Endo a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> ClientList -> a) -> ClientList -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> ClientList -> a
f) l
t)) a
z
nodeListList :: l -> [NodeInfo]
nodeListList = (ClientList -> [NodeInfo]) -> l -> [NodeInfo]
forall l m. (NodeList l, Monoid m) => (ClientList -> m) -> l -> m
foldMapClientLists ClientList -> [NodeInfo]
ClientList.nodeInfos
foldNodes :: (a -> NodeInfo -> a) -> a -> l -> a
foldNodes = (a -> ClientList -> a) -> a -> l -> a
forall l a. NodeList l => (a -> ClientList -> a) -> a -> l -> a
foldlClientLists ((a -> ClientList -> a) -> a -> l -> a)
-> ((a -> NodeInfo -> a) -> a -> ClientList -> a)
-> (a -> NodeInfo -> a)
-> a
-> l
-> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> NodeInfo -> a) -> a -> ClientList -> a
forall a. (a -> NodeInfo -> a) -> a -> ClientList -> a
ClientList.foldNodes
lookupPublicKey :: PublicKey -> l -> Maybe NodeInfo
lookupPublicKey PublicKey
publicKey l
list = do
(Distance
dist,NodeInfo
node) <- [(Distance, NodeInfo)] -> Maybe (Distance, NodeInfo)
forall a. [a] -> Maybe a
listToMaybe ([(Distance, NodeInfo)] -> Maybe (Distance, NodeInfo))
-> [(Distance, NodeInfo)] -> Maybe (Distance, NodeInfo)
forall a b. (a -> b) -> a -> b
$ PublicKey -> l -> [(Distance, NodeInfo)]
forall l. NodeList l => PublicKey -> l -> [(Distance, NodeInfo)]
closeNodes PublicKey
publicKey l
list
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Distance
dist Distance -> Distance -> Bool
forall a. Eq a => a -> a -> Bool
== Distance
forall a. Monoid a => a
mempty)
NodeInfo -> Maybe NodeInfo
forall a. a -> Maybe a
Just NodeInfo
node
instance NodeList ClientList where
addNode :: Timestamp -> NodeInfo -> ClientList -> ClientList
addNode = Timestamp -> NodeInfo -> ClientList -> ClientList
ClientList.addNode
removeNode :: PublicKey -> ClientList -> ClientList
removeNode = PublicKey -> ClientList -> ClientList
ClientList.removeNode
viable :: NodeInfo -> ClientList -> Bool
viable = NodeInfo -> ClientList -> Bool
ClientList.viable
baseKey :: ClientList -> PublicKey
baseKey = ClientList -> PublicKey
ClientList.baseKey
traverseClientLists :: (ClientList -> f ClientList) -> ClientList -> f ClientList
traverseClientLists = (ClientList -> f ClientList) -> ClientList -> f ClientList
forall a. a -> a
id
closeNodes :: PublicKey -> ClientList -> [(Distance, NodeInfo)]
closeNodes = PublicKey -> ClientList -> [(Distance, NodeInfo)]
ClientList.closeNodes
instance NodeList KBuckets where
addNode :: Timestamp -> NodeInfo -> KBuckets -> KBuckets
addNode = Timestamp -> NodeInfo -> KBuckets -> KBuckets
KBuckets.addNode
removeNode :: PublicKey -> KBuckets -> KBuckets
removeNode = PublicKey -> KBuckets -> KBuckets
KBuckets.removeNode
viable :: NodeInfo -> KBuckets -> Bool
viable = NodeInfo -> KBuckets -> Bool
KBuckets.viable
baseKey :: KBuckets -> PublicKey
baseKey = KBuckets -> PublicKey
KBuckets.baseKey
traverseClientLists :: (ClientList -> f ClientList) -> KBuckets -> f KBuckets
traverseClientLists = (ClientList -> f ClientList) -> KBuckets -> f KBuckets
forall (f :: * -> *).
Applicative f =>
(ClientList -> f ClientList) -> KBuckets -> f KBuckets
KBuckets.traverseClientLists
closeNodes :: PublicKey -> KBuckets -> [(Distance, NodeInfo)]
closeNodes = PublicKey -> KBuckets -> [(Distance, NodeInfo)]
KBuckets.closeNodes
\end{code}