Skip to content

Commit

Permalink
Deprecate IntSet to BitSet.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sacha0 committed Oct 23, 2017
1 parent 175f7a1 commit 3e434ac
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 200 deletions.
6 changes: 3 additions & 3 deletions base/codevalidation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ InvalidCodeError(kind::AbstractString) = InvalidCodeError(kind, nothing)
Validate `c`, logging any violation by pushing an `InvalidCodeError` into `errors`.
"""
function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_level::Bool = false)
ssavals = IntSet()
lhs_slotnums = IntSet()
ssavals = BitSet()
lhs_slotnums = BitSet()
walkast(c.code) do x
if isa(x, Expr)
!is_top_level && x.head == :method && push!(errors, InvalidCodeError(NON_TOP_LEVEL_METHOD))
Expand Down Expand Up @@ -86,7 +86,7 @@ function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_
end
end
elseif isa(x, SSAValue)
id = x.id + 1 # ensures that id > 0 for use with IntSet
id = x.id + 1 # ensures that id > 0 for use with BitSet
!in(id, ssavals) && push!(ssavals, id)
end
end
Expand Down
6 changes: 3 additions & 3 deletions base/dates/query.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ end

# Total number of a day of week in the month
# e.g. are there 4 or 5 Mondays in this month?
const TWENTYNINE = IntSet([1, 8, 15, 22, 29])
const THIRTY = IntSet([1, 2, 8, 9, 15, 16, 22, 23, 29, 30])
const THIRTYONE = IntSet([1, 2, 3, 8, 9, 10, 15, 16, 17, 22, 23, 24, 29, 30, 31])
const TWENTYNINE = BitSet([1, 8, 15, 22, 29])
const THIRTY = BitSet([1, 2, 8, 9, 15, 16, 22, 23, 29, 30])
const THIRTYONE = BitSet([1, 2, 3, 8, 9, 10, 15, 16, 17, 22, 23, 24, 29, 30, 31])

"""
daysofweekinmonth(dt::TimeType) -> Int
Expand Down
3 changes: 3 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1909,6 +1909,9 @@ end
# issue #24006
@deprecate linearindices(s::AbstractString) eachindex(s)

# deprecate IntSet to BitSet
@deprecate_binding IntSet BitSet

# Issue 24219
@deprecate float(x::AbstractString) parse(Float64, x)
@deprecate float(a::AbstractArray{<:AbstractString}) parse.(Float64, a)
Expand Down
4 changes: 2 additions & 2 deletions base/distributed/process_messages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
def_rv_channel() = Channel(1)
mutable struct RemoteValue
c::AbstractChannel
clientset::IntSet # Set of workerids that have a reference to this channel.
clientset::BitSet # Set of workerids that have a reference to this channel.
# Keeping ids instead of a count aids in cleaning up upon
# a worker exit.

waitingfor::Int # processor we need to hear from to fill this, or 0

RemoteValue(c) = new(c, IntSet(), 0)
RemoteValue(c) = new(c, BitSet(), 0)
end

wait(rv::RemoteValue) = wait(rv.c)
Expand Down
2 changes: 1 addition & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export
IndexLinear,
IndexStyle,
InsertionSort,
IntSet,
BitSet,
IOBuffer,
IOStream,
LinSpace,
Expand Down
18 changes: 9 additions & 9 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ mutable struct InferenceState
# return type
bestguess #::Type
# current active instruction pointers
ip::IntSet
ip::BitSet
pc´´::LineNum
nstmts::Int
# current exception handler info
cur_hand #::Tuple{LineNum, Tuple{LineNum, ...}}
handler_at::Vector{Any}
n_handlers::Int
# ssavalue sparsity and restart info
ssavalue_uses::Vector{IntSet}
ssavalue_uses::Vector{BitSet}
ssavalue_defs::Vector{LineNum}
vararg_type_container #::Type

Expand Down Expand Up @@ -254,7 +254,7 @@ mutable struct InferenceState
handler_at = Any[ () for i=1:n ]
n_handlers = 0

W = IntSet()
W = BitSet()
push!(W, 1) #initial pc to visit

if !toplevel
Expand Down Expand Up @@ -2926,15 +2926,15 @@ end


function find_ssavalue_uses(body::Vector{Any}, nvals::Int)
uses = IntSet[ IntSet() for i = 1:nvals ]
uses = BitSet[ BitSet() for i = 1:nvals ]
for line in 1:length(body)
e = body[line]
isa(e, Expr) && find_ssavalue_uses(e, uses, line)
end
return uses
end

function find_ssavalue_uses(e::Expr, uses::Vector{IntSet}, line::Int)
function find_ssavalue_uses(e::Expr, uses::Vector{BitSet}, line::Int)
head = e.head
is_meta_expr_head(head) && return
skiparg = (head === :(=))
Expand Down Expand Up @@ -5805,7 +5805,7 @@ function getfield_elim_pass!(sv::OptimizationState)
end
end

function _getfield_elim_pass!(e::Expr, ssa_defs::Vector{LineNum}, ssa_uses::Vector{IntSet}, sv::OptimizationState)
function _getfield_elim_pass!(e::Expr, ssa_defs::Vector{LineNum}, ssa_uses::Vector{BitSet}, sv::OptimizationState)
nargs = length(e.args)
for i = 1:nargs
e.args[i] = _getfield_elim_pass!(e.args[i], ssa_defs, ssa_uses, sv)
Expand Down Expand Up @@ -5870,7 +5870,7 @@ function _getfield_elim_pass!(e::Expr, ssa_defs::Vector{LineNum}, ssa_uses::Vect
return e
end

_getfield_elim_pass!(@nospecialize(e), ssa_defs::Vector{LineNum}, ssa_uses::Vector{IntSet}, sv::OptimizationState) = e
_getfield_elim_pass!(@nospecialize(e), ssa_defs::Vector{LineNum}, ssa_uses::Vector{BitSet}, sv::OptimizationState) = e

# check if e is a successful allocation of an struct
# if it is, returns (n,f) such that it is always valid to call
Expand Down Expand Up @@ -5928,8 +5928,8 @@ end
function basic_dce_pass!(sv::OptimizationState)
body = sv.src.code
labelmap = get_label_map(body)
reachable = IntSet()
W = IntSet()
reachable = BitSet()
W = BitSet()
push!(W, 1)
while !isempty(W)
pc = pop!(W)
Expand Down
122 changes: 61 additions & 61 deletions base/intset.jl
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

struct IntSet <: AbstractSet{Int}
struct BitSet <: AbstractSet{Int}
bits::BitVector
IntSet() = new(sizehint!(falses(0), 256))
BitSet() = new(sizehint!(falses(0), 256))
end

"""
IntSet([itr])
BitSet([itr])
Construct a sorted set of positive `Int`s generated by the given iterable object, or an
empty set. Implemented as a bit string, and therefore designed for dense integer sets. Only
`Int`s greater than 0 can be stored. If the set will be sparse (for example holding a few
very large integers), use [`Set`](@ref) instead.
"""
IntSet(itr) = union!(IntSet(), itr)
BitSet(itr) = union!(BitSet(), itr)

eltype(::Type{IntSet}) = Int
similar(s::IntSet) = IntSet()
copy(s1::IntSet) = copy!(IntSet(), s1)
function copy!(dest::IntSet, src::IntSet)
eltype(::Type{BitSet}) = Int
similar(s::BitSet) = BitSet()
copy(s1::BitSet) = copy!(BitSet(), s1)
function copy!(dest::BitSet, src::BitSet)
resize!(dest.bits, length(src.bits))
copy!(dest.bits, src.bits)
dest
end
eltype(s::IntSet) = Int
sizehint!(s::IntSet, n::Integer) = (n > length(s.bits) && _resize0!(s.bits, n); s)
eltype(s::BitSet) = Int
sizehint!(s::BitSet, n::Integer) = (n > length(s.bits) && _resize0!(s.bits, n); s)

# An internal function for setting the inclusion bit for a given integer n >= 0
@inline function _setint!(s::IntSet, idx::Integer, b::Bool)
@inline function _setint!(s::BitSet, idx::Integer, b::Bool)
if idx > length(s.bits)
b || return s # setting a bit to zero outside the set's bits is a no-op
_resize0!(s.bits, idx)
Expand Down Expand Up @@ -83,124 +83,124 @@ function _bit_map!(f, b1::BitArray, b2::BitArray)
b1
end

@noinline _throw_intset_bounds_err() = throw(ArgumentError("elements of IntSet must be between 1 and typemax(Int)"))
@noinline _throw_intset_bounds_err() = throw(ArgumentError("elements of BitSet must be between 1 and typemax(Int)"))
@noinline _throw_keyerror(n) = throw(KeyError(n))

@inline function push!(s::IntSet, n::Integer)
@inline function push!(s::BitSet, n::Integer)
0 < n <= typemax(Int) || _throw_intset_bounds_err()
_setint!(s, n, true)
end
push!(s::IntSet, ns::Integer...) = (for n in ns; push!(s, n); end; s)
push!(s::BitSet, ns::Integer...) = (for n in ns; push!(s, n); end; s)

@inline function pop!(s::IntSet)
@inline function pop!(s::BitSet)
pop!(s, last(s))
end
@inline function pop!(s::IntSet, n::Integer)
@inline function pop!(s::BitSet, n::Integer)
n in s ? (_delete!(s, n); n) : _throw_keyerror(n)
end
@inline function pop!(s::IntSet, n::Integer, default)
@inline function pop!(s::BitSet, n::Integer, default)
n in s ? (_delete!(s, n); n) : default
end
@inline _delete!(s::IntSet, n::Integer) = _setint!(s, n, false)
@inline delete!(s::IntSet, n::Integer) = n > 0 ? _delete!(s, n) : s
shift!(s::IntSet) = pop!(s, first(s))
@inline _delete!(s::BitSet, n::Integer) = _setint!(s, n, false)
@inline delete!(s::BitSet, n::Integer) = n > 0 ? _delete!(s, n) : s
shift!(s::BitSet) = pop!(s, first(s))

empty!(s::IntSet) = (fill!(s.bits, false); s)
isempty(s::IntSet) = !any(s.bits)
empty!(s::BitSet) = (fill!(s.bits, false); s)
isempty(s::BitSet) = !any(s.bits)

# Mathematical set functions: union!, intersect!, setdiff!, symdiff!

union(s::IntSet) = copy(s)
union(s1::IntSet, s2::IntSet) = union!(copy(s1), s2)
union(s1::IntSet, ss::IntSet...) = union(s1, union(ss...))
union(s::IntSet, ns) = union!(copy(s), ns)
union!(s::IntSet, ns) = (for n in ns; push!(s, n); end; s)
function union!(s1::IntSet, s2::IntSet)
union(s::BitSet) = copy(s)
union(s1::BitSet, s2::BitSet) = union!(copy(s1), s2)
union(s1::BitSet, ss::BitSet...) = union(s1, union(ss...))
union(s::BitSet, ns) = union!(copy(s), ns)
union!(s::BitSet, ns) = (for n in ns; push!(s, n); end; s)
function union!(s1::BitSet, s2::BitSet)
_matched_map!(|, s1.bits, s2.bits)
s1
end

intersect(s1::IntSet) = copy(s1)
intersect(s1::IntSet, ss::IntSet...) = intersect(s1, intersect(ss...))
function intersect(s1::IntSet, ns)
s = IntSet()
intersect(s1::BitSet) = copy(s1)
intersect(s1::BitSet, ss::BitSet...) = intersect(s1, intersect(ss...))
function intersect(s1::BitSet, ns)
s = BitSet()
for n in ns
n in s1 && push!(s, n)
end
s
end
intersect(s1::IntSet, s2::IntSet) =
intersect(s1::BitSet, s2::BitSet) =
length(s1.bits) < length(s2.bits) ? intersect!(copy(s1), s2) : intersect!(copy(s2), s1)
"""
intersect!(s1::IntSet, s2::IntSet)
intersect!(s1::BitSet, s2::BitSet)
Intersects sets `s1` and `s2` and overwrites the set `s1` with the result. If needed, `s1`
will be expanded to the size of `s2`.
"""
function intersect!(s1::IntSet, s2::IntSet)
function intersect!(s1::BitSet, s2::BitSet)
_matched_map!(&, s1.bits, s2.bits)
s1
end

setdiff(s::IntSet, ns) = setdiff!(copy(s), ns)
setdiff!(s::IntSet, ns) = (for n in ns; delete!(s, n); end; s)
function setdiff!(s1::IntSet, s2::IntSet)
setdiff(s::BitSet, ns) = setdiff!(copy(s), ns)
setdiff!(s::BitSet, ns) = (for n in ns; delete!(s, n); end; s)
function setdiff!(s1::BitSet, s2::BitSet)
_matched_map!((p, q) -> p & ~q, s1.bits, s2.bits)
s1
end

symdiff(s::IntSet, ns) = symdiff!(copy(s), ns)
symdiff(s::BitSet, ns) = symdiff!(copy(s), ns)
"""
symdiff!(s, itr)
For each element in `itr`, destructively toggle its inclusion in set `s`.
"""
symdiff!(s::IntSet, ns) = (for n in ns; int_symdiff!(s, n); end; s)
symdiff!(s::BitSet, ns) = (for n in ns; int_symdiff!(s, n); end; s)
"""
symdiff!(s, n)
The set `s` is destructively modified to toggle the inclusion of integer `n`.
"""
symdiff!(s::IntSet, n::Integer) = int_symdiff!(s, n)
symdiff!(s::BitSet, n::Integer) = int_symdiff!(s, n)

function int_symdiff!(s::IntSet, n::Integer)
function int_symdiff!(s::BitSet, n::Integer)
0 < n < typemax(Int) || _throw_intset_bounds_err()
val = !(n in s)
_setint!(s, n, val)
s
end
function symdiff!(s1::IntSet, s2::IntSet)
function symdiff!(s1::BitSet, s2::BitSet)
_matched_map!(xor, s1.bits, s2.bits)
s1
end

@inline in(n::Integer, s::IntSet) = get(s.bits, n, false)
@inline in(n::Integer, s::BitSet) = get(s.bits, n, false)

# Use the next-set index as the state to prevent looking it up again in done
start(s::IntSet) = next(s, 0)[2]
function next(s::IntSet, i)
start(s::BitSet) = next(s, 0)[2]
function next(s::BitSet, i)
nextidx = i == typemax(Int) ? 0 : findnext(s.bits, i+1)
(i, nextidx)
end
done(s::IntSet, i) = i <= 0
done(s::BitSet, i) = i <= 0


@noinline _throw_intset_notempty_error() = throw(ArgumentError("collection must be non-empty"))

function first(s::IntSet)
function first(s::BitSet)
idx = findfirst(s.bits)
idx == 0 ? _throw_intset_notempty_error() : idx
end

function last(s::IntSet)
function last(s::BitSet)
idx = findprev(s.bits, length(s.bits))
idx == 0 ? _throw_intset_notempty_error() : idx
end

length(s::IntSet) = sum(s.bits)
length(s::BitSet) = sum(s.bits)

function show(io::IO, s::IntSet)
print(io, "IntSet([")
function show(io::IO, s::BitSet)
print(io, "BitSet([")
first = true
for n in s
!first && print(io, ", ")
Expand All @@ -210,7 +210,7 @@ function show(io::IO, s::IntSet)
print(io, "])")
end

function ==(s1::IntSet, s2::IntSet)
function ==(s1::BitSet, s2::BitSet)
l1 = length(s1.bits)
l2 = length(s2.bits)
# If the lengths are the same, simply punt to bitarray comparison
Expand All @@ -234,12 +234,12 @@ function ==(s1::IntSet, s2::IntSet)
return true
end

issubset(a::IntSet, b::IntSet) = isequal(a, intersect(a,b))
<(a::IntSet, b::IntSet) = (a<=b) && !isequal(a,b)
<=(a::IntSet, b::IntSet) = issubset(a, b)
issubset(a::BitSet, b::BitSet) = isequal(a, intersect(a,b))
<(a::BitSet, b::BitSet) = (a<=b) && !isequal(a,b)
<=(a::BitSet, b::BitSet) = issubset(a, b)

const hashis_seed = UInt === UInt64 ? 0x88989f1fc7dea67d : 0xc7dea67d
function hash(s::IntSet, h::UInt)
function hash(s::BitSet, h::UInt)
h ⊻= hashis_seed
bc = s.bits.chunks
i = length(bc)
Expand All @@ -254,7 +254,7 @@ function hash(s::IntSet, h::UInt)
h
end

minimum(s::IntSet) = first(s)
maximum(s::IntSet) = last(s)
extrema(s::IntSet) = (first(s), last(s))
issorted(s::IntSet) = true
minimum(s::BitSet) = first(s)
maximum(s::BitSet) = last(s)
extrema(s::BitSet) = (first(s), last(s))
issorted(s::BitSet) = true
Loading

0 comments on commit 3e434ac

Please sign in to comment.