Skip to content

Commit

Permalink
Revert "give back to IntSet its original name"
Browse files Browse the repository at this point in the history
This reverts commit a48e281.
  • Loading branch information
rfourquet committed Dec 11, 2017
1 parent b98c876 commit 951bfce
Show file tree
Hide file tree
Showing 22 changed files with 228 additions and 230 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ CORE_SRCS := $(addprefix $(JULIAHOME)/, \
base/hashing.jl \
base/inference.jl \
base/int.jl \
base/intset.jl \
base/bitset.jl \
base/number.jl \
base/operators.jl \
base/options.jl \
Expand Down
2 changes: 0 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,6 @@ Library improvements
definition relies on `ncodeunits` however, so for optimal performance you may need to
define a custom method for that function.

* `IntSet` now lives up to its premise and can store any `Int`.

Compiler/Runtime improvements
-----------------------------

Expand Down
148 changes: 74 additions & 74 deletions base/intset.jl → base/bitset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,41 @@ const NoOffset = -one(Int) << 60
# An offset is in the range -2^57:2^57
# + when the offset is NoOffset, the bits field *must* be empty
# + NoOffset could be made to be > 0, but a negative one allows
# a small optimization in the in(x, ::IntSet)
# a small optimization in the in(x, ::BitSet)

mutable struct IntSet <: AbstractSet{Int}
mutable struct BitSet <: AbstractSet{Int}
bits::Vector{UInt64}
# 1st stored Int equals 64*offset
offset::Int

IntSet() = new(sizehint!(zeros(UInt64, 0), 4), NoOffset)
BitSet() = new(sizehint!(zeros(UInt64, 0), 4), NoOffset)
end

"""
IntSet([itr])
BitSet([itr])
Construct a sorted set of `Int`s generated by the given iterable object, or an
empty set. Implemented as a bit string, and therefore designed for dense integer sets.
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)

@inline intoffset(s::IntSet) = s.offset << 6
@inline intoffset(s::BitSet) = s.offset << 6

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.offset = src.offset
dest
end

eltype(s::IntSet) = Int
eltype(s::BitSet) = Int

sizehint!(s::IntSet, n::Integer) = sizehint!(s.bits, n)
sizehint!(s::BitSet, n::Integer) = sizehint!(s.bits, n)

# given an integer i, return the chunk which stores it
chk_indice(i::Int) = i >> 6
Expand Down Expand Up @@ -70,7 +70,7 @@ function _bits_findprev(b::Bits, start::Int)
end

# An internal function for setting the inclusion bit for a given integer
@inline function _setint!(s::IntSet, idx::Int, b::Bool)
@inline function _setint!(s::BitSet, idx::Int, b::Bool)
cidx = chk_indice(idx)
len = length(s.bits)
diff = cidx - s.offset
Expand Down Expand Up @@ -110,7 +110,7 @@ end
@inbounds b[1:nchunks] = Chk0
end

function _matched_map!(f, s1::IntSet, s2::IntSet)
function _matched_map!(f, s1::BitSet, s2::BitSet)
left_false_is_false = f(false, false) == f(false, true) == false
right_false_is_false = f(false, false) == f(true, false) == false

Expand Down Expand Up @@ -194,130 +194,130 @@ function _matched_map!(f, a1::Bits, b1::Int, a2::Bits, b2::Int,
end


@noinline _throw_intset_bounds_err() =
throw(ArgumentError("elements of IntSet must be between typemin(Int) and typemax(Int)"))
@noinline _throw_bitset_bounds_err() =
throw(ArgumentError("elements of BitSet must be between typemin(Int) and typemax(Int)"))

@inline _is_convertible_Int(n) = typemin(Int) <= n <= typemax(Int)

@inline _check_intset_bounds(n) =
_is_convertible_Int(n) ? Int(n) : _throw_intset_bounds_err()
@inline _check_bitset_bounds(n) =
_is_convertible_Int(n) ? Int(n) : _throw_bitset_bounds_err()

@inline _check_intset_bounds(n::Int) = n
@inline _check_bitset_bounds(n::Int) = n

@noinline _throw_keyerror(n) = throw(KeyError(n))

@inline push!(s::IntSet, n::Integer) = _setint!(s, _check_intset_bounds(n), true)
@inline push!(s::BitSet, n::Integer) = _setint!(s, _check_bitset_bounds(n), true)

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 pop!(s::IntSet) = pop!(s, last(s))
@inline pop!(s::BitSet) = pop!(s, last(s))

@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::Int) = _setint!(s, n, false)
@inline delete!(s::IntSet, n::Integer) = _is_convertible_Int(n) ? delete!(s, Int(n)) : s
@inline delete!(s::BitSet, n::Int) = _setint!(s, n, false)
@inline delete!(s::BitSet, n::Integer) = _is_convertible_Int(n) ? delete!(s, Int(n)) : s

shift!(s::IntSet) = pop!(s, first(s))
shift!(s::BitSet) = pop!(s, first(s))

function empty!(s::IntSet)
function empty!(s::BitSet)
empty!(s.bits)
s.offset = NoOffset
s
end

isempty(s::IntSet) = all(equalto(Chk0), s.bits)
isempty(s::BitSet) = all(equalto(Chk0), 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)
union!(s1::IntSet, s2::IntSet) = _matched_map!(|, s1, s2)

intersect(s1::IntSet) = copy(s1)
intersect(s1::IntSet, ss::IntSet...) = intersect(s1, intersect(ss...))
function intersect(s1::IntSet, ns)
s = 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)
union!(s1::BitSet, s2::BitSet) = _matched_map!(|, s1, s2)

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`.
"""
intersect!(s1::IntSet, s2::IntSet) = _matched_map!(&, s1, s2)
intersect!(s1::BitSet, s2::BitSet) = _matched_map!(&, s1, s2)

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

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)
n0 = _check_intset_bounds(n)
function int_symdiff!(s::BitSet, n::Integer)
n0 = _check_bitset_bounds(n)
val = !(n0 in s)
_setint!(s, n0, val)
s
end

symdiff!(s1::IntSet, s2::IntSet) = _matched_map!(xor, s1, s2)
symdiff!(s1::BitSet, s2::BitSet) = _matched_map!(xor, s1, s2)

@inline in(n::Int, s::IntSet) = _bits_getindex(s.bits, n, s.offset)
@inline in(n::Integer, s::IntSet) = _is_convertible_Int(n) ? in(Int(n), s) : false
@inline in(n::Int, s::BitSet) = _bits_getindex(s.bits, n, s.offset)
@inline in(n::Integer, s::BitSet) = _is_convertible_Int(n) ? in(Int(n), s) : false

# Use the next-set index as the state to prevent looking it up again in done
start(s::IntSet) = _bits_findnext(s.bits, 0)
start(s::BitSet) = _bits_findnext(s.bits, 0)

function next(s::IntSet, i::Int)
function next(s::BitSet, i::Int)
nextidx = _bits_findnext(s.bits, i+1)
(i+intoffset(s), nextidx)
end

done(s::IntSet, i) = i == -1
done(s::BitSet, i) = i == -1

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

function first(s::IntSet)
function first(s::BitSet)
idx = _bits_findnext(s.bits, 0)
idx == -1 ? _throw_intset_notempty_error() : idx + intoffset(s)
idx == -1 ? _throw_bitset_notempty_error() : idx + intoffset(s)
end

function last(s::IntSet)
function last(s::BitSet)
idx = _bits_findprev(s.bits, (length(s.bits) << 6) - 1)
idx == -1 ? _throw_intset_notempty_error() : idx + intoffset(s)
idx == -1 ? _throw_bitset_notempty_error() : idx + intoffset(s)
end

length(s::IntSet) = bitcount(s.bits) # = mapreduce(count_ones, +, 0, s.bits)
length(s::BitSet) = bitcount(s.bits) # = mapreduce(count_ones, +, 0, 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 @@ -334,7 +334,7 @@ function _check0(a::Vector{UInt64}, b::Int, e::Int)
true
end

function ==(s1::IntSet, s2::IntSet)
function ==(s1::BitSet, s2::BitSet)
# Swap so s1 has always the smallest offset
if s1.offset > s2.offset
s1, s2 = s2, s1
Expand Down Expand Up @@ -363,12 +363,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
i = 1
Expand All @@ -391,9 +391,9 @@ 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

nothing
6 changes: 3 additions & 3 deletions base/codevalidation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ 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

ssavals = IntSet()
lhs_slotnums = IntSet()
ssavals = BitSet()
lhs_slotnums = BitSet()
for x in c.code
if isa(x, Expr)
head = x.head
Expand Down
2 changes: 1 addition & 1 deletion base/coreimg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ include("reduce.jl")

## core structures
include("bitarray.jl")
include("intset.jl")
include("bitset.jl")
include("associative.jl")
include("namedtuple.jl")

Expand Down
4 changes: 2 additions & 2 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2058,8 +2058,8 @@ end
@deprecate Vector(m::Integer) Vector(uninitialized, m)
@deprecate Matrix(m::Integer, n::Integer) Matrix(uninitialized, m, n)

# deprecate BitSet to IntSet
@deprecate_binding BitSet IntSet
# deprecate IntSet to BitSet
@deprecate_binding IntSet BitSet

# Issue 24219
@deprecate float(x::AbstractString) parse(Float64, x)
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 @@ -68,7 +68,7 @@ export
IndexLinear,
IndexStyle,
InsertionSort,
IntSet,
BitSet,
IOBuffer,
IOStream,
LinSpace,
Expand Down
Loading

0 comments on commit 951bfce

Please sign in to comment.