From 8d31455daa6dd0684249dbbd47cff432e75c1f20 Mon Sep 17 00:00:00 2001 From: pevnak Date: Fri, 8 Dec 2023 12:31:18 +0100 Subject: [PATCH] added exercise with channel --- docs/src/lecture_10/exercise.jl | 75 +++++++++++++++++++++++++++++++++ docs/src/lecture_10/lecture.md | 1 + 2 files changed, 76 insertions(+) create mode 100644 docs/src/lecture_10/exercise.jl diff --git a/docs/src/lecture_10/exercise.jl b/docs/src/lecture_10/exercise.jl new file mode 100644 index 00000000..957ef30f --- /dev/null +++ b/docs/src/lecture_10/exercise.jl @@ -0,0 +1,75 @@ +@everywhere begin + """ + sample_all_installed_pkgs(path::AbstractString) + + Returns root folders of all installed packages in the system. Package version is sampled. + """ + function sample_all_installed_pkgs(path::AbstractString) + pkgs = readdir(path) + # [rand(readdir(joinpath(path, p), join=true)) for p in pkgs] # sampling version + [readdir(joinpath(path, p), join=true)[1] for p in pkgs if isdir(joinpath(path, p))] # deterministic version + end + + """ + filter_jl(path) + + Recursively walks the directory structure to obtain all `.jl` files. + """ + filter_jl(path) = reduce(vcat, joinpath.(rootpath, filter(endswith(".jl"), files)) for (rootpath, dirs, files) in walkdir(path)) + + """ + tokenize(jl_path) + + Parses a ".jl" file located at `jl_path` and extracts all symbols and expression heads from the extracted AST. + """ + function tokenize(jl_path) + _extract_symbols(x) = Symbol[] + _extract_symbols(x::Symbol) = [x] + function _extract_symbols(x::Expr) + if length(x.args) > 0 + Symbol.(vcat(x.head, reduce(vcat, _extract_symbols(arg) for arg in x.args))) + else + Symbol[] + end + end + + scode = "begin\n" * read(jl_path, String) * "end\n" + try + code = Meta.parse(scode) + _extract_symbols(code) + catch e + if ~isa(e, Meta.ParseError) + rethrow(e) + end + Symbol[] + end + end + + + function histtokens!(h, filename::AbstractString) + for t in tokenize(filename) + h[t] = get(h, t, 0) + 1 + end + h + end + + function dohistogram(chnl) + h = Dict{Symbol, Int}() + while isready(chnl) + f = take!(chnl) + histtokens!(h, f) + end + return(h) + end +end + +chnl = RemoteChannel() do + Channel(typemax(Int)) do ch + for package in sample_all_installed_pkgs("/Users/tomas.pevny/.julia/packages") + foreach(c -> put!(ch, c), filter_jl(package)) + end + end +end + +mapreduce(fetch, mergewith(+), [@spawnat i dohistogram(chnl) for i in workers()]) + diff --git a/docs/src/lecture_10/lecture.md b/docs/src/lecture_10/lecture.md index 7d5c8404..37f7c54c 100644 --- a/docs/src/lecture_10/lecture.md +++ b/docs/src/lecture_10/lecture.md @@ -480,6 +480,7 @@ Alternatively, you can overwrite a global variable function set_g(x) global g g = x + nothing end end