Skip to content

Commit 7f41c8b

Browse files
committed
Speed up verbose revdep endpoint, clean up code
1 parent b168fb6 commit 7f41c8b

File tree

10 files changed

+186
-242
lines changed

10 files changed

+186
-242
lines changed

benchmarks/RevDeps.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ randomPacks gen limit generated | length generated < limit = do
3131
<*> pure mempty
3232
else do
3333
prevIdx <- uniformRM (0, length generated - 1) gen
34-
let Package { name = prevName } = generated Vector.! prevIdx
35-
(prevNamePacks, nonPrevName) = Vector.partition ((== prevName) . name) generated
34+
let Package { pName = prevName } = generated Vector.! prevIdx
35+
(prevNamePacks, nonPrevName) = Vector.partition ((== prevName) . pName) generated
3636
depPacks <-
3737
if mempty /= nonPrevName
3838
then do
@@ -46,13 +46,13 @@ randomPacks gen limit generated | length generated < limit = do
4646
let
4747
newVersion =
4848
if mempty /= prevNamePacks
49-
then 1 + maximum (fmap version prevNamePacks)
49+
then 1 + maximum (fmap pVersion prevNamePacks)
5050
else 0
5151
pure $
5252
Package
53-
{ name = prevName
54-
, version = newVersion
55-
, deps = map name depPacks
53+
{ pName = prevName
54+
, pVersion = newVersion
55+
, pDeps = map pName depPacks
5656
}
5757
let added = generated <> pure toInsert
5858
randomPacks gen limit added

exes/ReverseDepsForPackage.hs

Lines changed: 0 additions & 15 deletions
This file was deleted.

exes/ReverseDepsPreferredForPackage.hs

Lines changed: 0 additions & 38 deletions
This file was deleted.

hackage-server.cabal

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,3 @@ test-suite DocTests
630630
, lib-server
631631
, doctest-parallel ^>= 0.2.2
632632
-- doctest-parallel-0.2.2 is the first to filter out autogen-modules
633-
634-
executable ReverseDepsForPackage
635-
import: exe-defaults
636-
637-
main-is: ReverseDepsForPackage.hs
638-
639-
executable ReverseDepsPreferredForPackage
640-
import: exe-defaults
641-
642-
main-is: ReverseDepsPreferredForPackage.hs

src/Distribution/Server/Features/PackageList.hs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import Distribution.PackageDescription.Configuration
3131
import Distribution.Utils.ShortText (fromShortText)
3232

3333
import Control.Concurrent
34+
import qualified Data.List.NonEmpty as NE
3435
import Data.Maybe (mapMaybe)
3536
import Data.Map (Map)
3637
import qualified Data.Map as Map
@@ -113,7 +114,7 @@ initListFeature _env = do
113114
itemUpdate <- newHook
114115

115116
return $ \core@CoreFeature{..}
116-
revs@ReverseFeature{revPackageStats, reverseHook}
117+
revs@ReverseFeature{revDirectCount, reverseHook}
117118
download
118119
votesf@VotesFeature{..}
119120
tagsf@TagsFeature{..}
@@ -142,12 +143,15 @@ initListFeature _env = do
142143
runHook_ itemUpdate (Set.singleton pkgname)
143144
Nothing -> return ()
144145

145-
registerHook reverseHook $ \pkgids -> do
146-
let pkgs = map pkgName pkgids
147-
forM_ pkgs $ \pkgname -> do
148-
revCount <- revPackageStats pkgname
149-
modifyItem pkgname (updateReverseItem revCount)
150-
runHook_ itemUpdate $ Set.fromDistinctAscList pkgs
146+
registerHook reverseHook $ \pkginfos -> do
147+
let
148+
names = Set.fromDistinctAscList $
149+
map (pkgName . pkgInfoId . NE.head)
150+
pkginfos
151+
forM_ names $ \pkgname -> do
152+
revDirect <- revDirectCount pkgname
153+
modifyItem pkgname (updateReverseItem revDirect)
154+
runHook_ itemUpdate names
151155

152156
registerHook votesUpdated $ \(pkgname, _) -> do
153157
votes <- pkgNumScore pkgname
@@ -182,7 +186,7 @@ listFeature :: CoreFeature
182186
PackageName -> IO ())
183187

184188
listFeature CoreFeature{..}
185-
ReverseFeature{revPackageStats}
189+
ReverseFeature{revDirectCount}
186190
DownloadFeature{..}
187191
VotesFeature{..}
188192
TagsFeature{..}
@@ -247,7 +251,7 @@ listFeature CoreFeature{..}
247251
constructItem :: PkgInfo -> IO (PackageName, PackageItem)
248252
constructItem pkg = do
249253
let pkgname = packageName pkg
250-
revCount <- revPackageStats pkgname
254+
intRevDirectCount <- revDirectCount pkgname
251255
users <- queryGetUserDb
252256
tags <- queryTagsForPackage pkgname
253257
downs <- recentPackageDownloads
@@ -262,8 +266,8 @@ listFeature CoreFeature{..}
262266
, itemDownloads = cmFind pkgname downs
263267
, itemVotes = votes
264268
, itemLastUpload = fst (pkgOriginalUploadInfo pkg)
265-
, itemRevDepsCount = directCount revCount
266-
, itemHotness = votes + fromIntegral (cmFind pkgname downs) + fromIntegral (directCount revCount)*2
269+
, itemRevDepsCount = intRevDirectCount
270+
, itemHotness = votes + fromIntegral (cmFind pkgname downs) + fromIntegral intRevDirectCount * 2
267271
}
268272

269273
------------------------------
@@ -308,7 +312,7 @@ updateVoteItem :: Float -> PackageItem -> PackageItem
308312
updateVoteItem score item =
309313
item {
310314
itemVotes = score,
311-
itemHotness = fromIntegral (itemRevDepsCount item)*2 + score + fromIntegral (itemDownloads item)
315+
itemHotness = fromIntegral (itemRevDepsCount item) * 2 + score + fromIntegral (itemDownloads item)
312316
}
313317

314318
updateDeprecation :: Maybe [PackageName] -> PackageItem -> PackageItem
@@ -317,16 +321,16 @@ updateDeprecation pkgs item =
317321
itemDeprecated = pkgs
318322
}
319323

320-
updateReverseItem :: ReverseCount -> PackageItem -> PackageItem
321-
updateReverseItem revCount item =
324+
updateReverseItem :: Int -> PackageItem -> PackageItem
325+
updateReverseItem revDirectCount item =
322326
item {
323-
itemRevDepsCount = directCount revCount,
324-
itemDownloads = directCount revCount,
325-
itemHotness = fromIntegral (itemRevDepsCount item)*2 + itemVotes item + fromIntegral (itemDownloads item)
327+
itemRevDepsCount = revDirectCount,
328+
itemHotness = fromIntegral revDirectCount * 2 + itemVotes item + fromIntegral (itemDownloads item)
326329
}
327330

328331
updateDownload :: Int -> PackageItem -> PackageItem
329332
updateDownload count item =
330333
item {
331-
itemDownloads = count
334+
itemDownloads = count,
335+
itemHotness = fromIntegral (itemRevDepsCount item) * 2 + itemVotes item + realToFrac count
332336
}

src/Distribution/Server/Features/ReverseDependencies.hs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import Distribution.Server.Features.Core
1414
import Distribution.Server.Features.PreferredVersions
1515
import Distribution.Server.Features.PreferredVersions.State (PreferredVersions)
1616
import qualified Distribution.Server.Packages.PackageIndex as PackageIndex
17-
import Distribution.Server.Packages.PackageIndex (PackageIndex, packageNames, allPackagesByName)
18-
import Distribution.Server.Packages.Types (PkgInfo, pkgInfoId)
17+
import Distribution.Server.Packages.PackageIndex (PackageIndex, packageNames, allPackagesByNameNE)
18+
import Distribution.Server.Packages.Types (PkgInfo)
1919
import Distribution.Server.Features.ReverseDependencies.State
2020
import Distribution.Package
2121
import Distribution.Text (display)
@@ -26,6 +26,7 @@ import Data.Aeson
2626
import Data.ByteString.Lazy (ByteString)
2727
import Data.Containers.ListUtils (nubOrd)
2828
import Data.List (mapAccumL, sortOn)
29+
import qualified Data.List.NonEmpty as NE
2930
import Data.Maybe (catMaybes, fromJust)
3031
import Data.Function (fix)
3132
import qualified Data.Bimap as Bimap
@@ -35,21 +36,21 @@ import qualified Data.Map as Map
3536
import Data.Set (Set)
3637
import qualified Data.Set as Set
3738
import GHC.Generics hiding (packageName)
38-
import GHC.Stack
3939

4040
data ReverseFeature = ReverseFeature {
4141
reverseFeatureInterface :: HackageFeature,
4242

4343
reverseResource :: ReverseResource,
4444

45-
reverseHook :: Hook [PackageId] (),
45+
reverseHook :: Hook [NE.NonEmpty PkgInfo] (),
4646

4747
queryReverseDeps :: forall m. (MonadIO m, MonadCatch m) => PackageName -> m ([PackageName], [PackageName]),
4848
revPackageId :: forall m. (MonadCatch m, MonadIO m) => PackageId -> m ReverseDisplay,
4949
revPackageName :: forall m. (MonadIO m, MonadCatch m) => PackageName -> m ReverseDisplay,
5050
renderReverseRecent :: forall m. (MonadIO m, MonadCatch m) => PackageName -> ReverseDisplay -> m ReversePageRender,
5151
renderReverseOld :: forall m. (MonadIO m, MonadCatch m) => PackageName -> ReverseDisplay -> m ReversePageRender,
5252
revPackageFlat :: forall m. (MonadIO m, MonadCatch m) => PackageName -> m [(PackageName, Int)],
53+
revDirectCount :: forall m. (MonadIO m, MonadCatch m) => PackageName -> m Int,
5354
revPackageStats :: forall m. (MonadIO m, MonadCatch m) => PackageName -> m ReverseCount,
5455
revCountForAllPackages :: forall m. (MonadIO m, MonadCatch m) => m [(PackageName, ReverseCount)],
5556
revJSON :: forall m. (MonadIO m, MonadThrow m) => m ByteString,
@@ -95,9 +96,9 @@ initReverseFeature _ = do
9596
Just pkginfo -> do
9697
index <- queryGetPackageIndex
9798
r <- readMemState memState
98-
added <- addPackage (packageName pkgid) (getAllDependencies pkginfo index) r
99+
added <- addPackage index (packageName pkgid) (getDepNames pkginfo) r
99100
writeMemState memState added
100-
runHook_ updateReverse [pkgid]
101+
runHook_ updateReverse [pure pkginfo]
101102

102103
return feature
103104

@@ -128,7 +129,7 @@ instance ToJSON Edge
128129
reverseFeature :: IO (PackageIndex PkgInfo)
129130
-> IO PreferredVersions
130131
-> MemState ReverseIndex
131-
-> Hook [PackageId] ()
132+
-> Hook [NE.NonEmpty PkgInfo] ()
132133
-> ReverseFeature
133134

134135
reverseFeature queryGetPackageIndex
@@ -153,8 +154,7 @@ reverseFeature queryGetPackageIndex
153154
initReverseIndex = do
154155
index <- liftIO queryGetPackageIndex
155156
-- We build the proper index earlier, this just fires the reverse hooks
156-
let allPackages = map pkgInfoId $ concat $ allPackagesByName index
157-
runHook_ reverseHook allPackages
157+
runHook_ reverseHook $ allPackagesByNameNE index
158158

159159

160160
reverseResource = fix $ \r -> ReverseResource
@@ -187,14 +187,14 @@ reverseFeature queryGetPackageIndex
187187
let indirect = Set.difference rdepsall rdeps
188188
return (Set.toList rdeps, Set.toList indirect)
189189

190-
revPackageId :: (HasCallStack, MonadCatch m, MonadIO m) => PackageId -> m ReverseDisplay
190+
revPackageId :: (MonadCatch m, MonadIO m) => PackageId -> m ReverseDisplay
191191
revPackageId pkgid = do
192192
dispInfo <- revDisplayInfo
193193
pkgIndex <- liftIO queryGetPackageIndex
194194
revs <- queryReverseIndex
195195
perVersionReverse dispInfo pkgIndex revs pkgid
196196

197-
revPackageName :: (HasCallStack, MonadIO m, MonadCatch m) => PackageName -> m ReverseDisplay
197+
revPackageName :: (MonadIO m, MonadCatch m) => PackageName -> m ReverseDisplay
198198
revPackageName pkgname = do
199199
dispInfo <- revDisplayInfo
200200
pkgIndex <- liftIO queryGetPackageIndex
@@ -203,7 +203,7 @@ reverseFeature queryGetPackageIndex
203203

204204
revJSON :: (MonadIO m, MonadThrow m) => m ByteString
205205
revJSON = do
206-
ReverseIndex revdeps nodemap <- queryReverseIndex
206+
ReverseIndex revdeps nodemap _depmap <- queryReverseIndex
207207
let assoc = takeWhile (\(a,_) -> a < Bimap.size nodemap) $ Arr.assocs . Gr.transposeG $ revdeps
208208
nodeToString node = unPackageName (nodemap Bimap.!> node)
209209
-- nodes = map (uncurry Node) $ map (\n -> (fst n, nodeToString (fst n))) assoc
@@ -216,7 +216,7 @@ reverseFeature queryGetPackageIndex
216216
prefs <- liftIO queryGetPreferredVersions
217217
return $ getDisplayInfo prefs pkgIndex
218218

219-
renderReverseWith :: (HasCallStack, MonadIO m, MonadCatch m) => PackageName -> ReverseDisplay -> (Maybe VersionStatus -> Bool) -> m ReversePageRender
219+
renderReverseWith :: (MonadIO m, MonadCatch m) => PackageName -> ReverseDisplay -> (Maybe VersionStatus -> Bool) -> m ReversePageRender
220220
renderReverseWith pkg rev filterFunc = do
221221
let rev' = map fst $ Map.toList rev
222222
directCounts <- mapM revDirectCount (pkg:rev')
@@ -244,20 +244,20 @@ reverseFeature queryGetPackageIndex
244244

245245
-- -- This could also differentiate between direct and indirect dependencies
246246
-- -- with a bit more calculation.
247-
revPackageFlat :: (HasCallStack, MonadIO m, MonadCatch m) => PackageName -> m [(PackageName, Int)]
247+
revPackageFlat :: (MonadIO m, MonadCatch m) => PackageName -> m [(PackageName, Int)]
248248
revPackageFlat pkgname = do
249249
memState <- readMemState reverseMemState
250250
deps <- getDependenciesFlat pkgname memState
251251
let depList = Set.toList deps
252252
counts <- mapM (`getTotalCount` memState) depList
253253
return $ zip depList counts
254254

255-
revPackageStats :: (HasCallStack, MonadIO m, MonadCatch m) => PackageName -> m ReverseCount
255+
revPackageStats :: (MonadIO m, MonadCatch m) => PackageName -> m ReverseCount
256256
revPackageStats pkgname = do
257257
(direct, transitive) <- getReverseCount pkgname =<< readMemState reverseMemState
258258
return $ ReverseCount direct transitive
259259

260-
revDirectCount :: (HasCallStack, MonadIO m, MonadCatch m) => PackageName -> m Int
260+
revDirectCount :: (MonadIO m, MonadCatch m) => PackageName -> m Int
261261
revDirectCount pkgname = do
262262
getDirectCount pkgname =<< readMemState reverseMemState
263263

@@ -270,7 +270,7 @@ reverseFeature queryGetPackageIndex
270270
-- broken packages.
271271
--
272272
-- The returned list is sorted ascendingly on directCount (see ReverseCount).
273-
revCountForAllPackages :: (HasCallStack, MonadIO m, MonadCatch m) => m [(PackageName, ReverseCount)]
273+
revCountForAllPackages :: (MonadIO m, MonadCatch m) => m [(PackageName, ReverseCount)]
274274
revCountForAllPackages = do
275275
index <- liftIO queryGetPackageIndex
276276
let pkgnames = packageNames index
@@ -279,7 +279,7 @@ reverseFeature queryGetPackageIndex
279279

280280
revForEachVersion :: (MonadThrow m, MonadIO m) => PackageName -> m (Map.Map Version (Set PackageIdentifier))
281281
revForEachVersion pkg = do
282-
ReverseIndex revs nodemap <- readMemState reverseMemState
282+
ReverseIndex revs nodemap depmap <- readMemState reverseMemState
283283
index <- liftIO queryGetPackageIndex
284284
nodeid <- Bimap.lookup pkg nodemap
285285
revDepNames <- mapM (`Bimap.lookupR` nodemap) (Set.toList $ suc revs nodeid)
@@ -289,5 +289,5 @@ reverseFeature queryGetPackageIndex
289289
revDepVersions = do
290290
x <- nubOrd revDepNames
291291
pkginfo <- PackageIndex.lookupPackageName index pkg
292-
pure (packageVersion pkginfo, dependsOnPkg index (packageId pkginfo) x)
292+
pure (packageVersion pkginfo, dependsOnPkg index (packageId pkginfo) x depmap)
293293
pure $ Map.fromListWith Set.union revDepVersions

0 commit comments

Comments
 (0)