From b2b4fe3dd816427901a607a14baf005afc5f2390 Mon Sep 17 00:00:00 2001 From: Trolli Schmittlauch Date: Tue, 29 Sep 2020 02:06:31 +0200 Subject: [PATCH] change vserver ID representation type to Word8 - performance improvement: avoid unnecessary representation and conversion from/to Integer - part of hot path: with k-choices, all possible IDs are regularly generated and checked - preparation for #74 --- src/Hash2Pub/ASN1Coding.hs | 4 ++-- src/Hash2Pub/DHTProtocol.hs | 4 ++-- src/Hash2Pub/FediChord.hs | 10 +++++----- src/Hash2Pub/FediChordTypes.hs | 13 +++++++++---- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Hash2Pub/ASN1Coding.hs b/src/Hash2Pub/ASN1Coding.hs index c2a5cc4..65f5e21 100644 --- a/src/Hash2Pub/ASN1Coding.hs +++ b/src/Hash2Pub/ASN1Coding.hs @@ -206,7 +206,7 @@ encodeNodeState ns = [ , OctetString (ipAddrAsBS $ getIpAddr ns) , IntVal (toInteger . getDhtPort $ ns) , IntVal (toInteger . getServicePort $ ns) - , IntVal (getVServerID ns) + , IntVal (toInteger $ getVServerID ns) , End Sequence ] @@ -370,7 +370,7 @@ parseNodeState = onNextContainer Sequence $ do , domain = domain' , dhtPort = dhtPort' , servicePort = servicePort' - , vServerID = vServer' + , vServerID = fromInteger vServer' , ipAddr = ip' } diff --git a/src/Hash2Pub/DHTProtocol.hs b/src/Hash2Pub/DHTProtocol.hs index a51b117..3ad5747 100644 --- a/src/Hash2Pub/DHTProtocol.hs +++ b/src/Hash2Pub/DHTProtocol.hs @@ -313,7 +313,7 @@ handleIncomingRequest nsSTM sendQ msgSet sourceAddr = do aRequestPart = Set.elemAt 0 msgSet senderNs = sender aRequestPart givenSenderID = getNid senderNs - recomputedID = genNodeID addr (getDomain senderNs) (fromInteger $ getVServerID senderNs) + recomputedID = genNodeID addr (getDomain senderNs) (getVServerID senderNs) in if recomputedID == givenSenderID then Just <$> responder nsSTM' msgSet' @@ -779,7 +779,7 @@ requestPing ns target = do -- recompute ID for each received node and mark as verified in cache now <- getPOSIXTime forM_ responseVss (\vs -> - let recomputedID = genNodeID peerAddr (getDomain vs) (fromInteger $ getVServerID vs) + let recomputedID = genNodeID peerAddr (getDomain vs) (getVServerID vs) in if recomputedID == getNid vs then atomically $ writeTQueue (cacheWriteQueue ns) $ addNodeAsVerifiedPure now vs else pure () diff --git a/src/Hash2Pub/FediChord.hs b/src/Hash2Pub/FediChord.hs index d4a94a6..1aea94e 100644 --- a/src/Hash2Pub/FediChord.hs +++ b/src/Hash2Pub/FediChord.hs @@ -151,7 +151,7 @@ fediChordInit initConf serviceRunner = do -- this function. fediChordJoinNewVs :: (MonadError String m, MonadIO m, Service s (RealNodeSTM s)) => RealNodeSTM s -- ^ parent real node - -> Integer -- ^ vserver ID + -> Word8 -- ^ vserver ID -> RemoteNodeState -- ^ target node to join on -> m (NodeID, LocalNodeStateSTM s) -- ^ on success: (vserver ID, TVar of vserver) fediChordJoinNewVs nodeSTM vsId target = do @@ -164,7 +164,7 @@ fediChordJoinNewVs nodeSTM vsId target = do -- | initialises the 'NodeState' for this local node. -- Separated from 'fediChordInit' to be usable in tests. -nodeStateInit :: Service s (RealNodeSTM s) => RealNodeSTM s -> Integer -> IO (LocalNodeState s) +nodeStateInit :: Service s (RealNodeSTM s) => RealNodeSTM s -> Word8 -> IO (LocalNodeState s) nodeStateInit realNodeSTM vsID' = do realNode <- readTVarIO realNodeSTM let @@ -173,7 +173,7 @@ nodeStateInit realNodeSTM vsID' = do containedState = RemoteNodeState { domain = confDomain conf , ipAddr = confIP conf - , nid = genNodeID (confIP conf) (confDomain conf) $ fromInteger vsID + , nid = genNodeID (confIP conf) (confDomain conf) vsID , dhtPort = toEnum $ confDhtPort conf , servicePort = getListeningPortFromService $ nodeService realNode , vServerID = vsID @@ -257,7 +257,7 @@ kChoicesVsJoin queryVsSTM bootstrapNode capacity activeVss nodeSTM remainingTarg activeVsSet = HMap.keysSet activeVss -- tuples of node IDs and vserver IDs, because vserver IDs are needed for -- LocalNodeState creation - nonJoinedIDs = filter (not . flip HSet.member activeVsSet . fst) [ (genNodeID (confIP conf) (confDomain conf) (fromInteger v), v) | v <- [0..pred (confKChoicesMaxVS conf)]] + nonJoinedIDs = filter (not . flip HSet.member activeVsSet . fst) [ (genNodeID (confIP conf) (confDomain conf) v, v) | v <- [0..pred (confKChoicesMaxVS conf)]] queryVs <- liftIO $ readTVarIO queryVsSTM -- query load of all possible segments @@ -411,7 +411,7 @@ bootstrapQueryId nsSTM (bootstrapHost, bootstrapPort) targetID = do SockAddrInet6 _ _ bootstrapIP _ -> pure bootstrapIP _ -> throwError $ "Expected an IPv6 address, but got " <> show bootstrapAddr let possibleJoinIDs = - [ genNodeID bootstrapIP bootstrapHost (fromInteger v) | v <- [0..pred ( + [ genNodeID bootstrapIP bootstrapHost v | v <- [0..pred ( if confEnableKChoices nodeConf then confKChoicesMaxVS nodeConf else 1)]] tryQuery ns srcAddr nodeConf possibleJoinIDs where diff --git a/src/Hash2Pub/FediChordTypes.hs b/src/Hash2Pub/FediChordTypes.hs index a20c156..0171177 100644 --- a/src/Hash2Pub/FediChordTypes.hs +++ b/src/Hash2Pub/FediChordTypes.hs @@ -190,7 +190,7 @@ data RemoteNodeState = RemoteNodeState -- ^ port of the DHT itself , servicePort :: PortNumber -- ^ port of the service provided on top of the DHT - , vServerID :: Integer + , vServerID :: Word8 -- ^ ID of this vserver } deriving (Show, Eq) @@ -235,14 +235,14 @@ class NodeState a where getIpAddr :: a -> HostAddress6 getDhtPort :: a -> PortNumber getServicePort :: a -> PortNumber - getVServerID :: a -> Integer + getVServerID :: a -> Word8 -- setters for common properties setNid :: NodeID -> a -> a setDomain :: String -> a -> a setIpAddr :: HostAddress6 -> a -> a setDhtPort :: PortNumber -> a -> a setServicePort :: PortNumber -> a -> a - setVServerID :: Integer -> a -> a + setVServerID :: Word8 -> a -> a toRemoteNodeState :: a -> RemoteNodeState instance NodeState RemoteNodeState where @@ -391,6 +391,11 @@ genNodeID :: HostAddress6 -- ^a node's IPv6 address -> NodeID -- ^the generated @NodeID@ genNodeID ip nodeDomain vs = NodeID . byteStringToUInteger $ genNodeIDBS ip nodeDomain vs + +isValidIdForNode :: Word8 -> RemoteNodeState -> HostAddress6 -> Bool +isValidIdForNode numVs rns addr = getNid rns `elem` [genNodeID addr (getDomain rns) v | v <- [0..(numVs-1)] ] + + -- | generates a 256 bit long key identifier, represented as ByteString, for looking up its data on the DHT genKeyIDBS :: String -- ^the key string -> BS.ByteString -- ^the key ID represented as a @ByteString@ @@ -451,7 +456,7 @@ data FediChordConf = FediChordConf -- ^ fraction of capacity above which a node considers itself overloaded , confKChoicesUnderload :: Double -- ^ fraction of capacity below which a node considers itself underloaded - , confKChoicesMaxVS :: Integer + , confKChoicesMaxVS :: Word8 -- ^ upper limit of vserver index κ } deriving (Show, Eq)