The Close List and the Search Entries are termed the \texttt{Node Lists} of
the DHT State.
\begin{code}
{-# LANGUAGE StrictData #-}
module Network.Tox.DHT.NodeList where
import Control.Applicative (Applicative, Const (..),
getConst)
import Control.Monad (guard)
import Data.Maybe (listToMaybe)
import Data.Monoid (Dual (..), Endo (..), Monoid,
appEndo, getDual, mempty)
import Network.Tox.Crypto.Key (PublicKey)
import Network.Tox.DHT.ClientList (ClientList)
import qualified Network.Tox.DHT.ClientList as ClientList
import Network.Tox.DHT.Distance (Distance)
import Network.Tox.DHT.KBuckets (KBuckets)
import qualified Network.Tox.DHT.KBuckets as KBuckets
import Network.Tox.NodeInfo.NodeInfo (NodeInfo)
import Network.Tox.Time (Timestamp)
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}