[#1378] differences between Module and Class ? — Mathieu Bouchard <matju@...>

25 messages 2003/08/11
[#1387] Re: differences between Module and Class ? — matz@... (Yukihiro Matsumoto) 2003/08/12

Hi,

[#1442] Re: differences between Module and Class ? — Mathieu Bouchard <matju@...> 2003/08/21

[#1406] _id2ref bug? — Ryan Pavlik <rpav@...>

While debugging some caching code, I've come across a segfault related

22 messages 2003/08/14
[#1407] Re: _id2ref bug? — matz@... (Yukihiro Matsumoto) 2003/08/14

Hi,

[#1413] Re: _id2ref bug? (REPRODUCED, short) — Ryan Pavlik <rpav@...> 2003/08/14

On Fri, 15 Aug 2003 01:57:18 +0900

Re: _id2ref bug? (REPRODUCED, short)

From: Ryan Pavlik <rpav@...>
Date: 2003-08-14 18:09:19 UTC
List: ruby-core #1413
On Fri, 15 Aug 2003 01:57:18 +0900
matz@ruby-lang.org (Yukihiro Matsumoto) wrote:

<snip>
> We can't say much without error reproducing code.
<snip>

I was wrong, here's a short example that reproduces the problem exactly.


-- 
Ryan Pavlik <rpav@users.sf.net>

"I distinctly remember dancing on your grave." - 8BT

Attachments (1)

weakref.rb (1.34 KB, text/x-ruby)
class Object
  @@oid = 0

  def _oid
    unless defined?(@_oid)
      @_oid  = @@oid + 1
      @@oid += 1
    end

    @_oid
  end
end


class Cache
  def initialize(max = 5, reduce = 3)
    @s_cache = {}
    @w_cache = {}
    @cachehits = {}

    @max     = 5
    @reduce  = 3
  end #m:initialize

  def cache(o)
    oid = o._oid
    return if(@s_cache.has_key? oid)

    if(@s_cache.size + 1 > @max)
      cache_free(@reduce)
    end

    @cachehits[oid] = 1
    @s_cache[oid]   = o
    @w_cache[oid]   = o.__id__

    return oid
  end #m:cache

  def [](oid)
    if(o = @s_cache[oid])
      @cachehits[oid] += 1
      return o
    elsif(id = @w_cache[oid])
      begin
        o = ObjectSpace._id2ref(id)
        cache(o)
        return o
      rescue RangeError
        return nil
      end
    end

    return nil
  end #m:[]

  def cache_free(size)
    print "Freeing #{size}...\n"
    list = @cachehits.sort { |a, b| (a[1] <=> b[1]) }
    size.times {
      | i |

      break if(i >= list.size)

      oid              = list[i][0]
      store             @s_cache[oid]
      @s_cache.delete    oid
      @cachehits.delete  oid
      # oid remains in the weak cache
    }
  end #m:cache_free

  def store(object)
    # Does nothing in this example
  end #m:store
end #c:Cache


c = Cache.new

(1...100).each {
  c.cache(Object.new)
  (1..100).each { |i| p c[i]; }
}

In This Thread