Skip to content

Commit

Permalink
lazily allocate the threaded buffers and allocate them on the thread …
Browse files Browse the repository at this point in the history
…that will access it
  • Loading branch information
KristofferC committed Apr 28, 2021
1 parent 1c255e9 commit 4e3f8e2
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/URIs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ URI(;kw...) = URI(emptyuri; kw...)

# Based on regex from RFC 3986:
# https://tools.ietf.org/html/rfc3986#appendix-B
const uri_reference_regex =
[RegexAndMatchData(r"""^
const uri_reference_regex = RegexAndMatchData[]
const uri_reference_regex_f = function()
r = RegexAndMatchData(r"""^
(?: ([^:/?#]+) :) ? # 1. scheme
(?: // (?: ([^/?#@]*) @) ? # 2. userinfo
(?| (?: \[ ([^:\]]*:[^\]]*) \] ) # 3. host (ipv6)
Expand All @@ -93,7 +94,11 @@ const uri_reference_regex =
([^?#]*) # 5. path
(?: \?([^#]*) ) ? # 6. query
(?: [#](.*) ) ? # 7. fragment
$"""x)]
$"""x)
Base.compile(r.re)
initialize!(r)
r
end

"""
https://tools.ietf.org/html/rfc3986#section-3
Expand All @@ -111,7 +116,7 @@ https://tools.ietf.org/html/rfc3986#section-4.1
"""
function parse_uri_reference(str::Union{String, SubString{String}};
strict = false)
uri_reference_re = uri_reference_regex[Threads.threadid()]
uri_reference_re = access_threaded(uri_reference_regex_f, uri_reference_regex)
if !exec(uri_reference_re, str)
throw(ParseError("URI contains invalid character"))
end
Expand Down Expand Up @@ -518,10 +523,21 @@ function Base.joinpath(uri::URI, parts::String...)
return URI(uri; path=normpath(path))
end

function access_threaded(f, v::Vector)
tid = Threads.threadid()
0 < tid <= length(v) || _length_assert()
if @inbounds isassigned(v, tid)
@inbounds x = v[tid]
else
x = f()
@inbounds v[tid] = x
end
return x
end
@noinline _length_assert() = @assert false "0 < tid <= v"

function __init__()
Threads.resize_nthreads!(uri_reference_regex)
foreach(x -> Base.compile(x.re), uri_reference_regex)
foreach(initialize!, uri_reference_regex)
resize!(empty!(uri_reference_regex), Threads.nthreads())
return
end

Expand Down

0 comments on commit 4e3f8e2

Please sign in to comment.