MonetDB: histograms - Merged with default
Changeset: c17178356505 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/c17178356505 Modified Files: gdk/gdk.h gdk/gdk_bat.c gdk/gdk_bbp.c sql/backends/monet5/sql.c Branch: histograms Log Message: Merged with default diffs (truncated from 2176 to 300 lines): diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -763,3 +763,4 @@ cab90a348501b045e19cee5cebcc44f3800bd0a8 5872f047d97c98d3a848514438b8f97fa446855d Jan2022_11 025239a5a6f122042798c0f1132a2c6298514e06 Jan2022_13 025239a5a6f122042798c0f1132a2c6298514e06 Jan2022_SP2_release +2e54857a91306cc6304825c5596f65d00595db6b Jul2021_23 diff --git a/buildtools/conf/Maddlog b/buildtools/conf/Maddlog --- a/buildtools/conf/Maddlog +++ b/buildtools/conf/Maddlog @@ -189,6 +189,9 @@ fi file=ChangeLog.$RANDOM +# make sure we get the correct day and month names +export LC_ALL=en_US.utf-8 + case "$CL" in */*) cd "${CL%/*}" diff --git a/clients/Tests/MAL-signatures-hge.test b/clients/Tests/MAL-signatures-hge.test --- a/clients/Tests/MAL-signatures-hge.test +++ b/clients/Tests/MAL-signatures-hge.test @@ -58194,11 +58194,6 @@ pattern capi.eval_aggr(X_0:ptr, X_1:bit, CUDFevalAggr; grouped aggregates through CUDF capi -prelude -command capi.prelude():void -CUDFprelude; -(empty) -capi subeval_aggr pattern capi.subeval_aggr(X_0:ptr, X_1:bit, X_2:str, X_3:any...):any... CUDFevalAggr; @@ -59784,11 +59779,6 @@ command geom.mbrRight(X_0:wkb, X_1:wkb): mbrRight_wkb; Returns true if the mbr of geom1 is right of the mbr of geom2 geom -prelude -command geom.prelude():void -geom_prelude; -(empty) -geom setSRID command geom.setSRID(X_0:wkb, X_1:int):wkb wkbSetSRID; @@ -59983,11 +59973,6 @@ identifier command identifier.identifier(X_0:str):identifier IDentifier; Cast a string to an identifer -identifier -prelude -command identifier.prelude():void -IDprelude; -Initialize the module inet != command inet.!=(X_0:inet, X_1:inet):bit @@ -60429,11 +60414,6 @@ command json.number(X_0:json):dbl JSONjson2number; Convert simple JSON values to a double, return nil upon error. json -prelude -command json.prelude():void -JSONprelude; -(empty) -json renderarray pattern json.renderarray(X_0:any...):json JSONrenderarray; @@ -60819,11 +60799,6 @@ command mapi.ping(X_0:int):int SERVERping; Test availability of an Mserver. mapi -prelude -command mapi.prelude():int -SERVERlisten_default; -(empty) -mapi prepare command mapi.prepare(X_0:int, X_1:str):int SERVERprepare; @@ -61319,11 +61294,6 @@ command mmath.pow(X_0:flt, X_1:flt):flt MATHbinary_POWflt; (empty) mmath -prelude -command mmath.prelude():void -MATHprelude; -initilize mmath module -mmath radians command mmath.radians(X_0:dbl):dbl MATHunary_RADIANSdbl; @@ -62039,11 +62009,6 @@ pattern optimizer.postfix(X_0:str, X_1:s OPTwrapper; Postfix the plan,e.g. pushing projections optimizer -prelude -pattern optimizer.prelude():void -optimizer_prelude; -Initialize the optimizer -optimizer profiler pattern optimizer.profiler():str OPTwrapper; @@ -62199,11 +62164,6 @@ command pcre.pcre_quote(X_0:str):str PCREquote; Return a PCRE pattern string that matches the argument exactly. pcre -prelude -command pcre.prelude():void -pcre_init; -Initialize pcre -pcre replace command pcre.replace(X_0:str, X_1:str, X_2:str, X_3:str):str PCREreplace_wrap; @@ -62334,11 +62294,6 @@ unsafe pattern pyapi3.eval_loader(X_0:pt PYAPI3PyAPIevalLoader; loader functions through Python pyapi3 -prelude -command pyapi3.prelude():void -PYAPI3PyAPIprelude; -(empty) -pyapi3 subeval_aggr unsafe pattern pyapi3.subeval_aggr(X_0:ptr, X_1:str, X_2:any...):any... PYAPI3PyAPIevalAggr; @@ -62424,11 +62379,6 @@ pattern rapi.eval_aggr(X_0:ptr, X_1:str, RAPIevalAggr; grouped aggregates through R rapi -prelude -command rapi.prelude():void -RAPIprelude; -(empty) -rapi subeval_aggr pattern rapi.subeval_aggr(X_0:ptr, X_1:str, X_2:any...):any... RAPIevalAggr; @@ -62519,11 +62469,6 @@ command remote.isalive(X_0:str):int RMTisalive; check if conn is still valid and connected remote -prelude -command remote.prelude():void -RMTprelude; -initialise the remote module -remote put pattern remote.put(X_0:str, X_1:any):str RMTput; @@ -64224,11 +64169,6 @@ command str.prefix(X_0:str, X_1:int):str STRprefix; Extract the prefix of a given length str -prelude -command str.prelude():void -STRprelude; -(empty) -str r_search command str.r_search(X_0:str, X_1:str):int STRReverseStrSearch; @@ -65474,11 +65414,6 @@ command xml.pi(X_0:str, X_1:str):xml XMLpi; Construct a processing instruction xml -prelude -command xml.prelude():void -XMLprelude; -(empty) -xml root command xml.root(X_0:xml, X_1:str, X_2:str):xml XMLroot; diff --git a/clients/Tests/MAL-signatures.test b/clients/Tests/MAL-signatures.test --- a/clients/Tests/MAL-signatures.test +++ b/clients/Tests/MAL-signatures.test @@ -41779,11 +41779,6 @@ pattern capi.eval_aggr(X_0:ptr, X_1:bit, CUDFevalAggr;
MonetDB: default - reenable test on windows
Changeset: a2c358590574 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/a2c358590574 Modified Files: sql/test/BugTracker-2021/Tests/All Branch: default Log Message: reenable test on windows diffs (12 lines): diff --git a/sql/test/BugTracker-2021/Tests/All b/sql/test/BugTracker-2021/Tests/All --- a/sql/test/BugTracker-2021/Tests/All +++ b/sql/test/BugTracker-2021/Tests/All @@ -7,7 +7,7 @@ union-groupby.Bug-7108 merge-stmt.wrong-error.Bug-7109 remote-table-groupby.Bug-7110 conditional-execution-round.Bug-7125 -NOT_WIN32?lowercase-cryllic.Bug-7126 +lowercase-cryllic.Bug-7126 unnest-union.Bug-7127 subquery-missing.Bug-7128 batcalc-between-undefined.Bug-7129 ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - Add condition variables to gdk_system
Changeset: 6d90febdc9bc for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6d90febdc9bc Modified Files: gdk/gdk_system.c gdk/gdk_system.h Branch: default Log Message: Add condition variables to gdk_system diffs (172 lines): diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c --- a/gdk/gdk_system.c +++ b/gdk/gdk_system.c @@ -177,6 +177,8 @@ GDKlockstatistics(int what) #endif /* LOCK_STATS */ +static void MT_thread_setcondwait(MT_Cond *cond); + #if !defined(HAVE_PTHREAD_H) && defined(WIN32) static struct winthread { struct winthread *next; @@ -186,6 +188,7 @@ static struct winthread { void *data; MT_Lock *lockwait; /* lock we're waiting for */ MT_Sema *semawait; /* semaphore we're waiting for */ + MT_Cond *condwait; /* condition variable we're waiting for */ struct winthread *joinwait; /* process we are joining with */ const char *working;/* what we're currently doing */ char algorithm[512];/* the algorithm used in the last operation */ @@ -213,6 +216,7 @@ dump_threads(void) w->threadname, w->lockwait ? w->lockwait->name : w->semawait ? w->semawait->name : + w->condwait ? w->condwait->name : w->joinwait ? w->joinwait->threadname : "nothing", ATOMIC_GET(&w->exited) ? "exiting" : @@ -328,6 +332,17 @@ MT_thread_setsemawait(MT_Sema *sema) w->semawait = sema; } +static void +MT_thread_setcondwait(MT_Cond *cond) +{ + if (threadslot == TLS_OUT_OF_INDEXES) + return; + struct winthread *w = TlsGetValue(threadslot); + + if (w) + w->condwait = cond; +} + void MT_thread_setworking(const char *work) { @@ -591,6 +606,7 @@ static struct posthread { void *data; MT_Lock *lockwait; /* lock we're waiting for */ MT_Sema *semawait; /* semaphore we're waiting for */ + MT_Cond *condwait; /* condition variable we're waiting for */ struct posthread *joinwait; /* process we are joining with */ const char *working;/* what we're currently doing */ char algorithm[512];/* the algorithm used in the last operation */ @@ -623,6 +639,7 @@ dump_threads(void) p->threadname, p->lockwait ? p->lockwait->name : p->semawait ? p->semawait->name : + p->condwait ? p->condwait->name : p->joinwait ? p->joinwait->threadname : "nothing", ATOMIC_GET(&p->exited) ? "exiting" : @@ -738,6 +755,17 @@ MT_thread_setsemawait(MT_Sema *sema) } void +MT_thread_setcondwait(MT_Cond *cond) +{ + if (!thread_initialized) + return; + struct posthread *p = pthread_getspecific(threadkey); + + if (p) + p->condwait = cond; +} + +void MT_thread_setworking(const char *work) { if (!thread_initialized) @@ -1108,3 +1136,57 @@ MT_check_nr_cores(void) return ncpus; } + + +void +MT_cond_init(MT_Cond *cond) +{ +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + InitializeConditionVariable(&cond->cv); +#else + pthread_cond_init(&cond->cv, NULL); +#endif +} + + +void +MT_cond_destroy(MT_Cond *cond) +{ +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + /* no need */ +#else + pthread_cond_destroy(&cond->cv); +#endif +} + +void +MT_cond_wait(MT_Cond *cond, MT_Lock *lock) +{ + MT_thread_setcondwait(cond); +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + SleepConditionVariableCS(&cond->cv, &lock->lock); +#else + pthread_cond_wait(&cond->cv, &lock->lock); +#endif + MT_thread_setcondwait(NULL); +} + +void +MT_cond_signal(MT_Cond *cond) +{ +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + WakeConditionVariable(&cond->cv); +#else + pthread_cond_signal(&cond->cv); +#endif +} + +void +MT_cond_broadcast(MT_Cond *cond) +{ +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + WakeAllConditionVariable(&cond->cv); +#else + pthread_cond_broadcast(&cond->cv); +#endif +} diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h --- a/gdk/gdk_system.h +++ b/gdk/gdk_system.h @@ -710,4 +710,30 @@ gdk_export const char *MT_thread_getalgo gdk_export int MT_check_nr_cores(void); +/* + * @ Condition Variable API + */ + +typedef struct MT_Cond { +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) + CONDITION_VARIABLE cv; +#else + pthread_cond_t cv; +#endif + char name[MT_NAME_LEN]; +} MT_Cond; + +#if !defined(HAVE_PTHREAD_H) && defined(WIN32) +# define MT_COND_INITIALIZ
MonetDB: default - Add tests for the condition variables
Changeset: 6ba526d1d91c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/6ba526d1d91c Added Files: clients/Tests/testcondvar.py clients/examples/C/testcondvar.c Modified Files: MonetDB.spec clients/Tests/All clients/examples/C/CMakeLists.txt Branch: default Log Message: Add tests for the condition variables diffs (262 lines): diff --git a/MonetDB.spec b/MonetDB.spec --- a/MonetDB.spec +++ b/MonetDB.spec @@ -365,6 +365,7 @@ developer. %{_bindir}/smack00 %{_bindir}/smack01 %{_bindir}/streamcat +%{_bindir}/testcondvar %{_bindir}/testgetinfo %{_bindir}/testStmtAttr %{_bindir}/malsample.pl diff --git a/clients/Tests/All b/clients/Tests/All --- a/clients/Tests/All +++ b/clients/Tests/All @@ -3,3 +3,4 @@ HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&H !HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&HAVE_LIBPY3&HAVE_NETCDF&HAVE_SHP&NOT_WIN32?MAL-signatures NOT_WIN32&MERCURIAL?melcheck mclient-uri +testcondvar diff --git a/clients/Tests/testcondvar.py b/clients/Tests/testcondvar.py new file mode 100644 --- /dev/null +++ b/clients/Tests/testcondvar.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +try: +subprocess.check_output("testcondvar", stderr=subprocess.STDOUT) +except subprocess.CalledProcessError as e: +output = str(e.stdout, 'utf-8') +if not output.endswith('\n'): +output += '\n' +print(f"Test program failed with the following output:\n--", file=sys.stderr) +print(f"{output}-", file=sys.stderr) +sys.exit('TEST FAILED') diff --git a/clients/examples/C/CMakeLists.txt b/clients/examples/C/CMakeLists.txt --- a/clients/examples/C/CMakeLists.txt +++ b/clients/examples/C/CMakeLists.txt @@ -45,6 +45,16 @@ if(TESTING) monetdb_config_header stream) + add_executable(testcondvar +testcondvar.c) + + target_link_libraries(testcondvar +PRIVATE +monetdb_config_header +bat +Threads::Threads + ) + add_executable(bincopydata bincopydata.c bincopydata.h @@ -75,6 +85,7 @@ if(TESTING) smack00 smack01 streamcat +testcondvar bincopydata RUNTIME DESTINATION @@ -89,6 +100,7 @@ if(TESTING) $ $ $ + $ $ $ DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/clients/examples/C/testcondvar.c b/clients/examples/C/testcondvar.c new file mode 100644 --- /dev/null +++ b/clients/examples/C/testcondvar.c @@ -0,0 +1,183 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V. + */ + +#include "monetdb_config.h" +#include "gdk.h" +#include "gdk_system.h" + +#include + +#define NN (3) + +volatile int timeout = 100; // set this to 0 during interactive debugging + +/* global state protected by a lock: */ + +MT_Lock lock = MT_LOCK_INITIALIZER(the_lock); +MT_Cond condvar = MT_COND_INITIALIZER(the_condvar); +struct state { + MT_Id id; + int ticks; + int permits; + bool terminate; + bool terminated; +} states[NN] = { {0} }; + + +static void +let_run(void) +{ + MT_lock_unset(&lock); + + MT_sleep_ms(100); + + int attempts = 0; + while (!MT_lock_try(&lock)) { + if (timeout > 0 && ++attempts > timeout) { + fprintf(stderr, "Can't get hold of the lock after %d attempts\n", attempts); + abort(); + } + MT_sleep_ms(10); + } + + fprintf(stderr, "\n"); +} + + +static void +worker(void *arg) +{ + struct state *st = arg; + int id = (int)(st - &states[0]); + fprintf(stderr, "worker %d starting\n", id); + + MT_lock_set(&lock); + while (1) { + if (st->terminate) { + fprintf(stderr, "worker %d terminating\n", id); + break; + } + if (st->permits > 0) { + fprintf(stderr, "worker %d ticking\n", id); + st->ticks++; + st->permits--; + } + fprintf(stderr, "worker %d waiting\n", id); + MT_cond_wait(&condvar, &lock); + fprintf(stderr, "worker %d woke up\n", id); + } + st->terminated = true; + MT_lock_unset(&lock); +} + + +static void clear(void) +{ + for (int i = 0; i < NN; i++) { + struct state *st = &states[i]; + st->permits = 0; + st->ticks = 0; + } +} + + +static void +check_impl(int line, int expected_sum_ticks, int expected_max_ticks, int expected_sum_permits) +{ + int sum_ticks = 0; + int max_ticks = -1; + int sum_permits = 0; + + for (int i = 0; i < NN; i++) { + sum_permits += states[i].permits; + in
MonetDB: histograms - Use right type to print histogram
Changeset: 0220c3612bba for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/0220c3612bba Modified Files: gdk/gdk_histogram.c Branch: histograms Log Message: Use right type to print histogram diffs (30 lines): diff --git a/gdk/gdk_histogram.c b/gdk/gdk_histogram.c --- a/gdk/gdk_histogram.c +++ b/gdk/gdk_histogram.c @@ -431,7 +431,7 @@ HISTOGRAMcreate(BAT *b) #define histogram_print_loop(TPE) \ do { \ - ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[TYPE_##TPE].atomToStr; \ + ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[ptype].atomToStr; \ const HistogramBucket_##TPE *restrict hist = (HistogramBucket_##TPE *) b->thistogram->histogram; \ for (int i = 0 ; i < nbuckets ; i++) { \ const HistogramBucket_##TPE *restrict hb = &(hist[i]); \ @@ -465,7 +465,7 @@ HISTOGRAMprint(BAT *b) { size_t len = 0, rlen = 2048, minlen = 256, maxlen = 256; str res = NULL, minbuf = NULL, maxbuf = NULL; - int tpe = ATOMbasetype(b->ttype), nbuckets; + int tpe = ATOMbasetype(b->ttype), nbuckets, ptype = b->ttype; if (VIEWtparent(b)) /* don't look on views */ b = BBP_cache(VIEWtparent(b)); @@ -488,6 +488,8 @@ HISTOGRAMprint(BAT *b) len = sprintf(res, "Total entries: %d, buckets: %d\n", b->thistogram->size, b->thistogram->nbuckets); len += sprintf(res + len, "nulls -> %d\n", b->thistogram->nulls); + if (tpe == TYPE_str) /* strings use integer size buckets */ + ptype = TYPE_int; nbuckets = b->thistogram->nbuckets; switch (tpe) { case TYPE_bte: ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - Minor changes to get condition variables to c...
Changeset: f8170070186b for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/f8170070186b Modified Files: clients/examples/C/testcondvar.c gdk/gdk_system.c Branch: default Log Message: Minor changes to get condition variables to compile on Windows. diffs (24 lines): diff --git a/clients/examples/C/testcondvar.c b/clients/examples/C/testcondvar.c --- a/clients/examples/C/testcondvar.c +++ b/clients/examples/C/testcondvar.c @@ -18,7 +18,7 @@ volatile int timeout = 100; // set this /* global state protected by a lock: */ -MT_Lock lock = MT_LOCK_INITIALIZER(the_lock); +MT_Lock lock = MT_LOCK_INITIALIZER(lock); MT_Cond condvar = MT_COND_INITIALIZER(the_condvar); struct state { MT_Id id; diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c --- a/gdk/gdk_system.c +++ b/gdk/gdk_system.c @@ -1164,7 +1164,7 @@ MT_cond_wait(MT_Cond *cond, MT_Lock *loc { MT_thread_setcondwait(cond); #if !defined(HAVE_PTHREAD_H) && defined(WIN32) - SleepConditionVariableCS(&cond->cv, &lock->lock); + SleepConditionVariableCS(&cond->cv, &lock->lock, INFINITE); #else pthread_cond_wait(&cond->cv, &lock->lock); #endif ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: Jan2022 - Updated some comments.
Changeset: 5a2dd25c1de7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/5a2dd25c1de7 Modified Files: gdk/gdk_aggr.c Branch: Jan2022 Log Message: Updated some comments. diffs (44 lines): diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -1820,7 +1820,17 @@ BATprod(void *res, int tp, BAT *b, BAT * } \ } while (0) -/* calculate group averages with optional candidates list */ +/* There are three functions that are used for calculating averages. + * The first one (BATgroupavg) returns averages as a floating point + * value, the other two (BATgroupavg3 and BATgroupavg3combine) work + * together to return averages in the domain type (which should be an + * integer type). */ + +/* Calculate group averages with optional candidates list. The average + * that is calculated is returned in a dbl, independent of the type of + * the input. The average is calculated exactly, so not in a floating + * point which could potentially losse bits during processing + * (e.g. average of 2**62 and a billion 1's). */ gdk_return BATgroupavg(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT *s, int tp, bool skip_nils, bool abort_on_error, int scale) { @@ -2014,13 +2024,14 @@ BATgroupavg(BAT **bnp, BAT **cntsp, BAT return GDK_FAIL; } -/* An exact numeric average of a bunch of values consists of three parts: the - * average rounded down (towards minus infinity), the number of values that - * participated in the calculation, and the remainder. The remainder is in the - * range 0 (inclusive) to count (not inclusive). BATgroupavg3 calculates these - * values for each given group. The function below, BATgroupavg3combine, - * combines averages calculated this way to correct, rounded or truncated - * towards zero (depending on the symbol TRUNCATE_NUMBERS) averages. */ +/* An exact numeric average of a bunch of values consists of three + * parts: the average rounded down (towards minus infinity), the number + * of values that participated in the calculation, and the remainder. + * The remainder is in the range 0 (inclusive) to count (not inclusive). + * BATgroupavg3 calculates these values for each given group. The + * function below, BATgroupavg3combine, combines averages calculated + * this way to correct averages by rounding or truncating towards zero + * (depending on the symbol TRUNCATE_NUMBERS). */ gdk_return BATgroupavg3(BAT **avgp, BAT **remp, BAT **cntp, BAT *b, BAT *g, BAT *e, BAT *s, bool skip_nils) { ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: histograms - Extract variable from macro
Changeset: b11a3e64fa29 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/b11a3e64fa29 Modified Files: gdk/gdk_histogram.c Branch: histograms Log Message: Extract variable from macro diffs (19 lines): diff --git a/gdk/gdk_histogram.c b/gdk/gdk_histogram.c --- a/gdk/gdk_histogram.c +++ b/gdk/gdk_histogram.c @@ -431,7 +431,6 @@ HISTOGRAMcreate(BAT *b) #define histogram_print_loop(TPE) \ do { \ - ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[ptype].atomToStr; \ const HistogramBucket_##TPE *restrict hist = (HistogramBucket_##TPE *) b->thistogram->histogram; \ for (int i = 0 ; i < nbuckets ; i++) { \ const HistogramBucket_##TPE *restrict hb = &(hist[i]); \ @@ -490,6 +489,7 @@ HISTOGRAMprint(BAT *b) if (tpe == TYPE_str) /* strings use integer size buckets */ ptype = TYPE_int; + ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[ptype].atomToStr; nbuckets = b->thistogram->nbuckets; switch (tpe) { case TYPE_bte: ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: userprofile - fix post merge issues
Changeset: a3eb8da7135f for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/a3eb8da7135f Modified Files: sql/backends/monet5/sql_user.c Branch: userprofile Log Message: fix post merge issues diffs (69 lines): diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c --- a/sql/backends/monet5/sql_user.c +++ b/sql/backends/monet5/sql_user.c @@ -63,6 +63,7 @@ monet5_drop_user(ptr _mvc, str user) #define outside_str 1 #define inside_str 2 #define default_schema_path "\"sys\"" /* "sys" will be the default schema path */ +#define default_optimizer "default_pipe" static str parse_schema_path_str(mvc *m, str schema_path, bool build) /* this function for both building and validating the schema path */ @@ -152,11 +153,12 @@ monet5_create_user(ptr _mvc, str user, s sql_table *db_user_info = find_sql_table(m->session->tr, s, "db_user_info"), *auths = find_sql_table(m->session->tr, s, "auths"); Client c = MCgetClient(m->clientid); sqlstore *store = m->session->tr->store; - const char *opt = optimizer ? optimizer : (char*)str_nil; int log_res = 0; if (!schema_path) schema_path = default_schema_path; + if (!optimizer) + optimizer = default_optimizer; if ((ret = parse_schema_path_str(m, schema_path, false)) != MAL_SUCCEED) return ret; @@ -168,7 +170,7 @@ monet5_create_user(ptr _mvc, str user, s } user_id = store_next_oid(m->session->tr->store); - if ((log_res = store->table_api.table_insert(m->session->tr, db_user_info, &user, &fullname, &schema_id, &schema_path))) { + if ((log_res = store->table_api.table_insert(m->session->tr, db_user_info, &user, &fullname, &schema_id, &schema_path, &max_memory, &max_workers, &wlc, &optimizer))) { if (!enc) free(pwd); throw(SQL, "sql.create_user", SQLSTATE(42000) "Create user failed%s", log_res == LOG_CONFLICT ? " due to conflict with another transaction" : ""); @@ -186,16 +188,7 @@ monet5_create_user(ptr _mvc, str user, s c->user = grant_user; if (!enc) free(pwd); - if (ret != MAL_SUCCEED) - return ret; - - user_id = store_next_oid(m->session->tr->store); - db_user_info = find_sql_table(m->session->tr, s, "db_user_info"); - auths = find_sql_table(m->session->tr, s, "auths"); - store->table_api.table_insert(m->session->tr, db_user_info, &user, &fullname, &schema_id, &schema_path, &max_memory, - &max_workers, &wlc, &opt); - store->table_api.table_insert(m->session->tr, auths, &user_id, &user, &grantorid); - return NULL; + return ret; } static int @@ -342,14 +335,10 @@ monet5_create_privileges(ptr _mvc, sql_s char *username = "monetdb"; char *fullname = "MonetDB Admin"; char *schema_path = default_schema_path; - store->table_api.table_insert(m->session->tr, uinfo, &username, &fullname, &schema_id, &schema_path); - lng max_memory = 0; - int max_workers = 0; - bool wlc = true; char *optimizer = "default_pipe"; - store->table_api.table_insert(m->session->tr, uinfo, &username, &fullname, &schema_id, &schema_path, &max_memory, &max_workers, - &wlc, &optimizer); + store->table_api.table_insert(m->session->tr, uinfo, &username, &fullname, &schema_id, &schema_path, &lng_nil, &int_nil, + &bte_nil, &optimizer); } static int ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: userprofile - fix default values
Changeset: feb9e75a212c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/feb9e75a212c Modified Files: sql/backends/monet5/sql_user.c Branch: userprofile Log Message: fix default values diffs (22 lines): diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c --- a/sql/backends/monet5/sql_user.c +++ b/sql/backends/monet5/sql_user.c @@ -335,10 +335,15 @@ monet5_create_privileges(ptr _mvc, sql_s char *username = "monetdb"; char *fullname = "MonetDB Admin"; char *schema_path = default_schema_path; - char *optimizer = "default_pipe"; + // default values + char *optimizer = default_optimizer; + lng max_memory = 0; + int max_workers = 0; + bool wlc = true; - store->table_api.table_insert(m->session->tr, uinfo, &username, &fullname, &schema_id, &schema_path, &lng_nil, &int_nil, - &bte_nil, &optimizer); + + store->table_api.table_insert(m->session->tr, uinfo, &username, &fullname, &schema_id, &schema_path, &max_memory, &max_workers, + &wlc, &optimizer); } static int ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: properties - For a grouping column, compute number of p...
Changeset: d9ec566d2152 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/d9ec566d2152 Modified Files: sql/server/rel_statistics.c Branch: properties Log Message: For a grouping column, compute number of possible groups/rows using (max-min+1) for numeric types. Then compute the result with MIN((max-min+1),nuniques) diffs (85 lines): diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c --- a/sql/server/rel_statistics.c +++ b/sql/server/rel_statistics.c @@ -616,7 +616,7 @@ trivial_project_exp_card(sql_exp *e) } static BUN -rel_calc_nuniques(sql_rel *l, list *exps) +rel_calc_nuniques(mvc *sql, sql_rel *l, list *exps) { BUN lv = get_rel_count(l); @@ -629,14 +629,28 @@ rel_calc_nuniques(sql_rel *l, list *exps sql_exp *e = n->data; sql_rel *bt = NULL; prop *p = NULL; + BUN euniques = BUN_NONE; + atom *min, *max, *sub = NULL; + sql_subtype *tp = exp_subtype(e); + sql_class ec = tp ? tp->type->eclass : EC_STRING; /* if 'e' has no type (eg parameter), use a non-number type to fail condition */ if ((p = find_prop(e->p, PROP_NUNIQUES))) { - nuniques = MAX(nuniques, (BUN) p->value.dval); + euniques = (BUN) p->value.dval; } else if (e->type == e_column && rel_find_exp_and_corresponding_rel(l, e, false, &bt, NULL) && bt && (p = find_prop(bt->p, PROP_COUNT))) { - nuniques = MAX(nuniques, p->value.lval); - } else { + euniques = (BUN) p->value.lval; + } + /* use min to max range to compute number of possible values in the domain for number types */ + if ((EC_TEMP(ec)||ec==EC_NUM||ec==EC_MONTH||ec==EC_POS) && + (min = find_prop_and_get(e->p, PROP_MIN)) && (max = find_prop_and_get(e->p, PROP_MAX))) { + /* the range includes min and max, so the atom_inc call is needed */ + /* if 'euniques' has number of distinct values, compute min between both */ + if ((sub = atom_sub(sql->sa, max, min)) && (sub = atom_inc(sql->sa, sub)) && (sub = atom_cast(sql->sa, sub, sql_bind_localtype("oid" + euniques = MIN(euniques, (BUN) sub->data.val.oval); + } + if (euniques != BUN_NONE) + nuniques = MAX(nuniques, euniques); /* the highest cardinality sets the estimation */ + else nuniques = BUN_NONE; - } } if (nuniques != BUN_NONE) return nuniques; @@ -699,8 +713,8 @@ rel_get_statistics_(visitor *v, sql_rel /* propagate row count */ if (is_union(rel->op)) { - BUN lv = need_distinct(rel) ? rel_calc_nuniques(l, l->exps) : get_rel_count(l), - rv = need_distinct(rel) ? rel_calc_nuniques(r, r->exps) : get_rel_count(r); + BUN lv = need_distinct(rel) ? rel_calc_nuniques(v->sql, l, l->exps) : get_rel_count(l), + rv = need_distinct(rel) ? rel_calc_nuniques(v->sql, r, r->exps) : get_rel_count(r); if (lv == 0 && rv == 0) { /* both sides empty */ if (can_be_pruned) @@ -717,8 +731,8 @@ rel_get_statistics_(visitor *v, sql_rel set_count_prop(v->sql->sa, rel, (rv > (BUN_MAX - lv)) ? BUN_MAX : (lv + rv)); /* overflow check */ } } else if (is_inter(rel->op) || is_except(rel->op)) { - BUN lv = need_distinct(rel) ? rel_calc_nuniques(l, l->exps) : get_rel_count(l), - rv = need_distinct(rel) ? rel_calc_nuniques(r, r->exps) : get_rel_count(r); + BUN lv = need_distinct(rel) ? rel_calc_nuniques(v->sql, l, l->exps) : get_rel_count(l), + rv = need_distinct(rel) ? rel_calc_nuniques(v->sql, r, r->exps) : get_rel_count(r); if (lv == 0) { /* left side empty */ if (can_be_pruned) @@ -855,7 +869,7 @@ rel_get_statistics_(visitor *v, sql_rel case op_project: { if (l) { if (need_distinct(rel)) { - set_count_prop(v->sql->sa, rel, rel_calc_nuniques(l, rel->exps)); + set_count_prop(v->sql->sa, rel, rel_calc_nuniques(v->sql, l, rel->exps));
MonetDB: properties - Merged with default
Changeset: 99c9270bd729 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/99c9270bd729 Branch: properties Log Message: Merged with default diffs (truncated from 446 to 300 lines): diff --git a/MonetDB.spec b/MonetDB.spec --- a/MonetDB.spec +++ b/MonetDB.spec @@ -365,6 +365,7 @@ developer. %{_bindir}/smack00 %{_bindir}/smack01 %{_bindir}/streamcat +%{_bindir}/testcondvar %{_bindir}/testgetinfo %{_bindir}/testStmtAttr %{_bindir}/malsample.pl diff --git a/clients/Tests/All b/clients/Tests/All --- a/clients/Tests/All +++ b/clients/Tests/All @@ -3,3 +3,4 @@ HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&H !HAVE_HGE&HAVE_FITS&HAVE_GEOM&HAVE_LIBR&HAVE_LIBPY3&HAVE_NETCDF&HAVE_SHP&NOT_WIN32?MAL-signatures NOT_WIN32&MERCURIAL?melcheck mclient-uri +testcondvar diff --git a/clients/Tests/testcondvar.py b/clients/Tests/testcondvar.py new file mode 100644 --- /dev/null +++ b/clients/Tests/testcondvar.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +import subprocess +import sys + +try: +subprocess.check_output("testcondvar", stderr=subprocess.STDOUT) +except subprocess.CalledProcessError as e: +output = str(e.stdout, 'utf-8') +if not output.endswith('\n'): +output += '\n' +print(f"Test program failed with the following output:\n--", file=sys.stderr) +print(f"{output}-", file=sys.stderr) +sys.exit('TEST FAILED') diff --git a/clients/examples/C/CMakeLists.txt b/clients/examples/C/CMakeLists.txt --- a/clients/examples/C/CMakeLists.txt +++ b/clients/examples/C/CMakeLists.txt @@ -45,6 +45,16 @@ if(TESTING) monetdb_config_header stream) + add_executable(testcondvar +testcondvar.c) + + target_link_libraries(testcondvar +PRIVATE +monetdb_config_header +bat +Threads::Threads + ) + add_executable(bincopydata bincopydata.c bincopydata.h @@ -75,6 +85,7 @@ if(TESTING) smack00 smack01 streamcat +testcondvar bincopydata RUNTIME DESTINATION @@ -89,6 +100,7 @@ if(TESTING) $ $ $ + $ $ $ DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/clients/examples/C/testcondvar.c b/clients/examples/C/testcondvar.c new file mode 100644 --- /dev/null +++ b/clients/examples/C/testcondvar.c @@ -0,0 +1,183 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 1997 - July 2008 CWI, August 2008 - 2022 MonetDB B.V. + */ + +#include "monetdb_config.h" +#include "gdk.h" +#include "gdk_system.h" + +#include + +#define NN (3) + +volatile int timeout = 100; // set this to 0 during interactive debugging + +/* global state protected by a lock: */ + +MT_Lock lock = MT_LOCK_INITIALIZER(lock); +MT_Cond condvar = MT_COND_INITIALIZER(the_condvar); +struct state { + MT_Id id; + int ticks; + int permits; + bool terminate; + bool terminated; +} states[NN] = { {0} }; + + +static void +let_run(void) +{ + MT_lock_unset(&lock); + + MT_sleep_ms(100); + + int attempts = 0; + while (!MT_lock_try(&lock)) { + if (timeout > 0 && ++attempts > timeout) { + fprintf(stderr, "Can't get hold of the lock after %d attempts\n", attempts); + abort(); + } + MT_sleep_ms(10); + } + + fprintf(stderr, "\n"); +} + + +static void +worker(void *arg) +{ + struct state *st = arg; + int id = (int)(st - &states[0]); + fprintf(stderr, "worker %d starting\n", id); + + MT_lock_set(&lock); + while (1) { + if (st->terminate) { + fprintf(stderr, "worker %d terminating\n", id); + break; + } + if (st->permits > 0) { + fprintf(stderr, "worker %d ticking\n", id); + st->ticks++; + st->permits--; + } + fprintf(stderr, "worker %d waiting\n", id); + MT_cond_wait(&condvar, &lock); + fprintf(stderr, "worker %d woke up\n", id); + } + st->terminated = true; + MT_lock_unset(&lock); +} + + +static void clear(void) +{ + for (int i = 0; i < NN; i++) { + struct state *st = &states[i]; + st->permits = 0; + st->ticks = 0; + } +} + + +static void +check_impl(int line, int expected_sum_ticks, int expected_max_ticks, int expected_sum_permits) +{ + int sum_ticks = 0; + int max_ticks = -1; + int sum_permits = 0; + + for (int i = 0; i < NN; i++) { + sum_permits += states[i].permits; + int ticks = states[i].ticks; + sum_ticks += ticks; + if (ticks > max_ticks) + max_ticks = ticks; + } + + bool good = true; + go
MonetDB: default - Remove dead code.
Changeset: 5a5efa0feea2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/5a5efa0feea2 Modified Files: gdk/gdk_logger.c gdk/gdk_logger_internals.h Branch: default Log Message: Remove dead code. diffs (73 lines): diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -2367,12 +2367,6 @@ log_constant(logger *lg, int type, ptr v gdk_return ok = GDK_SUCCEED; logformat l; lng nr; - int is_row = 0; - - if (lg->row_insert_nrcols != 0) { - lg->row_insert_nrcols--; - is_row = 1; - } l.flag = LOG_UPDATE_CONST; l.id = id; nr = cnt; @@ -2389,12 +2383,10 @@ log_constant(logger *lg, int type, ptr v gdk_return (*wt) (const void *, stream *, size_t) = BATatoms[type].atomWrite; - if (is_row) - l.flag = tpe; if (log_write_format(lg, &l) != GDK_SUCCEED || - (!is_row && !mnstr_writeLng(lg->output_log, nr)) || - (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || - (!is_row && !mnstr_writeLng(lg->output_log, offset))) { + !mnstr_writeLng(lg->output_log, nr) || + mnstr_write(lg->output_log, &tpe, 1, 1) != 1 || + !mnstr_writeLng(lg->output_log, offset)) { (void) ATOMIC_DEC(&lg->refcount); ok = GDK_FAIL; goto bailout; @@ -2467,12 +2459,6 @@ internal_log_bat(logger *lg, BAT *b, log logformat l; BUN p; lng nr; - int is_row = 0; - - if (lg->row_insert_nrcols != 0) { - lg->row_insert_nrcols--; - is_row = 1; - } l.flag = LOG_UPDATE_BULK; l.id = id; nr = cnt; @@ -2487,12 +2473,10 @@ internal_log_bat(logger *lg, BAT *b, log gdk_return (*wt) (const void *, stream *, size_t) = BATatoms[b->ttype].atomWrite; - if (is_row) - l.flag = tpe; if (log_write_format(lg, &l) != GDK_SUCCEED || - (!is_row && !mnstr_writeLng(lg->output_log, nr)) || - (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || - (!is_row && !mnstr_writeLng(lg->output_log, offset))) { + !mnstr_writeLng(lg->output_log, nr) || + mnstr_write(lg->output_log, &tpe, 1, 1) != 1 || + !mnstr_writeLng(lg->output_log, offset)) { ok = GDK_FAIL; goto bailout; } diff --git a/gdk/gdk_logger_internals.h b/gdk/gdk_logger_internals.h --- a/gdk/gdk_logger_internals.h +++ b/gdk/gdk_logger_internals.h @@ -32,8 +32,6 @@ struct logger { logged_range *pending; logged_range *current; - int row_insert_nrcols; /* nrcols == 0 no rowinsert, log_update will include the logformat */ - bool inmemory; char *fn; char *dir; ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: pax-log - New branch pax-log.
Changeset: 18d094e0878d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/18d094e0878d Branch: pax-log Log Message: New branch pax-log. ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: pax-log - Introduce segmented internal_log_bat
Changeset: 5a1dd85be2ae for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/5a1dd85be2ae Modified Files: gdk/gdk_logger.c gdk/gdk_logger.h gdk/gdk_logger_internals.h sql/storage/bat/bat_storage.c Branch: pax-log Log Message: Introduce segmented internal_log_bat diffs (241 lines): diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -2460,7 +2460,7 @@ string_writer(logger *lg, BAT *b, lng of } static gdk_return -internal_log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, int sliced) +internal_log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, int sliced, lng total_cnt) { bte tpe = find_type(lg, b->ttype); gdk_return ok = GDK_SUCCEED; @@ -2489,13 +2489,18 @@ internal_log_bat(logger *lg, BAT *b, log if (is_row) l.flag = tpe; - if (log_write_format(lg, &l) != GDK_SUCCEED || - (!is_row && !mnstr_writeLng(lg->output_log, nr)) || - (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || - (!is_row && !mnstr_writeLng(lg->output_log, offset))) { - ok = GDK_FAIL; - goto bailout; - } + if (lg->total_cnt == 0) // signals single bulk message or first part of bat logged in parts + if (log_write_format(lg, &l) != GDK_SUCCEED || + (!is_row && !mnstr_writeLng(lg->output_log, total_cnt)) || + (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || + (!is_row && !mnstr_writeLng(lg->output_log, offset))) { + ok = GDK_FAIL; + goto bailout; + } + lg->total_cnt += cnt; + + if (lg->total_cnt == total_cnt) // This is the last to be logged part of this bat, we can already reset the total_cnt + lg->total_cnt = 0; /* if offset is just for the log, but BAT is already sliced, reset offset */ if (sliced) @@ -2581,7 +2586,7 @@ log_bat_persists(logger *lg, BAT *b, log lg->end++; if (lg->debug & 1) fprintf(stderr, "#persists id (%d) bat (%d)\n", id, b->batCacheid); - gdk_return r = internal_log_bat(lg, b, id, 0, BATcount(b), 0); + gdk_return r = internal_log_bat(lg, b, id, 0, BATcount(b), 0, BATcount(b)); logger_unlock(lg); if (r != GDK_SUCCEED) (void) ATOMIC_DEC(&lg->refcount); @@ -2619,10 +2624,10 @@ log_bat_transient(logger *lg, log_id id) } gdk_return -log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt) +log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, lng total_cnt) { logger_lock(lg); - gdk_return r = internal_log_bat(lg, b, id, offset, cnt, 0); + gdk_return r = internal_log_bat(lg, b, id, offset, cnt, 0, total_cnt); logger_unlock(lg); return r; } @@ -2638,7 +2643,7 @@ log_delta(logger *lg, BAT *uid, BAT *uva lng nr; if (BATtdense(uid)) { - ok = internal_log_bat(lg, uval, id, uid->tseqbase, BATcount(uval), 1); + ok = internal_log_bat(lg, uval, id, uid->tseqbase, BATcount(uval), 1, BATcount(uval)); logger_unlock(lg); if (!LOG_DISABLED(lg) && ok != GDK_SUCCEED) (void) ATOMIC_DEC(&lg->refcount); diff --git a/gdk/gdk_logger.h b/gdk/gdk_logger.h --- a/gdk/gdk_logger.h +++ b/gdk/gdk_logger.h @@ -57,7 +57,7 @@ gdk_export int logger_sequence(logger *l /* todo pass the transaction id */ gdk_export gdk_return log_constant(logger *lg, int type, ptr val, log_id id, lng offset, lng cnt); -gdk_export gdk_return log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt); /* log slice from b */ +gdk_export gdk_return log_bat(logger *lg, BAT *b, log_id id, lng offset, lng cnt, lng total_cnt); /* log slice from b */ gdk_export gdk_return log_bat_clear(logger *lg, log_id id); gdk_export gdk_return log_bat_persists(logger *lg, BAT *b, log_id id); gdk_export gdk_return log_bat_transient(logger *lg, log_id id); diff --git a/gdk/gdk_logger_internals.h b/gdk/gdk_logger_internals.h --- a/gdk/gdk_logger_internals.h +++ b/gdk/gdk_logger_internals.h @@ -34,6 +34,8 @@ struct logger { int row_insert_nrcols; /* nrcols == 0 no rowinsert, log_update will include the logformat */ + lng total_cnt; /* When logging the content of a bats in multiple runs, total_cnt is used the very first to signal this and keep track in the logging*/ + bool inmemory; char *fn; char *dir; diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c --- a/sql/storage/bat/bat_storage.c +++ b/sql/storage/bat/bat_storage.c @@ -3361,15 +3361,22 @@ log_segment(sql_trans *tr, segment *s, s } static int -log_segments(sql_trans *tr, segments *segs, sqlid id) +log_segments(sql_trans *tr, segments *segs, sqlid id, size_t* nr_appends) { /* log segments */ + s
MonetDB: Jan2022 - Don't push up selections on non-outer sides
Changeset: edbd77694605 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/edbd77694605 Modified Files: sql/server/rel_optimizer.c sql/test/SQLancer/Tests/sqlancer08.test Branch: Jan2022 Log Message: Don't push up selections on non-outer sides diffs (64 lines): diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -4708,10 +4708,10 @@ point_select_on_unique_column(sql_rel *r static sql_rel * rel_push_select_up(visitor *v, sql_rel *rel) { - if ((is_join(rel->op) || is_semi(rel->op)) && !rel_is_ref(rel) && !is_single(rel)) { + if ((is_innerjoin(rel->op) || is_left(rel->op) || is_right(rel->op) || is_semi(rel->op)) && !is_single(rel)) { sql_rel *l = rel->l, *r = rel->r; - bool can_pushup_left = is_select(l->op) && !rel_is_ref(l) && !is_single(l), -can_pushup_right = is_select(r->op) && !rel_is_ref(r) && !is_single(r) && !is_semi(rel->op); + bool can_pushup_left = is_select(l->op) && !rel_is_ref(l) && !is_single(l) && (is_innerjoin(rel->op) || is_left(rel->op) || is_semi(rel->op)), +can_pushup_right = is_select(r->op) && !rel_is_ref(r) && !is_single(r) && (is_innerjoin(rel->op) || is_right(rel->op)); if (can_pushup_left || can_pushup_right) { if (can_pushup_left) diff --git a/sql/test/SQLancer/Tests/sqlancer08.test b/sql/test/SQLancer/Tests/sqlancer08.test --- a/sql/test/SQLancer/Tests/sqlancer08.test +++ b/sql/test/SQLancer/Tests/sqlancer08.test @@ -430,3 +430,43 @@ ROLLBACK statement error 22003!overflow in conversion of 789092170 to bte. SELECT round(- (((-443710828)||(1616633099))), 789092170) +statement ok +START TRANSACTION + +statement ok +CREATE TABLE "rt0" ("c0" BOOLEAN,"c1" BOOLEAN NOT NULL, CONSTRAINT "rt0_c1_pkey" PRIMARY KEY ("c1")) + +statement ok rowcount 2 +INSERT INTO "rt0" VALUES (NULL, false), (false, true) + +query I nosort +SELECT rt0.c1 FROM rt0 FULL OUTER JOIN (VALUES (1)) x(x) ON TRUE AND 'a' = 'b' WHERE rt0.c1 + +1 + +query I nosort +SELECT rt0.c1 FROM rt0 RIGHT OUTER JOIN (VALUES (1)) x(x) ON TRUE AND 'a' = 'b' WHERE rt0.c1 + + +query I nosort +SELECT rt0.c1 FROM rt0 LEFT OUTER JOIN (VALUES (1)) x(x) ON TRUE AND 'a' = 'b' WHERE rt0.c1 + +1 + +query I nosort +SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST(rt0.c1 AS INT) as count FROM rt0 FULL OUTER JOIN (VALUES (1)) AS nort0(norc0) ON TRUE AND 'a' = 'b') as res + +1 + +query I nosort +SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST(rt0.c1 AS INT) as count FROM rt0 RIGHT OUTER JOIN (VALUES (1)) AS nort0(norc0) ON TRUE AND 'a' = 'b') as res + +NULL + +query I nosort +SELECT CAST(SUM(count) AS BIGINT) FROM (SELECT CAST(rt0.c1 AS INT) as count FROM rt0 LEFT OUTER JOIN (VALUES (1)) AS nort0(norc0) ON TRUE AND 'a' = 'b') as res + +1 + +statement ok +ROLLBACK ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - Merged with Jan2022
Changeset: 9440025edd3d for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9440025edd3d Modified Files: gdk/gdk_aggr.c sql/server/rel_optimize_sel.c sql/server/rel_optimizer.c sql/test/SQLancer/Tests/sqlancer08.test Branch: default Log Message: Merged with Jan2022 diffs (115 lines): diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -1815,7 +1815,17 @@ BATprod(void *res, int tp, BAT *b, BAT * } \ } while (0) -/* calculate group averages with optional candidates list */ +/* There are three functions that are used for calculating averages. + * The first one (BATgroupavg) returns averages as a floating point + * value, the other two (BATgroupavg3 and BATgroupavg3combine) work + * together to return averages in the domain type (which should be an + * integer type). */ + +/* Calculate group averages with optional candidates list. The average + * that is calculated is returned in a dbl, independent of the type of + * the input. The average is calculated exactly, so not in a floating + * point which could potentially losse bits during processing + * (e.g. average of 2**62 and a billion 1's). */ gdk_return BATgroupavg(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT *s, int tp, bool skip_nils, bool abort_on_error, int scale) { @@ -2008,13 +2018,14 @@ BATgroupavg(BAT **bnp, BAT **cntsp, BAT return GDK_FAIL; } -/* An exact numeric average of a bunch of values consists of three parts: the - * average rounded down (towards minus infinity), the number of values that - * participated in the calculation, and the remainder. The remainder is in the - * range 0 (inclusive) to count (not inclusive). BATgroupavg3 calculates these - * values for each given group. The function below, BATgroupavg3combine, - * combines averages calculated this way to correct, rounded or truncated - * towards zero (depending on the symbol TRUNCATE_NUMBERS) averages. */ +/* An exact numeric average of a bunch of values consists of three + * parts: the average rounded down (towards minus infinity), the number + * of values that participated in the calculation, and the remainder. + * The remainder is in the range 0 (inclusive) to count (not inclusive). + * BATgroupavg3 calculates these values for each given group. The + * function below, BATgroupavg3combine, combines averages calculated + * this way to correct averages by rounding or truncating towards zero + * (depending on the symbol TRUNCATE_NUMBERS). */ gdk_return BATgroupavg3(BAT **avgp, BAT **remp, BAT **cntp, BAT *b, BAT *g, BAT *e, BAT *s, bool skip_nils) { diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c --- a/sql/server/rel_optimize_sel.c +++ b/sql/server/rel_optimize_sel.c @@ -3835,10 +3835,10 @@ point_select_on_unique_column(sql_rel *r static sql_rel * rel_push_select_up_(visitor *v, sql_rel *rel) { - if ((is_join(rel->op) || is_semi(rel->op)) && !is_single(rel)) { + if ((is_innerjoin(rel->op) || is_left(rel->op) || is_right(rel->op) || is_semi(rel->op)) && !is_single(rel)) { sql_rel *l = rel->l, *r = rel->r; - bool can_pushup_left = is_select(l->op) && !rel_is_ref(l) && !is_single(l), -can_pushup_right = is_select(r->op) && !rel_is_ref(r) && !is_single(r) && !is_semi(rel->op); + bool can_pushup_left = is_select(l->op) && !rel_is_ref(l) && !is_single(l) && (is_innerjoin(rel->op) || is_left(rel->op) || is_semi(rel->op)), +can_pushup_right = is_select(r->op) && !rel_is_ref(r) && !is_single(r) && (is_innerjoin(rel->op) || is_right(rel->op)); if (can_pushup_left || can_pushup_right) { if (can_pushup_left) @@ -3877,5 +3877,5 @@ bind_push_select_up(visitor *v, global_p { int flag = v->sql->sql_optimizer; return gp->opt_level == 1 && gp->cnt[op_select] && (gp->cnt[op_join] || gp->cnt[op_left] || - gp->cnt[op_right] || gp->cnt[op_full] || gp->cnt[op_semi] || gp->cnt[op_anti]) && (flag & push_select_up) ? rel_push_select_up : NULL; + gp->cnt[op_right] || gp->cnt[op_semi] || gp->cnt[op_anti]) && (flag & push_select_up) ? rel_push_select_up : NULL; } diff --git a/sql/test/SQLancer/Tests/sqlancer08.test b/sql/test/SQLancer/Tests/sqlancer08.test --- a/sql/test/SQLancer/Tests/sqlancer08.test +++ b/sql/test/SQLancer/Tests/sqlancer08.test @@ -423,3 +423,43 @@ ROLLBACK statement error 22003!overflow in conversion of 789092170 to bte. SELECT round(- (((-443710828)||(1616633099))), 789092170) +statement ok +START TRANSACTION + +statement ok +CREATE TABLE "rt0" ("c0" BOOLEAN,"c1" BOOLEAN NOT NULL, CONSTRAINT "rt0_c1_pkey" PRIMARY KEY ("c1")) + +statement ok rowcount 2 +INSERT INTO "rt0" VALUES (NULL, false), (false, true) + +query I nosort +SELECT rt0.c1 FROM rt0 FULL OUTER JOIN (VALUE
MonetDB: properties - Merged with default
Changeset: 44168b1c3565 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/44168b1c3565 Modified Files: sql/server/rel_optimize_sel.c sql/server/rel_optimizer.c sql/server/rel_statistics.c Branch: properties Log Message: Merged with default diffs (181 lines): diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c --- a/gdk/gdk_aggr.c +++ b/gdk/gdk_aggr.c @@ -1815,7 +1815,17 @@ BATprod(void *res, int tp, BAT *b, BAT * } \ } while (0) -/* calculate group averages with optional candidates list */ +/* There are three functions that are used for calculating averages. + * The first one (BATgroupavg) returns averages as a floating point + * value, the other two (BATgroupavg3 and BATgroupavg3combine) work + * together to return averages in the domain type (which should be an + * integer type). */ + +/* Calculate group averages with optional candidates list. The average + * that is calculated is returned in a dbl, independent of the type of + * the input. The average is calculated exactly, so not in a floating + * point which could potentially losse bits during processing + * (e.g. average of 2**62 and a billion 1's). */ gdk_return BATgroupavg(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT *s, int tp, bool skip_nils, bool abort_on_error, int scale) { @@ -2008,13 +2018,14 @@ BATgroupavg(BAT **bnp, BAT **cntsp, BAT return GDK_FAIL; } -/* An exact numeric average of a bunch of values consists of three parts: the - * average rounded down (towards minus infinity), the number of values that - * participated in the calculation, and the remainder. The remainder is in the - * range 0 (inclusive) to count (not inclusive). BATgroupavg3 calculates these - * values for each given group. The function below, BATgroupavg3combine, - * combines averages calculated this way to correct, rounded or truncated - * towards zero (depending on the symbol TRUNCATE_NUMBERS) averages. */ +/* An exact numeric average of a bunch of values consists of three + * parts: the average rounded down (towards minus infinity), the number + * of values that participated in the calculation, and the remainder. + * The remainder is in the range 0 (inclusive) to count (not inclusive). + * BATgroupavg3 calculates these values for each given group. The + * function below, BATgroupavg3combine, combines averages calculated + * this way to correct averages by rounding or truncating towards zero + * (depending on the symbol TRUNCATE_NUMBERS). */ gdk_return BATgroupavg3(BAT **avgp, BAT **remp, BAT **cntp, BAT *b, BAT *g, BAT *e, BAT *s, bool skip_nils) { diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -2367,12 +2367,6 @@ log_constant(logger *lg, int type, ptr v gdk_return ok = GDK_SUCCEED; logformat l; lng nr; - int is_row = 0; - - if (lg->row_insert_nrcols != 0) { - lg->row_insert_nrcols--; - is_row = 1; - } l.flag = LOG_UPDATE_CONST; l.id = id; nr = cnt; @@ -2389,12 +2383,10 @@ log_constant(logger *lg, int type, ptr v gdk_return (*wt) (const void *, stream *, size_t) = BATatoms[type].atomWrite; - if (is_row) - l.flag = tpe; if (log_write_format(lg, &l) != GDK_SUCCEED || - (!is_row && !mnstr_writeLng(lg->output_log, nr)) || - (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || - (!is_row && !mnstr_writeLng(lg->output_log, offset))) { + !mnstr_writeLng(lg->output_log, nr) || + mnstr_write(lg->output_log, &tpe, 1, 1) != 1 || + !mnstr_writeLng(lg->output_log, offset)) { (void) ATOMIC_DEC(&lg->refcount); ok = GDK_FAIL; goto bailout; @@ -2467,12 +2459,6 @@ internal_log_bat(logger *lg, BAT *b, log logformat l; BUN p; lng nr; - int is_row = 0; - - if (lg->row_insert_nrcols != 0) { - lg->row_insert_nrcols--; - is_row = 1; - } l.flag = LOG_UPDATE_BULK; l.id = id; nr = cnt; @@ -2487,12 +2473,10 @@ internal_log_bat(logger *lg, BAT *b, log gdk_return (*wt) (const void *, stream *, size_t) = BATatoms[b->ttype].atomWrite; - if (is_row) - l.flag = tpe; if (log_write_format(lg, &l) != GDK_SUCCEED || - (!is_row && !mnstr_writeLng(lg->output_log, nr)) || - (!is_row && mnstr_write(lg->output_log, &tpe, 1, 1) != 1) || - (!is_row && !mnstr_writeLng(lg->output_log, offset))) { + !mnstr_writeLng(lg->output_log, nr) || + mnstr_write(lg->output_log, &tpe, 1, 1) != 1 || + !mnstr_writeLng(lg->output_log, offset)) { ok = GDK_FAIL; goto bailout; } diff --git a/gdk/gdk_logger_internals.h b/gdk/gdk_logger_internals.h --- a/gdk/gdk_logger_
MonetDB: properties - Propagate relation counts on remote/replic...
Changeset: 1612d4ada618 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1612d4ada618 Modified Files: sql/server/rel_distribute.c Branch: properties Log Message: Propagate relation counts on remote/replica table rewrites diffs (36 lines): diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c --- a/sql/server/rel_distribute.c +++ b/sql/server/rel_distribute.c @@ -10,6 +10,7 @@ #include "rel_optimizer_private.h" #include "rel_basetable.h" #include "rel_exp.h" +#include "rel_rewriter.h" #include "sql_privileges.h" static int @@ -68,6 +69,7 @@ rewrite_replica(mvc *sql, list *exps, sq node *n, *m; sql_rel *r = rel_basetable(sql, p, t->base.name); int allowed = 1; + sqlstore *store = sql->session->tr->store; if (!table_privs(sql, p, PRIV_SELECT)) /* Test for privileges */ allowed = 0; @@ -98,6 +100,8 @@ rewrite_replica(mvc *sql, list *exps, sq exp_prop_alias(sql->sa, ne, e); } list_hash_clear(r->exps); /* the child table may have different column names, so clear the hash */ + if (isTable(p) && p->s && !isDeclaredTable(p)) /* count active rows only */ + set_count_prop(sql->sa, r, (BUN)store->storage_api.count_col(sql->session->tr, ol_first_node(p->columns)->data, 10)); /* set_remote() */ if (remote_prop && p && isRemote(p)) { @@ -372,6 +376,7 @@ rel_remote_func_(visitor *v, sql_rel *re if (find_prop(rel->p, PROP_REMOTE) != NULL) { list *exps = rel_projections(v->sql, rel, NULL, 1, 1); rel = rel_relational_func(v->sql->sa, rel, exps); + set_count_prop(v->sql->sa, rel, get_rel_count(rel->l)); } return rel; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: properties - Better solution. Run remote/replica rewrit...
Changeset: 93d6c5bdeaa0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/93d6c5bdeaa0 Modified Files: sql/server/rel_distribute.c sql/server/rel_optimizer.c sql/server/rel_statistics.c Branch: properties Log Message: Better solution. Run remote/replica rewriters before statistics diffs (86 lines): diff --git a/sql/server/rel_distribute.c b/sql/server/rel_distribute.c --- a/sql/server/rel_distribute.c +++ b/sql/server/rel_distribute.c @@ -10,7 +10,6 @@ #include "rel_optimizer_private.h" #include "rel_basetable.h" #include "rel_exp.h" -#include "rel_rewriter.h" #include "sql_privileges.h" static int @@ -69,7 +68,6 @@ rewrite_replica(mvc *sql, list *exps, sq node *n, *m; sql_rel *r = rel_basetable(sql, p, t->base.name); int allowed = 1; - sqlstore *store = sql->session->tr->store; if (!table_privs(sql, p, PRIV_SELECT)) /* Test for privileges */ allowed = 0; @@ -100,8 +98,6 @@ rewrite_replica(mvc *sql, list *exps, sq exp_prop_alias(sql->sa, ne, e); } list_hash_clear(r->exps); /* the child table may have different column names, so clear the hash */ - if (isTable(p) && p->s && !isDeclaredTable(p)) /* count active rows only */ - set_count_prop(sql->sa, r, (BUN)store->storage_api.count_col(sql->session->tr, ol_first_node(p->columns)->data, 10)); /* set_remote() */ if (remote_prop && p && isRemote(p)) { @@ -376,7 +372,6 @@ rel_remote_func_(visitor *v, sql_rel *re if (find_prop(rel->p, PROP_REMOTE) != NULL) { list *exps = rel_projections(v->sql, rel, NULL, 1, 1); rel = rel_relational_func(v->sql->sa, rel, exps); - set_count_prop(v->sql->sa, rel, get_rel_count(rel->l)); } return rel; } diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c --- a/sql/server/rel_optimizer.c +++ b/sql/server/rel_optimizer.c @@ -656,14 +656,14 @@ const sql_optimizer pre_sql_optimizers[] /* these optimizers/rewriters only run once after the cycle loop */ const sql_optimizer post_sql_optimizers[] = { {22, "setjoins_2_joingroupby", bind_setjoins_2_joingroupby}, - {23, "get_statistics", bind_get_statistics}, /* gather statistics */ - {24, "join_order2", bind_join_order2}, /* run join order one more time with statistics */ - {25, "final_optimization_loop", bind_final_optimization_loop}, /* run select and group by order with statistics gathered */ /* Merge table rewrites may introduce remote or replica tables */ - /* At the moment, make sure the remote table rewriters always run last */ - {26, "rewrite_remote", bind_rewrite_remote}, - {27, "rewrite_replica", bind_rewrite_replica}, - {28, "remote_func", bind_remote_func}, + /* At the moment, make sure the remote table rewriters always run after the merge table one */ + {23, "rewrite_remote", bind_rewrite_remote}, + {24, "rewrite_replica", bind_rewrite_replica}, + {25, "remote_func", bind_remote_func}, + {26, "get_statistics", bind_get_statistics}, /* gather statistics */ + {27, "join_order2", bind_join_order2}, /* run join order one more time with statistics */ + {28, "final_optimization_loop", bind_final_optimization_loop}, /* run select and group by order with statistics gathered */ { 0, NULL, NULL} /* If an optimizer is going to be added, don't forget to update NSQLREWRITERS macro */ }; diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c --- a/sql/server/rel_statistics.c +++ b/sql/server/rel_statistics.c @@ -679,7 +679,7 @@ rel_get_statistics_(visitor *v, sql_rel for (node *n = rel->exps->h ; n ; n = n->next) rel_basetable_column_get_statistics(v->sql, rel, n->data); } - /* Set table row count. TODO? look for remote/replica tables. Don't look at storage for declared tables, because it won't be cleaned */ + /* Set table row count. TODO? look for remote tables. Don't look at storage for declared tables, because it won't be cleaned */ if (isTable(t) && t->s && !isDeclaredTable(t)) /* count active rows only */ set_count_prop(v->sql->sa, rel, (BUN)store->storage_api.count_col(v->sql->session->tr, ol_first_node(t->columns)->data, 10)); } break; @@ -692,10 +692,10 @@ rel_get_statistics_(visitor *v, sql_rel while (is_sample(pl->op) || is_topn(pl->op)) /* skip topN and sample relations in the middle */ pl = pl->l; - while (is_sample(r->op) || is_topn(pr->op)) + while (is_sample(pr->op) || is_topn(pr->op)) pr = pr->l; /* if it's not a projection, then project and propagate statistics */ - if (!is_project(pl->op) && !is_base(l->o
MonetDB: default - Simplify function signature.
Changeset: dc7411906a33 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/dc7411906a33 Modified Files: sql/storage/bat/bat_storage.c Branch: default Log Message: Simplify function signature. diffs (30 lines): diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c --- a/sql/storage/bat/bat_storage.c +++ b/sql/storage/bat/bat_storage.c @@ -3907,7 +3907,7 @@ log_table_append(sql_trans *tr, sql_tabl } static int -log_storage(sql_trans *tr, sql_table *t, storage *s, sqlid id) +log_storage(sql_trans *tr, sql_table *t, storage *s) { int ok = LOG_OK, cleared = s->cs.cleared; if (ok == LOG_OK && cleared) @@ -3915,7 +3915,7 @@ log_storage(sql_trans *tr, sql_table *t, if (ok == LOG_OK) ok = segments2cs(tr, s->segs, &s->cs); if (ok == LOG_OK) - ok = log_segments(tr, s->segs, id); + ok = log_segments(tr, s->segs, t->base.id); if (ok == LOG_OK && !cleared) ok = log_table_append(tr, t, s->segs); return ok; @@ -4244,7 +4244,7 @@ log_update_del( sql_trans *tr, sql_chang sql_table *t = (sql_table*)change->obj; if (!isTempTable(t) && !tr->parent) /* don't write save point commits */ - return log_storage(tr, t, ATOMIC_PTR_GET(&t->data), t->base.id); + return log_storage(tr, t, ATOMIC_PTR_GET(&t->data)); return LOG_OK; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org
MonetDB: default - Deduplicate code a bit.
Changeset: 354fc17b25b0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/354fc17b25b0 Modified Files: sql/storage/bat/bat_storage.c Branch: default Log Message: Deduplicate code a bit. diffs (82 lines): diff --git a/sql/storage/bat/bat_storage.c b/sql/storage/bat/bat_storage.c --- a/sql/storage/bat/bat_storage.c +++ b/sql/storage/bat/bat_storage.c @@ -328,55 +328,30 @@ segments2cs(sql_trans *tr, segments *seg size_t pos = s->start; dst = (uint32_t *) Tloc(b, 0) + (pos/32); uint32_t cur = 0; - if (s->deleted) { - size_t used = pos&31, end = 32; - if (used) { - if (lnr < (32-used)) - end = used + lnr; - assert(end > used); - cur |= ((1U << (end - used)) - 1) << used; - lnr -= end - used; - *dst++ |= cur; - cur = 0; - } - size_t full = lnr/32; - size_t rest = lnr%32; - if (full > 0) { - memset(dst, ~0, full * sizeof(*dst)); - dst += full; - lnr -= full * 32; - } - if (rest > 0) { - cur |= (1U << rest) - 1; - lnr -= rest; - *dst |= cur; - } - assert(lnr==0); - } else { - size_t used = pos&31, end = 32; - if (used) { - if (lnr < (32-used)) - end = used + lnr; - assert(end > used); - cur |= ((1U << (end - used)) - 1) << used; - lnr -= end - used; - *dst++ &= ~cur; - cur = 0; - } - size_t full = lnr/32; - size_t rest = lnr%32; - if (full > 0) { - memset(dst, 0, full * sizeof(*dst)); - dst += full; - lnr -= full * 32; - } - if (rest > 0) { - cur |= (1U << rest) - 1; - lnr -= rest; - *dst &= ~cur; - } - assert(lnr==0); + size_t used = pos&31, end = 32; + if (used) { + if (lnr < (32-used)) + end = used + lnr; + assert(end > used); + cur |= ((1U << (end - used)) - 1) << used; + lnr -= end - used; + *dst = s->deleted ? *dst | cur : *dst & ~cur; + dst++; + cur = 0; } + size_t full = lnr/32; + size_t rest = lnr%32; + if (full > 0) { + memset(dst, s->deleted?~0:0, full * sizeof(*dst)); + dst += full; + lnr -= full * 32; + } + if (rest > 0) { + cur |= (1U << rest) - 1; + lnr -= rest; + *dst = s->deleted ? *dst | cur : *dst & ~cur; + } + assert(lnr==0); if (cnt < s->end) cnt = s->end; } ___ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org