{-# LANGUAGE OverloadedStrings #-} module Blockchain.Database.MerklePatricia.Map ( map ) where --In the Haskel sense of the word, 'map' is perhaps the incorrect word to use here. --This is more of a 'mapM', but this is a one-off situation that is --more about iterating over the full MP space than a complete functional treatment --of the MP tree. I could also call this traverse, but I think it makes --more sense to just go with the simple term here. import Prelude hiding (map) import Control.Monad --import Control.Monad.IO.Class --import qualified Data.ByteString.Char8 as BC --import qualified Data.ByteString.Base16 as B16 import qualified Data.NibbleString as N import qualified Database.LevelDB as LDB import Blockchain.Data.RLP import Blockchain.Database.MerklePatricia import Blockchain.Database.MerklePatricia.Internal import Blockchain.Database.MerklePatricia.NodeData map::LDB.MonadResource m=>(Key->RLPObject->m ())->MPDB->m () map f mpdb = do mapNodeRef (ldb mpdb) "" f (PtrRef $ stateRoot mpdb) mapNodeData::LDB.MonadResource m=>LDB.DB->Key->(Key->RLPObject->m ())->NodeData->m () mapNodeData _ _ _ EmptyNodeData = return () mapNodeData db partialKey f FullNodeData {choices=choices', nodeVal = maybeV} = do forM_ (zip [0..] choices') $ \(k, ch) -> do mapNodeRef db (partialKey `N.append` N.singleton k) f ch case maybeV of Nothing -> return () Just v -> f partialKey v mapNodeData db partialKey f ShortcutNodeData {nextNibbleString=remainingKey, nextVal=nv} = case nv of Left nr -> mapNodeRef db (partialKey `N.append` remainingKey) f nr Right v -> f (partialKey `N.append` remainingKey) v mapNodeRef::LDB.MonadResource m=>LDB.DB->Key->(Key->RLPObject->m ())->NodeRef->m () mapNodeRef db partialKey f (PtrRef sr) = do nodeData <- getNodeData (MPDB db sr) $ PtrRef sr mapNodeData db partialKey f nodeData mapNodeRef _ _ _ (SmallRef _) = return () --TODO I might have to deal with this also