Permalink
Browse files

integrating Aaron's test

  • Loading branch information...
jmettraux committed Jan 5, 2010
1 parent da65023 commit d59866cd65972dc69d281b2149a24bc74fac7b30
Showing with 126 additions and 1 deletion.
  1. +1 −1 CHANGELOG.txt
  2. +46 −0 test/aaron.rb
  3. +79 −0 test/jeg.rb
View
@@ -5,7 +5,7 @@
== rufus-tokyo - 1.0.4 released 2009/12/25
- bug : memory leak, gotten values not freed
-- todo : Rufus::Tokyo::Tyrant and TyrantTable now reconnets (120 seconds)
+- todo : Rufus::Tokyo::Tyrant and TyrantTable now reconnects (120 seconds)
== rufus-tokyo - 1.0.3 released 2009/11/16
View
@@ -0,0 +1,46 @@
+
+require 'rubygems'
+require 'rufus/tokyo'
+
+def show_memory
+ 3.times { GC.start } # try to clean up
+ mem = `ps -o rss -p #{Process.pid}`[/\d+/]
+ puts "Current memory: #{mem}"
+end
+
+p :before_put
+show_memory
+
+
+db = Rufus::Tokyo::Cabinet.new('test.tch')
+db['some_key'] = "X" * 1024
+
+p :after_put
+show_memory
+
+p :first_round
+
+10.times do
+ 5000.times do
+ db["some_key"] # reading causes the memory leak
+ end
+ show_memory
+end
+
+sleep 1
+show_memory
+
+p :second_round
+
+10.times do
+ 5000.times do
+ db["some_key"] # reading causes the memory leak
+ end
+ show_memory
+end
+
+db.close
+
+sleep 1
+show_memory
+
View
@@ -0,0 +1,79 @@
+#!/usr/bin/env ruby -wKU
+
+require "rubygems"
+require "ffi"
+
+# map the C interface
+module Lib
+ extend FFI::Library
+ ffi_lib(
+ *Array(
+ ENV.fetch(
+ "TOKYO_CABINET_LIB",
+ Dir["/{opt,usr}/{,local/}lib{,64}/libtokyocabinet.{dylib,so*}"]
+ )
+ )
+ )
+
+ attach_function :tcfree, [ :pointer ], :void
+
+ attach_function :tchdbnew, [ ], :pointer
+ attach_function :tchdbopen, [:pointer, :string, :int], :bool
+ attach_function :tchdbput, [:pointer, :pointer, :int, :pointer,
+ :int], :bool
+ attach_function :tchdbget, [:pointer, :pointer, :int, :pointer], :pointer
+ attach_function :tchdbclose, [:pointer], :bool
+end
+
+# translate the interface to Ruby
+class TokyoCabinet
+ def self.open(*args)
+ db = new(*args)
+ yield db
+ ensure
+ db.close if db
+ end
+
+ def initialize(path)
+ @db = Lib.tchdbnew
+ Lib.tchdbopen(@db, path, (1 << 1) | (1 << 2)) # write create mode
+ end
+
+ def []=(key, value)
+ k, v = key.to_s, value.to_s
+ Lib.tchdbput(@db, k, k.size, v, v.size)
+ end
+
+ def [](key)
+ k = key.to_s
+ size = FFI::MemoryPointer.new(:int)
+ value = Lib.tchdbget(@db, k, k.size, size)
+ value.address.zero? ? nil : value.get_bytes(0, size.get_int(0))
+ ensure
+ size.free if size
+ # FIXME: How do I free value here?
+ Lib.tcfree(value)
+ end
+
+ def close
+ Lib.tchdbclose(@db)
+ end
+end
+
+# show the problem
+def show_memory
+ 3.times { GC.start } # try to clean up
+ mem = `ps -o rss -p #{Process.pid}`[/\d+/]
+ puts "Current memory: #{mem}"
+end
+
+TokyoCabinet.open("leak.tch") do |db|
+ db[:some_key] = "X" * 1024
+ 10.times do
+ 5000.times do
+ db[:some_key] # reading causes the memory leak
+ end
+ show_memory
+ end
+end
+

0 comments on commit d59866c

Please sign in to comment.