From a36b16b8e0c5b8b6db92a7de0664535c310349f2 Mon Sep 17 00:00:00 2001 From: adam Date: Sat, 5 Jan 2013 16:33:06 +0700 Subject: [PATCH] #27 #26 v1.0.41 --- Changelog | 7 +++++++ package.json | 2 +- tcejdb/configure | 18 +++++++++--------- tcejdb/configure.ac | 2 +- tcejdb/ejdb.c | 27 +++++++++++++++++++++++++-- tcejdb/testejdb/t2.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 92 insertions(+), 14 deletions(-) diff --git a/Changelog b/Changelog index aa8ac03..bc599e9 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,10 @@ +2013-01-05 Anton Adamansky. + * Optimized count(*) on whole collection (ticket #27) + * Optimized $dropall on whole collection (ticket #26) + * Database files can be opened directly from CLI command line + * Fixed minor bug in $upsert operation + - Release 1.0.41 + 2012-12-31 Anton Adamansky. * Added `$upsert` opration (ticket #25) * Expose ejdb transactions API in Nodejs binding (ticket #22) diff --git a/package.json b/package.json index 8f866b0..93e5e13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name" : "ejdb", - "version" : "1.0.40", + "version" : "1.0.41", "main" : "node/ejdb.js", "homepage" : "http://ejdb.org", "description" : "EJDB - Embedded JSON Database engine", diff --git a/tcejdb/configure b/tcejdb/configure index 1478c0c..a56ec0e 100755 --- a/tcejdb/configure +++ b/tcejdb/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tcejdb 1.0.40. +# Generated by GNU Autoconf 2.69 for tcejdb 1.0.41. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='tcejdb' PACKAGE_TARNAME='tcejdb' -PACKAGE_VERSION='1.0.40' -PACKAGE_STRING='tcejdb 1.0.40' +PACKAGE_VERSION='1.0.41' +PACKAGE_STRING='tcejdb 1.0.41' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1257,7 +1257,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures tcejdb 1.0.40 to adapt to many kinds of systems. +\`configure' configures tcejdb 1.0.41 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1318,7 +1318,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of tcejdb 1.0.40:";; + short | recursive ) echo "Configuration of tcejdb 1.0.41:";; esac cat <<\_ACEOF @@ -1424,7 +1424,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -tcejdb configure 1.0.40 +tcejdb configure 1.0.41 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1722,7 +1722,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by tcejdb $as_me 1.0.40, which was +It was created by tcejdb $as_me 1.0.41, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4870,7 +4870,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by tcejdb $as_me 1.0.40, which was +This file was extended by tcejdb $as_me 1.0.41, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4923,7 +4923,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -tcejdb config.status 1.0.40 +tcejdb config.status 1.0.41 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/tcejdb/configure.ac b/tcejdb/configure.ac index 0bcd11e..4f1cfc7 100644 --- a/tcejdb/configure.ac +++ b/tcejdb/configure.ac @@ -11,7 +11,7 @@ test -n "$CPPFLAGS" && MYCPPFLAGS="$CPPFLAGS $MYCPPFLAGS" test -n "$LDFLAGS" && MYLDFLAGS="$LDFLAGS $MYLDFLAGS" # Package name -AC_INIT(tcejdb, 1.0.40) +AC_INIT(tcejdb, 1.0.41) # Package information MYLIBVER=9 diff --git a/tcejdb/ejdb.c b/tcejdb/ejdb.c index 7904593..052002e 100644 --- a/tcejdb/ejdb.c +++ b/tcejdb/ejdb.c @@ -1950,6 +1950,14 @@ static TCLIST* _qryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *outcount, int for (int i = 0; i < ofsz; ++i) assert(ofs[i] != NULL); } + if ((ejq->flags & EJQONLYCOUNT) && qfsz == 0) { //primitive count(*) query + count = jcoll->tdb->hdb->rnum; + if (log) { + tcxstrprintf(log, "SIMPLE COUNT(*): %u\n", count); + } + goto finish; + } + if (!(ejq->flags & EJQONLYCOUNT) && aofsz > 0 && (!midx || mqf->orderseq != 1)) { //Main index is not the main order field all = true; //Need all records for ordering for some other fields } @@ -2431,10 +2439,25 @@ static TCLIST* _qryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *outcount, int fullscan: /* Full scan */ assert(count == 0); assert(!res || TCLISTNUM(res) == 0); + + if ((ejq->flags & EJQDROPALL) && (ejq->flags & EJQONLYCOUNT)) { + //if we are in primitive $dropall case. Query: {$dropall:true} + if (qfsz == 1 && qfs[0]->tcop == TDBQTRUE) { //single $dropall field + if (log) { + tcxstrprintf(log, "VANISH WHOLE COLLECTION ON $dropall\n"); + } + //write lock already acquired so use impl + count = jcoll->tdb->hdb->rnum; + if (!tctdbvanish(jcoll->tdb)) { + count = 0; + } + goto finish; + } + } + if (log) { tcxstrprintf(log, "RUN FULLSCAN\n"); } - uint64_t hdbiter; TCMAP *updkeys = (ejq->flags & EJQUPDATING) ? tcmapnew2(100 * 1024) : NULL; if (!tchdbiterinit4(hdb, &hdbiter)) { @@ -2557,7 +2580,7 @@ finish: } *outcount = count; if (log) { - tcxstrprintf(log, "RS COUNT: %d\n", count); + tcxstrprintf(log, "RS COUNT: %u\n", count); tcxstrprintf(log, "RS SIZE: %d\n", (res ? TCLISTNUM(res) : 0)); tcxstrprintf(log, "FINAL SORTING: %s\n", ((ejq->flags & EJQONLYCOUNT) || aofsz <= 0) ? "NO" : "YES"); } diff --git a/tcejdb/testejdb/t2.c b/tcejdb/testejdb/t2.c index 62c543c..e86712b 100644 --- a/tcejdb/testejdb/t2.c +++ b/tcejdb/testejdb/t2.c @@ -3762,6 +3762,53 @@ void test$upsert() { ejdbquerydel(q1); } +void testPrimitiveCases1() { + EJCOLL *coll = ejdbcreatecoll(jb, "abcd", NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(coll); + bson bsq1; + bson_init_as_query(&bsq1); + bson_finish(&bsq1); + CU_ASSERT_FALSE_FATAL(bsq1.err); + + EJQ *q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + uint32_t count = 0; + TCXSTR *log = tcxstrnew(); + ejdbqryexecute(coll, q1, &count, JBQRYCOUNT, log); + CU_ASSERT_EQUAL(count, 1); + //fprintf(stderr, "%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "SIMPLE COUNT(*): 1")); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "RS COUNT: 1")); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "RS SIZE: 0")); + + bson_destroy(&bsq1); + tcxstrdel(log); + ejdbquerydel(q1); + + //$dropall on whole collection + bson_init_as_query(&bsq1); + bson_append_bool(&bsq1, "$dropall", true); + bson_finish(&bsq1); + CU_ASSERT_FALSE_FATAL(bsq1.err); + + q1 = ejdbcreatequery(jb, &bsq1, NULL, 0, NULL); + CU_ASSERT_PTR_NOT_NULL_FATAL(q1); + count = 0; + log = tcxstrnew(); + ejdbqryexecute(coll, q1, &count, JBQRYCOUNT, log); + CU_ASSERT_EQUAL(count, 1); + //fprintf(stderr, "%s", TCXSTRPTR(log)); + CU_ASSERT_EQUAL(count, 1); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "VANISH WHOLE COLLECTION ON $dropall")); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "RS COUNT: 1")); + CU_ASSERT_PTR_NOT_NULL(strstr(TCXSTRPTR(log), "RS SIZE: 0")); + + bson_destroy(&bsq1); + tcxstrdel(log); + ejdbquerydel(q1); +} + int main() { setlocale(LC_ALL, "en_US.UTF-8"); @@ -3824,7 +3871,8 @@ int main() { (NULL == CU_add_test(pSuite, "testFindInComplexArray", testFindInComplexArray)) || (NULL == CU_add_test(pSuite, "test$elemMatch", test$elemMatch)) || (NULL == CU_add_test(pSuite, "testTicket16", testTicket16)) || - (NULL == CU_add_test(pSuite, "test$upsert", test$upsert)) + (NULL == CU_add_test(pSuite, "test$upsert", test$upsert)) || + (NULL == CU_add_test(pSuite, "testPrimitiveCases1", testPrimitiveCases1)) ) { CU_cleanup_registry(); return CU_get_error(); -- 2.7.4