|
| 1 | +{-# LANGUAGE ScopedTypeVariables , TypeApplications #-} |
| 2 | +module Main where |
| 3 | + |
| 4 | +import Control.Monad (replicateM) |
| 5 | +import Data.Containers.ListUtils (nubOrd) |
| 6 | +import qualified Data.Vector as Vector |
| 7 | +import Distribution.Package (packageName) |
| 8 | +import Distribution.Server.Features.ReverseDependencies.State (constructReverseIndex, getDependenciesFlat) |
| 9 | +import Distribution.Server.Packages.PackageIndex as PackageIndex |
| 10 | + |
| 11 | +import Gauge.Benchmark (nfAppIO, bench) |
| 12 | +import Gauge.Main (defaultMain) |
| 13 | +import System.Random.Stateful |
| 14 | + |
| 15 | +import RevDepCommon (Package(..), packToPkgInfo, TestPackage(..)) |
| 16 | + |
| 17 | +randomPacks |
| 18 | + :: forall m g. StatefulGen g m |
| 19 | + => g |
| 20 | + -> Int |
| 21 | + -> Vector.Vector (Package TestPackage) |
| 22 | + -> m (Vector.Vector (Package TestPackage)) |
| 23 | +randomPacks gen limit generated | length generated < limit = do |
| 24 | + makeNewPack <- uniformM gen -- if not new pack, just make a new version of an existing |
| 25 | + toInsert <- |
| 26 | + if makeNewPack || generated == mempty |
| 27 | + then |
| 28 | + Package |
| 29 | + <$> pure (TestPackage (fromIntegral @Int @Word $ Vector.length generated)) |
| 30 | + <*> uniformRM (0, 10) gen |
| 31 | + <*> pure mempty |
| 32 | + else do |
| 33 | + prevIdx <- uniformRM (0, length generated - 1) gen |
| 34 | + let Package { pName = prevName } = generated Vector.! prevIdx |
| 35 | + (prevNamePacks, nonPrevName) = Vector.partition ((== prevName) . pName) generated |
| 36 | + depPacks <- |
| 37 | + if mempty /= nonPrevName |
| 38 | + then do |
| 39 | + -- TODO this should have an expected amount of deps equal to what is actually on hackage. what is it? |
| 40 | + numOfDeps <- uniformRM (1, min (length nonPrevName - 1) 7) gen |
| 41 | + indicesMayDuplicate <- replicateM numOfDeps (uniformRM (0, length nonPrevName - 1) gen) |
| 42 | + let indices = nubOrd indicesMayDuplicate |
| 43 | + pure $ map (nonPrevName Vector.!) indices |
| 44 | + else |
| 45 | + pure [] |
| 46 | + let |
| 47 | + newVersion = |
| 48 | + if mempty /= prevNamePacks |
| 49 | + then 1 + maximum (fmap pVersion prevNamePacks) |
| 50 | + else 0 |
| 51 | + pure $ |
| 52 | + Package |
| 53 | + { pName = prevName |
| 54 | + , pVersion = newVersion |
| 55 | + , pDeps = map pName depPacks |
| 56 | + } |
| 57 | + let added = generated <> pure toInsert |
| 58 | + randomPacks gen limit added |
| 59 | +randomPacks _ _ generated = pure generated |
| 60 | + |
| 61 | +main :: IO () |
| 62 | +main = do |
| 63 | + packs :: Vector.Vector (Package TestPackage) <- randomPacks globalStdGen 20000 mempty |
| 64 | + let idx = PackageIndex.fromList $ map packToPkgInfo (Vector.toList packs) |
| 65 | + Right revs <- pure $ constructReverseIndex idx |
| 66 | + let numPacks = length packs |
| 67 | + defaultMain $ |
| 68 | + (:[]) $ |
| 69 | + bench "get transitive dependencies for one randomly selected package" $ |
| 70 | + flip nfAppIO revs $ \revs' -> do |
| 71 | + select <- uniformRM (0, numPacks - 1) globalStdGen |
| 72 | + -- TODO why are there so many transitive deps? |
| 73 | + length <$> |
| 74 | + getDependenciesFlat |
| 75 | + (packageName $ packToPkgInfo (packs Vector.! select)) |
| 76 | + revs' |
0 commit comments