2012-03-13 13 views
5

के अंदर तो मेरी समस्या निम्नानुसार है। मैं आरडीबी फाइलों के लिए एक स्ट्रीमिंग पार्सर को लागू करने की कोशिश कर रहा हूं (रेडिस का उत्पादन करने वाली डंप फाइलें)। मैं mapM_ के समान फ़ंक्शन को कार्यान्वित करना चाहता हूं, जिससे मैं कर सकता हूं, डंप फ़ाइल में प्रदर्शित प्रत्येक ऑब्जेक्ट को प्रिंट करें क्योंकि इसे पार्स किया गया है। हालांकि, मैं इसे स्थिर स्थान पर संचालित करने के लिए प्रतीत नहीं कर सकता। मुझे लगता है कि क्या हो रहा है कि मैं एक महान आईओ() गेट मोनाड के अंदर थंक बना रहा हूं, गेट मोनड से लौट रहा हूं और फिर आईओ को निष्पादित कर रहा हूं। क्या मेरी वस्तुओं को स्ट्रीम करने के लिए वैसे भी है क्योंकि उन्हें मुद्रित करने के लिए पार्स किया गया है और फिर उन्हें त्याग दिया गया है? मैंने गणक और कंडिटेक्ट्स की कोशिश की है लेकिन मैंने कोई वास्तविक लाभ नहीं देखा है। यहां मेरे पास अब तक है:आईओओ गेट मोनाड

loadObjs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a) 
loadObjs_ f = do 
      code <- lookAhead getWord8 
      case code of 
       0xfd -> do 
       skip 1 
       expire <- loadTime 
       getPairs_ f (Just expire) 
       0xfc -> do 
       skip 1 
       expire <- loadTimeMs 
       getPairs_ f (Just expire) 
       0xfe -> f Nothing "Switching Database" RDBNull 
       0xff -> f Nothing "" RDBNull 
       _ -> getPairs_ f Nothing 

getPairs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Maybe Integer -> Get (m a) 
getPairs_ f ex = do 
       !t <- getWord8 
       !key <- loadStringObj False 
       !obj <- loadObj t 
       !rest <- loadObjs_ f 
       !out <- f ex key obj 
       return (out >> rest) 


(loadObj does the actual parsing of a single object but I believe that whatever I need to fix the streaming to operate in constant or near-constant memory is at a higher level in the iteration than loadObj) 

getDBs_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a) 
getDBs_ f = do 
      opc <- lookAhead getWord8 
      if opc == opcodeSelectdb 
       then do 
        skip 1 
        (isEncType,dbnum) <- loadLen 
        objs <- loadObjs_ f 
        rest <- getDBs_ f 
        return (objs >> rest) 
       else f Nothing "EOF" RDBNull 

processRDB_ :: (Monad m) => (Maybe Integer -> BL8.ByteString -> RDBObj -> Get (m a)) -> Get (m a) 
processRDB_ f = do 
       header <- getBytes 9 
       dbs <- getDBs_ f 
       eof <- getWord8 
       return (dbs) 

printRDBObj :: Maybe Integer -> BL8.ByteString -> RDBObj -> Get (IO()) 
printRDBObj (Just exp) key obj = return $ (print ("Expires: " ++ show exp) >> 
              print ("Key: " ++ (BL8.unpack key)) >> 
              print ("Obj: " ++ show obj)) 
printRDBObj Nothing key RDBNull = return $ (print $ BL8.unpack key) 
printRDBObj Nothing key obj = return $ (print ("Key: " ++ (BL8.unpack key)) >> 
             print ("Obj: " ++ show obj)) 


main = do 
     testf <- BL8.readFile "./dump.rdb" 
     runGet (processRDB_ printRDBObj) testf 

सभी को अग्रिम धन्यवाद।

बेस्ट, एरिक

संपादित करें: यहाँ आलसी सूची पर आईओ एक आलसी सूची में वस्तुओं को पार्स और फिर करने के लिए अपने प्रयास है।

processRDB :: Get [RDBObj] 

processRDB = do 
       header <- getBytes 9 
       dbs <- getDBs 
       eof <- getWord8 
       return (dbs) 

main = do 
     testf <- BL8.readFile "./dump.rdb" 
     mapM_ (print . show) $ runGet processRDB testf 
+0

क्या आपने http://hackage.haskell.org/package/binary-strict की कोशिश की है? –

+0

मैंने बाइनरी-सख्त कोशिश नहीं की है, लेकिन मैंने अनाज के सख्त होने का कोई फायदा नहीं उठाया। –

+0

आप इसे कठोर बनाना नहीं चाहते हैं, आप इसे आलसी बनाना चाहते हैं। कहीं कहीं सख्त हो रहा है। लेकिन मैं प्रासंगिक पैकेजों के आस-पास अपने रास्ते को अच्छी तरह से नहीं जानता। –

उत्तर

2

अगर मैं अपने कोड सही ढंग से समझ, आप संवर्द्धित, आईओ कार्यों में फ़ाइल की सामग्री परिवर्तित करने के लिए तो उन कार्यों को क्रियान्वित करने संवर्द्धित करने की आशा में कोशिश कर रहे हैं।

एक बेहतर तरीका यह होगा कि आपका पार्सर उन ऑब्जेक्ट्स की आलसी सूची लौटाएगा जिन्हें आप प्रिंट करते हैं।

+1

आह हाँ, मैंने यह भी कोशिश की है। मेरे पास कोड का एक संस्करण है जो आरडीबी को उन वस्तुओं की सूची में पार्स करता है जिन पर मैं 'mapM_' कहता हूं। (प्रिंट। शो) 'हां, मैं अपने निष्पादन की शुरुआत में एक ही ढेर स्पाइक देखता हूं जो धीरे-धीरे गायब हो जाता है क्योंकि कचरा इकट्ठा होता है और कचरा इकट्ठा होता है: –

+0

मैंने संपादन को जोड़ा जो मेरा मतलब है ऊपर दिखा रहा है। –

संबंधित मुद्दे