Skip to content

Commit

Permalink
Replaced IdentityMap.
Browse files Browse the repository at this point in the history
Notes:

* Moved IdentityMap from Array to Rubinius.
* IdentityMap now supports re-mapping (#redistribute) when the entries
  exceed a certain threshhold. This happens automatically. The size is
  never reduced, however, because this is not a realistic need for the
  current use. Should this become necessary, it would be fairly simple
  to add to the #delete method as #redistribute could grow or shrink
  without any modification.
* The basic structure is a hybrid table of direct entries and rows mixed.
  On collision, the entry in the main table is promoted to a row and the
  colliding entry is added there.
* Deleting merely sets the entry for the item's hash value to nil. Under
  highly mutable loads (ie many inserts and deletes), this could lead to
  significant fragmentation. There are several ways this could be handled
  but, again, that is not in the current use cases.
* There is a slightly higher cost for small structures due to this being
  actually mutable rather than fixed. However, there is significantly
  greater performance as the load grows due to not having the spill array.
  Overall, this structure is much more robust.
  • Loading branch information
Brian Ford committed Sep 6, 2010
1 parent ee60ddb commit 65c5e4d
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 163 deletions.
17 changes: 11 additions & 6 deletions kernel/common/array.rb
Expand Up @@ -269,7 +269,7 @@ def &(other)
other = Type.coerce_to other, Array, :to_ary

array = []
im = IdentityMap.new other
im = Rubinius::IdentityMap.from other

each { |x| array << x if im.delete x }

Expand All @@ -281,8 +281,7 @@ def &(other)
def |(other)
other = Type.coerce_to other, Array, :to_ary

im = IdentityMap.new self, other.size
im.load other
im = Rubinius::IdentityMap.from self, other
im.to_array
end

Expand Down Expand Up @@ -330,7 +329,7 @@ def -(other)
other = Type.coerce_to other, Array, :to_ary

array = []
im = IdentityMap.new other
im = Rubinius::IdentityMap.from other

each { |x| array << x unless im.include? x }

Expand Down Expand Up @@ -1464,11 +1463,17 @@ def uniq

# Removes duplicates from the Array in place as #uniq
def uniq!
im = IdentityMap.new self
im = Rubinius::IdentityMap.from self
return if im.size == size

Ruby.check_frozen
im.to_array self

array = im.to_array
@tuple = array.tuple
@start = array.start
@total = array.total

self
end

# Returns a new Array populated from the elements in
Expand Down

0 comments on commit 65c5e4d

Please sign in to comment.