Selective enable || disable GC for result retrieval with Mysql#disable_gc = true|false

This commit is contained in:
Lourens Naude 2008-10-08 22:11:14 +01:00
parent 8e6f300f9d
commit 35d2545c17
2 changed files with 46 additions and 9 deletions

View File

@ -60,6 +60,7 @@ struct mysql {
MYSQL handler;
char connection;
char query_with_result;
char gc_disabled;
char blocking;
int async_in_progress;
};
@ -181,7 +182,7 @@ static void mysql_raise(MYSQL* m)
rb_exc_raise(e);
}
static VALUE mysqlres2obj(MYSQL_RES* res)
static VALUE mysqlres2obj(MYSQL_RES* res, VALUE gc_disabled)
{
VALUE obj;
struct mysql_res* resp;
@ -191,8 +192,9 @@ static VALUE mysqlres2obj(MYSQL_RES* res)
resp->res = res;
resp->freed = Qfalse;
rb_obj_call_init(obj, 0, NULL);
if (++store_result_count > GC_STORE_RESULT_LIMIT)
rb_gc();
if (++store_result_count > GC_STORE_RESULT_LIMIT && gc_disabled == Qfalse){
rb_gc();
}
return obj;
}
@ -228,6 +230,7 @@ static VALUE init(VALUE klass)
mysql_init(&myp->handler);
myp->connection = Qfalse;
myp->query_with_result = Qtrue;
myp->gc_disabled = Qfalse;
rb_obj_call_init(obj, 0, NULL);
return obj;
}
@ -646,7 +649,7 @@ static VALUE list_fields(int argc, VALUE* argv, VALUE obj)
res = mysql_list_fields(m, StringValuePtr(table), NILorSTRING(field));
if (res == NULL)
mysql_raise(m);
return mysqlres2obj(res);
return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
}
/* list_processes() */
@ -656,7 +659,7 @@ static VALUE list_processes(VALUE obj)
MYSQL_RES* res = mysql_list_processes(m);
if (res == NULL)
mysql_raise(m);
return mysqlres2obj(res);
return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
}
/* list_tables(table=nil) */
@ -750,7 +753,7 @@ static VALUE store_result(VALUE obj)
MYSQL_RES* res = mysql_store_result(m);
if (res == NULL)
mysql_raise(m);
return mysqlres2obj(res);
return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
}
/* thread_id() */
@ -766,7 +769,7 @@ static VALUE use_result(VALUE obj)
MYSQL_RES* res = mysql_use_result(m);
if (res == NULL)
mysql_raise(m);
return mysqlres2obj(res);
return mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
}
static VALUE res_free(VALUE);
@ -788,7 +791,7 @@ static VALUE query(VALUE obj, VALUE sql)
if (mysql_field_count(m) != 0)
mysql_raise(m);
} else {
VALUE robj = mysqlres2obj(res);
VALUE robj = mysqlres2obj(res, GetMysqlStruct(obj)->gc_disabled);
rb_ensure(rb_yield, robj, res_free, robj);
}
#if MYSQL_VERSION_ID >= 40101
@ -859,6 +862,20 @@ static VALUE reconnected( VALUE obj ){
return ( current_connection_id == mysql_thread_id( m ) ) ? Qfalse : Qtrue;
}
/* disable_gc(true|false) */
static VALUE disable_gc_set(VALUE obj, VALUE flag)
{
if (TYPE(flag) != T_TRUE && TYPE(flag) != T_FALSE)
rb_raise(rb_eTypeError, "invalid type, required true or false.");
GetMysqlStruct(obj)->gc_disabled = flag;
return flag;
}
/* gc_disabled */
static VALUE gc_disabled( VALUE obj ){
return GetMysqlStruct(obj)->gc_disabled ? Qtrue: Qfalse;
}
static void validate_async_query( VALUE obj )
{
MYSQL* m = GetHandler(obj);
@ -1986,7 +2003,7 @@ static VALUE stmt_result_metadata(VALUE obj)
mysql_stmt_raise(s->stmt);
return Qnil;
}
return mysqlres2obj(res);
return mysqlres2obj(res, Qfalse);
}
/* row_seek(offset) */
@ -2254,6 +2271,8 @@ void Init_mysql(void)
rb_define_method(cMysql, "retry?", retry, 0);
rb_define_method(cMysql, "interrupted?", interrupted, 0);
rb_define_method(cMysql, "blocking?", blocking, 0);
rb_define_method(cMysql, "gc_disabled?", gc_disabled, 0);
rb_define_method(cMysql, "disable_gc=", disable_gc_set, 1);
rb_define_method(cMysql, "socket", socket, 0);
rb_define_method(cMysql, "refresh", refresh, 1);
rb_define_method(cMysql, "reload", reload, 0);

18
test/gc_benchmark.rb Normal file
View File

@ -0,0 +1,18 @@
require 'rubygems'
require 'mysqlplus'
require 'benchmark'
with_gc = Mysql.real_connect('localhost','root','','mysql')
without_gc = Mysql.real_connect('localhost','root','','mysql')
without_gc.disable_gc = true
n = 1000
Benchmark.bm do |x|
x.report( 'With GC' ) do
n.times{ with_gc.c_async_query( 'SELECT * FROM user' ) }
end
GC.start
x.report( 'Without GC' ) do
n.times{ without_gc.c_async_query( 'SELECT * FROM user' ) }
end
end