]> git.immae.eu Git - github/fretlink/purs-loader.git/commitdiff
Optimizing dependency list generation
authoreric thul <thul.eric@gmail.com>
Sat, 2 May 2015 14:27:36 +0000 (10:27 -0400)
committereric thul <thul.eric@gmail.com>
Sat, 2 May 2015 14:27:36 +0000 (10:27 -0400)
Improving the generation of the dependencies in `mkDeps` to avoid a
`RangeError` on large inputs.

Resolves #9

bower.json
src/Loader.purs

index dddddf9e4d9c53685da7e09a8e5324768ebd614c..2ee248681cae4c9d0dc205534f3c147cf690d125 100644 (file)
@@ -11,6 +11,7 @@
     "purescript-tuples": "~0.3.4",
     "purescript-maps": "~0.3.3",
     "purescript-arrays": "~0.3.7",
-    "purescript-monad-eff": "~0.1.0"
+    "purescript-monad-eff": "~0.1.0",
+    "purescript-sets": "0.3.2"
   }
 }
index 523aa7a693b6720b4de5300e6e4bb456650d4d38..aae51c0b0ca250df1967854515695966f3d7d677 100644 (file)
@@ -9,9 +9,11 @@ import Control.Monad.Eff (Eff())
 import Control.Monad.Eff.Class (liftEff)
 import Control.Monad.Eff.Exception (error)
 
-import Data.Array ((!!), catMaybes, concat, nub, null)
+import Data.Array ((!!), catMaybes, concat, filter, null)
+import Data.Foldable (foldl)
 import Data.Function (Fn2(), mkFn2)
 import Data.Maybe (Maybe(..), fromMaybe, maybe)
+import Data.Set (Set(), empty, insert, member, toList, unions)
 import Data.String (joinWith, split)
 import Data.String.Regex (Regex(), match, noFlags, regex)
 import Data.StrMap (StrMap(), fromList, lookup)
@@ -60,11 +62,16 @@ mkGraph files = (fromList <<< catMaybes) <$> sequence (parse <$> files)
                         return $ (\a -> tuple2 a { file: file, imports: imports }) <$> key
 
 mkDeps :: forall eff. String -> Graph -> [String]
-mkDeps key graph = nub $ go [] key
-  where go acc key =
-    maybe acc (\a -> if null a.imports
-                       then acc
-                       else concat $ go (acc <> a.imports) <$> a.imports) (lookup key graph)
+mkDeps key graph = toList $ go empty key
+  where
+    go :: Set String -> String -> Set String
+    go acc key =
+      let node = fromMaybe {file: "", imports: []} (lookup key graph)
+          uniq = filter (not <<< flip member acc) node.imports
+          acc' = foldl (flip insert) acc node.imports
+       in if null uniq
+             then acc'
+             else unions $ go acc' <$> uniq
 
 addDeps :: forall eff. LoaderRef -> Graph -> [String] -> Eff (loader :: Loader | eff) Unit
 addDeps ref graph deps = const unit <$> (sequence $ add <$> deps)