Changeset: 3f12364cfdd1 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3f12364cfdd1 Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 clients/Tests/exports.stable.out gdk/gdk_bbp.c gdk/gdk_logger.c gdk/gdk_utils.c monetdb5/modules/atoms/mtime.c monetdb5/modules/atoms/mtime.h monetdb5/modules/atoms/mtime_analytic.c monetdb5/modules/atoms/mtime_private.h monetdb5/modules/kernel/alarm.mal monetdb5/modules/mal/clients.c monetdb5/modules/mal/oltp.c monetdb5/modules/mal/sysmon.c sql/backends/monet5/UDF/capi/capi.c sql/backends/monet5/generator/generator.c sql/backends/monet5/sql.c sql/backends/monet5/sql_bat2time.c sql/backends/monet5/sql_cast.c sql/backends/monet5/sql_datetrunc.c sql/backends/monet5/sql_result.c sql/server/sql_atom.c Branch: mtime Log Message:
Changed internal representation of the daytime and timestamp types. Daytime is now a 64 bit value that represents microseconds since the start of the day. Timestamp is a combination of the daytime and date types. diffs (truncated from 3821 to 300 lines): diff --git a/clients/Tests/MAL-signatures.stable.out b/clients/Tests/MAL-signatures.stable.out --- a/clients/Tests/MAL-signatures.stable.out +++ b/clients/Tests/MAL-signatures.stable.out @@ -521,10 +521,10 @@ stdout of test 'MAL-signatures` in direc [ "aggr", "variancep", "command aggr.variancep(b:bat[:sht], g:bat[:oid], e:bat[:any_1]):bat[:dbl] ", "AGGRvariancep3_dbl;", "Grouped tail variance (population/biased) on sht" ] [ "aggr", "variancep", "command aggr.variancep(b:bat[:any_2]):dbl ", "ALGvariancep;", "Gives the variance of all tail values" ] [ "alarm", "ctime", "unsafe command alarm.ctime():str ", "ALARMctime;", "Return the current time as a C-time string." ] -[ "alarm", "epoch", "unsafe command alarm.epoch():int ", "ALARMepoch;", "Return the current time as UNIX epoch." ] +[ "alarm", "epoch", "unsafe command alarm.epoch():int ", "ALARMepoch;", "Return time since Jan 1, 1970 in seconds." ] [ "alarm", "sleep", "unsafe command alarm.sleep(secs:int):void ", "ALARMsleep;", "Sleep a few seconds" ] -[ "alarm", "time", "unsafe command alarm.time():int ", "ALARMtime;", "Return time in milliseconds." ] -[ "alarm", "usec", "unsafe command alarm.usec():lng ", "ALARMusec;", "Return time in microseconds." ] +[ "alarm", "time", "unsafe command alarm.time():int ", "ALARMtime;", "Return time since program start in milliseconds." ] +[ "alarm", "usec", "unsafe command alarm.usec():lng ", "ALARMusec;", "Return time since Jan 1, 1970 in microseconds." ] [ "algebra", "antijoin", "function algebra.antijoin(l:bat[:any_1], r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]);", "", "" ] [ "algebra", "bandjoin", "command algebra.bandjoin(l:bat[:any_1], r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], c1:any_1, c2:any_1, li:bit, hi:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "Band join: values in l and r match if r - c1 <[=] l <[=] r + c2" ] [ "algebra", "copy", "command algebra.copy(b:bat[:any_1]):bat[:any_1] ", "ALGcopy;", "Returns physical copy of a BAT." ] diff --git a/clients/Tests/MAL-signatures.stable.out.int128 b/clients/Tests/MAL-signatures.stable.out.int128 --- a/clients/Tests/MAL-signatures.stable.out.int128 +++ b/clients/Tests/MAL-signatures.stable.out.int128 @@ -625,10 +625,10 @@ stdout of test 'MAL-signatures` in direc [ "aggr", "variancep", "command aggr.variancep(b:bat[:sht], g:bat[:oid], e:bat[:any_1]):bat[:dbl] ", "AGGRvariancep3_dbl;", "Grouped tail variance (population/biased) on sht" ] [ "aggr", "variancep", "command aggr.variancep(b:bat[:any_2]):dbl ", "ALGvariancep;", "Gives the variance of all tail values" ] [ "alarm", "ctime", "unsafe command alarm.ctime():str ", "ALARMctime;", "Return the current time as a C-time string." ] -[ "alarm", "epoch", "unsafe command alarm.epoch():int ", "ALARMepoch;", "Return the current time as UNIX epoch." ] +[ "alarm", "epoch", "unsafe command alarm.epoch():int ", "ALARMepoch;", "Return time since Jan 1, 1970 in seconds." ] [ "alarm", "sleep", "unsafe command alarm.sleep(secs:int):void ", "ALARMsleep;", "Sleep a few seconds" ] -[ "alarm", "time", "unsafe command alarm.time():int ", "ALARMtime;", "Return time in milliseconds." ] -[ "alarm", "usec", "unsafe command alarm.usec():lng ", "ALARMusec;", "Return time in microseconds." ] +[ "alarm", "time", "unsafe command alarm.time():int ", "ALARMtime;", "Return time since program start in milliseconds." ] +[ "alarm", "usec", "unsafe command alarm.usec():lng ", "ALARMusec;", "Return time since Jan 1, 1970 in microseconds." ] [ "algebra", "antijoin", "function algebra.antijoin(l:bat[:any_1], r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]);", "", "" ] [ "algebra", "bandjoin", "command algebra.bandjoin(l:bat[:any_1], r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], c1:any_1, c2:any_1, li:bit, hi:bit, estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "Band join: values in l and r match if r - c1 <[=] l <[=] r + c2" ] [ "algebra", "copy", "command algebra.copy(b:bat[:any_1]):bat[:any_1] ", "ALGcopy;", "Returns physical copy of a BAT." ] diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -1503,7 +1503,6 @@ str MTIMEdate_extract_quarter_bulk(bat * str MTIMEdate_extract_weekofyear(int *ret, const date *v); str MTIMEdate_extract_year(int *ret, const date *v); str MTIMEdate_extract_year_bulk(bat *ret, const bat *bid); -str MTIMEdate_extract_ymd(int *year, int *month, int *day, const date *v); str MTIMEdate_fromstr(date *ret, const char *const *s); str MTIMEdate_sub_msec_interval_lng_wrap(date *ret, const date *t, const lng *msec); str MTIMEdate_sub_sec_interval_wrap(date *ret, const date *t, const int *sec); @@ -1532,8 +1531,9 @@ str MTIMEepilogue(void *ret); str MTIMEepoch2int(int *res, const timestamp *ts); str MTIMEepoch2lng(lng *res, const timestamp *ts); str MTIMEepoch_bulk(bat *ret, bat *bid); -void MTIMEfromdate(date n, int *d, int *m, int *y); +void MTIMEfromdate(date n, int *y, int *m, int *d); void MTIMEfromtime(daytime n, int *hour, int *min, int *sec, int *msec); +void MTIMEfromtimestamp(timestamp t, int *Y, int *M, int *D, int *h, int *m, int *s, int *ms); str MTIMElocal_timezone(lng *res); str MTIMEmonth_from_str(int *ret, const char *const *month); str MTIMEmonth_to_str(str *ret, const int *month); @@ -1603,8 +1603,9 @@ str MTIMEtimestamp_to_str(str *s, const str MTIMEtimestamp_year(int *ret, const timestamp *t); str MTIMEtimestamplng(timestamp *ret, const lng *sec); str MTIMEtimezone(tzone *z, const char *const *name); -date MTIMEtodate(int day, int month, int year); +date MTIMEtodate(int year, int month, int day); daytime MTIMEtotime(int hour, int min, int sec, int msec); +timestamp MTIMEtotimestamp(int year, int month, int day, int hour, int min, int sec, int msec); str MTIMEtzone_create(tzone *ret, const int *minutes); str MTIMEtzone_create_dst(tzone *ret, const int *minutes, const rule *start, const rule *end); str MTIMEtzone_create_lng(tzone *ret, const lng *minutes); @@ -2674,7 +2675,6 @@ str thetaselectRef; str tidRef; str timestampRef; ssize_t timestamp_fromstr(const char *buf, size_t *len, timestamp **ret, bool external); -timestamp *timestamp_nil; ssize_t timestamp_tostr(str *buf, size_t *len, const timestamp *val, bool external); ssize_t timestamp_tz_fromstr(const char *buf, size_t *len, timestamp **ret, bool external); ssize_t timestamp_tz_tostr(str *buf, size_t *len, const timestamp *val, const tzone *timezone, bool external); diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c --- a/gdk/gdk_bbp.c +++ b/gdk/gdk_bbp.c @@ -617,6 +617,13 @@ leapyears(int year) #define DTMONTH_SHIFT (DTDAY_WIDTH+DTDAY_SHIFT) #define mkdate(d, m, y) (((((y) + YEAR_OFFSET) * 12 + (m) - 1) << DTMONTH_SHIFT) \ | ((d) << DTDAY_SHIFT)) +#define TSTIME_WIDTH 37 /* [0..24*60*60*1000000) */ +#define TSTIME_SHIFT 0 +#define TSDATE_WIDTH (DTDAY_WIDTH+DTMONTH_WIDTH) +#define TSDATE_SHIFT (TSTIME_SHIFT+TSTIME_WIDTH) +#define mktimestamp(d, t) ((lng) (((uint64_t) (d) << TSDATE_SHIFT) | \ + ((uint64_t) (t) << TSTIME_SHIFT))) + int cvtdate(int n) { @@ -710,7 +717,7 @@ fixdateheap(BAT *b, const char *anme) /* create new heap */ h2 = b->theap; stpconcat(h2.filename, nme, ".tail", NULL); - if (HEAPalloc(&h2, b->batCapacity, b->twidth) != GDK_SUCCEED) { + if (HEAPalloc(&h2, b->batCapacity, strcmp(anme, "date") == 0 ? 4 : 8) != GDK_SUCCEED) { GDKfree(srcdir); HEAPfree(&h1, false); GDKerror("fixdateheap: allocating new tail heap " @@ -733,7 +740,7 @@ fixdateheap(BAT *b, const char *anme) nofix = false; } } - } else { + } else if (strcmp(anme, "timestamp") == 0) { union timestamp { lng l; struct { @@ -747,14 +754,28 @@ fixdateheap(BAT *b, const char *anme) } t; }; const union timestamp *restrict o = (const union timestamp *) h1.base; - union timestamp *restrict n = (union timestamp *) h2.base; + lng *restrict n = (lng *) h2.base; for (i = 0; i < b->batCount; i++) { if (is_lng_nil(o[i].l)) { b->tnil = true; - n[i].l = lng_nil; + n[i] = lng_nil; } else { - n[i].t.p_days = cvtdate(o[i].t.p_days); - n[i].t.p_msecs = o[i].t.p_msecs; + n[i] = mktimestamp(cvtdate(o[i].t.p_days), + o[i].t.p_msecs * LL_CONSTANT(1000)); + nofix = false; + } + } + } else { + /* daytime */ + const int *restrict o = (const int *) h1.base; + lng *restrict n = (lng *) h2.base; + + for (i = 0; i < b->batCount; i++) { + if (is_int_nil(o[i])) { + b->tnil = true; + n[i] = lng_nil; + } else { + n[i] = o[i] * LL_CONSTANT(1000); nofix = false; } } diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -416,6 +416,27 @@ dateRead(void *dst, stream *s, size_t cn } static void * +daytimeRead(void *dst, stream *s, size_t cnt) +{ + int *ptr; + lng *lptr; + + if ((dst = BATatoms[TYPE_int].atomRead(dst, s, cnt)) == NULL) + return NULL; + ptr = dst; + lptr = dst; + /* work backwards so that we do this in place */ + for (size_t i = cnt; i > 0; ) { + i--; + if (is_int_nil(ptr[i])) + lptr[i] = lng_nil; + else + lptr[i] = ptr[i] * LL_CONSTANT(1000); + } + return dst; +} + +static void * timestampRead(void *dst, stream *s, size_t cnt) { union timestamp { @@ -518,7 +539,9 @@ log_read_updates(logger *lg, trans *tr, if (lg->convert_date && tt > TYPE_str) { if (strcmp(BATatoms[tt].name, "date") == 0) rt = dateRead; - if (strcmp(BATatoms[tt].name, "timestamp") == 0) + else if (strcmp(BATatoms[tt].name, "daytime") == 0) + rt = daytimeRead; + else if (strcmp(BATatoms[tt].name, "timestamp") == 0) rt = timestampRead; } #endif diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c --- a/gdk/gdk_utils.c +++ b/gdk/gdk_utils.c @@ -301,9 +301,12 @@ static ATOMIC_TYPE GDK_vm_cursize = ATOM size_t _MT_pagesize = 0; /* variable holding page size */ size_t _MT_npages = 0; /* variable holding memory size in pages */ +static lng programepoch; + void MT_init(void) { + programepoch = GDKusec(); #ifdef _MSC_VER { SYSTEM_INFO sysInfo; @@ -1238,63 +1241,37 @@ lng GDKusec(void) { /* Return the time in microseconds since an epoch. The epoch - * is roughly the time this program started. */ -#ifdef _MSC_VER - static LARGE_INTEGER freq, start; /* automatically initialized to 0 */ - LARGE_INTEGER ctr; - - if (start.QuadPart == 0 && - (!QueryPerformanceFrequency(&freq) || - !QueryPerformanceCounter(&start))) - start.QuadPart = -1; - if (start.QuadPart > 0) { - QueryPerformanceCounter(&ctr); - return (lng) (((ctr.QuadPart - start.QuadPart) * 1000000) / freq.QuadPart); - } -#endif -#ifdef HAVE_CLOCK_GETTIME -#if defined(CLOCK_UPTIME_FAST) -#define CLK_ID CLOCK_UPTIME_FAST /* FreeBSD */ + * is currently midnight at the start of January 1, 1970, UTC. */ +#if defined(NATIVE_WIN32) + FILETIME ft; + ULARGE_INTEGER f; + GetSystemTimeAsFileTime(&ft); /* time since Jan 1, 1601 */ + f.LowPart = ft.dwLowDateTime; + f.HighPart = ft.dwHighDateTime; + /* there are 369 years, of which 89 are leap years from + * January 1, 1601 to January 1, 1970 which makes 134774 days; + * multiply that with the number of seconds in a day and the + * number of 100ns units in a second; subtract that from the + * value for the current time since January 1, 1601 to get the + * time since the Unix epoch */ + f.QuadPart -= LL_CONSTANT(134774) * 24 * 60 * 60 * 10000000; + /* and convert to microseconds */ + return (lng) (f.QuadPart / 10); +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (lng) (ts.tv_sec * LL_CONSTANT(1000000) + ts.tv_nsec / 1000); +#elif defined(HAVE_GETTIMEOFDAY) + struct timeval tv; + gettimeofday(&tv, NULL); + return (lng) (tv.tv_sec * LL_CONSTANT(1000000) + tv.tv_usec); +#elif defined(HAVE_FTIME) + struct timeb tb; + ftime(&tb); + return (lng) (tb.time * LL_CONSTANT(1000000) + tb.millitm * LL_CONSTANT(1000)); #else -#define CLK_ID CLOCK_MONOTONIC /* Posix (fallback) */ -#endif - { - static struct timespec tsbase; - struct timespec ts; - if (tsbase.tv_sec == 0) { - clock_gettime(CLK_ID, &tsbase); - return tsbase.tv_nsec / 1000; - } - if (clock_gettime(CLK_ID, &ts) == 0) - return (ts.tv_sec - tsbase.tv_sec) * 1000000 + ts.tv_nsec / 1000; - } -#endif -#ifdef HAVE_GETTIMEOFDAY - { - static struct timeval tpbase; /* automatically initialized to 0 */ - struct timeval tp; - - if (tpbase.tv_sec == 0) { - gettimeofday(&tpbase, NULL); - return (lng) tpbase.tv_usec; - } - gettimeofday(&tp, NULL); - return (lng) (tp.tv_sec - tpbase.tv_sec) * 1000000 + (lng) tp.tv_usec; - } -#else -#ifdef HAVE_FTIME - { - static struct timeb tbbase; /* automatically initialized to 0 */ - struct timeb tb; - - if (tbbase.time == 0) { - ftime(&tbbase); - return (lng) tbbase.millitm * 1000; - } - ftime(&tb); - return (lng) (tb.time - tbbase.time) * 1000000 + (lng) tb.millitm * 1000; - } -#endif + /* last resort */ + return (lng) (time(NULL) * LL_CONSTANT(1000000)); #endif } @@ -1302,7 +1279,8 @@ GDKusec(void) int GDKms(void) { - return (int) (GDKusec() / 1000); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list