Skip to content

Commit

Permalink
New hash-based Set implementation [closes #1].
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed Jun 15, 2011
1 parent cf87fd8 commit a555efb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 48 deletions.
66 changes: 18 additions & 48 deletions j/set.j
Original file line number Diff line number Diff line change
@@ -1,58 +1,28 @@
type Set{T}
items::Array{T,1}
hash::HashTable{T,Bool}

Set() = new(Array(Any,0))
Set{T}(T::Type) = new(Array(T,0))
Set{T}(T::Type) = new(HashTable(T,Bool))
Set() = Set(Any)
end

set{T}(x::T...) = (s = Set(T); add(s, x...))
show(s::Set) = show_comma_array(s,'{','}')

isempty(set::Set) = isempty(set.items)
length(set::Set) = length(set.items)

has(set::Set, x) = anyp(y->isequal(x,y), set.items)

function add(set::Set, x)
if !has(set,x)
items = clone(set.items, length(set.items)+1)
for i = 1:length(set.items)
items[i] = set.items[i]
end
items[end] = x
set.items = items
end
set
end
isempty(s::Set) = isempty(s.hash)
length(s::Set) = length(s.hash)

add(set::Set, xs...) = (for x = xs; add(set, x); end; set)
add(set::Set, s2::Set) = (for x = s2; add(set, x); end; set)

function del(set::Set, x)
if has(set,x)
items = clone(set.items, length(set.items)-1)
j = 1
for i = 1:length(set.items)
if !isequal(set.items[i],x)
items[j] = set.items[i]
j += 1
end
end
set.items = items
end
set
end
has(s::Set, x) = has(s.hash, x)

del(set::Set, xs...) = (for x = xs; del(set, x); end; set)
del(set::Set, s2::Set) = (for x = s2; del(set, x); end; set)
add(s::Set, x) = (s.hash[x] = true; s)
add(s::Set, xs...) = (for x=xs; add(s, x); end; s)
add(s::Set, s2::Set) = (for x=s2; add(s, x); end; s)

start(set::Set) = start(set.items)
done(set::Set, x) = done(set.items, x)
next(set::Set, x) = next(set.items, x)
del(s::Set, x) = (del(s.hash, x); s)
del(s::Set, xs...) = (for x=xs; del(s, x); end; s)
del(s::Set, s2::Set) = (for x=s2; del(s, x); end; s)

function union{T}(sets::Set{T}...)
u = Set(T)
for set = sets
add(u,set)
end
return u
end
start(s::Set) = start(s.hash)
done(s::Set, state) = done(s.hash, state)
next(s::Set, state) = (((k,v),state) = next(s.hash, state); (k,state))

union{T}(sets::Set{T}...) = (u = Set(T); for s=sets; add(u,s); end; u)
1 change: 1 addition & 0 deletions j/table.j
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ function hash(a::Array)
h
end

hash(x::Any) = uid(x)
hash(s::ByteString) = ccall(:memhash32, Uint32, (Ptr{Void}, Size), s.data, length(s.data))

# hash table
Expand Down

0 comments on commit a555efb

Please sign in to comment.