Skip to content

Reverse Dependencies indexed on PackageName #1082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions benchmarks/RevDeps.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{-# LANGUAGE ScopedTypeVariables , TypeApplications #-}
module Main where

import Control.Monad (replicateM)
import Data.Containers.ListUtils (nubOrd)
import qualified Data.Vector as Vector
import Distribution.Package (packageName)
import Distribution.Server.Features.ReverseDependencies.State (constructReverseIndex, getDependenciesFlat)
import Distribution.Server.Packages.PackageIndex as PackageIndex

import Gauge.Benchmark (nfAppIO, bench)
import Gauge.Main (defaultMain)
import System.Random.Stateful

import RevDepCommon (Package(..), packToPkgInfo, TestPackage(..))

randomPacks
:: forall m g. StatefulGen g m
=> g
-> Int
-> Vector.Vector (Package TestPackage)
-> m (Vector.Vector (Package TestPackage))
randomPacks gen limit generated | length generated < limit = do
makeNewPack <- uniformM gen -- if not new pack, just make a new version of an existing
toInsert <-
if makeNewPack || generated == mempty
then
Package
<$> pure (TestPackage (fromIntegral @Int @Word $ Vector.length generated))
<*> uniformRM (0, 10) gen
<*> pure mempty
else do
prevIdx <- uniformRM (0, length generated - 1) gen
let Package { pName = prevName } = generated Vector.! prevIdx
(prevNamePacks, nonPrevName) = Vector.partition ((== prevName) . pName) generated
depPacks <-
if mempty /= nonPrevName
then do
-- TODO this should have an expected amount of deps equal to what is actually on hackage. what is it?
numOfDeps <- uniformRM (1, min (length nonPrevName - 1) 7) gen
indicesMayDuplicate <- replicateM numOfDeps (uniformRM (0, length nonPrevName - 1) gen)
let indices = nubOrd indicesMayDuplicate
pure $ map (nonPrevName Vector.!) indices
else
pure []
let
newVersion =
if mempty /= prevNamePacks
then 1 + maximum (fmap pVersion prevNamePacks)
else 0
pure $
Package
{ pName = prevName
, pVersion = newVersion
, pDeps = map pName depPacks
}
let added = generated <> pure toInsert
randomPacks gen limit added
randomPacks _ _ generated = pure generated

main :: IO ()
main = do
packs :: Vector.Vector (Package TestPackage) <- randomPacks globalStdGen 20000 mempty
let idx = PackageIndex.fromList $ map packToPkgInfo (Vector.toList packs)
Right revs <- pure $ constructReverseIndex idx
let numPacks = length packs
defaultMain $
(:[]) $
bench "get transitive dependencies for one randomly selected package" $
flip nfAppIO revs $ \revs' -> do
select <- uniformRM (0, numPacks - 1) globalStdGen
-- TODO why are there so many transitive deps?
length <$>
getDependenciesFlat
(packageName $ packToPkgInfo (packs Vector.! select))
revs'
1 change: 1 addition & 0 deletions datafiles/static/graph/graph.css

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions datafiles/static/graph/tmpl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* JavaScript Templates
* https://github.com/blueimp/JavaScript-Templates
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
*
* Inspired by John Resig's JavaScript Micro-Templating:
* http://ejohn.org/blog/javascript-micro-templating/
*/

/*global document, define, module */

;(function ($) {
'use strict'
var tmpl = function (str, data) {
var f = !/[^\w\-\.:]/.test(str)
? tmpl.cache[str] = tmpl.cache[str] || tmpl(tmpl.load(str))
: new Function(// eslint-disable-line no-new-func
tmpl.arg + ',tmpl',
'var _e=tmpl.encode' + tmpl.helper + ",_s='" +
str.replace(tmpl.regexp, tmpl.func) + "';return _s;"
)
return data ? f(data, tmpl) : function (data) {
return f(data, tmpl)
}
}
tmpl.cache = {}
tmpl.load = function (id) {
return document.getElementById(id).innerHTML
}
tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g
tmpl.func = function (s, p1, p2, p3, p4, p5) {
if (p1) { // whitespace, quote and backspace in HTML context
return {
'\n': '\\n',
'\r': '\\r',
'\t': '\\t',
' ': ' '
}[p1] || '\\' + p1
}
if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
if (p2 === '=') {
return "'+_e(" + p3 + ")+'"
}
return "'+(" + p3 + "==null?'':" + p3 + ")+'"
}
if (p4) { // evaluation start tag: {%
return "';"
}
if (p5) { // evaluation end tag: %}
return "_s+='"
}
}
tmpl.encReg = /[<>&"'\x00]/g
tmpl.encMap = {
'<': '&lt;',
'>': '&gt;',
'&': '&amp;',
'"': '&quot;',
"'": '&#39;'
}
tmpl.encode = function (s) {
return (s == null ? '' : '' + s).replace(
tmpl.encReg,
function (c) {
return tmpl.encMap[c] || ''
}
)
}
tmpl.arg = 'o'
tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" +
',include=function(s,d){_s+=tmpl(s,d);}'
if (typeof define === 'function' && define.amd) {
define(function () {
return tmpl
})
} else if (typeof module === 'object' && module.exports) {
module.exports = tmpl
} else {
$.tmpl = tmpl
}
}(this))
Loading