diff options
author | Fedor Yudanov <fedwiz@academ.org> | 2013-04-10 18:05:09 +0700 |
---|---|---|
committer | Fedor Yudanov <fedwiz@academ.org> | 2013-04-10 18:05:09 +0700 |
commit | 13a9ddc0a66782d20c33aacfb356129e294c31f4 (patch) | |
tree | cf5aa7eea479db4038f70fd7427e602299f4c2d4 /rbejdb | |
parent | ffac50b3b15e905267273799770a05adf8a96d03 (diff) | |
download | ejdb-13a9ddc0a66782d20c33aacfb356129e294c31f4.tar.gz ejdb-13a9ddc0a66782d20c33aacfb356129e294c31f4.tar.bz2 ejdb-13a9ddc0a66782d20c33aacfb356129e294c31f4.zip |
#50 - optimizing query results iteration
Diffstat (limited to 'rbejdb')
-rw-r--r-- | rbejdb/src/rbejdb.c | 53 | ||||
-rw-r--r-- | rbejdb/test/t2.rb | 26 |
2 files changed, 55 insertions, 24 deletions
diff --git a/rbejdb/src/rbejdb.c b/rbejdb/src/rbejdb.c index 921eebd..7e7648b 100644 --- a/rbejdb/src/rbejdb.c +++ b/rbejdb/src/rbejdb.c @@ -27,6 +27,7 @@ typedef struct { typedef struct { TCLIST* results; + TCLIST* results_raw; TCXSTR* log; } RBEJDB_RESULTS; @@ -403,8 +404,8 @@ VALUE EJDB_find_one(int argc, VALUE* argv, VALUE self) { return results; } -VALUE EJDB_update(int argc, VALUE* argv, VALUE self) { - return EJDB_find(argc, argv, self); +void EJDB_update(int argc, VALUE* argv, VALUE self) { + EJDB_find(argc, argv, self); } @@ -630,8 +631,20 @@ VALUE EJDB_check_valid_oid_string(VALUE clazz, VALUE oid) { void close_ejdb_results_internal(RBEJDB_RESULTS* rbres) { - tclistdel(rbres->results); - rbres->results = NULL; + if (rbres->results) { + int i; + for (i = 0; i < TCLISTNUM(rbres->results); i++) { + bson* bsonval = *(bson**) TCLISTVALPTR(rbres->results, i); + bson_dispose(bsonval); + } + + tclistdel(rbres->results); + rbres->results = NULL; + } + if (rbres->results_raw) { + tclistdel(rbres->results_raw); + rbres->results_raw = NULL; + } if (rbres->log) { tcxstrdel(rbres->log); rbres->log = NULL; @@ -639,21 +652,29 @@ void close_ejdb_results_internal(RBEJDB_RESULTS* rbres) { } void EJDB_results_free(RBEJDB_RESULTS* rbres) { - if (rbres->results) { - close_ejdb_results_internal(rbres); - } + close_ejdb_results_internal(rbres); ruby_xfree(rbres); } VALUE create_EJDB_query_results(TCLIST* qres, TCXSTR *log) { - VALUE results = Data_Wrap_Struct(ejdbResultsClass, NULL, EJDB_results_free, ruby_xmalloc(sizeof(RBEJDB_RESULTS))); + VALUE resultsWrap = Data_Wrap_Struct(ejdbResultsClass, NULL, EJDB_results_free, ruby_xmalloc(sizeof(RBEJDB_RESULTS))); RBEJDB_RESULTS* rbresults; - Data_Get_Struct(results, RBEJDB_RESULTS, rbresults); + Data_Get_Struct(resultsWrap, RBEJDB_RESULTS, rbresults); - rbresults->results = qres; + TCLIST* results = tclistnew2(TCLISTNUM(qres)); + int i; + for (i = 0; i < TCLISTNUM(qres); i++) { + char* bsrawdata = TCLISTVALPTR(qres, i); + bson* bsonval = bson_create(); + bson_init_finished_data(bsonval, bsrawdata); + tclistpush(results, &bsonval, sizeof(bson*)); + } + + rbresults->results = results; + rbresults->results_raw = qres; rbresults->log = log; - return results; + return resultsWrap; } void EJDB_results_each(VALUE self) { @@ -664,13 +685,11 @@ void EJDB_results_each(VALUE self) { rb_raise(rb_eRuntimeError, "each() method called on invalid ejdb query results"); } - TCLIST* qres = rbresults->results; + TCLIST* results = rbresults->results; int i; - for (i = 0; i < TCLISTNUM(qres); i++) { - char* bsrawdata = TCLISTVALPTR(qres, i); - bson bsonval; - bson_init_finished_data(&bsonval, bsrawdata); - rb_yield(bson_to_ruby(&bsonval)); + for (i = 0; i < TCLISTNUM(results); i++) { + bson* bsonval = *(bson**) TCLISTVALPTR(results, i); + rb_yield(bson_to_ruby(bsonval)); } } diff --git a/rbejdb/test/t2.rb b/rbejdb/test/t2.rb index c52403b..dee8512 100644 --- a/rbejdb/test/t2.rb +++ b/rbejdb/test/t2.rb @@ -511,7 +511,7 @@ class EJDBTestUnit < Test::Unit::TestCase minfixnum = -(2**(0.size * 8 -2)) oid = $jb.save("monsters", { :nil => nil, - :object => Object.new, + :object => EJDBTestUnit.new("test"), :float => 0.2323232, :string => "string", :regexp => /regexp.*\\\n/imx, @@ -529,7 +529,7 @@ class EJDBTestUnit < Test::Unit::TestCase obj = $jb.load("monsters", oid) assert_nil obj["nil"] - assert obj["object"].is_a? Object + assert obj["object"].is_a? Hash assert_equal(0.2323232, obj["float"]) assert_equal("string", obj["string"]) assert_equal(/regexp.*\\\n/imx, obj["regexp"]) @@ -547,18 +547,27 @@ class EJDBTestUnit < Test::Unit::TestCase assert_equal([1, 0, 255], obj["binary"].to_a) assert obj["time"].is_a? Time - #what we can't save + #what we can't save (yet? :) assert_raise(RangeError) { - $jb.save("monsters", {:toobigint => 3791237293719837192837292}) + $jb.save("monsters", :toobigint => 3791237293719837192837292) } assert_raise(RuntimeError) { - $jb.save("monsters", {:class => Array}) + $jb.save("monsters", :class => Array) } assert_raise(RuntimeError) { - $jb.save("monsters", {:data => $jb}) + $jb.save("monsters", :data => $jb) } assert_raise(RuntimeError) { - $jb.save("monsters", {:module => Math}) + $jb.save("monsters", :module => Math) + } + assert_raise(RuntimeError) { + $jb.save("monsters", :range => 0..100500) + } + assert_raise(RuntimeError) { + $jb.save("monsters", :complex => Complex::polar(1, 1)) + } + assert_raise(RuntimeError) { + $jb.save("monsters", :file => File::open("/tmp")) } #puts $jb.find("monsters").to_a.to_s @@ -583,6 +592,9 @@ class EJDBTestUnit < Test::Unit::TestCase assert_equal(1, $jb.find("monsters", {:maxfixnum => {"$exists" => true}}, {:onlycount => true})) assert_equal(6, $jb.find("monsters", {:maxfixnum => {"$exists" => false}}, {:onlycount => true})) + assert_equal(0, $jb.find("monsters", {:maxfixnum => {"$in" => [maxfixnum - 1, maxfixnum + 1]}}, {:onlycount => true})) + assert_equal(1, $jb.find("monsters", {:maxfixnum => {"$gt" => maxfixnum - 1, "$lt" => maxfixnum + 1}}, {:onlycount => true})) + puts __method__.inspect + " has passed successfull" end |