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}